Android 6 Permissions => 禁用权限并返回应用程序时崩溃

Posted

技术标签:

【中文标题】Android 6 Permissions => 禁用权限并返回应用程序时崩溃【英文标题】:Android 6 Permissions => Crash when disable permission and go back to the app 【发布时间】:2016-01-04 16:15:43 【问题描述】:

我想在我的应用程序中使用 android 6 的权限,但我看到了一个奇怪的事件。也许你可以帮我解决这个问题。

如果您使用“危险”权限启动应用,这些权限会显示在您的 Android 设备的“应用权限”中。完美!

但是,如果您将应用程序保持在后台,请转到“应用程序权限”菜单,禁用(您可以启用然后禁用它)权限并返回您的应用程序,android 永远不会进入 onStart(片段或活动) ?!以后再也不去那里了。

如果您没有触及权限或启用权限 => 它转到 onStart 和其他人。

这是有问题的,例如,如果您的应用使用侦听器,则无法重新启动它,并且可能会崩溃...

你知道当你禁用一个权限时Android去哪里了吗?

我试过了 创建 开始 恢复 重启 onRestoreInstanceState onActionModeStarted onRestoreInstanceState onPostResume onContentChanged

...但没办法...:/

【问题讨论】:

“android 永远不会去 onStart(片段或活动)?!永远不会再去那里。” -- 如果用户从设置中撤销权限,Android 会终止您的进程。如果 Android 在您处于后台时出于任何其他原因终止您的进程,您也可以采用相同的方式处理此问题。 感谢您的回答!我继续调查。当我创建我的活动时,我显示 1 个片段。如果我更改权限并返回应用程序,则有 2 个片段(权限更改之前和之后的片段)。您知道为什么保留旧片段吗? "你知道为什么保留旧片段吗?" -- 因为您的任务仍然未完成,所以 Android 正在重新创建活动并尽其所能恢复其状态,其中包括重新创建任何现有片段。如果您进行配置更改(例如,旋转屏幕),您将获得相同的结果,因为您的活动将被销毁并默认重新创建。在添加之前检查片段是否存在。 非常感谢!!!现在好多了! :p 我们也遇到了同样的问题。修复了吗? 【参考方案1】:

这是我的解决方案:

我在 mainActivity 中使用了一些片段。

如您所知,当用户禁用权限时,Activity 会重新创建 => 执行 onCreate,...

我在 mainActivity 的 onCreate(...) 中做了什么,我删除了所有加载的片段并将我的应用程序置于与第一次运行相同的状态。

像这样:

    // Clean fragments (only if the app is recreated (When user disable permission))
    FragmentManager fragmentManager = getSupportFragmentManager();
    if (fragmentManager.getBackStackEntryCount() > 0) 
        fragmentManager.popBackStack(null, FragmentManager.POP_BACK_STACK_INCLUSIVE);
    

    // Remove previous fragments (case of the app was restarted after changed permission on android 6 and higher)
    List<Fragment> fragmentList = fragmentManager.getFragments();
    if (fragmentList != null) 
        for (Fragment fragment : fragmentList) 
            if (fragment != null) 
                fragmentManager.beginTransaction().remove(fragment).commit();
            
        
    

小心!!! :我在 appcompat 和设计库的 23.2.0 版本中崩溃了。重新创建应用时出现此崩溃!

查看此link 了解更多信息。

【讨论】:

当我们知道活动被重新创建时?出现崩溃“片段不再存在”。 @Santosh 您可以检查片段管理器是否有任何如上所述的片段,或者您使用我的解决方案并在应用程序类中保持初始化状态。您的应用程序通常会在启动活动启动屏幕上启动,以防重启启动活动被跳过并直接显示最后一个活动。【参考方案2】:

正如已经指出的那样,正确的 android 正在重新启动您的应用程序。这与您的应用程序处于后台并且系统在使用更多内存时终止您的应用程序时的行为相同。 当您返回您的应用程序时,会重新创建最后一个包含活动的片段。

通常使用启动屏幕(启动屏幕)来初始化应用程序。 一旦应用程序初始化(例如服务、视图模型准备就绪),启动活动将切换到主活动。

在重新创建应用程序(例如撤销权限)时,许多应用程序会发生常见崩溃,因为应用程序未初始化并且使用的服务或视图模型为空。 我认为没有办法避免在应用重启后重新创建最后一个活动。

您可以做的是检查应用程序是否已初始化,否则切换到启动活动并初始化应用程序。 请注意,您必须处理 Activity 和 Fragment 中的单元化应用程序。

Xamarin 示例代码:

if (!((MyApplication)ApplicationContext).IsInitialized)

    Intent intent = new Intent(Application.Context,typeof(StartupActivity));
    intent.SetFlags(ActivityFlags.NewTask);
    StartActivity(intent);
    Finish();

一旦调用 base.onCreate,就会创建片段,因此即使 acs-team 提供的“解决方法”也不会避免重新创建最后一个片段。

使用上面提供的示例代码,生命周期将是活动有片段的情况:

撤销权限应用被杀 重启应用 应用程序 OnCreate LastActivity.OnCreate LastFragment.OnAttach LastFragment.OnCreate LastFragment.OnCreateView LastFragment.OnViewCreated LastFragment.OnDestroy LastFragment.OnDettach LastActivity.OnDestroy StartupActivity.OnCreate

顺便说一句,您还可以通过 adb shell 测试应用重启:

打开您的应用,然后转到 android 主屏幕,以便您的应用在后台运行

adb shell "ps | grep <com.yourpackage>" // get the app process id
adb shell run-as <com.yourpackage> kill <app-process-id>    // kill the app

通过图标或最近的任务再次启动您的应用

【讨论】:

您也可以发布 Java 示例代码吗? Java 中似乎不存在 IsInitialized 方法。 @Cody 这是您在初始化所有必需服务后在应用程序中设置的标志。它在 Xamarin 和 Java 中不可用,您必须自己完成。 @eugstman 我在用户撤销任何权限时遇到问题。在这种情况下,应用程序会立即崩溃,并且不会在应用程序中调用生命周期事件。有什么办法可以处理这种情况吗? @JanNepraš 你的应用程序被杀死并使用最后一个打开的活动重新启动。撤销权限后立即检查 logcat,您应该在那里发现异常。您也不应该进行调试,否则重启可能会失败。 您将如何检测从设置中删除权限的事件@eugstman

以上是关于Android 6 Permissions => 禁用权限并返回应用程序时崩溃的主要内容,如果未能解决你的问题,请参考以下文章

Android 6.0 应用权限 -- 与系统权限一起工作(Working with System Permissions) 使用MarkDown重新整理了排版

Android M 权限对话框未显示

运行 android 应用程序时,nativescript-permissions 出错

Android 6.0 删除无用功能

Android API Guides –System Permissions

navigator.permissions.query 在 android/ios webview 中不起作用