知识点目录
知识点回顾
7.1 内容提供器简介
内容提供器(Content Provider)主要用于在不同的应用程序之间实现数据共享的功能。它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访问数据的安全性。
内容提供器可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄漏的风险。
7.2 运行权限
Android 6.0引用了运行时权限功能,很好地保护了用户的安全和隐私。
7.2.1 Android权限机制详解
Android要求我们在访问用户涉及到安全性的时候,需要在AndroidManifest.xml中加入相应的权限。这样用户就在如下两个方面得到了保护:
-
在低于6.0的系统设备上安装程序时,就会在安装界面提醒用户该apk需要的权限
-
用户可以在应用程序管理界面查看任意一个程序的权限申请情况
但很多常用的软件存在“店大欺客”的情况,滥用很多权限。因此Android研发团队在6.0时就加入了运行时权限功能。即用户不需要在安装软件的时候一次性授权所有申请的权限,而是可以在软件的使用过程中再对某一项权限申请进行授权。
当然并不是所有的权限都是在运行时申请。Android将所有的权限分为了两类:
-
普通权限
-
危险权限
普通权限:是指那些不会威胁到用户的安全和隐私的权限,系统会自动帮我们进行授权。
危险权限:是指那些可能会触及用户隐私或者对设备安全性造成影响的权限,必须要由用户手动点击授权才行,否则程序就无法使用相应的功能。
Android中的危险权限主要有如下几种:

注意:表中每一个权限都属于一个权限组,在处理运行时权限时使用权限名,如果用户一旦同意授权了,那么该权限所对应的权限组中所有的其他权限也会同时被授权。
Android系统中完整的权限列表如下:
7.2.2 在程序运行时申请权限
下面我们来使用CALL_PHONE来演示。
示例代码:
-
定义一个button触发点
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <Button android:id="@+id/make_call" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="Make Call" android:textAllCaps="false"/> </LinearLayout>
-
在AndroidManifest.xml中声明权限
<uses-permission android:name="android.permission.CALL_PHONE"/>
-
运行时权限
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); Button makeCall = (Button) findViewById(R.id.make_call); makeCall.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //检查权限 if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { //向用户申请授权 ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CALL_PHONE}, 1); } else { call(); } } }); } private void call() { try { Intent intent = new Intent(Intent.ACTION_CALL); intent.setData(Uri.parse("tel:10086")); if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) { return; } startActivity(intent); } catch (Exception e) { e.printStackTrace(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { switch (requestCode) { case 1: //如果授权成功则调用call()方法 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { call(); } else { Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show(); } break; default: } } }
解释说明:
第一步:判断用户是不是已经给我们授权过
用ContextCompat.checkSelfPermission()方法去判断用户是否授过权。共接收两个参数:
-
参数一:上下文
-
参数二:具体的权限名
第二步:将返回值与PackageManager.PERMISSION_GRANTED做比较,如果相等就说明用户已经授权,如果不相等就表示用户没有授权。
第三步:如果授权了,则直接调用call()方法,如果没有授权,则调用ActivityCompat.requestPermissions()方法向用户申请授权。requestPermissions()共接收三个参数:
-
参数一:Activity实例
-
参数二:String数组,把要申请的权限名放在数组中
-
参数三:请求码,只要确保是唯一值就行