我有一个简单的空活动,用于检查是否需要请求权限。当registerForActivityResult
被调用时,它会因错误而崩溃java.lang.IllegalStateException: LifecycleOwner com.example.app.PermsRequester@41a30da is attempting to register while current state is RESUMED. LifecycleOwners must call register before they are STARTED.
根据我的研究,我想我需要检查是否savedInstanceState
是null
,如果是,则创建一个新的fragment
? 我不确定这是否是正确的解决方案或如何实施。下面是代码:
class PermsRequester : AppCompatActivity() {
requestPerms = false
override fun onCreate(savedInstanceState: Bundle?) {
setTheme(R.style.AppTheme)
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_perms_requester)
findViewById<Button>(R.id.acceptButton).setOnClickListener { accepted() }
}
private fun accepted() {
//There is code here to check if rationale dialog needs to be displayed
//There is code here to build a mutable list …
Run Code Online (Sandbox Code Playgroud) setTargetFragment()
在 Java 中已弃用,我不明白它的正确替代品,因为 android 文档使用它并且已经过时。我相信这FragmentManager
是它的正确替代品。我setTargetFragment
在我的设置首选项中使用已弃用的功能来创建多个首选项屏幕。为此,我最初遵循了此处的指南,该指南在setTargetFragment
示例中使用起来很混乱。下面是我的代码:
build.gradle (Module: app)
...
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
implementation 'androidx.preference:preference:1.1.1'
...
Run Code Online (Sandbox Code Playgroud)
MainActivity.kt
class MainActivity : AppCompatActivity() {
private lateinit var settingsButton: ImageButton
override fun onCreate(savedInstanceState: Bundle?) {
...
settingsButton = findViewById(R.id.settingsButtonMain)
settingsButton.setOnClickListener {
settingsClicked()
}
...
}
private fun settingsClicked() {
val settingsIntent = Intent(this, SettingsActivity::class.java)
startActivity(settingsIntent)
}
}
Run Code Online (Sandbox Code Playgroud)
SettingsActivity.kt
class SettingsActivity : AppCompatActivity(), PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
override fun onCreate(savedInstanceState: Bundle?) {
...
supportFragmentManager.beginTransaction().replace(R.id.settings, SettingsFragment(this)).commit()
supportFragmentManager.addOnBackStackChangedListener …
Run Code Online (Sandbox Code Playgroud) 正如标题所暗示的那样,SpeechRecognizer.isRecognitionAvailable()
在 Android 11 中返回 false,我不确定为什么会这样,因为设备 (Pixel 3 XL) 可以识别语音。该文档并未表明它在 API v30 中发生了变化。奇怪的是,即使isRecognitionAvailable
是false ,我仍然成功获得STT提示。下面是说明这一点的示例代码。为什么 isRecognitionAvailable 检查总是错误的?无论如何,代码都不完整,但我添加了重要的相关部分:
AndroidManifest.xml
...
<uses-permission android:name="android.permission.RECORD_AUDIO" />
...
Run Code Online (Sandbox Code Playgroud)
MainActivity.kt
...
override fun onCreate(savedInstanceState: Bundle?) {
...
if(ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
if(shouldShowRequestPermissionRationale(Manifest.permission.RECORD_AUDIO)) { //rationale prompt
}
val requestPermissionLauncher = registerForActivityResult(ActivityResultContracts.RequestPermission()
){ isGranted: Boolean ->
if(isGranted) { checkSTT() }
else { //error perms not granted
}
requestPermissionLauncher.launch(Manifest.permission.RECORD_AUDIO)
} else { checkSTT() }
}
private fun checkSTT() {
if(SpeechRecognizer.isRecognitionAvailable(this)) { runSTT() }
else …
Run Code Online (Sandbox Code Playgroud) startActivityForResult(intent: Intent!, options: Bundle?)
已被弃用。我正在尝试替换为,ActivityResultLauncher
但我需要通过options
. 我怎样才能用新方法做到这一点?以下是原始(现已弃用)方法的示例,该方法将打开“联系人”菜单,然后根据 的值在开关中执行以下两项操作之一code
:
...
val code = contactType //can be either 1 or 2
val contactsIntent = Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI)
contactsIntent.type = ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE
startActivityForResult(contactsIntent, code)
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
if(resultCode == Activity.RESULT_OK) {
when(requestCode) {
1 -> { //Do something
}
2 -> { //Do something else
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我试图将上述内容转换为使用,ActivityResultLauncher
但我还没有弄清楚如何将 的值传递code
给它。以下是我到目前为止所拥有的:
val code = contactType //can be either 1 or …
Run Code Online (Sandbox Code Playgroud)