Android 为什么进程死亡后片段中不会触发onRequestPermissionsResult?

Android 为什么进程死亡后片段中不会触发onRequestPermissionsResult?,android,android-fragments,android-camera,android-permissions,Android,Android Fragments,Android Camera,Android Permissions,我在片段中遇到了一个关于onRequestPermissionsResult的奇怪问题。基本上,fragment在onCreate中请求摄影机权限: override fun onCreate(savedInstanceState: Bundle?) { AppCompatDelegate.setCompatVectorFromResourcesEnabled(true) super.onCreate(savedInstanceState) if(!permissions

我在片段中遇到了一个关于onRequestPermissionsResult的奇怪问题。基本上,fragment在onCreate中请求摄影机权限:

override fun onCreate(savedInstanceState: Bundle?) {
    AppCompatDelegate.setCompatVectorFromResourcesEnabled(true)
    super.onCreate(savedInstanceState)
    if(!permissionsGranted){
        requestPermissions(arrayOf(Manifest.permission.CAMERA),
                PermissionsDelegateUtil.REQUEST_PERMISSIONS_CAMERA
        )
    }
}
然后我在onRequestPermissionsResult中处理权限:

 override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
    val resultResponse = permissionsDelegateUtil.resultGranted(requestCode=requestCode, permissions = permissions, grantResults = grantResults)
    when(resultResponse){
        PermissionResult.PermissionGranted -> {
            setupCameraX()
        }
        PermissionResult.PermissionNotGrantedRetryAuto -> {
            //retrying again
            requestPermissions(arrayOf(Manifest.permission.CAMERA),
                PermissionsDelegateUtil.REQUEST_PERMISSIONS_CAMERA
        )
        }
        PermissionResult.PermissionNotGrantedCantRetry -> {
                //show a screen that user must enabled permission
        }
       PermissionResult.PermissionNotGrantedDontAsk -> {
           //Don't do anything, because you can't retry here, otherwise it will cause infinite loop.
        }
    }
}
我还尝试在返回PermissionResult.PermissionNotGrantedDontAsk后重试调用权限。它可以工作,但会导致权限请求和响应的无限循环触发,结果导致应用程序崩溃

编辑

我在不使用backbackback的情况下添加了一个片段:

fun addCameraSessionFragment(supportFragmentManager: FragmentManager) {
    val fragment = supportFragmentManager.findFragmentByTag(CAMERA_SESSION_FRAGMENT_TAG)
    if (fragment == null) {
        val cameraSessionFragment =
                CameraSessionFragment()
        val fragmentTransaction = supportFragmentManager.beginTransaction()
        fragmentTransaction.replace(getTranscationRootId(), cameraSessionFragment, CAMERA_SESSION_FRAGMENT_TAG).commitNow()
    }
}
问题是这个添加逻辑是由ViewModel作为LiveData事件触发的。过程死亡发生后,加法实际上发生两次。第一个是因为它是最后一个碎片,在进程死亡后被恢复。第二个由ViewModel操作触发

编辑

我创建了一个新项目,即使不使用片段,也可以再次复制这个问题,只需活动。以下是存储库:
在权限对话框打开时,尝试强制进程终止。返回应用程序后,对话框会出现,但如果您按下任何按钮,onRequestPermissionsResult仍将不会被触发,但它应该被触发。

您提供的代码不完整(即使在要点中),因为没有提供片段。 但这并不奇怪。如果我理解正确,您请求的是活动级别的权限,而不是片段级别的权限。因此触发的方法是来自活动的onRequestPermissionsResult,而不是片段。 关于如何实施,请查看以下答案:

摘录:

我认为您混淆了片段和活动的方法。上个月我的项目也遇到了类似的问题。请检查您是否已完成以下各项:

在AppCompatActivity中,使用ActivityCompat.requestpermissions方法 在v4支持片段中,您应该使用requestpermissions 捕获是若在片段中调用AppcompatActivity.requestpermissions,则回调将转到活动而不是片段 确保从活动的onRequestPermissionsResult调用super.onRequestPermissionsResult


权限请求与用户的交互可能被中断。在这种情况下,您将收到空权限和结果数组,这些权限和结果数组应被视为取消

解决方案:对主要活动使用
android:launchMode=“singleInstance”


如何添加片段可能是内存泄漏,因此内存中有多个主活动或片段实例。如果您能提供演示项目,我可以帮助调试。@HarisDautović谢谢。我创建了一个新的android项目,粘贴了这段代码,可以重现这个问题@维克托沃斯特里科夫。我做了研究,对为什么会发生这种情况有一些假设,但还没有任何解决方案。以防万一,你能检查一下你是否有同样的行为吗?这是一段视频:(我使用的是:Android API 29,Android Studio 4.4.1)@HarisDautović是的,我有同样的行为。通过按下Android studio中的终止按钮,即使拒绝响应,它也能正常工作。但是,如果我在设备设置中启用“不保留活动”,然后转到后台/返回,则问题仍然存在。不,我认为您理解不正确:)我提供了一个活动示例,因为它更易于复制。此问题发生在活动和片段上。我将编辑我的问题。@ViktorVostrikov我刚刚试过你的例子。我使用的是运行安卓7.0的三星Galaxy S7(SM-G930F),工作正常。当我从后台回来时,当“保持活动”为false时,活动按预期创建,对话框显示,按钮触发
onRequestPermissionsResult
这确实很奇怪。我和Haris Dautović都可以复制这个问题。我在API 29中使用了Pixel XL 4模拟器,在API 29中使用了Xioami mi A3。我在安卓7.0中没有看到这个问题。你能分享一个完整的演示项目,包括gradle文件和所有东西,这样我们就可以运行相同的代码吗?好的,就是这样:)评论不用于扩展讨论或调试会话;这段对话已经结束。请确保用所有相关信息更新答案。
2020-12-17 18:48:17.816 22496-22496/? V/GrantPermissionsActivity: Logged buttons presented and clicked permissionGroupName=android.permission-group.CAMERA uid=10135 package=com.test.app  presentedButtons=25 clickedButton=8
2020-12-17 18:48:17.821 22496-22496/? V/GrantPermissionsActivity: Permission grant result requestId=-2584100455717644829 callingUid=10135 callingPackage=com.test.app permission=android.permission.CAMERA isImplicit=false result=6
fun addCameraSessionFragment(supportFragmentManager: FragmentManager) {
    val fragment = supportFragmentManager.findFragmentByTag(CAMERA_SESSION_FRAGMENT_TAG)
    if (fragment == null) {
        val cameraSessionFragment =
                CameraSessionFragment()
        val fragmentTransaction = supportFragmentManager.beginTransaction()
        fragmentTransaction.replace(getTranscationRootId(), cameraSessionFragment, CAMERA_SESSION_FRAGMENT_TAG).commitNow()
    }
}
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/Theme.StackOverflowSolutions">
    <activity android:name="dh.sos.MainActivity" android:launchMode="singleInstance">>
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
</application>