以编程方式请求用户的权限?

时间:2016-11-27 06:39:47

标签: android android-manifest android-permissions

我想添加第一次打开应用后立即向用户提供批准权限列表的功能。

我从this文章中读到了如何做到这一点。

但我仍然对此有一些疑问,以使我的应用程序的这个功能真正动态:

  • 如何从清单文件中读取所需权限列表? (这是为了避免对每个所需的进行明确的硬编码验证 权限)

  • 如何以编程方式将这些权限分类为 NORMAL DANGEROUS ,因为我只需要在权限时明确询问用户是危险类型? (根据文档,操作系统会自动授予普通权限,而无需请求用户)

4 个答案:

答案 0 :(得分:6)

当您想要执行与该权限相关的某些操作时,您需要在每次授予天气权限时检查您的应用程序。

因为用户可以随时从设置中禁用该权限。

危险权限和权限组:

日历

READ_CALENDAR
WRITE_CALENDAR

CALL_LOG

READ_CALL_LOG 
WRITE_CALL_LOG 
PROCESS_OUTGOING_CALLS

CAMERA

CAMERA

联系人

READ_CONTACTS
WRITE_CONTACTS
GET_ACCOUNTS

位置

ACCESS_FINE_LOCATION
ACCESS_COARSE_LOCATION

MICROPHONE

RECORD_AUDIO

电话

READ_PHONE_STATE
READ_PHONE_NUMBERS
CALL_PHONE
ANSWER_PHONE_CALLS
ADD_VOICEMAIL
USE_SIP

传感器

BODY_SENSORS

短信

SEND_SMS
RECEIVE_SMS
READ_SMS
RECEIVE_WAP_PUSH
RECEIVE_MMS

存储

READ_EXTERNAL_STORAGE
WRITE_EXTERNAL_STORAGE

来源Dangerous permissions

正常权限:

ACCESS_LOCATION_EXTRA_COMMANDS
ACCESS_NETWORK_STATE
ACCESS_NOTIFICATION_POLICY
ACCESS_WIFI_STATE
BLUETOOTH
BLUETOOTH_ADMIN
BROADCAST_STICKY
CHANGE_NETWORK_STATE
CHANGE_WIFI_MULTICAST_STATE
CHANGE_WIFI_STATE
DISABLE_KEYGUARD
EXPAND_STATUS_BAR
FOREGROUND_SERVICE
GET_PACKAGE_SIZE
INSTALL_SHORTCUT
INTERNET
KILL_BACKGROUND_PROCESSES
MANAGE_OWN_CALLS
MODIFY_AUDIO_SETTINGS
NFC
READ_SYNC_SETTINGS
READ_SYNC_STATS
RECEIVE_BOOT_COMPLETED
REORDER_TASKS
REQUEST_COMPANION_RUN_IN_BACKGROUND
REQUEST_COMPANION_USE_DATA_IN_BACKGROUND
REQUEST_DELETE_PACKAGES
REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
SET_ALARM
SET_WALLPAPER
SET_WALLPAPER_HINTS
TRANSMIT_IR
USE_FINGERPRINT
VIBRATE
WAKE_LOCK
WRITE_SYNC_SETTINGS

来源Normal permissions

以编程方式获取所需权限列表:

public void readPermission()
{
    try {
        PackageInfo info = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_PERMISSIONS);
        if (info.requestedPermissions != null) {
            for (String p : info.requestedPermissions) {
                Log.d(TAG, "Permission : " + p);
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

答案 1 :(得分:2)

AFAIK,无法以编程方式从清单中读取所有权限。但是,由于您在发布APK之前已经在Manifest中列出了它们,因此您已经知道需要请求哪些权限。不是吗?

假设您的清单中有READ_PHONE_STATE和WRITE_EXTERNAL_STORAGE,您可以在MainActivity.java中的权限检查中添加:

ArrayList<String> arrPerm = new ArrayList<>();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) {
    arrPerm.add(Manifest.permission.READ_PHONE_STATE);
}
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    arrPerm.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
}
if(!arrPerm.isEmpty()) {
    String[] permissions = new String[arrPerm.size()];
    permissions = arrPerm.toArray(permissions);
    ActivityCompat.requestPermissions(this, permissions, MY_PERMISSIONS_REQUEST);
}

这将一个接一个地触发WRITE_EXTERNAL_STORAGE和READ_PHONE_STATE的权限请求。要检查授予的权限,请执行以下操作:

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

    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0) {
                for(int i = 0; i < grantResults.length; i++) {
                    String permission = permissions[i];
                    if(Manifest.permission.READ_PHONE_STATE.equals(permission)) {
                        if(grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                            // you now have permission
                        }
                    }
                    if(Manifest.permission.WRITE_EXTERNAL_STORAGE.equals(permission)) {
                        if(grantResults[i] == PackageManager.PERMISSION_GRANTED) {
                            // you now have permission
                        }
                    }
                }
            } else {
                // permission denied, boo! Disable the
                // functionality that depends on this permission.
            }
            break;
        }
    }

    // other 'case' lines to check for other
    // permissions this app might request
}

答案 2 :(得分:0)

运行时权限在Android中从Android 6.0(API级别23)添加,之后只能在清单中定义权限。但是在执行任务之前,您需要从用户那里获取运行时权限(危险),而Android 6及更高版本。

来自问题中的文档

  

如果您的应用需要危险许可,则必须检查是否存在   每次执行需要的操作时都拥有该权限   那个许可。

因此,如果您正在执行需要危险权限的任务,那么必须要求用户执行该操作,否则会抛出运行时异常。

您可以阅读this以最佳方式获取权限

答案 3 :(得分:0)

manifest中定义的权限 &lt; uses-permission android:name =&#34; ...&#34; /&gt; 将自动适用于API级别低于23的Android设备。对于android(6.0)以上的设备,您必须在运行时检查权限。

https://developer.android.com/guide/topics/security/permissions.html 此链接有一个危险权限列表