Как можно проверить разрешение во время выполнения, не выбрасывая SecurityException?

93

Я разрабатываю функцию, которая может получать / устанавливать ресурс из SD, и если он не найден из SD, то беру его из Asset и, если возможно, записывает актив обратно в SD
Эта функция может проверять вызовом метода, если SD установлен и доступен ...

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

Моя разработанная функция может использоваться из одного приложения (проекта) в другое (с android.permission.WRITE_EXTERNAL_STORAGE или без него)

Затем я хотел бы проверить, имеет ли текущее приложение это конкретное разрешение, не играя с SecurityException.

Существует ли «хороший» способ просмотреть текущие определенные разрешения во время выполнения?

Эммануэль Дево
источник

Ответы:

196

Вы можете использовать Context.checkCallingorSelfPermission()для этого функцию. Вот пример:

private boolean checkWriteExternalPermission()
{
    String permission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
    int res = getContext().checkCallingOrSelfPermission(permission);
    return (res == PackageManager.PERMISSION_GRANTED);            
}
Иназарук
источник
Этот метод может представлять угрозу безопасности.
TalMihr
13
@TalMihr, почему вы считаете, что `checkCallingOrSelfPermission () 'представляет угрозу безопасности?
Уильям
2
Нет. Вы не можете дать себе разрешение во время выполнения.
Anubian Noob,
3
Лучше использовать checkCallingPermission()вместо checkCallingOrSelfPermission()метода.
hasanghaforian
9
Теперь для этого есть оболочка совместимости: ContextCompat.checkSelfPermission
yoah
51

Это тоже другое решение

PackageManager pm = context.getPackageManager();
int hasPerm = pm.checkPermission(
    android.Manifest.permission.WRITE_EXTERNAL_STORAGE, 
    context.getPackageName());
if (hasPerm != PackageManager.PERMISSION_GRANTED) {
   // do stuff
}
user123321
источник
Так что я должен просто обернуть этот код внутри этого оператора if? Я сделал это, чтобы увидеть, получает ли пользователь звонок или находится ли он в режиме разговора, чтобы отключить звук: snag.gy/uIxsv.jpg
Ruchir Baronia
В чем разница между вызовом пакета для разрешения или iPC?
htafoya
1
Большое спасибо, очень полезно. Прекрасно работает на Android 5.1.1. Если вы еще не определили «контекст», вы можете заменить «контекст» на «getBaseContext ()».
JamisonMan111 07
19

Вы также можете использовать это:

private boolean doesUserHavePermission()
{
    int result = context.checkCallingOrSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
    return result == PackageManager.PERMISSION_GRANTED;
}
MrAppa
источник
11

Как документация Google :

// Assume thisActivity is the current activity
int permissionCheck = ContextCompat.checkSelfPermission(thisActivity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
Бени
источник
8

Делюсь своими методами на случай, если они кому-то понадобятся:

 /** 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;

}

И назвать это:

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,
        });
Хтафоя
источник
6

Вы должны проверить разрешения следующим образом (как описано здесь разрешения Android ):

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

затем сравните свой результат с одним из следующих:

result == PackageManager.PERMISSION_DENIED

или:

result == PackageManager.PERMISSION_GRANTED
коробка
источник
Спасибо. Это было полезно.
Судхир Хангер
3

Шаг 1 - добавьте запрос на разрешение

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

Шаг 2 - Обработка результата разрешения

     @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 
            }
        }
    }
}
Джайдип Добария
источник
2

Код, который отлично работает для меня: -

  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
источник
1

Проверить права доступа в KOTLIN (время выполнения)

В манифесте: (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

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


          }
    }
Анкуш Шривастава
источник
0

Включить GPS-местоположение Android Studio

  1. Добавить запись о разрешении в AndroidManifest.Xml

  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;
        }
    }
    
Навин Шарма
источник
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
источник