2016-05-11 67 views
7

Marsmallow已重新設計獲取權限。所以調用它需要的權限,並能正常工作的方法之前已處理的權限,但它崩潰在以下情形:Marsmallow:在運行時更改權限崩潰應用程序

第1步:打開應用程序,並給了所有必要的權限

步驟2:被點擊主頁按鈕(所以該應用是背景)

步驟3:手動改變的權限在設置

步驟4:從推出多任務應用,現在它崩潰,因爲應用程序上下文的變爲無效

觀察到應用程序被重新創建,不明白爲什麼會發生這種情況。任何建議來糾正這個問題將受到歡迎!

+0

有什麼異常嗎?如果是的話,你應該在嘗試catch塊中處理它 –

+0

檢查這個.... http://stackoverflow.com/questions/33488589/android-marshmallow-dynamic-permission-change-kills-all-application-processes – Nikunj

+0

Spotted問題,當我們通過保持應用程序在後臺運行來動態更改權限時,由於應用程序會重新創建,我用來訪問共享首選項的上下文變爲空。 – ABI

回答

1

這是因爲從棉花糖添加額外的功能。您需要在運行時從用戶請求。爲了這個,我使用了這個類。然後在任何需要的地方使用它

public class AppPermission { 

    public static boolean isMarshmallowPlusDevice() { 
     return Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1; 
    } 

    @TargetApi(Build.VERSION_CODES.M) 
    public static boolean isPermissionRequestRequired(Activity activity, @NonNull String[] permissions, int requestCode) { 
     if (isMarshmallowPlusDevice() && permissions.length > 0) { 
      List<String> newPermissionList = new ArrayList<>(); 
      for (String permission : permissions) { 
       if (PackageManager.PERMISSION_GRANTED != activity.checkSelfPermission(permission)) { 
        newPermissionList.add(permission); 
       } 
      } 
      if (newPermissionList.size() > 0) { 
       activity.requestPermissions(newPermissionList.toArray(new String[newPermissionList.size()]), requestCode); 
       return true; 
      } 
     } 
     return false; 
    } 
} 

然後把這段代碼放在需要用戶許可的地方。

if (!AppPermission.isPermissionRequestRequired(SignInActivity.this, new String[]{"android.permission.GET_ACCOUNTS"}, 
     REQUEST_APP_PERMISSION)) { 
    // Your code if permission available 
} 

在此之後,在你FragmentActivity把這段代碼 -

@Override 
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 
    super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    switch (requestCode) { 
     case REQUEST_APP_PERMISSION: 
      for (int i = 0; i < permissions.length; i++) { 
       String permission = permissions[i]; 
       int grantResult = grantResults[i]; 
       switch (permission) { 
        case "android.permission.GET_ACCOUNTS": 
         if (PackageManager.PERMISSION_GRANTED == grantResult) { 
          // Your code 
         } 
         break; 
       } 
      } 
      break; 
    } 
} 

上面的代碼是請求許可GET_ACCOUNTS你可以把它改成什麼要求。

+1

您是否已閱讀並理解上面給出的場景? – ABI

+0

然後把一些代碼,如果上面不足。上面的代碼主要是什麼都沒有輸出 –

+2

它沒有代碼級別的問題,我只是想確保當我手動更改設置中的權限時重新創建應用程序(當啓動在後臺運行的應用程序時,它得到墜毀) – ABI

0

觀察到應用程序被重新創建,不明白爲什麼這個 發生。任何建議來糾正這個問題將受到歡迎!

因爲權限更改時,應用程序「狀態」應該失效。這樣做的正確方法是銷燬根環境,這是應用程序本身。

每次查詢需要這些權限的API方法時,您都必須檢查權限授予狀態。你不能依靠一些SharedPreferences標誌表明「用戶授予了入職權限,好吧,讓我們玩得開心」。在這方面讓你的應用程序成爲無狀態的。

例如,您可以創建一些BaseActivity/BaseFragment或Utility並移動其中的所有檢查邏輯。

0

在第一

private boolean isPermissionGranted = false; 

定義一個布爾值,然後檢查是否許可​​授予:

if (!isPermissionGranted) { 
     checkPermission(); 
    } 

的運行時間許可檢查實際的代碼如下:

private void checkPermission() { 
    int hasPermission = ContextCompat.checkSelfPermission(UserProfile.this, Manifest.permission.CAMERA); 
    int hasWritePermission = ContextCompat.checkSelfPermission(UserProfile.this, Manifest.permission.WRITE_EXTERNAL_STORAGE); 
    if (hasPermission != PackageManager.PERMISSION_GRANTED && hasWritePermission != PackageManager.PERMISSION_GRANTED) { 
     if (!ActivityCompat.shouldShowRequestPermissionRationale(UserProfile.this, Manifest.permission.CAMERA) && !ActivityCompat.shouldShowRequestPermissionRationale(UserProfile.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)) { 
      showMessage(getString(R.string.allow_access_to_camera_external_storage), 
        new DialogInterface.OnClickListener() { 
         @Override 
         public void onClick(DialogInterface dialog, int which) { 
          ActivityCompat.requestPermissions(UserProfile.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 
            REQUEST_CODE_ASK_PERMISSIONS); 
         } 
        }); 
      return; 
     } 
     ActivityCompat.requestPermissions(UserProfile.this, new String[]{Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 
       REQUEST_CODE_ASK_PERMISSIONS); 
     return; 
    } else { 
     isPermissionGranted = true; 
    } 
} 

private void showMessage(String message, DialogInterface.OnClickListener  listener) { 
    new AlertDialog.Builder(UserProfile.this) 
      .setMessage(message) 
      .setPositiveButton(R.string.ok, listener) 
      .setNegativeButton(R.string.cancel, null) 
      .create() 
      .show(); 
} 

    @Override 
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { 
    switch (requestCode) { 
     case REQUEST_CODE_ASK_PERMISSIONS: 
      if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 
       isPermissionGranted = true; 

      } else { 
       isPermissionGranted = false; 
       Toast.makeText(UserProfile.this, R.string.permission_denied, Toast.LENGTH_SHORT) 
         .show(); 
      } 
      break; 

     default: 
      super.onRequestPermissionsResult(requestCode, permissions, grantResults); 
    } 
} 

你可以從上面的代碼中引用並在您的應用程序中實現它。

+0

如果您對以上示例代碼有任何疑問,您可以詢問... – Riten

相關問題