跨程序共享数据-ContentProvider
如果程序与程序之间的数据不能共享的话,你就不能从抖音里看到你的联系人发了什么视频了,所以我们会采用安全可靠的ContentPricider
技术
ContentPricider
- 主要用于程序与程序之间的数据共享
- 提供了一套完整的机制,允许一个程序访问另一个程序中的数据
- 同时保证了被访问数据的安全性
- 是Android实现跨程序共享数据的标准方式
运行时权限
访问数据不可避免要涉及权限问题
Android权限机制
当时我们在尝试静态广播的时候,为了监听开机广播,我们在AndroidManifest.xml
中添加了一句权限声明
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.bo.a6_learnbroadcastreceiver">
···
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
···
</manifest>
声明权限后用户的两个方面得到了保护:
- 如果用户在低于Android6.0的系统的设备上安装该程序,会在安装界面有提醒程序用到哪些权限,再决定是否安装
- 用户可以在应用程序管理界面查看任意一个程序的权限申请情况.
比如微信会索要超级多的权限(即使有些我觉得会暴露我的隐私),但是不得不用,又会同意
其实android团队想到了这个问题:
- 用户不需要在安装的时候同意所有权限,只需要用到这个功能的时候再同意,不同意就不用这个功能,但可以使用其他功能
但是所有的权限都要用户来一个个设定,那太多了,用户体验极差
所以权限分成了三类:
- 普通权限: 不会威胁到用户的安全和隐私,系统会自动授权这部分权限,比如:
BOOT_COMPLETED
就是普通权限 - 危险权限: 可能会威胁到用户的安全和隐私,比如:用户的地理位置,这就必须要用户自己授权了
- 特殊权限: 使用很少,暂且不提
Android10.0为止所有的危险权限
表格中的每个危险权限都属于会属于一个权限组,但我们用户授权一个权限后,一整个权限组都会被授权
但是不能按照权限组来设定逻辑,因为Android团队随时会改动权限组
程序运行时申请权限
示例-CALL_PHONE
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Button
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/makeCall"
android:text="打电话给10086"/>
</LinearLayout>
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
···
makeCall.setOnClickListener {
try {
val intent=Intent(Intent.ACTION_CALL)
//这个动作是打电话,打电话是需要申请权限的
//Intent.ACTION_DIAL,是打开拨号界面,不需要声明权限
intent.data= Uri.parse("tel:10086")
startActivity(intent)
}catch (e:SecurityException){
e.printStackTrace()
}
}
}
}
权限申请
<uses-permission android:name="android.permission.CALL_PHONE"/>
但是我们发现是会报错的,这是因为权限被禁止导致的,因为android6.0及以上系统使用危险权限时必须进行权限处理
可以修改成
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
makeCall.setOnClickListener {
//ContextCompat.checkSelfPermission(上下文,权限名称)!=PackageManager.PERMISSION_GRANTED
//就是不授权
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CALL_PHONE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CALL_PHONE), 1