2016-05-11 4 views
7

Marsmallow изменил права доступа. Так обрабатывались разрешения перед вызовом метода, который нуждается разрешения и он работает нормально, но он выходит из строя по следующему сценарию:Marsmallow: Изменение разрешений при запуске приложения сбой

Шаг 1: Открытый приложение и дал все необходимые разрешения

Шаг 2: Clicked кнопку Home (So приложение работает в фоновом режиме)

Шага 3: вручную изменил разрешение в настройках

Шаг 4: Запущенное приложение из многозадачности, теперь он выходит из строя из-за контекст приложения становится недействительной

Наблюдалось, что приложение снова создается, не понимая, почему это происходит. Любые предложения по исправлению этой проблемы приветствуются!

+0

Есть ли исключение? Если да, вы должны обработать его в блоке try catch –

+0

. Проверьте это. Http://stackoverflow.com/questions/33488589/android-marshmallow-dynamic-permission-change-kills-all-application-processes – Nikunj

+0

Пятнистый проблема, из-за того, что приложение восстанавливается, когда мы динамически меняем разрешения, сохраняя приложение в фоновом режиме, контекст, который я использовал для доступа к общим настройкам, становится нулевым. – 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 
} 

После этого, в вашем Fragment или Activity поместить этот код -

@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, указывающий, что «пользователь предоставил права доступа на onboarding, ok, позволяет получать удовольствие». Сделайте это приложение без гражданства в этом отношении.

Например, вы можете создать 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); 
    } 
} 

You может взять ссылку из кода выше и реализовать его в своем приложении.

+0

Если у вас есть какие-либо вопросы с вышеуказанным примером кода, вы можете спросить ... – Riten

Смежные вопросы