2016-05-11 5 views
7

Marsmallow hat die Erlangung von Berechtigungen neu gestaltet. So Berechtigungen Behandelt vor dem Aufruf der Methode, die Berechtigungen benötigt und es funktioniert gut, aber es stürzt in das folgende Szenario:Marsmallow: Ändern der Berechtigungen zur Laufzeit stürzt ab app

Schritt 1: Geöffnete App und gab alle notwendigen Berechtigungen

Schritt 2: Clicked Home-Taste (so die App im Hintergrund)

Schritt 3: manuell die Berechtigungen in den Einstellungen geändert

Schritt 4: die App von Multitasking gestartet, ist es nun wegen der App Zusammenhang stürzt ungültig

Beobachten, dass App erneut erstellt wird, verstehe nicht, warum das passiert. Vorschläge zur Behebung dieses Problems wären willkommen!

+0

Gibt es irgendeine Ausnahme ?? Wenn ja, sollten Sie es in Versuch fangen Block –

+0

überprüfen Sie dies .... http://stackoverflow.com/questions/33488589/android-marshmallow-dynamic-permission-change-kills-all-application-processes – Nikunj

+0

Spotted the Problem, das aufgrund der App neu erstellt wird, wenn wir Berechtigungen dynamisch ändern, indem wir die App im Hintergrund laufen lassen, wird der Kontext, den ich für den Zugriff auf gemeinsame Einstellungen verwendet habe, Null. – ABI

Antwort

1

Es ist wegen der zusätzlichen Funktionen von Marshmallow hinzugefügt. Sie müssen den Benutzer zur Laufzeit anfordern. Benutze dafür diese Klasse, die ich gemacht habe. Dann verwenden Sie es wo immer erforderlich

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; 
    } 
} 

Dann legen Sie diesen Code, wo Sie die Erlaubnis des Benutzers benötigen.

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

Danach wird in Ihrem Fragment oder Activity Put dieser Code -

@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; 
    } 
} 

Der obige Code für GET_ACCOUNTS für die Erlaubnis ersuchen, ist, dass Sie es zu, was erforderlich ändern.

+1

Haben Sie das oben angegebene Szenario gelesen und verstanden? – ABI

+0

dann fügen Sie einige Code, wenn oben nicht ausreicht. Der obige Code ist meistens, was alles verpasst –

+2

Sein nicht Code-Level-Problem, mit dem ich konfrontiert bin, will nur sicherstellen, dass App neu erstellt wird, wenn ich die Berechtigungen in den Einstellungen manuell ändern (beim Starten der App, die im Hintergrund ausgeführt wird, es wird abgestürzt) – ABI

0

Beobachtet, dass App wieder erstellt wird, verstehe nicht, warum dies passiert . Vorschläge zur Behebung dieses Problems wären willkommen!

Da, wenn Berechtigungen ändern, sollte Anwendung "state" ungültig gemacht werden. Der richtige Weg, dies zu tun, ist den Wurzelkontext zu zerstören, der die Anwendung selbst ist.

Sie müssen den Status der gewährten Berechtigungen jedes Mal überprüfen, wenn Sie die API-Methoden abfragen, für die diese Berechtigungen erforderlich sind. Sie können sich nicht auf irgendein SharedPreferences Flag verlassen, das anzeigt, dass "Benutzer die Erlaubnis beim Onboarding gewährte, ok, lassen Sie Spaß haben". Machen Sie Ihre App in dieser Hinsicht staatenlos.

Sie können beispielsweise BaseActivity/BaseFragment oder Utility erstellen und die gesamte Prüflogik dorthin verschieben.

0

definieren einen Booleschen Wert auf den ersten

private boolean isPermissionGranted = false; 

Und dann prüfen, ob die Erlaubnis erteilt:

if (!isPermissionGranted) { 
     checkPermission(); 
    } 

tatsächliche Code für Berechtigungsprüfung der Laufzeit ist wie folgt:

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); 
    } 
} 

Sie kann den obigen Code verwenden und in Ihrer Anwendung implementieren.

+0

Wenn Sie eine Abfrage mit dem obigen Beispielcode haben, können Sie fragen ... – Riten

Verwandte Themen