Làm cách nào để có thể kiểm tra quyền trong thời gian chạy mà không phải ném SecurityException?


91

Tôi thiết kế một hàm có thể lấy / đặt tài nguyên từ SD và nếu không tìm thấy từ sd thì lấy nó từ Nội dung và nếu có thể ghi nội dung trở lại SD
Hàm này có thể kiểm tra bằng cách gọi nếu SD được gắn và có thể truy cập ...

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

Chức năng được thiết kế của tôi có thể được sử dụng từ ứng dụng (dự án) này sang ứng dụng khác (có hoặc không có android.permission.WRITE_EXTERNAL_STORAGE)

Sau đó, tôi muốn kiểm tra xem ứng dụng hiện tại có quyền cụ thể này hay không mà không cần chơi với SecurityException.

Nó có tồn tại một cách "hay" để tham khảo các quyền được xác định hiện tại trong thời gian chạy không?

Câu trả lời:


195

Bạn có thể sử dụng Context.checkCallingorSelfPermission()chức năng cho việc này. Đây là một ví dụ:

private boolean checkWriteExternalPermission()
{
    String permission = android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
    int res = getContext().checkCallingOrSelfPermission(permission);
    return (res == PackageManager.PERMISSION_GRANTED);            
}

Phương pháp này có thể có rủi ro bảo mật.
TalMihr

13
@TalMihr tại sao bạn tin rằng checkCallingOrSelfPermission () 'gây ra rủi ro bảo mật?
William

2
Không. Bạn không thể cho phép mình trong thời gian chạy.
Anubian Noob

3
Tốt hơn là sử dụng checkCallingPermission()thay vì checkCallingOrSelfPermission()phương pháp.
hasanghaforian

9
Bây giờ có một wrapper comatibility cho việc này: ContextCompat.checkSelfPermission
yoah

51

Đây cũng là một giải pháp khác

PackageManager pm = context.getPackageManager();
int hasPerm = pm.checkPermission(
    android.Manifest.permission.WRITE_EXTERNAL_STORAGE, 
    context.getPackageName());
if (hasPerm != PackageManager.PERMISSION_GRANTED) {
   // do stuff
}

Vì vậy, tôi có nên bọc mã này bên trong câu lệnh if đó không? Tôi làm điều này để xem nếu người dùng đang nhận được một cuộc gọi, hoặc là trong một cuộc gọi, tắt âm thanh: snag.gy/uIxsv.jpg
Ruchir Baronia

Đâu là sự khác biệt khi gọi gói để xin phép hoặc iPC?
htafoya

1
Cảm ơn bạn rất nhiều, rất hữu ích. Hoạt động như một sự quyến rũ trên Android 5.1.1. Nếu bạn chưa xác định "ngữ cảnh", bạn có thể thay thế "ngữ cảnh" bằng "getBaseContext ()".
JamisonMan111

19

Bạn cũng có thể sử dụng cái này:

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

11

Giống như tài liệu của Google :

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

8

Chia sẻ phương pháp của tôi trong trường hợp ai đó cần chúng:

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

}

Và để gọi nó là:

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

5

Bạn nên kiểm tra các quyền theo cách sau (như được mô tả ở đây các quyền của Android ):

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

sau đó, so sánh kết quả của bạn với:

result == PackageManager.PERMISSION_DENIED

hoặc là:

result == PackageManager.PERMISSION_GRANTED

Cảm ơn. Điều này rất hữu ích.
Sudhir Khanger

3

Bước 1 - thêm yêu cầu quyền

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

Bước 2 - Xử lý kết quả Quyền

     @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

Mã hoạt động tốt đối với tôi là: -

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

0

Bật vị trí GPS cho Android Studio

  1. Thêm mục nhập quyền trong 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);
    }
} 

0

Kiểm tra quyền trong KOTLIN (RunTime)

Trong Tệp kê khai: (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

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


          }
    }
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.