问题

在处理6.0运行时权限时,很多人都忽略了这样一个问题:
在一个App应用里,如果已经允许了一个权限比如(读取通讯权限),此刻去调用相机,弹出权限申请对话框,此刻点击拒绝,然后经过处理后弹出去设置权限界面(因为权限总归是要申请),如果再在置界面里打开应用权限设置,此刻不但不打开相机权限反而将已经申请的读取通讯录权限关闭会怎样?流程图如下图片步骤

  • 原图
      01.png
  • 步骤一,打开通讯权限,并点击允许
     02.png
  • 步骤二,打开相机申请权限,并点击拒绝
      03.png
  • 步骤三,相机权限拒绝后弹出去设置对话框
    去设置.png
    • 步骤四,点击设置打开应用设置

                   04.png
  • 步骤五,点击权限,打开权限设置,并关闭已经申请成功的读取通讯录权限
 
     05.png
 
      06.png
  • 步骤六,点击还回按键,回到自己的App

分析

经过以上的步骤可以发现,当权限关闭后应用会重新启动,并且会默认直接打开权限申请的那个界面,不会打开启动页,为什么呢,因为当权限关闭后,程序会被杀人,Activity是异常结束的,当返回是,app会默认修复最后打开的那个界面。

证实

上面的分析接下来一一证实,为了让权限申请界面避开自己是启动页界面,我将会在写两个界面,界面跳转步骤是

LanchActivity----》MainActivity----》PremissionActivity

  • LanchActivity
  LanchActivity.png
 
            1501507953(1).png
  • MainActivity
  MainActivity.png
              1501507990(1).png
    • PremissionActivity

        PremissionActivity.png
                  1501508027(1).png
  • MyApplication 用于应用重启判断
            1501507895(1).png

启动程序

启动程序,并且按照上面的步骤去关闭权限然后还回,看看打印结果

                  image.png

可以看得很清楚Application再次执行,并且PremissionActivity界面也会重新被加载,并且savedInstanceState不为空!也可以知道程序此刻并不会启动启动页LanchActivity!

此时按还回键会出现什么情况?看看打印结果:

                  image.png

可以看到会按正常的返回回到启动页,但是启动页和主界面都是异常杀死的,所以savedInstanceState都会有数据

总结

有了以上的测试就可以知道权限被强行关闭后的生命周期,有的时候程序有很多数据,关闭权限还回后,有些数据丢失并不能恢复,就会出现空指针异常的情况!所以这里可以按照微信的设计思路就是:

强行关闭权限后,让程序重新打开启动页!

处理如下:

疑难问题,关闭程序后返回会出现一下白屏的问题!目前还不知如何解决这个问题,请告知!

PremissionActivity代码:

public class PremissionActivity extends AppCompatActivity {
private static final int REQUEST_CAMERA_PERMISSION = 0x103;
private static final int REQUEST_PRE_SET = 0x104; @Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("PNH", "PremissionActivity启动savedInstanceState=" + savedInstanceState); if (null != savedInstanceState) {
Intent intent = new Intent(this, LanchActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
setContentView(R.layout.activity_premission);
findViewById(R.id.camera).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (ContextCompat.checkSelfPermission(PremissionActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(PremissionActivity.this, new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
}
});
findViewById(R.id.contact).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// 检查是否已经具有权限
if (ContextCompat.checkSelfPermission(PremissionActivity.this, Manifest.permission.READ_CONTACTS)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(PremissionActivity.this, new String[]{Manifest.permission.READ_CONTACTS}, );
}
}
});
} @Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION) {
if (grantResults.length > && grantResults[] == PackageManager.PERMISSION_GRANTED) { } else {
//权限拒绝
openAppSetting();
}
}
} protected void openAppSetting() {
MaterialDialog materialDialog = new MaterialDialog.Builder(this)
.content("在设置-应用-GcsSloop-权限中开启相机权限,以正常使用拍照、小视频、扫一扫等功能")
.positiveText("去设置")
.negativeText("取消")
.onNegative(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) {
}
})
.onPositive(new MaterialDialog.SingleButtonCallback() {
@Override
public void onClick(@NonNull MaterialDialog dialog, @NonNull DialogAction which) { // Intent intent = new Intent("/");
// ComponentName cm = new ComponentName("com.android.settings","com.android.settings.ManageApplications");
// intent.setComponent(cm);
// intent.setAction("android.intent.action.VIEW");
// startActivityForResult( intent , 0); // 打开权限设置界面
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.parse("package:" + getPackageName()));
// 申请权限返回执行
startActivityForResult(intent, REQUEST_PRE_SET);
}
}).build();
materialDialog.show(); } }

Android在应用设置里关闭权限,返回生命周期处理的更多相关文章

  1. Android服务Service具体解释(作用,生命周期,AIDL)系列文章-为什么须要服务呢?

    Android服务Service具体解释(作用,生命周期,AIDL) 近期沉迷于上班,没有时间写博客了.解衣入睡,未眠.随起床写一篇博客压压惊! ##我们android系统为什么须要服务Service ...

  2. android 学习随笔十五(Activity的生命周期与摧毁时返回数据 )

    1.Activity的生命周期 onCreate:创建时调用 onStart:在屏幕上可见,但是还没有获得焦点 onResume:可见并且获得焦点 onPause:可见,但是失去焦点 onStop:不 ...

  3. Android基础_1 四大基本组件介绍与生命周期

    Android四大基本组件分别是Activity,Service(服务),Content Provider(内容提供者),BroadcastReceiver(广播接收器). 一.四大基本组件 Acti ...

  4. Android开发之旅(二)服务生命周期和广播接收者生命周期

    引言 应用程序组件有一个生命周期——一开始Android实例化他们响应意图,直到结束实例被销毁.在这期间,他们有时候处于激活状态,有时候处于非激活状态:对于活动,对用户有时候可见,有时候不可见.组件生 ...

  5. Android学习路线(十二)Activity生命周期——启动一个Activity

    DEMO下载地址:http://download.csdn.net/detail/sweetvvck/7728735 不像其他的编程模式那样应用是通过main()函数启动的.Android系统通过调用 ...

  6. Android学习笔记(五)——活动的生命周期

    //此系列博文是<第一行Android代码>的学习笔记,如有错漏,欢迎指正! 为了能写出流畅连贯的程序,我们需要了解一下活动的生命周期. 一.返回栈 Android 中的活动是可以层叠的. ...

  7. android Fragments详解六:处理fragement的生命周期

    把条目添加到动作栏 你的fragment们可以向activity的菜单(按Manu键时出现的东西)添加项,同时也可向动作栏(界面中顶部的那个区域)添加条目,这都需通过实现方法onCreateOptio ...

  8. Android学习路线(十四)Activity生命周期——停止和重新启动(Stopping and Restarting)一个Activity

    正确地停止和重新启动你的activity在activity的生命周期中是一个非常重要的过程.这样可以确保你的用户感觉到你的应用一直都活着而且没有丢失进度.你的activity的停止和重新启动时有几个重 ...

  9. 【Android基础】Fragment 详解之Fragment生命周期

    上一篇文章简单介绍了一下Fragment,这一篇文章会详细的说一下Fragment的生命周期和创建一个用户界面. Fragment的主要功能就是创建一个View,并且有一个生命周期来管理这个View的 ...

随机推荐

  1. 5. Python大法之告别脚本小子--各类URL采集器编写

    在i春秋上面,有很多不错的脚本: https://bbs.ichunqiu.com/forum.php?mod=collection&action=view&ctid=137 http ...

  2. fatal: Authentication failed (二)

    一.前言 前面一段时间写了一篇解决 git 上传代码出现的权限验证问题,还是没有很好的解决.现在还了方式,具体步骤如下: 二.操作流程 我们在上传代码到服务器,我们都需要安装 Git 版本控制.在安装 ...

  3. Jquery选择器(三)

    过滤选择器 4.属性过滤器 查找所有含有 id 属性的 div 元素$(document).ready(function(){ $("div[id]").css("col ...

  4. Docker小白使用笔记

    本文来自网易云社区. 本人DBA一枚,但因为工作的关系,接手的机器越来越多,要部署的东西也从MySQL扩展到其他千奇百怪的各种应用服务,因此需要使用自动化部署的场景也越来越多.早就听运维部的其他大大们 ...

  5. 51nod1307(暴力树剖/二分&dfs/并查集)

    题目链接: http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1307 题意: 中文题诶~ 思路: 解法1:暴力树剖 用一个数 ...

  6. Docker 快速安装&搭建 Ngnix 环境,并配置反向代理

    欢迎关注个人微信公众号: 小哈学Java, 文末分享阿里 P8 高级架构师吐血总结的 <Java 核心知识整理&面试.pdf>资源链接!! 个人网站: https://www.ex ...

  7. php类内方法使用类外变量和类外函数

    如果要调用另一个类的属性和方法,直接实例化后调用就可以 但是要使用的变量和函数是独立的,不在本类或其他类里面,这时调用就要用下面的方法(本例是在同一个php文件里,如果不再同一个类文件可以requir ...

  8. POJ3696 The Luckiest Number 欧拉定理

    昨天终于把欧拉定理的证明看明白了...于是兴冲冲地写了2道题,发现自己啥都不会qwq 题意:给定一个正整数L<=2E+9,求至少多少个8连在一起组成正整数是L的倍数. 这很有意思么... 首先, ...

  9. 01.Spring Ioc 容器

    基本概念 Spring 的 Ioc 容器,通常也称应用上下文.它包含了两个概念 Ioc 和 容器: 容器:顾名思义就是用来装东西的,在 Spring 中容器里盛放的就是各种各样的 Bean.既然装了东 ...

  10. C# String.Format方法

    一.定义String.Format是将指定的 String类型的数据中的每个格式项替换为相应对象的值的文本等效项. 如: (1)string p1 = "Jackie";strin ...