Android Architecture Components: Room の Migration で IllegalStateException

データを移行せずに捨ててしまうのなら、以下でいいのですが。


Room.databaseBuilder(context, RepoDatabase.class, DB_NAME)
    .fallbackToDestructiveMigration()
    .build();

きっと捨てることができませんよね。

テーブル定義を変更しながら、データを移行しますよね。


Room.databaseBuilder(context, RepoDatabase.class, DB_NAME)
    .addMigrations(FROM_1_TO_2)
    .build();

static final Migration FROM_1_TO_2 = new Migration(1, 2) {
    @Override
    public void migrate(final SupportSQLiteDatabase database) {
        database.execSQL("ALTER TABLE Repo
                         ADD COLUMN createdAt TEXT");
        }
    };

database.execSQL()でSQLをベタに実行しながらデータを別テーブルにRENAME後、CREATE→INSERT→DROP というかんじでスキーマを変更していますが。

すると、こんなのに遭遇します。

java.lang.IllegalStateException: Room cannot verify the data integrity. Looks like you’ve changed schema but forgot to update the version number. You can simply fix this by increasing the version number.

データベースのバージョンナンバーは上げることは、まあ上げるとして、それでもインデクスなどうまく意図通りに移行できてない場合があります。

データモデルにアノテーションで記述した「Room が利用しようとしているスキーマ」と、Migration部分にベタ記述した「SQLiteのスキーマ」が合致しないといけません。

また、最近のAndroidでは、.dbファイルが、OS上で取り回しづらく、実態を把握しづらかったりします。

Roomが認識しようとしているテーブルスキーマは以下で書き出すことができます。


android {
    javaCompileOptions {
        annotationProcessorOptions {
            arguments = ["room.schemaLocation":
                         "$projectDir/schemas".toString()]
            }
        }
    }
}


"tableName": "Repo",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` INTEGER NOT NULL, `name` TEXT, `url` TEXT, PRIMARY KEY(`id`))"

モデルクラスに記述したアノテーションのRoomが認識している状態(expected)をSQLで書き出してくれます。

これと、MIGRATION部分のベタSQL(found)を比較すると、意味が分かってきます。

複数フィールドに対してのUNIQUE なインデクスなど、公式ドキュメントとは違う内部的絶賛更新中な処理な部分など、書き出してみると先に進むことができます。


プレインストールアプリを削除する

ずっと、Nexus/Pixelシリーズの、素のAndroid OS を使ってきましたが、 今回、ドコモ版のGalaxy S8を周回遅れで購入しましたが、使わないベンダーやキャリアのアプリが頻繁に通知を送ってきます。

後付なおせっかい機能です。

Androidの煩わしさの原因に見えたりします。

以下、自己責任の不具合覚悟の方のみ。

OS OTAアップデート当たらないかもしれません。 キャリア依存。


// パッケージ名のリストをみる。
adb shell pm list packages -s

無効化できないアプリは、もう強制的に消してしまいます。


// パッケージを強制的に消す
adb shell pm uninstall -k --user 0 com.nttdocomo.android.applicationmanager

adb shell pm uninstall -k --user 0 com.nttdocomo.android.dhome

adb shell pm uninstall -k --user 0 com.nttdocomo.android.store

adb shell pm uninstall -k --user 0 jp.co.nttdocomo.lcsapp

adb shell pm uninstall -k --user 0 com.nttdocomo.android.voiceeditor (ドコモ文字編集)

adb shell pm uninstall -k --user 0 com.sec.android.inputmethod.iwnnime.japan

素のAndroid(Nexus/Pixelシリーズ)では表示されてた「パッケージ名」は、それ以外の端末では、表示できないようにされています。

ので、アンインストールしたい「アプリ名」が分かっていても、「パッケージ名」との紐づけができず困ったりします。

adb badge を使ってやるのも面倒なので、簡単にアプリ内から、「アプリ名」-「パッケージ名」のリストを見ましょう。


inline fun Context.listPackages() {
  val packages = packageManager
      .getInstalledApplications(PackageManager.GET_META_DATA)
      .sortedBy { it.packageName }

  packages.forEach {
    println(
        "%s %s %s".format(
            it.packageName,
            it.loadLabel(packageManager),
            it.uid
        )
    )
  }
}

OSアップデートや国内独自機能(NFC/トルカ?)など不具合が起こり始めるのだろうが、それを差し引いても快適で。

格安の素のAndroidを国内キャリアはなぜ出さないのかが謎。

Androidに関しては「付加価値を」とか「他社と違い」てなフレーズを使ったビジネスするしか?

いまどきのAndroid端末ってアプリのパッケージ名見れないのですか?
Package Info - Apps on Google Play


Android 端末 キーボード切り替え方法あれこれ

 

なんとなくやっているけどイライラすることありません?

 

[準備] キーボードの有効化/無効化

プレインストールアプリなどいくつかのキーボードアプリがインストールされていると思います。

端末の設定から、インストールしたキーボードアプリを「有効化」しておけばキーボード入力中に素早く簡単に切り替えられるようになります。


「設定」

  ↓

「一般管理」

  ↓

「言語とキーボード」

  ↓

「オンスクリーンキーボード」

  ↓

「キーボードを管理」

使わないキーボードアプリはOFFにして「無効化」しておくと選択時に煩わしくありません。

ここをきちんと設定しておくことで、切り替えの動作がわかりやすくなりますので大事な設定です。

 

A. Android機能の「キーボード(切り替え)ボタン」を使う

Androidの機能なので、キーボードアプリにかかわらず入力中に切り替えができます。

Android機能の「キーボード(切り替え)ボタン」を使う

Android機能の「キーボード(切り替え)ボタン」を使う

 

B. キーボード上でスペースキーの長押し

スペースキーを長押しすることでキーボード選択のダイアログが表示されて切り替えることができるようになります。

動画では、「Google日本語入力」と「Gboard」で切り替えていますが、同じGoogle製ということで、UIが似ているために切り替えたかどうかが分かりづらいです。

この方法は、スペースキーを押すキーボードアプリに依存します。

 

C. キーボード上で多言語(地球マーク)ボタンのタップ/長押し

タップで同言語対応キーボードの中での切り替え、

長押しで、キーボード切り替えダイアログの表示となります。

キーボード上で多言語(地球マーク)ボタンのタップ/長押し

この方法は、利用してるキーボードアプリに依存します。

 

まとめ

今回は、「Google日本語キーボード」や、「Google Gboard」で説明していますが、他のキーボードアプリでは切り替えをしづらくなっているものもありますので、OS機能を利用した「1」の方法であれば、どのキーボードアプリでも切り替えやすいと思われます。

もうひとつ「英数切り替え」も以下から。

👉 【Gboard】QWERTYキーが3種類あってはまる件【日本語入力】 
→ 入力文字の 日本語 と 英数記号 切り替えをシンプルにする設定

あと、アプリの最速な切替方法など (動画/Android Pie版 あり)。

→ アプリをすばやく切り替える方法

👉 【Android11】スクショ 
👉 【Android Pie】2画面表示(分割画面)の方法 
👉 初めての Gboard キーボードのレイアウト設定