Wie kann die Berechtigung zur Laufzeit überprüft werden, ohne SecurityException auszulösen?

90

Ich entwerfe eine Funktion, die eine Ressource von SD abrufen / festlegen kann. Wenn sie nicht von SD gefunden wird, nehme ich sie von Asset und schreibe das Asset nach Möglichkeit zurück in SD.
Diese Funktion kann durch Methodenaufruf prüfen, ob SD bereitgestellt ist und auf sie zugegriffen werden kann.

boolean bSDisAvalaible = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);

Meine entworfene Funktion kann von einer App (Projekt) zu einer anderen verwendet werden (mit oder ohne android.permission.WRITE_EXTERNAL_STORAGE)

Dann möchte ich überprüfen, ob die aktuelle Anwendung diese spezielle Berechtigung hat, ohne mit SecurityException zu spielen.

Gibt es eine "nette" Möglichkeit, zur Laufzeit die aktuell definierten Berechtigungen abzurufen?

Emmanuel Devaux
quelle

Antworten:

194

Sie können hierfür die Context.checkCallingorSelfPermission()Funktion verwenden. Hier ist ein Beispiel:

private boolean checkWriteExternalPermission()
{
    String permission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
    int res = getContext().checkCallingOrSelfPermission(permission);
    return (res == PackageManager.PERMISSION_GRANTED);            
}
inazaruk
quelle
Diese Methode kann ein Sicherheitsrisiko darstellen.
TalMihr
13
@TalMihr, warum ist Ihrer Meinung nach "checkCallingOrSelfPermission ()" ein Sicherheitsrisiko?
William
2
Nein. Sie können sich zur Laufzeit keine Erlaubnis geben.
Anubian Noob
3
Es ist besser, checkCallingPermission()anstelle der checkCallingOrSelfPermission()Methode zu verwenden.
Hasanghaforian
9
Es gibt jetzt einen Komatibilitäts-Wrapper dafür: ContextCompat.checkSelfPermission
yoah
51

Dies ist auch eine andere Lösung

PackageManager pm = context.getPackageManager();
int hasPerm = pm.checkPermission(
    android.Manifest.permission.WRITE_EXTERNAL_STORAGE, 
    context.getPackageName());
if (hasPerm != PackageManager.PERMISSION_GRANTED) {
   // do stuff
}
user123321
quelle
Soll ich diesen Code einfach in diese if-Anweisung einschließen? Ich habe dies gemacht, um zu sehen, ob der Benutzer einen Anruf erhält oder sich in einem Anruf befindet, um das Audio stumm zu schalten
Ruchir Baronia
Was ist der Unterschied beim Aufrufen des Pakets zur Erlaubnis oder des iPC?
Htafoya
1
Vielen Dank, sehr hilfreich. Funktioniert wie ein Zauber unter Android 5.1.1. Wenn Sie den "Kontext" noch nicht definiert haben, können Sie "Kontext" durch "getBaseContext ()" ersetzen.
JamisonMan111
19

Sie können auch Folgendes verwenden:

private boolean doesUserHavePermission()
{
    int result = context.checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    return result == PackageManager.PERMISSION_GRANTED;
}
MrAppa
quelle
11

Wie Google- Dokumentation :

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
beni
quelle
8

Teilen Sie meine Methoden, falls jemand sie benötigt:

 /** Determines if the context calling has the required permission
 * @param context - the IPC context
 * @param permissions - The permissions to check
 * @return true if the IPC has the granted permission
 */
public static boolean hasPermission(Context context, String permission) {

    int res = context.checkCallingOrSelfPermission(permission);

    Log.v(TAG, "permission: " + permission + " = \t\t" + 
    (res == PackageManager.PERMISSION_GRANTED ? "GRANTED" : "DENIED"));

    return res == PackageManager.PERMISSION_GRANTED;

}

/** Determines if the context calling has the required permissions
 * @param context - the IPC context
 * @param permissions - The permissions to check
 * @return true if the IPC has the granted permission
 */
public static boolean hasPermissions(Context context, String... permissions) {

    boolean hasAllPermissions = true;

    for(String permission : permissions) {
        //you can return false instead of assigning, but by assigning you can log all permission values
        if (! hasPermission(context, permission)) {hasAllPermissions = false; }
    }

    return hasAllPermissions;

}

Und um es zu nennen:

boolean hasAndroidPermissions = SystemUtils.hasPermissions(mContext, new String[] {
                android.Manifest.permission.ACCESS_WIFI_STATE,
                android.Manifest.permission.READ_PHONE_STATE,
                android.Manifest.permission.ACCESS_NETWORK_STATE,
                android.Manifest.permission.INTERNET,
        });
htafoya
quelle
5

Sie sollten auf folgende Weise nach Berechtigungen suchen (wie hier für Android-Berechtigungen beschrieben ):

int result = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.READ_PHONE_STATE);

Vergleichen Sie dann Ihr Ergebnis mit:

result == PackageManager.PERMISSION_DENIED

oder:

result == PackageManager.PERMISSION_GRANTED
Box
quelle
Vielen Dank. Das war hilfreich.
Sudhir Khanger
3

Schritt 1 - Berechtigungsanforderung hinzufügen

    String[] permissionArrays = new String[]{Manifest.permission.CAMERA, 
    Manifest.permission.WRITE_EXTERNAL_STORAGE};
    int REQUEST_CODE = 101;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(permissionArrays, REQUEST_CODE );
        } else {
             // if already permition granted
            // PUT YOUR ACTION (Like Open cemara etc..)
        }
    }

Schritt 2 - Berechtigungsergebnis behandeln

     @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    boolean openActivityOnce = true;
    boolean openDialogOnce = true;
    if (requestCode == REQUEST_CODE ) {
        for (int i = 0; i < grantResults.length; i++) {
            String permission = permissions[i];

            isPermitted = grantResults[i] == PackageManager.PERMISSION_GRANTED;

            if (grantResults[i] == PackageManager.PERMISSION_DENIED) {
                // user rejected the permission

            }else {
                //  user grant the permission
                // you can perfome your action 
            }
        }
    }
}
Jaydeep Dobariya
quelle
2

Der Code, der für mich gut funktioniert, ist: -

  final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 102;
  if ((ContextCompat.checkSelfPermission(getActivity(),Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {

                requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
            } else {
        // user already provided permission
                // perform function for what you want to achieve
     }

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {

    boolean canUseExternalStorage = false;

    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                canUseExternalStorage = true;
            }

            if (!canUseExternalStorage) {
                Toast.makeText(getActivity(), "Cannot use this feature without requested permission", Toast.LENGTH_SHORT).show();
            } else {
                // user now provided permission
                // perform function for what you want to achieve
            }
        }
      }
 }
Sanoop
quelle
0

Aktivieren Sie den GPS-Standort Android Studio

  1. Fügen Sie einen Berechtigungseintrag in AndroidManifest.Xml hinzu

  1. MapsActivity.java

    public class MapsActivity extends FragmentActivity implements OnMapReadyCallback {
    
    private GoogleMap mMap;
    private Context context;
    private static final int PERMISSION_REQUEST_CODE = 1;
    Activity activity;
    /**
     * ATTENTION: This was auto-generated to implement the App Indexing API.
     * See https://g.co/AppIndexing/AndroidStudio for more information.
     */
    private GoogleApiClient client;
    
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        context = getApplicationContext();
        activity = this;
        super.onCreate(savedInstanceState);
        requestPermission();
        checkPermission();
        setContentView(R.layout.activity_maps);
        // Obtain the SupportMapFragment and get notified when the map is ready to be used.
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    
    }
    
    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        LatLng location = new LatLng(0, 0);
        mMap.addMarker(new MarkerOptions().position(location).title("Marker in Bangalore"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(location));
        mMap.setMyLocationEnabled(true);
    }
    
    private void requestPermission() {
        if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION)) {
            Toast.makeText(context, "GPS permission allows us to access location data. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
        } else {
            ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, PERMISSION_REQUEST_CODE);
        }
    }
    
    private boolean checkPermission() {
        int result = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION);
        if (result == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            return false;
        }
    }
Naveen Sharma
quelle
0
if ((ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) && (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)) {

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {

        requestPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA},
                MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
    }
} 
Dhaval Malavia
quelle
0

Überprüfen Sie die Berechtigungen in KOTLIN (RunTime).

Im Manifest: (android.permission.WRITE_EXTERNAL_STORAGE)

    fun checkPermissions(){

      var permission_array=arrayOf(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
      if((ContextCompat.checkSelfPermission(this,permission_array[0]))==PackageManager.PERMI   SSION_DENIED){
        requestPermissions(permission_array,0)
      }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)

          if(requestCode==0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){

       //Do Your Operations Here

        ---------->
         //


          }
    }
Ankush Shrivastava
quelle