Android M新的运行时权限开发者需要知道的一切

android M 的名字官方刚发布不久,最终正式版即将来临!android在不断发展,最近的更新 M 非常不同,一些主要的变化例如运行时权限将有颠覆性影响。惊讶的是android社区鲜有谈论这事儿,尽管这事很重要或许在不远的将来会引发很严重的问 题。这是今天我写这篇博客的原因。这里有一切关于android运行时权限你需要知道的,包括如何在代码中实现。现在亡羊补牢还不晚。

作者:微凉一季来源:简书翻译|2015-08-31 09:41

分享

翻译的国外一篇文章。

android M 的名字官方刚发布不久,最终正式版即将来临!

android在不断发展,最近的更新 M 非常不同,一些主要的变化例如运行时权限将有颠覆性影响。惊讶的是android社区鲜有谈论这事儿,尽管这事很重要或许在不远的将来会引发很严重的问题。

这是今天我写这篇博客的原因。这里有一切关于android运行时权限你需要知道的,包括如何在代码中实现。现在亡羊补牢还不晚。

新运行时权限

android的权限系统一直是首要的安全概念,因为这些权限只在安装的时候被询问一次。一旦安装了,app可以在用户毫不知晓的情况下访问权限内的所有东西。

难怪一些坏蛋利用这个缺陷恶意收集用户数据用来做坏事了!

android小组也知道这事儿。7年了!权限系统终于被重新设计了。在android6.0棉花糖,app将不会在安装的时候授予权限。取而代之的是,app不得不在运行时一个一个询问用户授予权限。

Paste_Image.png

注意权限询问对话框不会自己弹出来。开发者不得不自己调用。如果开发者要调用的一些函数需要某权限而用户又拒绝授权的话,函数将抛出异常直接导致程序崩溃。

Paste_Image.png

另外,用户也可以随时在设置里取消已经授权的权限。

Paste_Image.png

你或许已经感觉到背后生出一阵寒意。。。如果你是个android开发者,意味着要完全改变你的程序逻辑。你不能像以前那样直接调用方法了,你不得不为每个需要的地方检察权限,否则app就崩溃了!

是的。我不能哄你说这是简单的事儿。尽管这对用户来说是好事,但是对开发者来说就是噩梦。我们不得不修改编码不然不论短期还是长远来看都是潜在的问题。

这个新的运行时权限仅当我们设置targetSdkVersion to 23(这意味着你已经在23上测试通过了)才起作用,当然还要是M系统的手机。app在6.0之前的设备依然使用旧的权限系统。

已经发布了的app会发生什么

新运行时权限可能已经让你开始恐慌了。“hey,伙计!我三年前发布的app可咋整呢。如果他被装到android 6.0上,我的app会崩溃吗?!?”

莫慌张,放轻松。android小队又不傻,肯定考虑到了这情况。如果app的targetSdkVersion 低于 23,那将被认为app没有用23新权限测试过,那将被继续使用旧有规则:用户在安装的时候不得不接受所有权限,安装后app就有了那些权限咯!

Paste_Image.png

然后app像以前一样奔跑!注意,此时用户依然可以取消已经同意的授权!用户取消授权时,android 6.0系统会警告,但这不妨碍用户取消授权。

Paste_Image.png

问题又来了,这时候你的app崩溃吗?

善意的主把这事也告诉了android小组,当我们在targetSdkVersion 低于23的app调用一个需要权限的函数时,这个权限如果被用户取消授权了的话,不抛出异常。但是他将啥都不干,结果导致函数返回值是null或者0.

Paste_Image.png

别高兴的太早。尽管app不会调用这个函数时崩溃,返回值null或者0可能接下来依然导致崩溃。

好消息(至少目前看来)是这类取消权限的情况比较少,我相信很少用户这么搞。如果他们这么办了,后果自负咯。

但从长远看来,我相信还是会有大量用户会关闭一些权限。我们app不能再新设备完美运行这是不可接受的。

怎样让他完美运行呢,你最好修改代码支持最新的权限系统,而且我建议你立刻着手搞起!

代码没有成功改为支持最新运行时权限的app,不要设置targetSdkVersion 23 发布,否则你就有麻烦了。只有当你测试过了,再改为targetSdkVersion 23 。

警告:现在你在android studio新建项目,targetSdkVersion 会自动设置为 23。如果你还没支持新运行时权限,我建议你首先把targetSdkVersion 降级到22

PROTECTION_NORMAL类权限

当用户安装或更新应用时,系统将授予应用所请求的属于 PROTECTION_NORMAL 的所有权限(安装时授权的一类基本权限)。这类权限包括:

  1. android.permission.ACCESS_LOCATION_EXTRA_COMMANDS
  2. android.permission.ACCESS_NETWORK_STATE
  3. android.permission.ACCESS_NOTIFICATION_POLICY
  4. android.permission.ACCESS_WIFI_STATE
  5. android.permission.ACCESS_WIMAX_STATE
  6. android.permission.BLUETOOTH
  7. android.permission.BLUETOOTH_ADMIN
  8. android.permission.BROADCAST_STICKY
  9. android.permission.CHANGE_NETWORK_STATE
  10. android.permission.CHANGE_WIFI_MULTICAST_STATE
  11. android.permission.CHANGE_WIFI_STATE
  12. android.permission.CHANGE_WIMAX_STATE
  13. android.permission.DISABLE_KEYGUARD
  14. android.permission.EXPAND_STATUS_BAR
  15. android.permission.FLASHLIGHT
  16. android.permission.GET_ACCOUNTS
  17. android.permission.GET_PACKAGE_SIZE
  18. android.permission.INTERNET
  19. android.permission.KILL_BACKGROUND_PROCESSES
  20. android.permission.MODIFY_AUDIO_SETTINGS
  21. android.permission.NFC
  22. android.permission.READ_SYNC_SETTINGS
  23. android.permission.READ_SYNC_STATS
  24. android.permission.RECEIVE_BOOT_COMPLETED
  25. android.permission.REORDER_TASKS
  26. android.permission.REQUEST_INSTALL_PACKAGES
  27. android.permission.SET_TIME_ZONE
  28. android.permission.SET_WALLPAPER
  29. android.permission.SET_WALLPAPER_HINTS
  30. android.permission.SUBSCRIBED_FEEDS_READ
  31. android.permission.TRANSMIT_IR
  32. android.permission.USE_FINGERPRINT
  33. android.permission.VIBRATE
  34. android.permission.WAKE_LOCK
  35. android.permission.WRITE_SYNC_SETTINGS
  36. com.android.alarm.permission.SET_ALARM
  37. com.android.launcher.permission.INSTALL_SHORTCUT
  38. com.android.launcher.permission.UNINSTALL_SHORTCUT

只需要在AndroidManifest.xml中简单声明这些权限就好,安装时就授权。不需要每次使用时都检查权限,而且用户不能取消以上授权。

让你的app支持新运行时权限

是时候让我们的app支持新权限模型了,从设置compileSdkVersion and targetSdkVersion为 23开始吧.

  1. android {
  2. compileSdkVersion 23
  3. ...
  4. defaultConfig {
  5. ...
  6. targetSdkVersion 23
  7. ...
  8. }

例子,我想用一下方法添加联系人。

  1. private static final String TAG = "Contacts";
  2. private void insertDummyContact() {
  3. // Two operations are needed to insert a new contact.
  4. ArrayList<ContentProviderOperation> operations = new ArrayList<ContentProviderOperation>(2);
  5. // First, set up a new raw contact.
  6. ContentProviderOperation.Builder op =
  7. ContentProviderOperation.newInsert(ContactsContract.RawContacts.CONTENT_URI)
  8. .withValue(ContactsContract.RawContacts.ACCOUNT_TYPE, null)
  9. .withValue(ContactsContract.RawContacts.ACCOUNT_NAME, null);
  10. operations.add(op.build());
  11. // Next, set the name for the contact.
  12. op = ContentProviderOperation.newInsert(ContactsContract.Data.CONTENT_URI)
  13. .withValueBackReference(ContactsContract.Data.RAW_CONTACT_ID, 0)
  14. .withValue(ContactsContract.Data.MIMETYPE,
  15. ContactsContract.CommonDataKinds.StructuredName.CONTENT_ITEM_TYPE)
  16. .withValue(ContactsContract.CommonDataKinds.StructuredName.DISPLAY_NAME,
  17. "__DUMMY CONTACT from runtime permissions sample");
  18. operations.add(op.build());
  19. // Apply the operations.
  20. ContentResolver resolver = getContentResolver();
  21. try {
  22. resolver.applyBatch(ContactsContract.AUTHORITY, operations);
  23. } catch (RemoteException e) {
  24. Log.d(TAG, "Could not add a new contact: " + e.getMessage());
  25. } catch (OperationApplicationException e) {
  26. Log.d(TAG, "Could not add a new contact: " + e.getMessage());
  27. }
  28. }

上面代码需要WRITE_CONTACTS权限。如果不询问授权,app就崩了。

下一步像以前一样在AndroidManifest.xml添加声明权限。

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

下一步,不得不再写个方法检查有没有权限。如果没有弹个对话框询问用户授权。然后你才可以下一步创建联系人。

权限被分组了,如下表:

Paste_Image.png

同一组的任何一个权限被授权了,其他权限也自动被授权。例如,一旦WRITE_CONTACTS被授权了,app也有READ_CONTACTS和GET_ACCOUNTS了。
源码中被用来检查和请求权限的方法分别是Activity的checkSelfPermission和requestPermissions。这些方法api23引入。

  1. final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
  2. private void insertDummyContactWrapper() {
  3. int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);
  4. if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
  5. requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
  6. REQUEST_CODE_ASK_PERMISSIONS);
  7. return;
  8. }
  9. insertDummyContact();
  10. }

如果已有权限,insertDummyContact()会执行。否则,requestPermissions被执行来弹出请求授权对话框,如下:

Paste_Image.png

不论用户同意还是拒绝,activity的onRequestPermissionsResult会被回调来通知结果(通过第三个参数),grantResults,如下:

  1. @Override
  2. public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
  3. switch (requestCode) {
  4. case REQUEST_CODE_ASK_PERMISSIONS:
  5. if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  6. // Permission Granted
  7. insertDummyContact();
  8. } else {
  9. // Permission Denied
  10. Toast.makeText(MainActivity.this, "WRITE_CONTACTS Denied", Toast.LENGTH_SHORT)
  11. .show();
  12. }
  13. break;
  14. default:
  15. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  16. }
  17. }

这就是新权限模型工作过程。代码真复杂但是只能去习惯它。。。为了让app很好兼容新权限模型,你不得不用以上类似方法处理所有需要的情况。
如果你想捶墙,现在是时候了。。。

处理 “不再提醒”

如果用户拒绝某授权。下一次弹框,用户会有一个“不再提醒”的选项的来防止app以后继续请求授权。

Paste_Image.png

如果这个选项在拒绝授权前被用户勾选了。下次为这个权限请求requestPermissions时,对话框就不弹出来了,结果就是,app啥都不干。

这将是很差的用户体验,用户做了操作却得不到响应。这种情况需要好好处理一下。在请求requestPermissions前,我们需要检查是否需
要展示请求权限的提示通过activity的shouldShowRequestPermissionRationale,代码如下:

  1. final private int REQUEST_CODE_ASK_PERMISSIONS = 123;
  2. private void insertDummyContactWrapper() {
  3. int hasWriteContactsPermission = checkSelfPermission(Manifest.permission.WRITE_CONTACTS);
  4. if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
  5. if (!shouldShowRequestPermissionRationale(Manifest.permission.WRITE_CONTACTS)) {
  6. showMessageOKCancel("You need to allow access to Contacts",
  7. new DialogInterface.OnClickListener() {
  8. @Override
  9. public void onClick(DialogInterface dialog, int which) {
  10. requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
  11. REQUEST_CODE_ASK_PERMISSIONS);
  12. }
  13. });
  14. return;
  15. }
  16. requestPermissions(new String[] {Manifest.permission.WRITE_CONTACTS},
  17. REQUEST_CODE_ASK_PERMISSIONS);
  18. return;
  19. }
  20. insertDummyContact();
  21. }
  22. private void showMessageOKCancel(String message, DialogInterface.OnClickListener okListener) {
  23. new AlertDialog.Builder(MainActivity.this)
  24. .setMessage(message)
  25. .setPositiveButton("OK", okListener)
  26. .setNegativeButton("Cancel", null)
  27. .create()
  28. .show();
  29. }

当一个权限第一次被请求和用户标记过不再提醒的时候,我们写的对话框被展示。

后一种情况,onRequestPermissionsResult 会收到PERMISSION_DENIED ,系统询问对话框不展示。

Paste_Image.png

搞定!

一次请求多个权限

当然了有时候需要好多权限,可以用上面方法一次请求多个权限。不要忘了为每个权限检查“不再提醒”的设置。
修改后的代码:

  1. final private int REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS = 124;
  2. private void insertDummyContactWrapper() {
  3. List<String> permissionsNeeded = new ArrayList<String>();
  4. final List<String> permissionsList = new ArrayList<String>();
  5. if (!addPermission(permissionsList, Manifest.permission.ACCESS_FINE_LOCATION))
  6. permissionsNeeded.add("GPS");
  7. if (!addPermission(permissionsList, Manifest.permission.READ_CONTACTS))
  8. permissionsNeeded.add("Read Contacts");
  9. if (!addPermission(permissionsList, Manifest.permission.WRITE_CONTACTS))
  10. permissionsNeeded.add("Write Contacts");
  11. if (permissionsList.size() > 0) {
  12. if (permissionsNeeded.size() > 0) {
  13. // Need Rationale
  14. String message = "You need to grant access to " + permissionsNeeded.get(0);
  15. for (int i = 1; i < permissionsNeeded.size(); i++)
  16. message = message + ", " + permissionsNeeded.get(i);
  17. showMessageOKCancel(message,
  18. new DialogInterface.OnClickListener() {
  19. @Override
  20. public void onClick(DialogInterface dialog, int which) {
  21. requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
  22. REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
  23. }
  24. });
  25. return;
  26. }
  27. requestPermissions(permissionsList.toArray(new String[permissionsList.size()]),
  28. REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS);
  29. return;
  30. }
  31. insertDummyContact();
  32. }
  33. private boolean addPermission(List<String> permissionsList, String permission) {
  34. if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
  35. permissionsList.add(permission);
  36. // Check for Rationale Option
  37. if (!shouldShowRequestPermissionRationale(permission))
  38. return false;
  39. }
  40. return true;
  41. }

如果所有权限被授权,依然回调onRequestPermissionsResult,我用hashmap让代码整洁便于阅读。

  1. @Override
  2. public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
  3. switch (requestCode) {
  4. case REQUEST_CODE_ASK_MULTIPLE_PERMISSIONS:
  5. {
  6. Map<String, Integer> perms = new HashMap<String, Integer>();
  7. // Initial
  8. perms.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
  9. perms.put(Manifest.permission.READ_CONTACTS, PackageManager.PERMISSION_GRANTED);
  10. perms.put(Manifest.permission.WRITE_CONTACTS, PackageManager.PERMISSION_GRANTED);
  11. // Fill with results
  12. for (int i = 0; i < permissions.length; i++)
  13. perms.put(permissions[i], grantResults[i]);
  14. // Check for ACCESS_FINE_LOCATION
  15. if (perms.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
  16. && perms.get(Manifest.permission.READ_CONTACTS) == PackageManager.PERMISSION_GRANTED
  17. && perms.get(Manifest.permission.WRITE_CONTACTS) == PackageManager.PERMISSION_GRANTED) {
  18. // All Permissions Granted
  19. insertDummyContact();
  20. } else {
  21. // Permission Denied
  22. Toast.makeText(MainActivity.this, "Some Permission is Denied", Toast.LENGTH_SHORT)
  23. .show();
  24. }
  25. }
  26. break;
  27. default:
  28. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  29. }
  30. }

条件灵活的,你自己设置。有的情况,一个权限没有授权,就不可用;但是也有情况,能工作,但是表现的是有所限制的。对于这个我不做评价,你自己设计吧。

用兼容库使代码兼容旧版

以上代码在android 6.0以上运行没问题,但是23 api之前就不行了,因为没有那些方法。

粗暴的方法是检查版本

  1. if (Build.VERSION.SDK_INT >= 23) {
  2. // Marshmallow+
  3. } else {
  4. // Pre-Marshmallow
  5. }

但是太复杂,我建议用v4兼容库,已对这个做过兼容,用这个方法代替:

  • ContextCompat.checkSelfPermission()
    被授权函数返回PERMISSION_GRANTED,否则返回PERMISSION_DENIED ,在所有版本都是如此。
  • ActivityCompat.requestPermissions()
    这个方法在M之前版本调用,OnRequestPermissionsResultCallback 直接被调用,带着正确的 PERMISSION_GRANTED或者 PERMISSION_DENIED 。
  • ActivityCompat.shouldShowRequestPermissionRationale()
    在M之前版本调用,永远返回false。
    用v4包的这三方法,完美兼容所有版本!这个方法需要额外的参数,Context or Activity。别的就没啥特别的了。下面是代码:
  1. private void insertDummyContactWrapper() {
  2. int hasWriteContactsPermission = ContextCompat.checkSelfPermission(MainActivity.this,
  3. Manifest.permission.WRITE_CONTACTS);
  4. if (hasWriteContactsPermission != PackageManager.PERMISSION_GRANTED) {
  5. if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,
  6. Manifest.permission.WRITE_CONTACTS)) {
  7. showMessageOKCancel("You need to allow access to Contacts",
  8. new DialogInterface.OnClickListener() {
  9. @Override
  10. public void onClick(DialogInterface dialog, int which) {
  11. ActivityCompat.requestPermissions(MainActivity.this,
  12. new String[] {Manifest.permission.WRITE_CONTACTS},
  13. REQUEST_CODE_ASK_PERMISSIONS);
  14. }
  15. });
  16. return;
  17. }
  18. ActivityCompat.requestPermissions(MainActivity.this,
  19. new String[] {Manifest.permission.WRITE_CONTACTS},
  20. REQUEST_CODE_ASK_PERMISSIONS);
  21. return;
  22. }
  23. insertDummyContact();
  24. }

后两个方法,我们也可以在Fragment中使用,用v13兼容包:FragmentCompat.requestPermissions() and FragmentCompat.shouldShowRequestPermissionRationale().和activity效果一样。

第三方库简化代码

以上代码真尼玛复杂。为解决这事,有许多第三方库已经问世了,真屌真有速度。我试了很多最终找到了个满意的hotchemi‘s PermissionsDispatcher
他和我上面做的一样,只是简化了代码。灵活易扩展,试一下吧。如果不满足你可以找些其他的。

如果我的app还开着呢,权限被撤销了,会发生生么

权限随时可以被撤销。

Paste_Image.png

当app开着的时候被撤消了会发生什么呢?我试过了发现这时app会突然终止
terminated。app中的一切都被简单粗暴的停止了,因为terminated!对我来说这可以理解,因为系统如果允许它继续运行(没有某权
限),这会召唤弗雷迪到我的噩梦里。或许更糟...

结论建议

我相信你对新权限模型已经有了清晰的认识。我相信你也意识到了问题的严峻。

但是你没得选择。新运行时权限已经在棉花糖中被使用了。我们没有退路。我们现在唯一能做的就是保证app适配新权限模型.

欣慰的是只有少数权限需要运行时权限模型。大多数常用的权限,例如,网络访问,属于Normal Permission 在安装时自动会授权,当然你要声明,以后无需检查。因此,只有少部分代码你需要修改。

两个建议:

1.严肃对待新权限模型

2.如果你代码没支持新权限,不要设置targetSdkVersion 23 。尤其是当你在Studio新建工程时,不要忘了修改!

说一下代码修改。这是大事,如果代码结构被设计的不够好,你需要一些很蛋疼的重构。每个app都要被修正。如上所说,我们没的选择。。。

列出所有你需要请求的权限所有情形,如果A被授权,B被拒绝,会发生什么。blah,blah。

祝重构顺利。把它列为你需要做的大事,从现在就开始着手做,以保证M正式发布的时候没有问题。

希望本文对你有用,快乐编码!艹

http://mdsa.51cto.com/art/201508/489882_all.htm

时间: 2024-08-01 22:43:28

Android M新的运行时权限开发者需要知道的一切的相关文章

Android M 新的运行时权限开发者需要知道的一切

本文来自微凉一季的博客http://jijiaxin89.com/2015/08/30/Android-s-Runtime-Permission/ 更多文章点击跳转微凉一季 tags: 翻译,这是一篇译文. android M 的名字官方刚发布不久,最终正式版即将来临! android在不断发展,最近的更新 M 非常不同,一些主要的变化例如运行时权限将有颠覆性影响.惊讶的是android社区鲜有谈论这事儿,尽管这事很重要或许在不远的将来会引发很严重的问题. 这是今天我写这篇博客的原因.这里有一切

一行代码解决Android M新的运行时权限问题

Android M运行时权限是个啥东西 啥是运行时权限呢?Android M对权限管理系统进行了改版,之前我们的App需要权限,只需在manifest中申明即可,用户安装后,一切申明的权限都可来去自如的使用.但是Android M把权限管理做了加强处理,在manifest申明了,在使用到相关功能时,还需重新授权方可使用.当然,不是所有权限都需重新授权,所以就把这些需要重新授权方可使用的权限称之为运行时权限. 运行时权限的影响 运行时权限的好处可以让用户使用时更有主动权,不会让app随便乱来.但是

Android 6.0的运行时权限

原文  http://droidyue.com/blog/2016/01/17/understanding-marshmallow-runtime-permission/ 主题 安卓开发 Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发者在实践开发中需要做出改变. 没有深入了解运行时权限的开发者通常会有很多疑问,比如什么是运行时权限,哪些是运行时的权限,我的应用是不是会在6.0系统上各种崩溃呢,如何才能

聊一聊 Android 6.0 的运行时权限

权限一刀切 棉花糖运行时权限 权限的分组 正常权限 正常权限列表 特殊权限危险权限 请求SYSTEM_ALERT_WINDOW 请求WRITE_SETTINGS 必须要支持运行时权限么 不支持运行时权限会崩溃么 然而有点糟糕的是 该来的还得来 一个标准的流程 如何批量申请 申请这么多权限岂不是很累 注意事项两个权限 API问题 多系统问题 些许建议 注意 Android 6.0,代号棉花糖,自发布伊始,其主要的特征运行时权限就很受关注.因为这一特征不仅改善了用户对于应用的使用体验,还使得应用开发

permission 新 运行时权限 6.0 总结

demo地址:https://github.com/baiqiantao/PermissionTest.git 关于运行时权限 在旧的权限管理系统中,权限仅仅在App安装时询问用户一次,用户同意了这些权限App才能被安装(某些深度定制系统另说),App一旦安装后就可以偷偷的做一些不为人知的事情了(同样,某些深度定制系统另说). 从Android6.0开始,App可以直接安装,App在运行时一个一个询问用户是否授予权限,系统会弹出一个对话框让用户选择是否授权某个权限给App(这个Dialog是系统

Android M运行时权限详解

好久之前在网上看到国外一篇关于M的权限机制详解,由于是英文的,刚好最近闲的没事做,顺手翻译一下. 英文原文地址:https://inthecheesefactory.com/blog/things-you-need-to-know-about-android-m-permission-developer-edition/en 翻译水平有限,凑合着看吧. 前几天官方公布了Android M的名字,最终版本也将在不久后发布. 虽然Android还在不断发生着变化,最新M版本的更新和以往是完全不同的,

Android6.0运行时权限(基于RxPermission开源库)

版权声明:本文为博主原创文章,未经博主允许不得转载. 前言 在6.0以前的系统,都是权限一刀切的处理方式,只要用户安装,Manifest申请的权限都会被赋予,并且安装后权限也撤销不了. Android 6.0 采用新的权限模型,只有在需要权限的时候,才告知用户是否授权:是在runtime时候授权,而不是在原来安装的时候 ,同时默认情况下每次在运行时打开页面时候,需要先检查是否有所需要的权限申请. 判断是否是需要运行时权限的标记就是targetSDKVersion. 当targetSDKVersi

Android 6.0 运行时权限处理完全解析

一.概述 随着Android 6.0发布以及普及,我们开发者所要应对的主要就是新版本SDK带来的一些变化,首先关注的就是权限机制的变化.对于6.0的几个主要的变化,查看查看官网的这篇文章http://developer.android.com/intl/zh-cn/about/versions/marshmallow/android-6.0-changes.html,其中当然包含Runtime Permissions. ok,本篇文章目的之一就是对运行时权限处理的一个介绍,以及对目前权限相关的库

Android 6.0 运行时权限管理

android 6.0 对权限进行了严格的管理 新的权限策略讲权限分为两类,第一类是不涉及用户隐私的,只需要在Manifest中声明即可,比如网络.蓝牙.NFC等:第二类是涉及到用户隐私信息的,需要用户授权后才可使用,比如SD卡读写.联系人.短信读写等. Normal Permissions 此类权限都是正常保护的权限,只需要在AndroidManifest.xml中简单声明这些权限即可,安装即授权,不需要每次使用时都检查权限,而且用户不能取消以上授权,除非用户卸载App. ACCESS_LOC