Android在應用設定裡關閉許可權,返回生命週期處理
問題
在處理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都會有資料
總結
有了以上的測試就可以知道許可權被強行關閉後的生命週期,有的時候程式有很多資料,關閉許可權還回後,有些資料丟失並不能恢復,就會出現空指標異常的情況!所以這裡可以按照微信的設計思路就是:
強行關閉許可權後,讓程式重新開啟啟動頁!
處理如下:
image.png
疑難問題,關閉程式後返回會出現一下白屏的問題!目前還不知如何解決這個問題,請告知!
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();
}
}