kotlinやandroidxの勉強も兼ねて、以前作った自作androidアプリケーションを一から作り直しているんですが、Activity#startActivityForResult
は代わりにActivityResultAPIを使う事を薦められているとの事。
いきなり使うのはためらうので、まずはテストプロジェクトで試してみましたが、まぁ、何ていうかその…。
トラブル解決に自信があるなら別にいいけど、そうでないならあと1年は様子見でいいよ。
テストしてみる。
とりあえずテストした結果を書いておきます。
まず、「build.gradle
」に依存関係を書きます。
dependencies {
implementation "androidx.activity:activity:1.2.0-alpha08"
implementation "androidx.activity:activity-ktx:1.2.0-alpha08"
implementation "androidx.fragment:fragment:1.3.0-alpha06"
}
ここに注目。
というのも、結構新しいAPIなので、仕様が変わっていて、ネットの情報が間違っている事も多い。
ぶっちゃけ、これから書く内容も、将来的には間違いかもしれないですよ。
そして、Activityのコード。
package com.example.test1012a
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.TextView
import android.content.Intent
import android.app.Activity
import android.util.Log
import androidx.activity.result.contract.ActivityResultContracts
import android.widget.Toast
//private const val REQUEST_CODE = 1
class MainActivity(): AppCompatActivity(), View.OnClickListener {
private val launcher = registerForActivityResult(ActivityResultContracts.CreateDocument()) { uri ->
Log.d("test1012a", String.format("uri = %s.", uri.toString()))
this@MainActivity.getContentResolver().openOutputStream(uri)?.writer()?.use {
it.write("Hello, world!\n")
}
}
protected override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
this.setContentView(R.layout.main)
this.findViewById<View>(R.id.button1).setOnClickListener(this)
}
override fun onClick(view: View)
{
when (view.getId()) {
R.id.button1 -> {
// val intent = Intent(Intent.ACTION_CREATE_DOCUMENT).apply {
// this.addCategory(Intent.CATEGORY_OPENABLE)
// this.type = "*/*"
// }
// this.startActivityForResult(intent, REQUEST_CODE)
this.launcher.launch("hoge")
}
}
}
// override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?)
// {
// if (requestCode == REQUEST_CODE && resultCode == Activity.RESULT_OK) {
// resultData?.data?.also {
// this.findViewById<TextView>(R.id.result).setText(it.toString())
// }
// }
// }
}
以下、ハマった点です。
prepareCall
ではなく、registerForActivityResult
先の公式サイトのとおりに記述したら、「prepareCall
」でビルドエラー。
「なんでじゃー」と叫びつついろいろと探してみると、バージョン1.2.0-alpha04の変更点に以下の記述が。
prepareCall() メソッドの名前が、ここの ComponentActivity と Fragment 1.3.0-alpha04 の両方で、registerForActivityResult() に変更されました。
ドキュメント直しておけよーー。
(これに限らず、最近のandroidのドキュメントはおざなりになっていない?量が膨大になってきたのはわかりますけど、わかりますけどね)
「Can only use lower 16 bits for requestCode」
めでたくビルドが通って、実行してみると、ボタンを押した時点でアプリが落ちてしまいます。
ログを見てみると、「Can only use lower 16 bits for requestCode」とのエラーが出力。
実は、当初依存関係に「fragment:1.3.0-alpha06」は含んでいなかったのです。いやだって、fragment使ってないし。
でも、試しに加えてみたら、エラーが発生しなくなりました。もしかすると、FragmentActivity
辺りが古いせいなのかもしれません。