【问题标题】:Android marshmallow request permission?Android棉花糖请求权限?
【发布时间】:2016-02-13 11:02:50
【问题描述】:

我目前正在开发一个需要多个“危险”权限的应用程序。所以我尝试在Android Marshmallow(API Level 23)中添加“请求许可”,但找不到如何做到这一点。

如何在我的应用中使用新的权限模型请求权限?

【问题讨论】:

标签: android android-6.0-marshmallow android-permissions


【解决方案1】:

我从我的旧代码中找到了一个解决方案,它真的很好用,仍在我的最新应用程序上运行。

把它放在 MainActivity 类或你的 Start Activity 类上

private RequestPermissionHandler mRequestPermissionHandler;

创建时

@Override
protected void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.activity_main);
   mRequestPermissionHandler = new RequestPermissionHandler();
   handleButtonClicked();
}

私有函数handleButtonClicked()

private void handleButtonClicked() {
        mRequestPermissionHandler.requestPermission(this, new String[]{
                Manifest.permission.WRITE_EXTERNAL_STORAGE,
                Manifest.permission.READ_EXTERNAL_STORAGE,
                Manifest.permission.INTERNET,
                Manifest.permission.ACCESS_COARSE_LOCATION,
                Manifest.permission.ACCESS_FINE_LOCATION,
                Manifest.permission.READ_PHONE_STATE,
                Manifest.permission.ACCESS_NETWORK_STATE,
                Manifest.permission.WAKE_LOCK

        }, 123, new RequestPermissionHandler.RequestPermissionListener() {
            @Override
            public void onSuccess() {
                //Toast.makeText(MainActivity.this, "request permission success", Toast.LENGTH_SHORT).show();
            }

            @Override
            public void onFailed() {
                Toast.makeText(MainActivity.this, "request permission failed", Toast.LENGTH_SHORT).show();
            }
        });

    }

RequestPermissionHandler.java 类

import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Build;

import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.core.app.ActivityCompat;

public class RequestPermissionHandler {
    private Activity mActivity;
    private RequestPermissionListener mRequestPermissionListener;
    private int mRequestCode;

    public void requestPermission(Activity activity, @NonNull String[] permissions, int requestCode,
                                  RequestPermissionListener listener) {
        mActivity = activity;
        mRequestCode = requestCode;
        mRequestPermissionListener = listener;

        if (!needRequestRuntimePermissions()) {
            mRequestPermissionListener.onSuccess();
            return;
        }
        requestUnGrantedPermissions(permissions, requestCode);
    }

    private boolean needRequestRuntimePermissions() {
        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.M;
    }

    private void requestUnGrantedPermissions(String[] permissions, int requestCode) {
        String[] unGrantedPermissions = findUnGrantedPermissions(permissions);
        if (unGrantedPermissions.length == 0) {
            mRequestPermissionListener.onSuccess();
            return;
        }
        ActivityCompat.requestPermissions(mActivity, unGrantedPermissions, requestCode);
    }

    private boolean isPermissionGranted(String permission) {
        return ActivityCompat.checkSelfPermission(mActivity, permission)
                == PackageManager.PERMISSION_GRANTED;
    }

    private String[] findUnGrantedPermissions(String[] permissions) {
        List<String> unGrantedPermissionList = new ArrayList<>();
        for (String permission : permissions) {
            if (!isPermissionGranted(permission)) {
                unGrantedPermissionList.add(permission);
            }
        }
        return unGrantedPermissionList.toArray(new String[0]);
    }

    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                           @NonNull int[] grantResults) {
        if (requestCode == mRequestCode) {
            if (grantResults.length > 0) {
                for (int grantResult : grantResults) {
                    if (grantResult != PackageManager.PERMISSION_GRANTED) {
                        mRequestPermissionListener.onFailed();
                        return;
                    }
                }
                mRequestPermissionListener.onSuccess();
            } else {
                mRequestPermissionListener.onFailed();
            }
        }
    }

    public interface RequestPermissionListener {
        void onSuccess();

        void onFailed();
    }
}

【讨论】:

    【解决方案2】:

    将权限添加到AndroidManifest.xml

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <application ...>
     ....
    </application>
    

    检查Android版本是否需要运行时权限。

    if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP_MR1) {
        askForPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, 1);
    }
    

    如果未授予权限,请用户授予权限。

    private void askForPermission(String permission, int requestCode) {
        if (ContextCompat.checkSelfPermission(c, permission)
                != PackageManager.PERMISSION_GRANTED) {
            if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, permission)) {
                Toast.makeText(c, "Please grant the requested permission to get your task done!", Toast.LENGTH_LONG).show();
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
            } else {
                ActivityCompat.requestPermissions(MainActivity.this, new String[]{permission}, requestCode);
            }
        }
    }
    

    无论是否获得许可,都做某事。

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case 1:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    //permission with request code 1 granted
                    Toast.makeText(this, "Permission Granted" , Toast.LENGTH_LONG).show();
                } else {
                    //permission with request code 1 was not granted
                    Toast.makeText(this, "Permission was not Granted" , Toast.LENGTH_LONG).show();
                }
                break;
            default:
                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
    

    【讨论】:

      【解决方案3】:

      Android 中的运行时权限

      private static final int PERMISSION_REQ_WRITE_EXTERNAL_STORAGE = 101;
      
      public void onClick(View view) {
          if (view.getId() == yourBtn.getId()) {
              if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
                  this.storageWork();
              } else {
                  ActivityCompat.requestPermissions(this, new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE }, PERMISSION_REQ_WRITE_EXTERNAL_STORAGE);
              }
          }
      }
      
      @Override
      public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
          if (requestCode == PERMISSION_REQ_WRITE_EXTERNAL_STORAGE) {
              if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                  this.storageWork();
              }
          }
      }
      
      public void storageWork(){
      }
      

      OnClick 方法是检查运行时权限

      如果权限受到限制,则请求权限

      【讨论】:

        【解决方案4】:

        如果您使用的是AndroidX Activity 1.2.0AndroidX Fragment 1.3.0

        您可以使用新的活动结果 API 来请求权限:

        val launcher = registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
            if (isGranted) {
                // Permission granted. Do the tasks.
            }
        }
        launcher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
        

        【讨论】:

        • 警告!截至 2020 年 9 月,这两个库仍处于 alpha 阶段。
        • 仍然不稳定所以我不推荐这个功能。
        【解决方案5】:

        运行时权限会在高度耦合的活动中创建大量样板代码。为了减少代码并使事情变得简单,您可以使用Dexter 库。

        【讨论】:

          【解决方案6】:

          从 Android Marshmallow 开始,我们需要向用户请求特定权限。我们还可以通过代码检查是否已经授予权限。以下是常用权限列表:

          • android.permission_group.CALENDAR

            • android.permission.READ_CALENDAR
            • android.permission.WRITE_CALENDAR
          • android.permission_group.CAMERA

            • android.permission.CAMERA
          • android.permission_group.CONTACTS

            • android.permission.READ_CONTACTS
            • android.permission.WRITE_CONTACTS
            • android.permission.GET_ACCOUNTS
          • android.permission_group.LOCATION

            • android.permission.ACCESS_FINE_LOCATION
            • android.permission.ACCESS_COARSE_LOCATION
          • android.permission_group.MICROPHONE

            • android.permission.RECORD_AUDIO
          • android.permission_group.PHONE

            • android.permission.READ_PHONE_STATE
            • android.permission.CALL_PHONE
            • android.permission.READ_CALL_LOG
            • android.permission.WRITE_CALL_LOG
            • android.permission.ADD_VOICEMAIL
            • android.permission.USE_SIP
            • android.permission.PROCESS_OUTGOING_CALLS
          • android.permission_group.SENSORS

            • android.permission.BODY_SENSORS
          • android.permission_group.SMS

            • android.permission.SEND_SMS
            • android.permission.RECEIVE_SMS
            • android.permission.READ_SMS
            • android.permission.RECEIVE_WAP_PUSH
            • android.permission.RECEIVE_MMS
            • android.permission.READ_CELL_BROADCASTS
          • android.permission_group.STORAGE

            • android.permission.READ_EXTERNAL_STORAGE
            • android.permission.WRITE_EXTERNAL_STORAGE

          这是检查权限的示例代码:

          if (ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_CALENDAR) != PackageManager.PERMISSION_GRANTED) {
              if (ActivityCompat.shouldShowRequestPermissionRationale((Activity) context, Manifest.permission.WRITE_CALENDAR)) {
                  AlertDialog.Builder alertBuilder = new AlertDialog.Builder(context);
                  alertBuilder.setCancelable(true);
                  alertBuilder.setMessage("Write calendar permission is necessary to write event!!!");
                  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.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
                      }
                  });
              } else {
                  ActivityCompat.requestPermissions((Activity)context, new String[]{Manifest.permission.WRITE_CALENDAR}, MY_PERMISSIONS_REQUEST_WRITE_CALENDAR);
              }
          }
          

          【讨论】:

            【解决方案7】:

            我的班级在ActivityFragment 中请求运行时权限

            它还可以帮助您更轻松地显示基本原理或打开设置以在用户拒绝权限后启用权限(带/不带Never ask again)选项更容易

            class RequestPermissionHandler(private val activity: Activity? = null,
                                           private val fragment: Fragment? = null,
                                           private val permissions: Set<String> = hashSetOf(),
                                           private val listener: Listener? = null
            ) {
                private var hadShowRationale: Boolean = false
            
                fun requestPermission() {
                    hadShowRationale = showRationaleIfNeed()
                    if (!hadShowRationale) {
                        doRequestPermission(permissions)
                    }
                }
            
                fun retryRequestDeniedPermission() {
                    doRequestPermission(permissions)
                }
            
                private fun showRationaleIfNeed(): Boolean {
                    val unGrantedPermissions = getPermission(permissions, Status.UN_GRANTED)
                    val permanentDeniedPermissions = getPermission(unGrantedPermissions, Status.PERMANENT_DENIED)
                    if (permanentDeniedPermissions.isNotEmpty()) {
                        val consume = listener?.onShowSettingRationale(unGrantedPermissions)
                        if (consume != null && consume) {
                            return true
                        }
                    }
            
                    val temporaryDeniedPermissions = getPermission(unGrantedPermissions, Status.TEMPORARY_DENIED)
                    if (temporaryDeniedPermissions.isNotEmpty()) {
                        val consume = listener?.onShowPermissionRationale(temporaryDeniedPermissions)
                        if (consume != null && consume) {
                            return true
                        }
                    }
                    return false
                }
            
                fun requestPermissionInSetting() {
                    val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS)
                    val packageName = activity?.packageName ?: run {
                        fragment?.requireActivity()?.packageName
                    }
                    val uri = Uri.fromParts("package", packageName, null)
                    intent.data = uri
                    activity?.apply {
                        startActivityForResult(intent, REQUEST_CODE)
                    } ?: run {
                        fragment?.startActivityForResult(intent, REQUEST_CODE)
                    }
                }
            
                fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
                                               grantResults: IntArray) {
                    if (requestCode == REQUEST_CODE) {
                        for (i in grantResults.indices) {
                            if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                                markNeverAskAgainPermission(permissions[i], false)
                            } else if (!shouldShowRequestPermissionRationale(permissions[i])) {
                                markNeverAskAgainPermission(permissions[i], true)
                            }
                        }
                        var hasShowRationale = false
                        if (!hadShowRationale) {
                            hasShowRationale = showRationaleIfNeed()
                        }
                        if (hadShowRationale || !hasShowRationale) {
                            notifyComplete()
                        }
                    }
                }
            
                fun onActivityResult(requestCode: Int) {
                    if (requestCode == REQUEST_CODE) {
                        getPermission(permissions, Status.GRANTED).forEach {
                            markNeverAskAgainPermission(it, false)
                        }
                        notifyComplete()
                    }
                }
            
                fun cancel() {
                    notifyComplete()
                }
            
                private fun doRequestPermission(permissions: Set<String>) {
                    activity?.let {
                        ActivityCompat.requestPermissions(it, permissions.toTypedArray(), REQUEST_CODE)
                    } ?: run {
                        fragment?.requestPermissions(permissions.toTypedArray(), REQUEST_CODE)
                    }
                }
            
                private fun getPermission(permissions: Set<String>, status: Status): Set<String> {
                    val targetPermissions = HashSet<String>()
                    for (p in permissions) {
                        when (status) {
                            Status.GRANTED -> {
                                if (isPermissionGranted(p)) {
                                    targetPermissions.add(p)
                                }
                            }
                            Status.TEMPORARY_DENIED -> {
                                if (shouldShowRequestPermissionRationale(p)) {
                                    targetPermissions.add(p)
                                }
                            }
                            Status.PERMANENT_DENIED -> {
                                if (isNeverAskAgainPermission(p)) {
                                    targetPermissions.add(p)
                                }
                            }
                            Status.UN_GRANTED -> {
                                if (!isPermissionGranted(p)) {
                                    targetPermissions.add(p)
                                }
                            }
                        }
                    }
                    return targetPermissions
                }
            
                private fun isPermissionGranted(permission: String): Boolean {
                    return activity?.let {
                        ActivityCompat.checkSelfPermission(it, permission) == PackageManager.PERMISSION_GRANTED
                    } ?: run {
                        ActivityCompat.checkSelfPermission(fragment!!.requireActivity(), permission) == PackageManager.PERMISSION_GRANTED
                    }
                }
            
                private fun shouldShowRequestPermissionRationale(permission: String): Boolean {
                    return activity?.let {
                        ActivityCompat.shouldShowRequestPermissionRationale(it, permission)
                    } ?: run {
                        ActivityCompat.shouldShowRequestPermissionRationale(fragment!!.requireActivity(), permission)
                    }
                }
            
                private fun notifyComplete() {
                    listener?.onComplete(getPermission(permissions, Status.GRANTED), getPermission(permissions, Status.UN_GRANTED))
                }
            
                private fun getPrefs(context: Context): SharedPreferences {
                    return context.getSharedPreferences("SHARED_PREFS_RUNTIME_PERMISSION", Context.MODE_PRIVATE)
                }
            
                private fun isNeverAskAgainPermission(permission: String): Boolean {
                    return getPrefs(requireContext()).getBoolean(permission, false)
                }
            
                private fun markNeverAskAgainPermission(permission: String, value: Boolean) {
                    getPrefs(requireContext()).edit().putBoolean(permission, value).apply()
                }
            
                private fun requireContext(): Context {
                    return fragment?.requireContext() ?: run {
                        activity!!
                    }
                }
            
                enum class Status {
                    GRANTED, UN_GRANTED, TEMPORARY_DENIED, PERMANENT_DENIED
                }
            
                interface Listener {
                    fun onComplete(grantedPermissions: Set<String>, deniedPermissions: Set<String>)
                    fun onShowPermissionRationale(permissions: Set<String>): Boolean
                    fun onShowSettingRationale(permissions: Set<String>): Boolean
                }
            
                companion object {
                    const val REQUEST_CODE = 200
                }
            }
            

            Activity 中使用喜欢

            class MainActivity : AppCompatActivity() {
                private lateinit var smsAndStoragePermissionHandler: RequestPermissionHandler
            
                override fun onCreate(savedInstanceState: Bundle?) {
                    super.onCreate(savedInstanceState)
                    setContentView(R.layout.activity_main)
            
                    smsAndStoragePermissionHandler = RequestPermissionHandler(this@MainActivity,
                            permissions = setOf(Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_EXTERNAL_STORAGE),
                            listener = object : RequestPermissionHandler.Listener {
                                override fun onComplete(grantedPermissions: Set<String>, deniedPermissions: Set<String>) {
                                    Toast.makeText(this@MainActivity, "complete", Toast.LENGTH_SHORT).show()
                                    text_granted.text = "Granted: " + grantedPermissions.toString()
                                    text_denied.text = "Denied: " + deniedPermissions.toString()
                                }
            
                                override fun onShowPermissionRationale(permissions: Set<String>): Boolean {
                                    AlertDialog.Builder(this@MainActivity).setMessage("To able to Send Photo, we need SMS and" + " Storage permission")
                                            .setPositiveButton("OK") { _, _ ->
                                                smsAndStoragePermissionHandler.retryRequestDeniedPermission()
                                            }
                                            .setNegativeButton("Cancel") { dialog, _ ->
                                                smsAndStoragePermissionHandler.cancel()
                                                dialog.dismiss()
                                            }
                                            .show()
                                    return true // don't want to show any rationale, just return false here
                                }
            
                                override fun onShowSettingRationale(permissions: Set<String>): Boolean {
                                    AlertDialog.Builder(this@MainActivity).setMessage("Go Settings -> Permission. " + "Make SMS on and Storage on")
                                            .setPositiveButton("Settings") { _, _ ->
                                                smsAndStoragePermissionHandler.requestPermissionInSetting()
                                            }
                                            .setNegativeButton("Cancel") { dialog, _ ->
                                                smsAndStoragePermissionHandler.cancel()
                                                dialog.cancel()
                                            }
                                            .show()
                                    return true
                                }
                            })
            
                    button_request.setOnClickListener { handleRequestPermission() }
                }
            
                private fun handleRequestPermission() {
                    smsAndStoragePermissionHandler.requestPermission()
                }
            
                override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<String>,
                                                        grantResults: IntArray) {
                    super.onRequestPermissionsResult(requestCode, permissions, grantResults)
                    smsAndStoragePermissionHandler.onRequestPermissionsResult(requestCode, permissions,
                            grantResults)
                }
            
                override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
                    super.onActivityResult(requestCode, resultCode, data)
                    smsAndStoragePermissionHandler.onActivityResult(requestCode)
                }
            }
            

            Code on Github

            Demo

            【讨论】:

            • 我能找到的关于请求许可的最佳解决方案
            • @Phan,你有代码 sn-p 请求权限和处理不处理
            • 这段代码似乎在 kotlin 中。有可用的 java 版本吗?
            【解决方案8】:

            我浏览了所有答案,但不满足我确切需要的答案,所以这是一个我编写的并且完美运行的示例,即使用户点击了不再询问复选框。

            1. 创建一个方法,当你想请求运行时权限时会调用它,比如readContacts(),或者你也可以拥有openCamera(),如下所示:

              private void readContacts() {
                  if (!askContactsPermission()) {
                      return;
                  } else {
                      queryContacts();
                  } }
              

            现在我们需要创建askContactsPermission(),您也可以将其命名为askCameraPermission() 或您要请求的任何权限。

                private boolean askContactsPermission() {
                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
                    return true;
                }
                if (checkSelfPermission(READ_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
                    return true;
                }
                if (shouldShowRequestPermissionRationale(READ_CONTACTS)) {
                    Snackbar.make(parentLayout, R.string.permission_rationale, Snackbar.LENGTH_INDEFINITE)
                            .setAction(android.R.string.ok, new View.OnClickListener() {
                                @Override
                                @TargetApi(Build.VERSION_CODES.M)
                                public void onClick(View v) {
                                    requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
                                }
                            }).show();
                } else if (contactPermissionNotGiven) {
                    openPermissionSettingDialog();
                } else {
                    requestPermissions(new String[]{READ_CONTACTS}, REQUEST_READ_CONTACTS);
                    contactPermissionNotGiven = true;
            
                }
                return false;
            }
            

            在编写此函数之前,请确保您已定义如下实例变量,如下所示:

                private View parentLayout;
                private boolean contactPermissionNotGiven;;
            
            
            /**
             * Id to identity READ_CONTACTS permission request.
             */
            private static final int REQUEST_READ_CONTACTS = 0;
            

            现在是覆盖onRequestPermissionsResult方法的最后一步,如下所示:

            /**
             * Callback received when a permissions request has been completed.
             */
            @RequiresApi(api = Build.VERSION_CODES.M)
            @Override
            public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                                   @NonNull int[] grantResults) {
                if (requestCode == REQUEST_READ_CONTACTS) {
                    if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                        queryContacts();
                    }
                }
            }
            

            这里我们完成了运行时权限,插件是openPermissionSettingDialog(),如果用户通过单击不再询问复选框永久禁用权限,它只需打开设置屏幕。下面是方法:

                private void openPermissionSettingDialog() {
                String message = getString(R.string.message_permission_disabled);
                AlertDialog alertDialog =
                        new AlertDialog.Builder(MainActivity.this, AlertDialog.THEME_DEVICE_DEFAULT_LIGHT)
                                .setMessage(message)
                                .setPositiveButton(getString(android.R.string.ok),
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                Intent intent = new Intent();
                                                intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
                                                Uri uri = Uri.fromParts("package", getPackageName(), null);
                                                intent.setData(uri);
                                                startActivity(intent);
                                                dialog.cancel();
                                            }
                                        }).show();
                alertDialog.setCanceledOnTouchOutside(true);
            }
            

            我们错过了什么? 1.在strings.xml中定义使用的字符串

            <string name="permission_rationale">"Contacts permissions are needed to display Contacts."</string>
                <string name="message_permission_disabled">You have disabled the permissions permanently,
                    To enable the permissions please go to Settings -> Permissions and enable the required Permissions,
                    pressing OK you will be navigated to Settings screen</string>
            1. onCreate方法中初始化parentLayout变量

              parentLayout = findViewById(R.id.content);

            2. AndroidManifest.xml中定义所需的权限

            &lt;uses-permission android:name="android.permission.READ_CONTACTS" /&gt;
            1. queryContacts 方法,根据您的需要或运行时权限,您可以调用需要permission 的方法。就我而言,我只是使用加载器来获取联系人,如下所示:

              private void queryContacts() {
              getLoaderManager().initLoader(0, null, this);}
              

            这工作非常愉快的编码:)

            【讨论】:

              【解决方案9】:

              应用程序中任何位置的运行时权限Here is Example

              use dependency
              maven { url 'https://jitpack.io' }
              dependencies {
              implementation 'com.github.irshadsparky:PermissionLib:master-SNAPSHOT'
              }
              

              并像这样调用代码:

              PermissionHelper.requestCamera(new PermissionHelper.OnPermissionGrantedListener() {
              @Override
              public void onPermissionGranted() {
              
              }
              });
              

              你可以找到更多Github

              【讨论】:

                【解决方案10】:

                我使用RxPermission library library 请求许可。因为它是很长的代码,我们必须编写来请求许可。

                RxPermissions rxPermissions = new RxPermissions(this); // where this is an Activity instance // Must be done during an initialization phase like onCreate
                rxPermissions
                    .request(Manifest.permission.CAMERA)
                    .subscribe(granted -> {
                        if (granted) { // Always true pre-M
                           // I can control the camera now
                        } else {
                           // Oups permission denied
                        }
                    });
                

                在你的build.gradle中添加这些依赖

                allprojects {
                    repositories {
                        ...
                        maven { url 'https://jitpack.io' }
                    }
                }
                
                dependencies {
                    implementation 'com.github.tbruyelle:rxpermissions:0.10.1'
                    implementation 'com.jakewharton.rxbinding2:rxbinding:2.1.1'
                }
                

                【讨论】:

                  【解决方案11】:

                  通过避免编写大量代码来获得许可的简单方法,

                  https://github.com/sachinvarma/EasyPermission

                  如何添加:

                  repositories {
                          maven { url "https://jitpack.io" }
                      }
                  
                  implementation 'com.github.sachinvarma:EasyPermission:1.0.1'
                  

                  如何申请许可:

                   List<String> permission = new ArrayList<>();
                   permission.add(EasyPermissionList.READ_EXTERNAL_STORAGE);
                   permission.add(EasyPermissionList.ACCESS_FINE_LOCATION);
                  
                   new EasyPermissionInit(MainActivity.this, permission);
                  

                  希望对某人有所帮助。

                  【讨论】:

                    【解决方案12】:

                    下面这段代码完美运行。我用一个例子来解释。

                    在我的例子中,我将权限检查分别放在一个 util 类中,并通过了我需要从适当的类中检查的特定权限。这使得在整个应用程序中重用权限检查 util 文件成为可能。

                    以下代码部分显示了函数调用。在这种情况下,我正在请求android.Manifest.permission.READ_EXTERNAL_STORAGE 权限。

                    //the below call is from a fragment
                         @OnClick(R.id.button)//butterknife implementation
                            public void attachPressed() {
                                if (PermissionUtils.hasThisPermission(getContext(), android.Manifest.permission.READ_EXTERNAL_STORAGE)) {
                                    onAttachPressed();
                                } else {
                                    PermissionUtils.isPermissionRequestNeeded(getActivity(), this, android.Manifest.permission.READ_EXTERNAL_STORAGE, PermissionUtils.REQUEST_GROUP_STORAGE);
                                }
                            }   
                    

                    在上述情况下,如果允许则检查权限,如果允许,则调用onAttachPressed(); 函数,否则我们检查请求权限。

                    在我的例子中,下面是 util 类中的代码 PermissionUtils

                    public final class PermissionUtils {
                    
                        public static final int REQUEST_GROUP_STORAGE = 1508;
                    
                        private PermissionUtils() {
                        }
                    
                        public static boolean hasThisPermission(Context context, String permission) {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                return ActivityCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
                            } else {
                                return true;
                            }
                        }
                    
                        public static boolean isPermissionRequestNeeded(Activity activity, Fragment fragment, String permission, int requestCode) {
                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !hasThisPermission(activity, permission)) {
                                final String[] permissions = new String[]{permission};
                                if (fragment == null) {
                                    activity.requestPermissions(permissions, requestCode);
                                } else {
                                    fragment.requestPermissions(permissions, requestCode);
                                }
                                return true;
                            }
                            return false;
                        }
                    }
                    

                    在请求之后,如果您可能想从onRequestPermissionsResult 调用函数,否则您需要再次按下按钮才能调用函数。

                    所以只需通过onRequestPermissionsResult 调用它

                    //the below call  is from a fragment
                         @Override
                            public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
                                if (requestCode == PermissionUtils.REQUEST_GROUP_STORAGE && grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                                    onAttachPressed();
                                } else {
                                    Log.e("value", "Permission Denied, You cannot use local drive .");
                                }
                            }
                    

                    【讨论】:

                      【解决方案13】:

                      试试这个

                      这是 Marshmallow 版本中最简单的请求权限。

                       if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED&&ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
                          {
                              //TO do here if permission is granted by user
                          }
                          else
                          {
                              //ask for permission if user didnot given
                              if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
                              {
                                  requestPermissions(new String[]{Manifest.permission.CAMERA,Manifest.permission.ACCESS_FINE_LOCATION}, 0);
                              }
                          }
                      

                      注意:-不要忘记在清单文件中添加相同的权限

                       <uses-permission android:name="android.permission.CAMERA" />
                      <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
                      

                      第二种方法 检查权限的代码是否被授予?

                      ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.CAMERA}, 1);
                      

                      并重写方法

                      @Override
                      public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
                          switch (requestCode) {
                              case 1: {
                                  if (grantResults.length > 0 && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
                               //                    grantResult[0] means it will check for the first postion permission which is READ_EXTERNAL_STORAGE
                              //                    grantResult[1] means it will check for the Second postion permission which is CAMERA
                                      Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
                                  }
                                  else
                                      Toast.makeText(this, "Permission not Granted", Toast.LENGTH_SHORT).show();
                                  return;
                              }
                          }
                      }
                      

                      【讨论】:

                      • 所以你是说如果我以 Marshmallow 或更高版本为目标,那么我不需要在清单中声明权限?我知道无论我们的目标是什么安卓版本,我们都必须把它放进去。如果我错了,请纠正我@Sunil
                      • @Nilabja 在清单中声明权限对于所有 android 版本天气无论是否是棉花糖都是强制性的
                      【解决方案14】:

                      Android-M 即 API 23 引入了Runtime Permissions 以减少 android 设备中的安全漏洞,用户现在可以在运行时直接管理应用程序权限。因此,如果用户拒绝您的应用程序的特定权限,您必须通过询问您在查询中提到的权限对话框。

                      所以在操作之前检查,即检查您是否有权访问资源link,如果您的应用程序没有该特定权限,您可以请求权限link 并处理权限请求响应,如下所示。

                      @Override
                      public void onRequestPermissionsResult(int requestCode,
                              String permissions[], int[] grantResults) {
                          switch (requestCode) {
                              case MY_PERMISSIONS_REQUEST_READ_CONTACTS: {
                                  // If request is cancelled, the result arrays are empty.
                                  if (grantResults.length > 0
                                      && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                      
                                      // permission was granted, yay! Do the
                                      // contacts-related task you need to do.
                      
                                     } else {
                      
                                      // permission denied, boo! Disable the
                                      // functionality that depends on this permission.
                                  }
                                  return;
                              }
                      
                              // other 'case' lines to check for other
                              // permissions this app might request
                          }
                      }
                      

                      最后,如果您打算使用新版本以避免强制关闭,最好通过behavior changes 进行操作:)

                      Permissions Best Practices.

                      您可以通过官方示例应用程序here

                      【讨论】:

                      • 请记住我们必须有 noHistory=false 才能接收回调。如果您没有收到回拨,也请参考this。我浪费了几个小时来弄清楚。
                      【解决方案15】:

                      你可以使用我的库——NoPermission(只是一个类)

                      compile 'ru.alexbykov:nopermission:1.1.1'

                      示例

                      PermissionHelper permissionHelper = new PermissionHelper(this); //don't use getActivity in fragment!
                      
                      permissionHelper.check(Manifest.permission.READ_CONTACTS)
                                      .onSuccess(this::onSuccess)
                                      .onDenied(this::onDenied)
                                      .onNeverAskAgain(this::onNeverAskAgain)
                                      .run();
                      

                      onRequestPermissionResult:

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

                      我觉得 api 比 Google 的 EasyPermissions 更方便。

                      【讨论】:

                        【解决方案16】:
                          if (CommonMethod.isNetworkAvailable(MainActivity.this)) {
                                            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                                int permissionCheck = ContextCompat.checkSelfPermission(MainActivity.this,
                                                        android.Manifest.permission.CAMERA);
                                                if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
                                                    //showing dialog to select image
                                                    callFacebook();
                                                    Log.e("permission", "granted MarshMallow");
                                                } else {
                                                    ActivityCompat.requestPermissions(MainActivity.this,
                                                            new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE,
                                                                    android.Manifest.permission.WRITE_EXTERNAL_STORAGE, android.Manifest.permission.CAMERA}, 1);
                                                }
                                            } else {
                                                Log.e("permission", "Not Required Less than MarshMallow Version");
                                                callFacebook();
                                            }
                                        } else {
                                            CommonMethod.showAlert("Internet Connectivity Failure", MainActivity.this);
                                        }
                        

                        【讨论】:

                          【解决方案17】:

                          Android Marshmallow(API 23) 及以上版本默认禁用所有危险权限(根据官方文档official doc)。安装后,应用程序首次打开时,您必须在运行时授予权限。

                          我通过以下方式实现了这一点:

                          public class MarshMallowPermission {
                          
                              public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_GALLERY = 0;
                              public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_CAMERA = 1;
                              public static final int EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE = 2;
                              public static final int CAMERA_PERMISSION_REQUEST_CODE = 3;
                              public static final int LOCATION_PERMISSION_REQUEST_CODE = 4;
                              Activity activity;
                              Context mContext;
                          
                              public MarshMallowPermission(Activity activity) {
                                  this.activity = activity;
                                  this.mContext = activity;
                              }
                          
                              public boolean checkPermissionForExternalStorage(){
                                  int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
                                  if (result == PackageManager.PERMISSION_GRANTED){
                                      return true;
                                  } else {
                                      return false;
                                  }
                              }
                          
                              public boolean checkPermissionForCamera(){
                                  int result = ContextCompat.checkSelfPermission(activity, Manifest.permission.CAMERA);
                                  if (result == PackageManager.PERMISSION_GRANTED){
                                      return true;
                                  } else {
                                      return false;
                                  }
                              }
                          
                              public boolean checkLocationPermission(){
                          
                                  int result = ActivityCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_FINE_LOCATION);
                                  if (result == PackageManager.PERMISSION_GRANTED){
                                      return true;
                                  } else {
                                      return false;
                                  }
                              }
                          
                              public void requestPermissionForExternalStorage(int requestCode){
                                  if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE)){
                                      Toast.makeText(mContext.getApplicationContext(), "External Storage permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
                                  } else {
                                      ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},requestCode);
                                  }
                              }
                          
                              public void requestPermissionForCamera(){
                                  if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.CAMERA)){
                                      Toast.makeText(mContext.getApplicationContext(), "Camera permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
                                  } else {
                                      ActivityCompat.requestPermissions(activity,new String[]{Manifest.permission.CAMERA},CAMERA_PERMISSION_REQUEST_CODE);
                                  }
                              }
                              public void requestPermissionForLocation(){
                                  if (ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_FINE_LOCATION) && ActivityCompat.shouldShowRequestPermissionRationale(activity, Manifest.permission.ACCESS_COARSE_LOCATION)){
                                      Toast.makeText(mContext.getApplicationContext(), "Location permission needed. Please allow in App Settings for additional functionality.", Toast.LENGTH_LONG).show();
                                  } else {
                                      ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION}, LOCATION_PERMISSION_REQUEST_CODE);
                                  }
                              }
                          }
                          

                          IN 你的活动课:

                           public class MainActivity extends AppCompatActivity{
                          
                             private MarshMallowPermission marshMallowPermission;
                          
                              @Override
                              protected void onCreate(Bundle savedInstanceState) {
                                  Log.d("NavHome", "Oncreate_nav");
                                  super.onCreate(savedInstanceState);
                                  setContentView(R.layout.activity_main);
                          
                                  marshMallowPermission = new MarshMallowPermission(MainActivity.this);
                          
                          
                          
                                  if (!marshMallowPermission.checkPermissionForExternalStorage()) {
                                      marshMallowPermission.requestPermissionForExternalStorage(MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE);
                                  }
                              }
                          
                              @Override
                              public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
                                  super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                          
                                  switch (requestCode) {
                                      case MarshMallowPermission.EXTERNAL_STORAGE_PERMISSION_REQUEST_CODE_BY_LOAD_PROFILE:
                                          if (grantResults.length > 0
                                                  && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                          
                                              //permission granted successfully
                          
                                          } else {
                          
                                           //permission denied
                          
                                          }
                                          break;
                              }
                              }
                          
                          }
                          

                          【讨论】:

                            【解决方案18】:

                            这可能是一种更清洁的方式。将所有权限添加到数组中,例如

                            private static final String[] INITIAL_PERMS={
                                        android.Manifest.permission.ACCESS_FINE_LOCATION,
                                        android.Manifest.permission.ACCESS_COARSE_LOCATION
                                };
                                private static final int INITIAL_REQUEST=1337;
                            

                            无论你的权限是什么,每个权限的创建方法

                            @RequiresApi(api = Build.VERSION_CODES.M)
                            private boolean canAccessFineLocation() {
                                return(hasPermission(Manifest.permission.ACCESS_FINE_LOCATION));
                            }
                            
                            @RequiresApi(api = Build.VERSION_CODES.M)
                            private boolean canAccessCoarseLocation() {
                                return(hasPermission(Manifest.permission.ACCESS_COARSE_LOCATION));
                            }
                            
                            @RequiresApi(api = Build.VERSION_CODES.M)
                            private boolean hasPermission(String perm) {
                                return(PackageManager.PERMISSION_GRANTED == checkSelfPermission(perm));
                            }
                            

                            onCreate中调用这个方法

                             if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                                  if(!canAccessCoarseLocation() || !canAccessFineLocation()){
                                        requestPermissions(INITIAL_PERMS, INITIAL_REQUEST);
                                    }
                             }
                            

                            现在覆盖 onRequestPermissionsResult

                            @Override
                            public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
                            
                                if(requestCode == INITIAL_REQUEST){
                                    if (canAccessFineLocation() && canAccessCoarseLocation())  {
                                        //call your method
                                    }
                                    else {
                                        //show Toast or alert that this permissions is neccessary
                                    }
                                }
                            }
                            

                            【讨论】:

                            • 没有 requireApi,我的活动出错了我使用 TragetApi 注释
                            • @Jawad,这很有效,但如果你添加一些被拒绝的权限回调会更好
                            【解决方案19】:

                            为了处理运行时权限,谷歌提供了一个库项目。你可以从这里查看https://github.com/googlesamples/easypermissions

                            EasyPermissions 通过将以下依赖项添加到您的 build.gradle 文件来安装:

                            dependencies {
                            compile 'pub.devrel:easypermissions:0.3.0'
                            }
                            

                            要开始使用 EasyPermissions,请让您的 Activity(或 Fragment)覆盖 onRequestPermissionsResult 方法:

                            public class MainActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks {
                            
                            @Override
                            protected void onCreate(Bundle savedInstanceState) {
                                super.onCreate(savedInstanceState);
                                setContentView(R.layout.activity_main);
                            }
                            
                            @Override
                            public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
                                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                            
                                // Forward results to EasyPermissions
                                EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this);
                            }
                            
                            @Override
                            public void onPermissionsGranted(int requestCode, List<String> list) {
                                // Some permissions have been granted
                                // ...
                            }
                            
                            @Override
                            public void onPermissionsDenied(int requestCode, List<String> list) {
                                // Some permissions have been denied
                                // ...
                            }
                            }
                            

                            在这里,您将获得一个工作示例,该库是如何工作的 https://github.com/milon87/EasyPermission

                            【讨论】:

                              【解决方案20】:

                              有一个很好的库可以在后台服务需要权限时询问权限时使用。尽管库的一个限制是它不能仅用于确定当前是否授予应用程序权限。它总是询问用户应用是否还没有它们。

                              试试吧,因为它让生活更简单:Android Permissions

                              【讨论】:

                                【解决方案21】:

                                我使用这个结构来检查我的应用是否有权限,如果没有权限则请求。所以在我要检查的主要代码中写以下内容:

                                int MyVersion = Build.VERSION.SDK_INT;
                                if (MyVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
                                                if (!checkIfAlreadyhavePermission()) {
                                                    requestForSpecificPermission();
                                                }
                                }
                                

                                模块 checkIfAlreadyhavePermission() 实现为:

                                private boolean checkIfAlreadyhavePermission() {
                                    int result = ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS);
                                    if (result == PackageManager.PERMISSION_GRANTED) {
                                        return true;
                                    } else {
                                        return false;
                                    }
                                }
                                

                                模块 requestForSpecificPermission() 实现为:

                                private void requestForSpecificPermission() {
                                        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.GET_ACCOUNTS, Manifest.permission.RECEIVE_SMS, Manifest.permission.READ_SMS, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, 101);
                                }
                                

                                并在 Activity 中覆盖:

                                @Override
                                public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
                                    switch (requestCode) {
                                        case 101:
                                            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                                                //granted
                                            } else {
                                                //not granted
                                            }
                                            break;
                                        default:
                                            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                                    }
                                }
                                

                                更多详情请参考此链接:http://revisitingandroid.blogspot.in/2017/01/how-to-check-and-request-for-run-time.html

                                【讨论】:

                                • 友情建议:将checkIfAlreadyhavePermission中的if语句替换为return result == PackageManager.PERMISSION_GRANTED;
                                【解决方案22】:

                                一次要获得多个权限,您可以使用它。这对我有用..我得到了另一个解决方案。如果你给你的 targetSdkVersion bellow 22 它对我有用。它的行为就像从 manifest.xml 获得许可一样。经过测试并为我工作。

                                final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
                                
                                    private void insertDummyContactWrapper() {
                                        List<String> permissionsNeeded = new ArrayList<String>();
                                
                                        final List<String> permissionsList = new ArrayList<String>();
                                        if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
                                            permissionsNeeded.add("GPS");
                                        if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
                                            permissionsNeeded.add("Read Contacts");
                                        if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
                                            permissionsNeeded.add("Write Contacts");
                                
                                        if (permissionsList.size() > 0) {
                                            if (permissionsNeeded.size() > 0) {
                                                // Need Rationale
                                                String message = "You need to grant access to " + permissionsNeeded.get(0);
                                                for (int i = 1; i < permissionsNeeded.size(); i++)
                                                    message = message + ", " + permissionsNeeded.get(i);
                                                showMessageOKCancel(message,
                                                        new DialogInterface.OnClickListener() {
                                                            @Override
                                                            public void onClick(DialogInterface dialog, int which) {
                                                                requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                                                        REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                                                            }
                                                        });
                                                return;
                                            }
                                            requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
                                                    REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
                                            return;
                                        }
                                
                                        insertDummyContact();
                                    }
                                
                                    private boolean addPermission(List<String> permissionsList, String permission) {
                                        if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                                            permissionsList.add(permission);
                                            // Check for Rationale Option
                                            if (!shouldShowRequestPermissionRationale(permission))
                                                return false;
                                        }
                                        return true;
                                    }
                                
                                
                                
                                
                                
                                
                                @Override
                                    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
                                        switch (requestCode) {
                                            case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
                                                {
                                                Map<String, Integer> perms = new HashMap<String, Integer>();
                                                // Initial
                                                perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
                                                perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
                                                perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);
                                                // Fill with results
                                                for (int i = 0; i < permissions.length; i++)
                                                    perms.put(permissions[i], grantResults[i]);
                                                // Check for ACCESS_FINE_LOCATION
                                                if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
                                                        && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
                                                        && perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
                                                    // All Permissions Granted
                                                    insertDummyContact();
                                                } else {
                                                    // Permission Denied
                                                    Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
                                                            .show();
                                                }
                                                }
                                                break;
                                            default:
                                                super.onRequestPermissionsResult(requestCode, permissions, grantResults);
                                        }
                                    }
                                

                                了解更多详情。检查下面的链接

                                https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en

                                【讨论】:

                                • 设置 targetSdkVersion bellow 22 会起作用,但是使用 android M 的用户拒绝设置的一项权限会发生什么?
                                • 是的..你是对的,此时应用程序会崩溃。所以,那个时候你需要再次检查用户是否拒绝许可..我不测试它,但我希望它会工作。形成用户的每一个动作,最好检查是否授予权限。
                                【解决方案23】:

                                使用以下代码打开一个对话框:

                                 ActivityCompat.requestPermissions(MainActivity.this,
                                                    new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
                                                    1);
                                

                                获取Activity结果如下:

                                @Override
                                public void onRequestPermissionsResult(int requestCode,
                                                                       String permissions[], int[] grantResults) {
                                    switch (requestCode) {
                                        case 1: {
                                
                                          // If request is cancelled, the result arrays are empty.
                                          if (grantResults.length > 0
                                                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                                
                                                // permission was granted, yay! Do the
                                                // contacts-related task you need to do.          
                                            } else {
                                
                                                // permission denied, boo! Disable the
                                                // functionality that depends on this permission.
                                                Toast.makeText(MainActivity.this, "Permission denied to read your External storage", Toast.LENGTH_SHORT).show();
                                            }
                                            return;
                                        }
                                
                                        // other 'case' lines to check for other
                                        // permissions this app might request
                                    }
                                }
                                

                                更多信息:https://developer.android.com/training/permissions/requesting.html

                                【讨论】:

                                • 我已经为它创建了库。通过简单的步骤即可轻松使用。 github.com/Kishanjvaghela/Ask-Permission
                                • 这部分也适用于如果用户单击取消:else if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_DENIED)
                                • ActivityCompat.requestPermissions 是否已弃用? (在努加特)
                                • 你从哪里得到这个变量?活动兼容性?
                                • @gumuruh,什么变量?
                                【解决方案24】:

                                我将它用作基本的 Fragment 类。我只请求片段的权限,但你可以重构它并制作一个类似的 Activity 版本。

                                public class BaseFragment extends Fragment {
                                
                                    private static final int PERMISSION_REQUEST_BLOCK_INTERNAL = 555;
                                    private static final String PERMISSION_SHARED_PREFERENCES = "permissions";
                                
                                    @Override
                                    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
                                        if (requestCode == PERMISSION_REQUEST_BLOCK_INTERNAL) {
                                            boolean allPermissionsGranted = true;
                                
                                            for (int iGranting : grantResults) {
                                                if (iGranting != PermissionChecker.PERMISSION_GRANTED) {
                                                    allPermissionsGranted = false;
                                                    break;
                                                }
                                            }
                                
                                            if (allPermissionsGranted && permissionBlock != null) {
                                                permissionBlock.run();
                                            }
                                
                                            permissionBlock = null;
                                        }
                                    }
                                
                                    public void runNowOrAskForPermissionsFirst(String permission, Runnable block) {
                                        if (hasPermission(permission)) {
                                            block.run();
                                        } else if (!hasPermissionOrWillAsk(permission)) {
                                            permissionBlock = block;
                                            askForPermission(permission, PERMISSION_REQUEST_BLOCK_INTERNAL);
                                        }
                                    }
                                
                                    public boolean hasPermissionOrWillAsk(String permission) {
                                        boolean hasPermission = hasPermission(permission);
                                        boolean hasAsked = hasPreviouslyAskedForPermission(permission);
                                        boolean shouldExplain = shouldShowRequestPermissionRationale(permission);
                                
                                        return hasPermission || (hasAsked && !shouldExplain);
                                    }
                                
                                    private boolean hasPermission(String permission) {
                                        return (ContextCompat.checkSelfPermission(getContext(), permission) == PackageManager.PERMISSION_GRANTED);
                                    }
                                
                                    private boolean hasPreviouslyAskedForPermission(String permission) {
                                        SharedPreferences prefs = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE);
                                        return prefs.getBoolean(permission, false);
                                    }
                                
                                    private void askForPermission(String permission, int requestCode) {
                                        SharedPreferences.Editor editor = getContext().getSharedPreferences(PERMISSION_SHARED_PREFERENCES, Context.MODE_PRIVATE).edit();
                                
                                        editor.putBoolean(permission, true);
                                        editor.apply();
                                
                                        requestPermissions(new String[] { permission }, requestCode);
                                    }
                                }
                                

                                您应该使用两种关键方法:

                                • hasPermissionOrWillAsk - 使用它来查看是否已请求权限并被不想再次请求的用户拒绝。当用户给出他们不想要某个功能的最终答案时,这对于禁用 UI 很有用。

                                • runNowOrAskForPermissionsFirst - 使用它来运行一些需要权限的代码。如果用户已经授予权限,代码将立即运行。否则,如果用户授予权限,代码将稍后运行。或者根本没有。这很好,因为您在一个地方指定了代码。

                                这是一个例子:

                                mFragment.runNowOrAskForPermissionsFirst(Manifest.permission.ACCESS_FINE_LOCATION, new Runnable() {
                                    @Override
                                    public void run() {
                                        ...do something if we have permission...
                                    }
                                });
                                

                                很高兴收到对此的反馈。并不是说这个特定示例稍微简化了一点,因为您还需要检查设备上是否启用了定位服务。 (这与权限不同。)此外,它一次只支持一个权限,但如果您需要一次支持多个权限,修改起来也很简单。

                                【讨论】:

                                  【解决方案25】:

                                  我使用了这个由谷歌开发者编写的包装器(推荐)。它超级好用。

                                  https://github.com/googlesamples/easypermissions

                                  处理检查并在需要时请求许可的功能

                                  public void locationAndContactsTask() {
                                      String[] perms = { Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.READ_CONTACTS };
                                      if (EasyPermissions.hasPermissions(this, perms)) {
                                          // Have permissions, do the thing!
                                          Toast.makeText(this, "TODO: Location and Contacts things", Toast.LENGTH_LONG).show();
                                      } else {
                                          // Ask for both permissions
                                          EasyPermissions.requestPermissions(this, getString(R.string.rationale_location_contacts),
                                                  RC_LOCATION_CONTACTS_PERM, perms);
                                      }
                                  }
                                  

                                  编码愉快:)

                                  【讨论】:

                                  • @Farhan 我明白 :) 我只希望 Android 的 API 更简单,这样我们就不必使用包装器了。
                                  • 我看不到“RC_CAMERA_AND_LOCATION”来自哪里,或者在哪里可以找到其他权限而不是那些,你知道它来自哪里吗?
                                  猜你喜欢
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2017-05-12
                                  • 1970-01-01
                                  • 1970-01-01
                                  • 2016-06-22
                                  • 1970-01-01
                                  相关资源
                                  最近更新 更多