問題
在處理6.0運行時權限時,很多人都忽略了這樣一個問題:
在一個App應用里,如果已經允許了一個權限比如(讀取通訊權限),此刻去調用相機,彈出權限申請對話框,此刻點擊拒絕,然后經過處理后彈出去設置權限界面(因為權限總歸是要申請),如果再在置界面里打開應用權限設置,此刻不但不打開相機權限反而將已經申請的讀取通訊錄權限關閉會怎樣?流程圖如下圖片步驟:
- 原圖
- 步驟一,打開通訊權限,並點擊允許
- 步驟二,打開相機申請權限,並點擊拒絕
- 步驟三,相機權限拒絕后彈出去設置對話框
-
-
步驟四,點擊設置打開應用設置
04.png
-
- 步驟五,點擊權限,打開權限設置,並關閉已經申請成功的讀取通訊錄權限
- 步驟六,點擊還回按鍵,回到自己的App
分析
經過以上的步驟可以發現,當權限關閉后應用會重新啟動,並且會默認直接打開權限申請的那個界面,不會打開啟動頁,為什么呢,因為當權限關閉后,程序會被殺人,Activity是異常結束的,當返回是,app會默認修復最后打開的那個界面。
證實
上面的分析接下來一一證實,為了讓權限申請界面避開自己是啟動頁界面,我將會在寫兩個界面,界面跳轉步驟是
LanchActivity----》MainActivity----》PremissionActivity
- LanchActivity
- MainActivity
-
-
PremissionActivity
PremissionActivity.png
-
- MyApplication 用於應用重啟判斷
啟動程序
啟動程序,並且按照上面的步驟去關閉權限然后還回,看看打印結果
可以看得很清楚Application再次執行,並且PremissionActivity界面也會重新被加載,並且savedInstanceState不為空!也可以知道程序此刻並不會啟動啟動頁LanchActivity!
此時按還回鍵會出現什么情況?看看打印結果:
可以看到會按正常的返回回到啟動頁,但是啟動頁和主界面都是異常殺死的,所以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}, 3); } } }); } @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 > 0 && grantResults[0] == 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(); } }
