本帖最后由 ming.m_cao 于 2015-9-11 22:56 编辑
Preview Along with the updating from Android L to android M, Google has promoted the android new permission model. According to new permissions model, as to non-normal permission, you must check to see if you have the permissions when using the content of permission.
<ignore_js_op> Pic-1
Normal permissions
Normal permissions Definition: Manypermissions are designated as PROTECTION_NORMAL, which indicates that there'sno great risk.
Normalpermission Feature: Normal permissions declared in manifest are granted when installingApp, and App does not need to check and request permissions when it's used.
Note:All the permissions, including normal permissions and non-normal permissions, should be declared in AndroidManifest.xml if you want to use them.
Currently, the following permissions are classified as PROTECTION_NORMAL:
- android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
- android.permission.ACCESS_NETWORK_STATE
- android.permission.ACCESS_NOTIFICATION_POLICY
- android.permission.ACCESS_WIFI_STATE
- android.permission.ACCESS_WIMAX_STATE
- android.permission.BLUETOOTH
- android.permission.BLUETOOTH_ADMIN
- android.permission.BROADCAST_STICKY
- android.permission.CHANGE_NETWORK_STATE
- android.permission.CHANGE_WIFI_MULTICAST_STATE
- android.permission.CHANGE_WIFI_STATE
- android.permission.CHANGE_WIMAX_STATE
- android.permission.DISABLE_KEYGUARD
- android.permission.EXPAND_STATUS_BAR
- android.permission.FLASHLIGHT
- android.permission.GET_PACKAGE_SIZE
- android.permission.INTERNET
- android.permission.KILL_BACKGROUND_PROCESSES
- android.permission.MODIFY_AUDIO_SETTINGS
- android.permission.NFC
- android.permission.READ_SYNC_SETTINGS
- android.permission.READ_SYNC_STATS
- android.permission.RECEIVE_BOOT_COMPLETED
- android.permission.REORDER_TASKS
- android.permission.REQUEST_INSTALL_PACKAGES
- android.permission.SET_TIME_ZONE
- android.permission.SET_WALLPAPER
- android.permission.SET_WALLPAPER_HINTS
- android.permission.SUBSCRIBED_FEEDS_READ
- android.permission.TRANSMIT_IR
- android.permission.USE_FINGERPRINT
- android.permission.VIBRATE
- android.permission.WAKE_LOCK
- android.permission.WRITE_SYNC_SETTINGS
- com.android.alarm.permission.SET_ALARM
- com.android.launcher.permission.INSTALL_SHORTCUT
- com.android.launcher.permission.UNINSTALL_SHORTCUT
Permission Groups
Permission groups definition: Permissionsare divided into permission groups, based on their functionality. Permission groups Feature: Aftergranted a permission in a group, the system automatically grants allpermissions from the group.
|
Permission Groups
|
Permissions
|
| android.permission-group.CALENDAR |
android.permission.READ_CALENDAR android.permission.WRITE_CALENDAR |
| android.permission-group.CAMERA |
android.permission.CAMERA |
| android.permission-group.CONTACTS |
android.permission.READ_CONTACTS android.permission.WRITE_CONTACTS android.permission.GET_ACCOUNTS |
| android.permission-group.LOCATION |
android.permission.ACCESS_FINE_LOCATION android.permission.ACCESS_COARSE_LOCATION |
| android.permission-group.MICROPHONE |
android.permission.RECORD_AUDIO |
| android.permission-group.PHONE |
android.permission.READ_PHONE_STATE android.permission.CALL_PHONE android.permission.READ_CALL_LOG android.permission.WRITE_CALL_LOG com.android.voicemail.permission.ADD_VOICEMAIL android.permission.USE_SIP android.permission.PROCESS_OUTGOING_CALLS |
| android.permission-group.SENSORS |
android.permission.BODY_SENSORS |
| android.permission-group.SMS |
android.permission.SEND_SMS android.permission.RECEIVE_SMS android.permission.READ_SMS android.permission.RECEIVE_WAP_PUSH android.permission.RECEIVE_MMS android.permission.READ_CELL_BROADCASTS |
| android.permission-group.STORAGE |
android.permission.READ_EXTERNAL_STORAGE android.permission.WRITE_EXTERNAL_STORAGE |
Permission Manage1. As to normal permissions, they are granted to App when installing. 2. As to non-normal permission, every time you use it, you should check whether you have the permission, even though you know the fact that you must have the permission. If yes, to use the functionality. If no, to require the permission. When you get the permission, you can use the functionality. 3.You can grant or revoke the permission in Permission manager. Settings => Security =>Permission manager <ignore_js_op> ![]() <ignore_js_op> ![]()
Pic-2 App list Pic-3 App permission listTesting Runtime Permissions
Install with permissions
You can use the adb install command's new -g option,which installs the app and grants all permissions listed in its manifest:
$ adb install -g <path_to_apk>
eg: adb install –g com.example.test
Grant and revoke permissions
Grant a permission, use the package manager's grant command:
$ adb shell pm grant <package_name><permission_name>
eg: $adb shell pm grant com.example.test android.permission.READ_CONTACTS
Revoke a permission, use the package manager's revoke command:
$ adb shell pm revoke <package_name><permission_name>
eg: $adb shell pm revoke com.example.test android.permission.READ_CONTACTSForwards and backwards platform compatibility
|
Apk SDK
|
Android L
|
Android M
|
|
API < 23
|
Use old permission model
|
Use old permission model
|
|
API = 23
|
Use old permission model
|
Use new permission model
|
Method Analysis 1. checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
Judge whether this App has the permission.
2. shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)
After App is installed and launched for the first time, this method will return false. If "DENY" the
permission, next time it will return true. Once App has the permission, it will return false.
If it returns true, you can show an dialog to explain the permission.
3. requestPermissions(String[] permissions, int requestCode)
If you have no permission, you can call this method to request permission. Android system will deal with it for you,
and then android system will call back onRequestPermissionsResult().
4. public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults){}
You should overwritten this method, which is automatically called by android system after calling requestPermissions().
5. In order to program a App which is compatible for the lower android system, developer can route to different code by judging the "ro.build.version.sdk".
SystemProperties.getInt("ro.build.version.sdk", -1);
adt-bundle-linux-x86_64-20140702/sdk/platforms/android-23/data/layoutlib.jar should be added.
Permission use case I write a code for writing card using android.permission.WRITE_EXTERNAL_STORAGE, which is a non-normal permission. This App can be run on Android L or Android M.
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.example.test"
- android:versionCode="1"
- android:versionName="1.0" >
- <uses-sdk
- android:minSdkVersion="8"
- android:targetSdkVersion="23" />
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
- <application
- android:allowBackup="true"
- android:icon="@drawable/ic_launcher"
- android:label="@string/app_name"
- android:theme="@style/AppTheme" >
- <activity
- android:name=".MainActivity"
- android:label="@string/app_name" >
- <intent-filter>
- <action android:name="android.intent.action.MAIN" />
- <category android:name="android.intent.category.LAUNCHER" />
- </intent-filter>
- </activity>
- </application>
- </manifest>
复制代码
- package com.example.test;
- import java.io.File;
- import android.Manifest;
- import android.app.Activity;
- import android.app.AlertDialog;
- import android.content.DialogInterface;
- import android.content.pm.PackageManager;
- import android.os.Bundle;
- import android.os.Environment;
- import android.os.SystemProperties;
- import android.util.Log;
- import android.view.View;
- import android.view.View.OnClickListener;
- import android.widget.Button;
- import android.widget.Toast;
- public class MainActivity extends Activity implements OnClickListener {
-
- private static final String TAG = "MainActivity";
- private static final String ROOT_PATH = Environment.getExternalStorageDirectory()
- .getAbsolutePath();
- private static final int PERMISSIONS_REQUEST_WRITE_CARD = 1;
- private static boolean mNewPermissionModel;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- Button writeCardBtn = (Button) findViewById(R.id.writeCard);
- writeCardBtn.setOnClickListener(this);
-
- mNewPermissionModel = judgePermissionModel();
- }
-
- @Override
- public void onClick(View v) {
- switch (v.getId()) {
- case R.id.writeCard:
- writeCard();
- break;
- }
- }
-
- private void writeCard() {
- if (mNewPermissionModel) {
- boolean result = checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED;
- if (!result) {
- boolean should = shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE);
- if (should) {
- new AlertDialog.Builder(this)
- .setTitle("Explain WRITE_EXTERNAL_STORAGE")
- .setMessage("WRITE_EXTERNAL_STORAGE is ......")
- .setPositiveButton(android.R.string.ok,
- new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- requestPermissions(
- new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
- PERMISSIONS_REQUEST_WRITE_CARD);
- }
- }).show();
- } else {
- requestPermissions(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
- PERMISSIONS_REQUEST_WRITE_CARD);
- }
-
- return;
- }
- }
-
- createCurrentTimeFile();
- }
-
- @Override
- public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
- switch (requestCode) {
- case PERMISSIONS_REQUEST_WRITE_CARD:
- if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
- createCurrentTimeFile();
- }
- break;
-
- default:
- break;
- }
- }
-
- private void createCurrentTimeFile() {
- long time = System.currentTimeMillis();
-
- String filePath = ROOT_PATH + "/" + time;
- File file = new File(filePath);
-
- if ((!file.exists()) || file.delete()) {
- try {
- file.createNewFile();
- Toast.makeText(this, "Create file successfully!", Toast.LENGTH_SHORT).show();
- } catch (Exception e) {
- Toast.makeText(this, "Fail to create file", Toast.LENGTH_SHORT).show();
- Log.e(TAG, "Faile to create a file:" + filePath);
- }
- } else {
- Log.w(TAG, "Fail to delete file: " + filePath);
- }
- }
-
- private static boolean judgePermissionModel() {
- int sdkApiLevel = SystemProperties.getInt("ro.build.version.sdk", 8);
- Log.d(TAG, "sdkApiLevel:" + sdkApiLevel);
- if (sdkApiLevel >= 23) {
- return true;
- } else {
- return false;
- }
- }
-
- }
复制代码
Test case 1:
1. $adb install Test.app
2. Launch the Test App
3. Press "WRITE CARD". It will show Dialog as Pic-4
4. Press ALLOW. Dialog will exit and it will show Toast:"Create file successfully!"
Test case 2:
1. $adb install Test.app
2. Launch the Test App
3. Press "WRITE CARD", It will show dialog as Pic-4
4. Press "DENY". Dialog will exit
5. Press "WRITE CARD". It will show dialog as Pic-5
6. Press "OK". It will show dialog as Pic-6
7. Press ALLOW. Dialog will exit and it will show Toast:"Create file successfully!"
Note: at step 7, if press "DENY", the dialog exits and it steps to Step 5.
<ignore_js_op> ![]() <ignore_js_op> ![]() <ignore_js_op> ![]()
Pic-4 Pic-5 Pic-6
Code Source: \\10.46.8.12\cht000\CHT200\CHT210\Private Folder\Cao Ming\share\a Apk for all platform\Test.tar.gz
|