安卓棉花糖请求许可?

q9yhzks0  于 2021-07-03  发布在  Java
关注(0)|答案(19)|浏览(512)

我目前正在处理一个需要几个“危险”权限的应用程序。所以我试着在androidmarshmallow(api级别23)中按要求添加“ask for permission”,但找不到方法。
如何在我的应用程序中使用新的权限模型请求权限?

voj3qocg

voj3qocg1#

如果您使用的是androidx activity 1.2.0或androidx 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)
jrcvhitl

jrcvhitl2#

从android棉花糖开始,我们需要向用户请求特定的权限。如果已经授予了权限,我们还可以通过代码进行检查。以下是常用权限列表:
android.permission\u group.calendar(android.permission\u组日历)
android.permission.read\日历
android.permission.write\日历
android.permission\u group.camera.权限
安卓.权限.摄像头
android.permission\u group.contacts联系人
android.permission.read\联系人
android.permission.write\联系人
android.permission.get\账户
android.permission\u group.location
android.permission.access\u fine\u位置
android.permission.access\u\u位置
android.permission\u group.麦克风
android.permission.record\u音频
android.permission\u group.phone手机
android.permission.read\手机\状态
android.permission.call\电话
android.permission.read\ call\日志
android.permission.write\ call\日志
android.permission.add\语音信箱
android.permission.use\u sip使用
android.permission.process\u传出的\u呼叫
android.u group.sensors
android.permission.body\u传感器
android.permission\u group.sms
android.permission.send\短信
android.permission.receive\短信
android.permission.read\短信
android.permission.receive\ wap\推送
android.permission.receive\彩信
android.permission.read\u cell\u广播
android.permission\u group.storage
android.permission.read\外部存储
android.permission.write\外部\存储
下面是检查权限的示例代码:

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

t98cgbkg3#

我使用许可证申请图书馆。因为这是一个很长的代码,我们必须写它来请求许可。

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

iih3973s

iih3973s4#

对于一次多个权限,可以使用此。这是我的工作。。我有另一个解决办法。如果你给你的目标版本低于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

ngynwnxp

ngynwnxp5#

下面的代码工作得很好。我用一个例子来解释。
在我的例子中,我将权限检查分别放在一个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 .");
            }
        }
dly7yett

dly7yett6#

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

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

活动结果如下:

@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

sbtkgmzw

sbtkgmzw7#

我检查了所有的答案,但没有满足我的确切需要的答案,所以这里有一个例子,我写的和完美的作品,甚至用户点击了不再问复选框。
创建一个方法,当您想请求运行时权限时,该方法将被调用,如 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 ```
"Contacts permissions are needed to display Contacts."
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

正在初始化 `parentLayout` 内部变量 `onCreate` 方法
parentlayout=findviewbyid(r.id.content);
在中定义所需的权限 `AndroidManifest.xml` 
gblwokeq

gblwokeq8#

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

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

并在活动中覆盖:

@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

az31mfrm

az31mfrm9#

我的类请求运行时权限 Activity 或者 Fragment 它还可以帮助您显示基本原理或打开设置,以便在用户拒绝权限(带/不带)后启用权限 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)
    }
}

github上的代码
演示

p5cysglq

p5cysglq10#

我用它作为基本片段类。我只请求片段的权限,但您可以重构它并生成类似的活动版本。

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

很高兴得到反馈。并不是说这个具体的例子有点简化,因为您还需要检查设备上是否启用了位置服务(另外,它一次只支持一个权限,但是如果您需要它一次支持多个权限,那么修改它会很简单。

monwx1rj

monwx1rj11#

我使用了这个由google开发者编写的 Package 器(推荐)。它非常容易使用。
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);
    }
}

快乐编码:)

tct7dpnv

tct7dpnv12#

通过避免编写大量代码来获得许可的简单方法,
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);

希望能对别人有所帮助。

bd1hkmkf

bd1hkmkf13#

为了处理运行时权限,google提供了一个库项目。你可以在这里查这个https://github.com/googlesamples/easypermissions
easypermissions是通过向build.gradle文件添加以下依赖项来安装的:

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

要开始使用easypermissions,请让您的活动(或片段)重写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

n3schb8v

n3schb8v14#

试试这个
这是在棉花糖版本中请求许可的最简单的方法。

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别忘了在清单文件中也添加同样的权限

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

vsikbqxv15#

将权限添加到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);
    }
}

相关问题