2020年11月5日木曜日

Android 11 では ACTION_CREATE_DOCUMENT と ACTION_OPEN_DOCUMENT には <queries> 指定が必要

Intent.ACTION_CREATE_DOCUMENT および Intent.ACTION_OPEN_DOCUMENT を startActivityForResult() で呼び出す以下のコードは、targetSdkVersion が 29 (Android 10)までは問題なく動きます。 private fun createDocument() { val intent = Intent(Intent.ACTION_CREATE_DOCUMENT) .addCategory(Intent.CATEGORY_OPENABLE) .setType("*/*") .putExtra(Intent.EXTRA_TITLE, "log.txt") if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_CODE_CREATE_DOCUMENT) } else { Toast.makeText( this, "Unable to resolve Intent.ACTION_CREATE_DOCUMENT", Toast.LENGTH_SHORT ) .show() } } private fun openDocument() { val intent = Intent(Intent.ACTION_OPEN_DOCUMENT) .addCategory(Intent.CATEGORY_OPENABLE) .setType("*/*") if (intent.resolveActivity(packageManager) != null) { startActivityForResult(intent, REQUEST_CODE_OPEN_DOCUMENT) } else { Toast.makeText( this, "Unable to resolve Intent.ACTION_OPEN_DOCUMENT", Toast.LENGTH_SHORT ) .show() } } しかし、targetSdkVersion を 30 (Android 11)にすると、intent.resolveActivity(packageManager) が null を返すようになってしまいます。

Android 11 では AndroidManifest.xml に以下の <queries> を指定すると動くようになります。 <manifest ...> ... <queries> <intent> <action android:name="android.intent.action.CREATE_DOCUMENT" /> <data android:mimeType="*/*" /> </intent> <intent> <action android:name="android.intent.action.OPEN_DOCUMENT" /> <data android:mimeType="*/*" /> </intent> </queries> ... </manifest>



2020年10月21日水曜日

DevFest 2020 で Material Design Components のカスタマイズについて話してきました。



資料はこちらです。



Android Studio 4.1 についてと、まとめの後のおまけにいくつかページを追加しています。
MDC をカスタマイズするときは便利だと思うので、是非参考にしてください。

2020年9月10日木曜日

Kotlin でスプレット演算子を使うと enum の values() に値を追加したリストを簡単に作れる

以下のような Rank クラスがあるとして、 enum class Rank { GOLD, SILVER, BRONZE } ランクなしという意味の null を含むリストを作りたいとします。

↓ 作りたいリスト val list: List<Rank?> = ... println(list) // [null, GOLD, SILVER, BRONZE] Rank の一覧は Rank.values() で取れるので val ranks: Array<Rank> = Rank.values() println(ranks.joinToString()) // GOLD, SILVER, BRONZE listOf(null) で null だけのリストを作って + で ranks と合わせたリストを作ることもできますが、 val list: List<Rank?> = listOf(null) + ranks スプレット演算子を使うと余計なリスト(= null だけのリスト)を作らずに済みます。 val list: List<Rank?> = listOf(null, *ranks)