在 Android Marshmallow 检查权限

Posted

技术标签:

【中文标题】在 Android Marshmallow 检查权限【英文标题】:Check Permission at Android Marshmallow 【发布时间】:2017-07-15 16:44:50 【问题描述】:

我正在 Eclipse IDE 中编写一个图形程序并使用 23 api 版本进行编译,minSdkVersion="11",这对我来说保持 targetSdkVersion="16" 很重要。 我必须在我的一项活动(DarjActivity)中使用设备摄像头。一切正常,但由于我试图改进我的代码以支持 android marshmallow (api 23) 的权限,所以添加了导致一些错误的 Check_Permission 类。请指导我解决这个令人困惑的问题! 感谢您的问候。

DarjActivity 类:

private void selectImage() 
    final CharSequence[] items =  "camera", "gallery",
        "cancel" ;

  AlertDialog.Builder builder = new AlertDialog.Builder(DarjActivity.this);
  builder.setTitle("capture photo");
  builder.setItems(items, new DialogInterface.OnClickListener() 
    @Override
     public void onClick(DialogInterface dialog, int item) 
        boolean result=Check_Permission.checkPermission(DarjActivity.this);

        if (items[item].equals("camera")) 
       //    userChoosenTask="Take Photo";
           if(result);
               Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(intent, 1);

         else if (items[item].equals("gallery")) 
       //    userChoosenTask="Choose from Library";
           if(result);

           Intent intent = new Intent();
        intent.setType("image/*");
        intent.setAction(Intent.ACTION_GET_CONTENT);//
        startActivityForResult(Intent.createChooser(intent, "select"),2);

         else if (items[item].equals("cancel")) 
            dialog.dismiss();
      
        
  );
  builder.show();

Check_Permission 类:

package com.codegostarNiloo.negar;

import android.Manifest;
import android.annotation.TargetApi;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.os.Build;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;

public class Check_Permission  
   public static final int MY_PERMISSIONS_REQUEST_CAMERA = 123;

   public static boolean checkPermission(final Context context)
   
       int currentAPIVersion = Build.VERSION.SDK_INT;
       if(Build.VERSION.SDK_INT >= 23)
//         if(currentAPIVersion>=Build.VERSION_CODES.M)
       
          if (ContextCompat.checkSelfPermission((Activity) context, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) 
               if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.CAMERA)) 
                   AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
                   alertBuilder.setCancelable(true);
                   alertBuilder.setTitle("Check Permission");
                   alertBuilder.setMessage("pleas let this applicathion to use your device camera");
                   alertBuilder.setPositiveButton(android.R.string.yes, new DialogInterface.OnClickListener() 
                      @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
                       public void onClick(DialogInterface dialog, int which) 
                           ActivityCompat.requestPermissions((Activity) context, new String[]Manifest.permission.READ_EXTERNAL_STORAGE, MY_PERMISSIONS_REQUEST_CAMERA);
                       
                   );
                   AlertDialog alert = alertBuilder.create();
                   alert.show();

                else 
                   ActivityCompat.requestPermissions((Activity) context, new String[]Manifest.permission.CAMERA, MY_PERMISSIONS_REQUEST_CAMERA);
               
              return false;
            else 
               return true;
           
        else 
           return true;
       
   

在 Check_Permission 类中, (checkSelfPermission) 、 (shouldShowRequestPermissionRationale) 和 (requestPermissions) 方法发生错误。 对于它们的第一个参数,我放置了(Activity)上下文、上下文上下文、上下文、this.Activity、Activity.this、DarjActivity 和 ext。我更新并替换了 bin 文件夹中的一些 android-support-v4.jar 文件。

AndroidManifest 权限:

<uses-feature android:name="android.hardware.camera"></uses-feature>
<uses-feature android:name="android.hardware.camera" android:required="false"></uses-feature>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="ANDROID.PERMISSION.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-sdk
    android:minSdkVersion="11"
    android:targetSdkVersion="16" />

【问题讨论】:

忽略代码中的任何错误,如果您拒绝将targetSdkVersion 向上移动,这是浪费的工作。运行时权限仅在您面向 API 23 及更高版本时可用。为什么不能更改目标版本? 发生了什么错误?请更具体 @0X0nosugar (error): ContextCompat 类型的方法 checkSelfPermission(Activity, String) 未定义 ActivityCompat 类型的方法 shouldShowRequestPermissionRationale(Activity, String) 未定义 @Tanis.7x :我已经改进了我的目标和构建目标版本到 23 并且错误仍然存​​在! :( 【参考方案1】:

第 1 步。

首先在您的活动中实现 ActivityCompat.OnRequestPermissionsResultCallback

    private static final int REQUEST_CAMERA_PERMISSION = 1;
    private static final String FRAGMENT_DIALOG = "dialog";

第 2 步覆盖方法

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

    switch (requestCode)
    
        case REQUEST_CAMERA_PERMISSION:
            if (permissions.length != 1 || grantResults.length != 1) 
                throw new RuntimeException("Error on requesting camera permission.");
            
            if (grantResults[0] != PackageManager.PERMISSION_GRANTED) 
                Toast.makeText(this, R.string.camera_permission_not_granted,
                        Toast.LENGTH_SHORT).show();
            
            // No need to start camera here; it is handled by onResume
            break;
    



@Override
protected void onResume()

    super.onResume();
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
            == PackageManager.PERMISSION_GRANTED) 

       //   Do whatever you want to do after the permission granted.


     else if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.CAMERA)) 
        ConfirmationDialogFragment
                .newInstance(R.string.camera_permission_confirmation,
                        new String[]Manifest.permission.CAMERA,
                        REQUEST_CAMERA_PERMISSION,
                        R.string.camera_permission_not_granted)
                .show(getSupportFragmentManager(), FRAGMENT_DIALOG);
     else 
        ActivityCompat.requestPermissions(this, new String[]Manifest.permission.CAMERA,
                REQUEST_CAMERA_PERMISSION);
    




步骤 3 编写一个对话框片段来请求权限 - 公共静态类 ConfirmationDialogFragment 扩展 DialogFragment

    private static final String ARG_MESSAGE = "message";
    private static final String ARG_PERMISSIONS = "permissions";
    private static final String ARG_REQUEST_CODE = "request_code";
    private static final String ARG_NOT_GRANTED_MESSAGE = "not_granted_message";

    public static ConfirmationDialogFragment newInstance(@StringRes int message,
                                                         String[] permissions, int requestCode, @StringRes int notGrantedMessage) 
        ConfirmationDialogFragment fragment = new ConfirmationDialogFragment();
        Bundle args = new Bundle();
        args.putInt(ARG_MESSAGE, message);
        args.putStringArray(ARG_PERMISSIONS, permissions);
        args.putInt(ARG_REQUEST_CODE, requestCode);
        args.putInt(ARG_NOT_GRANTED_MESSAGE, notGrantedMessage);
        fragment.setArguments(args);
        return fragment;
    

    @NonNull
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) 
        final Bundle args = getArguments();
        return new AlertDialog.Builder(getActivity())
                .setMessage(args.getInt(ARG_MESSAGE))
                .setPositiveButton(android.R.string.ok,
                        new DialogInterface.OnClickListener() 
                            @Override
                            public void onClick(DialogInterface dialog, int which) 
                                String[] permissions = args.getStringArray(ARG_PERMISSIONS);
                                if (permissions == null)
                                
                                    throw new IllegalArgumentException();
                                
                                ActivityCompat.requestPermissions(getActivity(),
                                        permissions, args.getInt(ARG_REQUEST_CODE));
                            
                        )
                .setNegativeButton(android.R.string.cancel,
                        new DialogInterface.OnClickListener() 
                            @Override
                            public void onClick(DialogInterface dialog, int which) 
                                Toast.makeText(getActivity(),
                                        args.getInt(ARG_NOT_GRANTED_MESSAGE),
                                        Toast.LENGTH_SHORT).show();
                            
                        )
                .create();
    


第 4 步始终检查 onResume() 以获得相机权限

    if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
            == PackageManager.PERMISSION_GRANTED) 
   
       // Do whatever you want to do if permission granted
     
   else if (ActivityCompat.shouldShowRequestPermissionRationale(this,
            Manifest.permission.CAMERA)) 
        ConfirmationDialogFragment
                .newInstance(R.string.camera_permission_confirmation,
                        new String[]Manifest.permission.CAMERA,
                        REQUEST_CAMERA_PERMISSION,
                        R.string.camera_permission_not_granted)
                .show(getSupportFragmentManager(), FRAGMENT_DIALOG);
        else 
        ActivityCompat.requestPermissions(this, new String[]              Manifest.permission.CAMERA,
                     REQUEST_CAMERA_PERMISSION);
    

希望对你有帮助!!

【讨论】:

感谢您的帮助。但是,我无法在我的 DarjActivity 中实现 ActivityCompat.OnRequestPermissionsResultCallback,因为在 eclipse 中发生错误(ActivityCompat 无法解析为类型)并提供快速修复:创建接口 ActivityCompat。 1-请写下如何实现它和它的进口,好吗? 2-我的 DarjActivity 中是否有第一步和第二步,或者我必须创建一个新类?【参考方案2】:

或者只使用像PermissionsDispatcher 或Dexter 或EasyPermissions 或许多others 这样的简单库。为什么你需要用权限处理来污染你的代码?

【讨论】:

那么日食呢,亲爱的?!

以上是关于在 Android Marshmallow 检查权限的主要内容,如果未能解决你的问题,请参考以下文章

Android Marshmallow:使用 Espresso 测试权限?

Android 6.0 (Marshmallow) READ_CONTACTS 权限允许在权限被拒绝时读取联系人的姓名

在 Genymotion 中测试打盹功能(Android 6.0 Marshmallow)

如何在 Android 6.0 Marshmallow 中访问相机?

如何在打盹模式下移动设备(Android Preview M / Marshmallow)?

Android 6.0 Marshmallow介绍