简体   繁体   English

Android marshmallow 请求权限?

[英]Android marshmallow request permission?

I am currently working on an application that requires several "dangerous" permissions.我目前正在开发一个需要多个“危险”权限的应用程序。 So I tried adding "ask for permission" as required in Android Marshmallow(API Level 23), but couldn't find how to do it.所以我尝试在 Android Marshmallow(API 级别 23)中添加“请求许可”,但找不到怎么做。

How can I ask for permission using new permission model in my app?如何在我的应用程序中使用新权限 model 请求权限?

Open a Dialog using the code below:使用以下代码打开对话框:

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

Get the Activity result as below:获取活动结果如下:

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

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

This structure I am using to check if my app has permission and than request if it does not have permission.我使用这个结构来检查我的应用程序是否有权限,如果没有权限则请求。 So in my main code from where i want to check write following :因此,在我要检查的主要代码中,写入以下内容:

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

Module checkIfAlreadyhavePermission() is implemented as :模块 checkIfAlreadyhavePermission() 实现为:

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

Module requestForSpecificPermission() is implemented as :模块 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);
}

and Override in Activity :并在 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);
    }
}

Refer this link for more details : http://revisitingandroid.blogspot.in/2017/01/how-to-check-and-request-for-run-time.html有关更多详细信息,请参阅此链接: http : //revisitingandroid.blogspot.in/2017/01/how-to-check-and-request-for-run-time.html

Starting in Android Marshmallow, we need to request the user for specific permissions.从 Android Marshmallow 开始,我们需要向用户请求特定的权限。 We can also check through code if the permission is already given.如果权限已经给我们,我们也可以通过代码检查。 Here is a list of commonly needed permissions:以下是常用权限列表:

  • android.permission_group.CALENDAR android.permission_group.CALENDAR

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

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

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

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

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

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

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

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

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

Here is sample code to check for permissions:以下是检查权限的示例代码:

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

I have used this wrapper (Recommended) written by google developers.我使用了谷歌开发人员编写的这个包装器(推荐)。 Its super easy to use.它超级容易使用。

https://github.com/googlesamples/easypermissions https://github.com/googlesamples/easypermissions

Function dealing with checking and ask for permission if required如果需要,处理检查和请求许可的功能

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

Happy coding :)快乐编码:)

My class for request runtime permissions in Activity or Fragment我在ActivityFragment请求运行时权限的类

It also help you show rationale or open Setting to enable permission after user denied a permission (with/without Never ask again ) option easier它还可以帮助您显示基本原理或打开设置以在用户拒绝权限后启用权限(有/没有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
    }
}

Using in Activity likeActivity使用

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 Github 上的代码

Demo演示

Android-M ie, API 23 introduced Runtime Permissions for reducing security flaws in android device, where users can now directly manage app permissions at runtime.so if the user denies a particular permission of your application you have to obtain it by asking the permission dialog that you mentioned in your query. Android-M 即 API 23 引入了运行时权限以减少 Android 设备中的安全漏洞,用户现在可以在运行时直接管理应用程序权限。因此,如果用户拒绝您的应用程序的特定权限,您必须通过询问权限对话框来获取它您在查询中提到的。

So check before action ie, check you have permission to access the resource link and if your application doesn't have that particular permission you can request the permission link and handle the the permissions request response like below.因此,请在操作前检查,即检查您是否有权访问资源链接,如果您的应用程序没有该特定权限,您可以请求权限链接并处理权限请求响应,如下所示。

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

So finally, It's a good practice to go through behavior changes if you are planning to work with new versions to avoid force closes :)所以最后,如果您打算使用新版本以避免强制关闭,那么进行行为更改是一个很好的做法:)

Permissions Best Practices. 权限最佳实践。

You can go through the official sample app here .您可以在此处浏览官方示例应用程序。

From Android Marshmallow(API 23) and above by default all dangerous permission ( as per official doc official doc ) disabled.默认情况下,Android Marshmallow(API 23) 及更高版本禁用所有危险权限(根据官方文档官方文档)。 After installation when app open first time then you have to grant permission at Run Time.安装后第一次打开应用程序时,您必须在运行时授予权限。

I achieved this following way:我通过以下方式实现了这一点:

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 Your activity class: 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;
    }
    }

}

Add the permissions to the AndroidManifest.xml将权限添加到AndroidManifest.xml

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

To check the Android version if it needs runtime permission or not.检查 Android 版本是否需要运行时权限。

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

Ask the user to grant the permission if not granted.如果未授予,请要求用户授予权限。

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

Do something if the permission was granted or not.如果许可被授予与否,做一些事情。

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

I'm using this as a base Fragment class.我使用它作为基础 Fragment 类。 I only ask for permissions from a fragment, but you could refactor it and make a similar Activity version.我只要求片段的权限,但你可以重构它并制作一个类似的 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);
    }
}

There are two key methods you should use:您应该使用两种关键方法:

  • hasPermissionOrWillAsk - Use this to see if a permission has been asked for and denies by a user who doesn't want to be asked again. hasPermissionOrWillAsk - 使用此选项可查看不想再次被询问的用户是否已请求或拒绝该权限。 This is useful for disabling UI when the user has given their final answer about NOT wanting a feature.当用户给出他们不想要某个功能的最终答案时,这对于禁用 UI 很有用。

  • runNowOrAskForPermissionsFirst - Use this to run some code that requires permissions. runNowOrAskForPermissionsFirst - 使用它来运行一些需要权限的代码。 If the user has already granted permission, the code will run immediately.如果用户已经授予权限,代码将立即运行。 Otherwise, the code will run later if the user grants permission.否则,如果用户授予权限,代码将在稍后运行。 Or not at all.或者根本没有。 It's nice because you specify the code in one place.这很好,因为您可以在一处指定代码。

Here's an example:下面是一个例子:

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

Happy to get feedback on this.很高兴得到这方面的反馈。 Not that this specific example is a little simplified in that you also need to check to see if Location Services are enabled on the device.并不是说这个特定示例有点简化,因为您还需要检查设备上是否启用了定位服务。 (That's different than permissions.) Also, it only supports one permission at a time, but would be simple to modify if you need it to support more than one at a time. (这与权限不同。)此外,它一次仅支持一个权限,但如果您需要一次支持多个权限,则修改起来很简单。

To handle runtime permission google has provided a library project.为了处理运行时权限,谷歌提供了一个库项目。 You can check this from here https://github.com/googlesamples/easypermissions你可以从这里检查这个https://github.com/googlesamples/easypermissions

EasyPermissions is installed by adding the following dependency to your build.gradle file: EasyPermissions 是通过将以下依赖项添加到 build.gradle 文件来安装的:

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

To begin using EasyPermissions, have your Activity (or Fragment) override the onRequestPermissionsResult method:要开始使用 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
    // ...
}
}

Here you will get a working example how this library works https://github.com/milon87/EasyPermission在这里,您将获得该库如何工作的工作示例https://github.com/milon87/EasyPermission

It may be a cleaner way.这可能是一种更清洁的方式。 Add all your permissions in an array like将您的所有权限添加到一个数组中,例如

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;

Whatever your permision is create method for each permision无论您的权限是什么,为每个权限创建方法

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

Call this method in onCreateonCreate 中调用此方法

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

Now override onRequestPermissionsResult现在覆盖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
        }
    }
}

If you're using AndroidX Activity 1.2.0 or AndroidX Fragment 1.3.0 :如果您使用的是AndroidX Activity 1.2.0AndroidX Fragment 1.3.0

There are new Activity Result APIs that you can use to ask for permissions:您可以使用新的活动结果 API 来请求权限:

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

For multiple permission at a time you can use this.一次获得多个权限,您可以使用它。 This work for me.. I got another solution.这对我有用..我得到了另一个解决方案。 if you give your targetSdkVersion bellow 22 it works for me.如果你给你的 targetSdkVersion 低于 22,它对我有用。 and it behavior as like getting permission from manifest.xml.它的行为就像从 manifest.xml 获得许可一样。 Tested and works for me.经过测试并为我工作。

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

For more details.更多细节。 Check bellow link检查波纹管链接

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

There is a good library that can be used in case permissions need to be asked when permission is needed by a background service.有一个很好的库,可以用于在后台服务需要权限时需要询问权限的情况。 Although a limitation of library is that it can not be used to just determine whether permissions are currently given to the app or not.尽管库的一个限制是它不能仅用于确定当前是否授予应用程序权限。 It always asks the user if app doesn't already have them.它总是询问用户应用程序是否还没有它们。

Do give it a try as it makes life simpler: Android Permissions尝试一下,因为它让生活更简单: Android 权限

This code below works perfectly.I am explaining with the help of an example.下面的这段代码工作得很好。我在一个例子的帮助下解释。

In my case i placed the permission checks separately in a util class and passed the specific permissions i need to check from the appropriate classes.This enabled to reuse the permission check util file in the whole application.在我的例子中,我将权限检查单独放在一个 util 类中,并传递了我需要从适当的类中检查的特定权限。这使得能够在整个应用程序中重用权限检查 util 文件。

The below code part shows the function call.In this case am requesting android.Manifest.permission.READ_EXTERNAL_STORAGE permission.下面的代码部分显示了函数调用。在这种情况下,我正在请求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);
            }
        }   

In the above case permission is checked if it is allowed the onAttachPressed();在上述情况下,检查权限是否允许onAttachPressed(); function is called else we check request permission.函数被调用,否则我们检查请求权限。

The below is the code present in the util class in my case PermissionUtils以下是在我的案例PermissionUtils出现在 util 类中的代码

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

And after the request if you might want to call the function from onRequestPermissionsResult or else you will need to press the button again for the function call.在请求之后,如果您可能想从onRequestPermissionsResult调用函数,否则您将需要再次按下按钮进行函数调用。

So just call it from 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 .");
            }
        }

I use RxPermission library library for asking permission.我使用RxPermission库来请求许可。 Because it is long code which we have to write to ask permission.因为它是很长的代码,我们必须编写以获得许可。

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

Add these dependency in your build.gradlebuild.gradle添加这些依赖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'
}

Try this尝试这个

This is the simplest way to ask for permission in Marshmallow version.这是在 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);
        }
    }

Note:- Don't forget to add this same permission in manifest file also注意:-不要忘记在清单文件中添加相同的权限

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

Second Method Code for checking the permission is granted or not?用于检查权限是否被授予的第二种方法代码?

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

And override the method并覆盖方法

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

Simple way to ask permission by avoiding writing lots of code,通过避免编写大量代码来获得许可的简单方法,

https://github.com/sachinvarma/EasyPermission https://github.com/sachinvarma/EasyPermission

How to add :如何添加:

repositories {
        maven { url "https://jitpack.io" }
    }

implementation 'com.github.sachinvarma:EasyPermission:1.0.1'

How to ask permission:如何请求许可:

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

 new EasyPermissionInit(MainActivity.this, permission);

Hoping it will be helpful for someone.希望它会对某人有所帮助。

I went through all answers, but doesn't satisfied my exact needed answer, so here is an example that I wrote and perfectly works, even user clicks the Don't ask again checkbox.我浏览了所有答案,但没有满足我确切需要的答案,所以这里是我编写的并且完美运行的示例,即使用户单击了不再询问复选框。

  1. Create a method that will be called when you want to ask for runtime permission like readContacts() or you can also have openCamera() as shown below:创建一个方法,当您想要请求运行时权限时将调用该方法,例如readContacts()或者您也可以使用openCamera() ,如下所示:

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

Now we need to make askContactsPermission() , you can also name it as askCameraPermission() or whatever permission you are going to ask.现在我们需要创建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;
}

Before writing this function make sure you have defined the below instance variable as shown:在编写此函数之前,请确保您已定义以下实例变量,如下所示:

    private View parentLayout;
    private boolean contactPermissionNotGiven;;


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

Now final step to override the onRequestPermissionsResult method as shown below:现在是覆盖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();
        }
    }
}

Here we are done with the RunTime permissions, the addon is the openPermissionSettingDialog() which simply open the Setting screen if user have permanently disable the permission by clicking Don't ask again checkbox.这里我们完成了运行时权限,插件是openPermissionSettingDialog()如果用户通过单击不再询问复选框永久禁用权限,它只需打开设置屏幕。 below is the method:下面是方法:

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

What we missed ?我们错过了什么? 1. Defining the used strings in strings.xml 1.在strings.xml定义使用的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. Initializing the parentLayout variable inside onCreate methodonCreate方法中初始化parentLayout变量

    parentLayout = findViewById(R.id.content); parentLayout = findViewById(R.id.content);

  2. Defining the required permission in AndroidManifest.xmlAndroidManifest.xml定义所需的权限

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

  1. The queryContacts method, based on your need or the runtime permission you can call your method before which the permission was needed. queryContacts方法,根据您的需要或运行时权限,您可以在需要permission之前调用您的方法。 in my case I simply use the loader to fetch the contact as shown below:就我而言,我只是使用加载程序来获取联系人,如下所示:

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

This works great happy coding :)这很有效,编码愉快:)

I have found a solutions from my old code and it's really works good, still working on my Latest Apps.我从我的旧代码中找到了一个解决方案,它真的很好用,仍在使用我的最新应用程序。

Put it on MainActivity Class or on your Start Activity Class将其放在 MainActivity Class 或 Start Activity Class

private RequestPermissionHandler mRequestPermissionHandler;

On Create创建时

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

Private function handleButtonClicked()私有 function 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 Class RequestPermissionHandler.java Class

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

You can use my library — NoPermission (It's just one class)你可以使用我的库——NoPermission (这只是一个类)

compile 'ru.alexbykov:nopermission:1.1.1'

Sample样本

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: onRequestPermissionResult:

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

I think api more convenient than EasyPermissions by Google.我认为 api 比 Google 的EasyPermissions更方便。

Runtime Permission AnyWhere In Application Here is Example应用程序中任何地方的运行时权限这里是示例

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

and call code like this :并调用这样的代码:

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

}
});

you can find more Github你可以找到更多Github

Run time permission creates a lot of boilerplate code in activity which is heavily coupled.运行时权限在高度耦合的活动中创建了大量样板代码。 To reduce code and make the thing easy, you can use Dexter library.为了减少代码并使事情变得简单,您可以使用Dexter库。

RUNTIME PERMISSION IN ANDROID 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 method is to check runtime permission OnClick 方法是检查运行时权限

and if Permission is restricted then it request permission如果权限受到限制,则请求权限

Just this will do:只需这样做:

        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_CONTACTS) != PackageManager.PERMISSION_GRANTED) {
            ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.READ_CONTACTS}, 0);
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM