【Kotlin/Android Studio】registerForActivityResultの使い方!launcherとは?

この記事からわかること
- Android Studio/KotlinのregisterForActivityResultの使い方
- 別のActivityを起動させるには?
- Activityの結果を取得する方法
- StartActivityForResultの挙動
- ActivityResultContractの設定値
- RequestPermission/RequestMultiplePermissionsを使用したパーミッションダイアログの結果取得
index
[open]
\ アプリをリリースしました /
環境
- Android Studio:Flamingo
- Kotlin:1.8.20
registerForActivityResult
abstract @NonNull ActivityResultLauncher<I> <I, O> registerForActivityResult(
@NonNull ActivityResultContract<I, O> contract,
@NonNull ActivityResultCallback<O> callback
)
registerForActivityResult
は別のアクティビティを起動し結果を取得することができるメソッドです。引数としてActivityResultContract
型を受け取りActivityResultLauncher
型を返します。
private val launcher = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
// 結果に対する処理
}
※ランチャーとは機能を保持し、あとは簡単な操作のみで起動させるだけの機能のことです。
ActivityResultContract型
公式リファレンス:ActivityResultContract
ActivityResultContract
には色々定義されており、渡すものによって機能が異なります。
StartActivityForResult
Activityを起動して結果を取得する
RequestPermission
単体のパーミッション許可ダイアログを表示して結果を取得する
RequestMultiplePermissions
複数個のパーミッション許可ダイアログを表示して結果を取得する
ActivityResultCallback
registerForActivityResult
の2つ目の引数ActivityResultCallback
(コールバック)で実際の結果を受け取ることが可能になっています。
別のActivityからデータを受け取る
今回はよくあるSecondActivityから入力されたデータをMainActivityで表示させてみます。

MainActivity側でregisterForActivityResult
メソッドを呼び出します。1つ目の引数にはActivityResultContracts.StartActivityForResult
を渡します。Activityから返ってくる値はコールバックで受け取れるので変数result
に格納し、resultCode
プロパティから識別コードを、data
プロパティからIntent
を参照することができます。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val button: Button = findViewById(R.id.done_button)
button.setOnClickListener {
// SecondActivityに送信する用のデータを準備する
val intent = Intent(applicationContext, SecondActivity::class.java)
// SecondActivityを起動
launcher.launch(intent)
}
}
// SecondActivityを起動する機能と結果を処理する機能をもったランチャー(ActivityResultLauncher型)
private val launcher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
// Resultコードをチェック
if (result.resultCode == Activity.RESULT_OK) {
// インテントを取得
val intent = result.data
// 中身を取り出す
val name = intent?.getStringExtra("name")
// 表示
Toast.makeText(this, name, Toast.LENGTH_SHORT)
.show()
}
}
}
Intent
の使い方は以下の記事を参考にしてください。
SecondActivity側はsetResult
メソッドを使用して結果として返すデータを設定します。1つ目の引数にはActivity.RESULT_OK
やActivity.RESULT_CANCELED
などの識別コードを渡し、2つ目にはIntentを渡します。
public final void setResult(int resultCode, Intent data) {
throw new RuntimeException("Stub!");
}
最後にActivityを終了するfinish
メソッドを呼び出して完了です。
class SecondActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_second)
val name: EditText = findViewById(R.id.name_edit)
val backBtn:Button = findViewById(R.id.back_button)
backBtn.setOnClickListener {
// インテントに値をセット
intent.putExtra("name", name.text.toString())
// 結果として返すデータをセット
setResult(Activity.RESULT_OK, intent)
// アクティビティを終了
finish()
}
}
}
これで以下のような機能を実装することができました。

RequestPermission:パーミッションダイアログを表示する
おすすめ記事:【Kotlin/Android Studio】パーミッション(権限)許可のリクエスト方法!requestPermissions
registerForActivityResult
の引数にRequestPermission
を渡すことで簡単にパーミッション許可申請ダイアログを表示することができます。ダイアログを出す際は忘れずにマニフェストファイルの追加をしといてください。
<uses-permission android:name="android.permission.CAMERA" />
実装は以下のとおりです。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 許可ダイアログを表示
launcher.launch(Manifest.permission.CAMERA)
}
private val launcher =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { result ->
// ダイアログの結果で処理を分岐
if (result) {
Toast.makeText(this, "許可されました", Toast.LENGTH_SHORT)
.show()
} else {
Toast.makeText(this, "否認されました", Toast.LENGTH_SHORT)
.show()
}
}
}
RequestMultiplePermissions:複数のパーミッションダイアログを表示する
複数のパーミッションダイアログを表示するにはRequestMultiplePermissions
を指定します。
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
launcher.launch(
arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.ACCESS_COARSE_LOCATION
)
)
}
private val launcher =
registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) {
it
val camera = it[Manifest.permission.CAMERA] ?: false
val location = it[Manifest.permission.ACCESS_COARSE_LOCATION] ?: false
if (camera && location) {
Toast.makeText(this, "許可されました", Toast.LENGTH_SHORT)
.show()
} else {
Toast.makeText(this, "否認されました", Toast.LENGTH_SHORT)
.show()
}
}
}
まだまだ勉強中ですので間違っている点や至らぬ点がありましたら教えていただけると助かります。
ご覧いただきありがとうございました。