【Android】跨程序共享数据——内容提供器初识

news2024/9/30 0:28:50

跨程序共享数据——探究内容提供器

内容提供器的简介

主要用于在不同的应用程序之间实现数据共享的功能,它提供了一套完整的机制,允许一个程序访问另一个程序中的数据,同时还能保证被访数据的安全性。目前,使用内容提供器是Android实现跨程序共享数据的标准方式。内容提供器可以选择只对哪一部分数据进行共享,从而保证我们程序中的隐私数据不会有泄漏的风险。

运行时权限

Android权限机制

在我们使用任何一个软件的时候,有时就会弹出来你是否允许使用摄像头…,这就是权限。安卓当中的权限非常多,要是所有的权限都要由我们来授权就会非常麻烦,因此Android现在将所有的权限归成了两类,一类是普通权限,一类是危险权限。普通权限指的是那些不会直接威胁到用户的安全和隐私的权限,对于这部分权限申请,系统会自动帮我们进行授权,而不需要用户再去手动操作了。危险权限则表示那些可能会触及用户隐私,或者对设备安全性造成影响的权限,如获取设备联系人信息、定位设备的地理位置等,对于这部分权限申请,必须要由用户手动点击授权才可以,否则程序就无法使用相应的功能。

下面Android中所有的危险权限,一共是9组24个权限:

在这里插入图片描述

当你要使用这张表中的权限,那么就需要进行运行时权限处理,如果不在这张表中,那么只需要在AndroidManifest.xml文件中添加一下权限声明就可以了。

注意,表格中每个危险权限都属于一个权限组,我们在进行运行时权限处理时使用的是权限名,但是用户一旦同意授权了,那么该权限所对应的权限组中所有的其他权限也会同时被授权。

在程序运行时申请权限

在上面的表格当中会看到CALL_PHONE权限是危险权限,就根据这个来学习在程序运行时申请权限吧。

对于一个权限无非就是授权和不授权两种情况:

  • PackageManager.PERMISSION_GRANTED:表示权限已经被授权
  • PackageManager.PERMISSION_DENIED:表示改权限处于未授权的状态

我们在程序运行时申请权限时,首先就是判断是否已经授权了,当处于已授权的状态时,就无需提示用户,直接进行操作,当没有授权我们就提示用户是否进行授权,根据用户的选择进行下一步改如何操作。下面就是代码的示例:

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_main);
        ViewCompat.setOnApplyWindowInsetsListener(findViewById(R.id.main), (v, insets) -> {
            Insets systemBars = insets.getInsets(WindowInsetsCompat.Type.systemBars());
            v.setPadding(systemBars.left, systemBars.top, systemBars.right, systemBars.bottom);
            return insets;
        });

        Button buttonmakecall = (Button) findViewById(R.id.makecall);
        buttonmakecall.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:17765079498"));
            startActivity(intent);
        } catch (SecurityException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        if (requestCode == 1) {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                call();
            } else {
                Toast.makeText(this, "You denied the permission", Toast.LENGTH_SHORT).show();
            }
        } else {
            ;
        }
    }
}
  1. 我们在点击按钮之后,先对权限进行判断是否已经被授权,借助ContextCompat.checkSelfPermission()方法,是一个静态方法,用于检查应用是否具有执行某个操作所需的权限,接收两个参数:
  • Context:第一个参数是需要检查权限的上下文,上下文提供了一个环境,使得权限检查能够关联到正确的应用程序
  • String permission:第二个参数是需要检查的权限的名称
  1. 遇到没有授权,我们就需要向用户申请授权,借助ActivityCompat.requestPermissions()方法,接收三个参数:
  • Activity:第一个参数是 Activity 的实例,通常是当前的 Activity。这是请求权限的上下文,并且是接收权限请求结果的回调所在
  • String[] permissions:第二个参数是一个包含权限名称的字符串数组。这些权限是应用请求授权的权限列表
  • int requestCode:第三个参数是一个整数值,它是请求代码,用于唯一标识权限请求。当权限请求的结果返回时,这个值将用于确定是哪个权限请求的结果。这个值应该大于0,并且最好是一个不会与 Activity 中其他请求代码冲突的值
  1. 在调用requestPermissions()方法之后,无论结果如何都会回调到onRequestPermissionsResult()方法,此时就可以写用户不同选择带来的操作,这个方法也是三个参数,都是由调用 requestPermissions() 方法时传入的:
  • int requestCode: 一个整型值,用于标识请求权限的请求码
  • String[] permissions:一个字符串数组,包含请求的权限名称
  • int[] grantResults:用户的授权结果就会保存在这里面

if语句当中与允许授权作比较是很好理解的,前面还有一个是判断字符串的长度是否大于0,是因为数字所存放的是被处理的请求,如果不做判断,当数组长度为0直接访问会报错。

这下去运行程序当你按下按钮,就会出现让用户授权的提示:

在这里插入图片描述

按下允许就会执行相关操作,以上面为例就会出现拨打电话的页面:

在这里插入图片描述

这时能再次按下按钮就不会再次让你授权,你想要关闭授权就在设置里面关闭

访问其他程序中的数据

内容提供器的用法有两种:

  • 使用现有的内容提供器来读取和操作相应程序中的数据
  • 创建自己的内容提供器给我们程序的数据提供外部访问接口

ContentResolver的基本用法

对于每一个应用程序来说,如果想要访问内容提供器中共享的数据,就一定要借助ContentResolver类,可以通过Context中的getContentResolver()方法获取到该类的实例,它提供了增删改查的操作,与SQLite的方法名是相同的,但在操作上面所传参数有些许不同,不接受表名参数,而是使用一个Uri参数代替,这个参数被称之为内容URI。

内容URI主要由两部分组成:

  • authority:是用于对不同的程序做区分,一般为了避免冲突,都会采用程序包名的方式来进行命名
  • path:对同一应用程序的不同表做区分的,通常加到authority的后面

例如:content://com.example.app.provider/table1

得到了字符串要先转成Uri对象,调用Uri.parse()方法:

Uri uri = Uri.parse("content://com.example.app.provider/table1")

查询表中数据

Cursor cursor = getContentResolver().query(uri, projection, selection, selectionArgs, sortOrder);

在这里插入图片描述

接下来就可以使用循环读取数据了。

添加表中数据

ContentValues values = new ContentValues();
values.put("column1", "text");
values.put("column2", 1);
getContentResolver().insert(uri, values);

更新表中数据

ContentValues values = new ContentValues();
values.put("column1", "");
getContentResolver().update(uri, values, "column1 = ? and column2 = ?", new String[] {"text", "1"});

这段代码的目的是更新那些column1列的值为"text"且column2列的值为"1"的记录。只有同时满足这两个条件的记录会被更新,且column1的值会被更新为一个空字符串

删除表中数据

getContentResolver().delete(uri, "column2 = ?", new String[] {"1"});

值为"text"且column2列的值为"1"的记录。只有同时满足这两个条件的记录会被更新,且column1的值会被更新为一个空字符串

删除表中数据

getContentResolver().delete(uri, "column2 = ?", new String[] {"1"});

文章到这里就结束了!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1979866.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

modbus控制传感器

文章目录 modbus报文分析实例移植libmodbus问题 添加freertos初始化发送和接收发送和接收的回调函数flush 主从设备代码分析-主控如何读写从机1、串口传输,设置哪个串口、波特率、校验码、数据个数、体制位2、connect连接只是初始化3、主设备读写从设备14、硬件操作…

LinuxC++(11):创建一个进程

Linux的0、1和2号进程 整个linux系统全部的进程是一个树形结构。 0号进程(系统进程)是所有进程的祖先,它创建了1号和2号进程。 (相当于是我们世界的时间线) 1号进程(systemd)负责执行内核的…

批发行业手机入库识别单据 源码CyberWinApp-SAAS 本地化及未来之窗行业应用跨平台架构

一、手机入库好处 1. 便捷性高:可以随时随地通过手机进行入库操作,不受时间和地点的限制,方便库存管理者或相关人员及时记录商品或物品的入库信息。 2. 提高效率:采用手机端快速数据录入,避免了繁琐的手工记录&#x…

Linux从0到1——基础IO(上)【文件描述符/重定向/缓冲区】

Linux从0到1——基础IO(上) 1. 预备知识2. 复习一下常见的C语言文件接口3. 系统调用接口3.1 函数传参小技巧——标志位3.2 使用系统调用接口3.2.1 open3.2.2 write3.2.3 read 4. 文件描述符fd4.1 fd的本质4.2 理解struct file结构体4.3 fd的分配规则 5. …

学习分享:解析电商 API 接入的技术重难点及解决方案

在当今电商业务迅速发展的时代,接入电商 API 已成为许多企业提升竞争力和拓展业务的重要手段。然而,在这个过程中,往往会遇到一系列的技术重难点。本文将深入解析这些问题,并提供相应的解决方案。 一、电商 API 接入的技术重难点 …

按摩虎口穴位的作用

按摩虎口穴位的作用 虎口穴位是人体手背上的一个重要穴位,它位于手指掌侧第一指骨和第二指骨之间的凹陷处。 按摩虎口穴位有很多益处,包括: 缓解头痛和眼疲劳: 按摩虎口穴位可以缓解头痛和眼疲劳,特别是由于长时间使用…

未授权访问漏洞系列详解①!

Redis未授权访问漏洞 Redis 默认情况下,会绑定在 0.0.0.0:6379 ,如果没有进行采用相关的策略,比如添加防火墙规则避免其他非信任来源 ip 访问等,这样将会将 Redis 服务暴露到公网上,如果在没有设置密码认证(一般为空)的…

Golang | Leetcode Golang题解之第322题零钱兑换

题目&#xff1a; 题解&#xff1a; func coinChange(coins []int, amount int) int {var (dfs func(x int) int // x金额 最少硬币个数memo make(map[int]int) // 记忆化)dfs func(x int) int {//边界if x 0 {return 0} else if x < 0 {return math.MaxInt32}//记…

wangpang.xingkong(tou)

目录 client │ ├── client.h/c connect login recv send getcommand pausecommand putscommand │ ├── main.c 登陆&监听 │ ├── str_util.h/c 分割token字符串 conf │ └── server.conf server │ ├── config.h/c 读取文…

Android----Depth Anything尝鲜 小米手机部署

题目要求&#xff1a;了解Depth Anything (以及Depth Anything v2)基本原理&#xff0c;创新点。 Depth Anything 论文&#xff1a;Depth Anything: Unleashing the Power of Large-Scale Unlabeled Data 参考代码&#xff1a;Depth-Anything-Android GitHub 分析&#xff1a; …

深度学习在生物信息学中的应用

一、深度学习概念定义 深度学习&#xff08;Deep Learning&#xff09;是机器学习的一个子领域&#xff0c;它基于人工神经网络&#xff0c;尤其是深度神经网络。深度学习的核心思想是通过学习数据的表示层次和抽象层次&#xff0c;让机器能够具有类似于人类的分析学习能力。深…

lowbit(x)

返回x的最右边的一位1以及后面的所有数 x 1010 lowbit(x) 10x 101000 lowbit(x) 1000 一个整数的负数是补码(取反1) 应用&#xff1a; 求二进制中1的个数 题目 给定一个长度为 n 的数列&#xff0c;请你求出数列中每个数的二进制表示中 1的个数。 输入格式 第一行包…

uvm_config_db 和 uvm_resource_db :

uvm_config_db class my_driver extends uvm_driver;int my_param;function new(string name, uvm_component parent);super.new(name, parent);endfunctionvirtual task run_phase(uvm_phase phase);// 在组件内部获取配置值if (!uvm_config_db#(int)::get(this, ""…

python3 pyside6图形库学习笔记及实践(四)

目录 前言列表控件(QListWidget)创建列表增删插改查添加元素插入元素删除元素修改元素查找元素 常用信号和槽currentItemChangeditemChangedclear 列表排序列表的上下文菜单 图形视图框架简介框架核心图元类(QGraphicsItem)场景类(QGraphicsScene)视图类(QGraphicsView)交互机制…

守护数据安全:有效应对.hmallox勒索病毒的策略

引言 近年来&#xff0c;随着网络技术的飞速发展&#xff0c;勒索病毒成为网络安全领域的一大威胁。其中&#xff0c;.hmallox勒索病毒作为malox勒索软件家族的新变种&#xff0c;给个人和企业带来了极大的数据安全和经济损失风险。本文将对.hmallox勒索病毒进行详细介绍&…

机器学习用python还是R,哪个更好?

机器学习领域中&#xff0c;Python和R都是非常流行的编程语言&#xff0c;它们各有优势和特点&#xff1a; Python: 优势: 拥有丰富的库和框架&#xff0c;如scikit-learn、TensorFlow、PyTorch等&#xff0c;适合各种级别的机器学习任务。语法简洁清晰&#xff0c;易于学习。社…

3DM游戏运行库合集离线安装包2024最新版

3DM游戏运行库合集离线安装包是一款由国内最大的游戏玩家论坛社区3DM推出的集成式游戏运行库合集软件&#xff0c;旨在解决玩家在玩游戏时遇到的运行库缺失或错误问题。该软件包含多种常用的系统运行库组件&#xff0c;支持32位和64位操作系统&#xff0c;能够自动识别系统版本…

LeetCode每日一题_572.另一棵树的子树

解题思路&#xff1a; Step1:首先我们要知道如何判断两颗树相同&#xff0c;思路就是遍历每个节点&#xff0c;然后判断是否均相等&#xff0c;需要用递归来实现。代码如下所示&#xff1a; public static boolean equals(TreeNode t1,TreeNode t2){if(t1null&&t2null…

[Java]面向对象,从浅到深

快速入门 计算机的核心作用就是处理数据, 变量用来存储单个数据, 数组用来储存一批数据, 对象用来存储一类数据 什么是对象: 对象就是一种特殊的数据结构, 在java中万物皆对象 面相对象编程的好处: 更加符合人类思维习惯 类和实例对象 在java中必须先设计类, 才能根据类创…

git学习入门1——下载安装与添加用户标识设置name与Email

想法是这样的&#xff0c;先是自己工作闲暇之余在学习C语言&#xff0c;在跟一个某平台的机构学习C语言的基础知识&#xff0c;空闲之余学习了几天&#xff0c;想起了之前学习过程中某学员提出的git每日提交代码的那个表格记录&#xff0c;忽然想起自己也先学习git的使用。 先是…