目录
(1) 调用 ContextWrapper.checkSelfPermission 确认是否有权限。 如果没有授权,则调用 Activity.requestPermissions
(2) onRequestPermissionsResult 回调结果
1. 概述
当使用一些服务时,涉及到用户隐私时(如相机、联系人、电话权限等),一般需要用户手动授权。用户授权后,才能进行操作。以此来保证用户隐私。
2. 自定义的service
对于自定义的服务, 在的AndroidManifest 会加上权限限定, 例如
<service android:name=".SimpleService"
android:permission="com.sample.simpleservice.permission.CALLME">
</service>
其中"com.sample.simpleservice.permission.CALLME" 是自定义的约定的权限
而用调用这个service 的应用Client中,就要申明使用到这个权限:
<uses-permission android:name="com.sample.simpleservice.permission.CALLME"/>
3. 系统service
如 TelecomManager.endCall,
参考 Android 四大组件之 Service_4_挂断电话(AIDL): https://blog.csdn.net/whjk20/article/details/112983081
这里调用endCall 需要Andoid.Manifest.java 中的权限
public static final String ANSWER_PHONE_CALLS = "android.permission.ANSWER_PHONE_CALLS";
因此,需要提示用户授权。
(1) 调用 ContextWrapper.checkSelfPermission 确认是否有权限。 如果没有授权,则调用 Activity.requestPermissions
private void checkPhoneCallPermission() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (this.checkSelfPermission(Manifest.permission.ANSWER_PHONE_CALLS) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ANSWER_PHONE_CALLS}, REQUEST_ANSWER_PHONE_CALLS_CODE);
}
}
}
注意 requestPermissions 的详细说明, 需要判断:
- 是否已经获取了权限
- 是否已经拒绝了权限
- 以上为否,才进行调用requestPermissions
需要传入权限名称,以及代码(自定义)。 并且结果会通过回调 Activity.onRequestPermissionsResult 通知
/**
* Requests permissions to be granted to this application. These permissions
* must be requested in your manifest, they should not be granted to your app,
* and they should have protection level {@link
* android.content.pm.PermissionInfo#PROTECTION_DANGEROUS dangerous}, regardless
* whether they are declared by the platform or a third-party app.
* <p>
* Normal permissions {@link android.content.pm.PermissionInfo#PROTECTION_NORMAL}
* are granted at install time if requested in the manifest. Signature permissions
* {@link android.content.pm.PermissionInfo#PROTECTION_SIGNATURE} are granted at
* install time if requested in the manifest and the signature of your app matches
* the signature of the app declaring the permissions.
* </p>
* <p>
* Call {@link #shouldShowRequestPermissionRationale(String)} before calling this API to
* check if the system recommends to show a rationale UI before asking for a permission.
* </p>
* <p>
* If your app does not have the requested permissions the user will be presented
* with UI for accepting them. After the user has accepted or rejected the
* requested permissions you will receive a callback on {@link
* #onRequestPermissionsResult(int, String[], int[])} reporting whether the
* permissions were granted or not.
* </p>
* <p>
* Note that requesting a permission does not guarantee it will be granted and
* your app should be able to run without having this permission.
* </p>
* <p>
* This method may start an activity allowing the user to choose which permissions
* to grant and which to reject. Hence, you should be prepared that your activity
* may be paused and resumed. Further, granting some permissions may require
* a restart of you application. In such a case, the system will recreate the
* activity stack before delivering the result to {@link
* #onRequestPermissionsResult(int, String[], int[])}.
* </p>
* <p>
* When checking whether you have a permission you should use {@link
* #checkSelfPermission(String)}.
* </p>
* <p>
* Calling this API for permissions already granted to your app would show UI
* to the user to decide whether the app can still hold these permissions. This
* can be useful if the way your app uses data guarded by the permissions
* changes significantly.
* </p>
* <p>
* You cannot request a permission if your activity sets {@link
* android.R.styleable#AndroidManifestActivity_noHistory noHistory} to
* <code>true</code> because in this case the activity would not receive
* result callbacks including {@link #onRequestPermissionsResult(int, String[], int[])}.
* </p>
* <p>
* The <a href="https://github.com/googlesamples/android-RuntimePermissions">
* RuntimePermissions</a> sample app demonstrates how to use this method to
* request permissions at run time.
* </p>
*
* @param permissions The requested permissions. Must me non-null and not empty.
* @param requestCode Application specific request code to match with a result
* reported to {@link #onRequestPermissionsResult(int, String[], int[])}.
* Should be >= 0.
*
* @throws IllegalArgumentException if requestCode is negative.
*
* @see #onRequestPermissionsResult(int, String[], int[])
* @see #checkSelfPermission(String)
* @see #shouldShowRequestPermissionRationale(String)
*/
public final void requestPermissions(@NonNull String[] permissions, int requestCode) {
(2) onRequestPermissionsResult 回调结果
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_ANSWER_PHONE_CALLS_CODE) {
if (grantResults.length == 1 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {//已获取了
Toast.makeText(this, "Have grant permission: ANSWER_PHONE_CALLS", Toast.LENGTH_SHORT).show();
} else {//没有允许,也没有拒绝过
Toast.makeText(this, "ANSWER_PHONE_CALLS permission was NOT granted", Toast.LENGTH_SHORT).show();
}
}
}
其中: PackageManager.java中定义
public static final int PERMISSION_GRANTED = 0;
public static final int PERMISSION_DENIED = -1;
在获取了结果后,再做相应处理,例如启动camera等等
参考Github上Android 官方的例子:
https://github.com/googlesamples/android-RuntimePermissions
(MainActivity.java)