安卓基础之《(15)—内容提供者(1)在应用之间共享数据》

一、通过ContentProvider封装数据

1、ContentProvider
ContentProvider为App存取内部数据提供统一的外部接口,让不同的应用之间得以共享数据

ContentProvider相当于一个窗口、一个门卫
一个应用读取另一个应用的数据,比如用户登录时,收到验证码自动读取

2、ContentProvider案例
Client App将用户的输入内容,通过ContentProvider跨进程通信传递给Server App

3、ContentProvider只是服务端App存取数据的抽象类,我们需要在其基础上实现一个完整的内容提供器,并重写下列方法
(1)onCreate:初始化资源
Provider在应用启动的时候就创建了
(2)insert:插入数据
(3)delete:删除数据
(4)update:更新数据
(5)query:查询数据
(6)getType:获取内容提供器支持的数据类型

4、Uri
Uri(通用资源标识符Universal Resource Identifer),代表数据操作的地址,每一个ContentProvider都会有唯一的地址,格式content://authority/data_path/id
说明:
(1)“content://”:通用前缀,表示该Uri用于ContentProvider定位资源
(2)“authority”:授权者名称,用来确定具体由哪一个ContentProvider提供资源。因此一般authority都由类的小写全称组成,以保证唯一性
(3)“data_path”:数据路径,用来确定请求的是哪个数据集
(4)id:数据编号,用来请求单条数据。如果是多条这个字段忽略

二、创建Server App

1、新建一个Module,chapter07-server

2、创建ContentProvider
【New】->【Other】->【Content Provider】,会自动生成文件

3、修改清单文件
authorities填生成的Provider文件的包名+类名

<provider android:name=".provider.UserInfoProvider" android:authorities="com.example.chapter07_server.provider.UserInfoProvider" android:enabled="true" android:exported="true" />

服务端要说明下访问客户端软件包

<queries> <package android:name="com.example.chapter07_client" /> </queries>

4、UserInfoProvider.java

package com.example.chapter07_server.provider; import android.content.ContentProvider; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.util.Log; public class UserInfoProvider extends ContentProvider { public UserInfoProvider() { } @Override public int delete(Uri uri, String selection, String[] selectionArgs) { Log.d("sam", "UserInfoProvider delete"); return 0; } @Override public String getType(Uri uri) { // TODO: Implement this to handle requests for the MIME type of the data // at the given URI. throw new UnsupportedOperationException("Not yet implemented"); } @Override public Uri insert(Uri uri, ContentValues values) { Log.d("sam", "UserInfoProvider insert"); Log.d("sam", "uri " + uri.toString()); Log.d("sam", "values " + values.toString()); return uri; } @Override public boolean onCreate() { Log.d("sam", "UserInfoProvider onCreate"); return true; } @Override public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { Log.d("sam", "UserInfoProvider query"); return null; } @Override public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { Log.d("sam", "UserInfoProvider update"); return 0; } }

5、清单文件

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 出于安全考虑,Android 11开始要求应用事先说明需要访问的其他软件包 --> <queries> <package android:name="com.example.chapter07_client" /> </queries> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication"> <provider android:name=".provider.UserInfoProvider" android:authorities="com.example.chapter07_server.provider.UserInfoProvider" android:enabled="true" android:exported="true" /> <activity android:name=".MainActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

Server端暴露数据访问接口,提供其他Client访问

三、通过ContentResolver访问数据

1、ContentResolver
利用ContentProvider只实现服务端App的数据封装,如果客户端App想访问对方的内部数据,就要通过内容解析器ContentResolver访问

四、创建Client App

1、新建一个Module,chapter07-client

2、ContentWriteActivity.java

package com.example.chapter07_client; import androidx.appcompat.app.AppCompatActivity; import android.content.ContentValues; import android.os.Bundle; import android.view.View; import android.widget.CheckBox; import android.widget.EditText; public class ContentWriteActivity extends AppCompatActivity implements View.OnClickListener { private EditText et_name; private EditText et_age; private EditText et_height; private EditText et_weight; private CheckBox ck_married; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_content_write); et_name = findViewById(R.id.et_name); et_age = findViewById(R.id.et_age); et_height = findViewById(R.id.et_height); et_weight = findViewById(R.id.et_weight); ck_married = findViewById(R.id.ck_married); findViewById(R.id.btn_save).setOnClickListener(this); findViewById(R.id.btn_delete).setOnClickListener(this); findViewById(R.id.btn_update).setOnClickListener(this); findViewById(R.id.btn_query).setOnClickListener(this); } @Override public void onClick(View view) { String name = et_name.getText().toString(); String age = et_age.getText().toString(); String height = et_height.getText().toString(); String weight = et_weight.getText().toString(); if (view.getId() == R.id.btn_save) { ContentValues values = new ContentValues(); values.put("name", name); values.put("age", Integer.parseInt(age)); values.put("height", Float.parseFloat(height)); values.put("weight", Float.parseFloat(weight)); values.put("married", ck_married.isChecked()); // 通过ContentResolver访问数据 getContentResolver().insert(UserInfoContent.CONTENT_URI, values); } else if (view.getId() == R.id.btn_delete) { } else if (view.getId() == R.id.btn_update) { } else if (view.getId() == R.id.btn_query) { } } }

3、UserInfoContent.java

package com.example.chapter07_client; import android.net.Uri; public class UserInfoContent { public static final String AUTHORITIES = "com.example.chapter07_server.provider.UserInfoProvider"; // 访问内容提供器的URI // content://com.example.chapter07_server.provider.UserInfoProvider/user public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITIES + "/user"); }

4、布局文件activity_content_write.xml

<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".ContentWriteActivity"> <GridLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:columnCount="2" android:rowCount="4"> <TextView android:layout_width="60dp" android:layout_height="wrap_content" android:text="姓名:" android:textSize="17sp"/> <EditText android:id="@+id/et_name" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_columnWeight="1" android:inputType="text" android:hint="请输入姓名"/> <TextView android:layout_width="60dp" android:layout_height="wrap_content" android:text="年龄:" android:textSize="17sp"/> <EditText android:id="@+id/et_age" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_columnWeight="1" android:inputType="number" android:maxLength="3" android:hint="请输入年龄"/> <TextView android:layout_width="60dp" android:layout_height="wrap_content" android:text="身高:" android:textSize="17sp"/> <EditText android:id="@+id/et_height" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_columnWeight="1" android:inputType="numberDecimal" android:maxLength="6" android:hint="请输入身高"/> <TextView android:layout_width="60dp" android:layout_height="wrap_content" android:text="体重:" android:textSize="17sp"/> <EditText android:id="@+id/et_weight" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_columnWeight="1" android:inputType="numberDecimal" android:maxLength="6" android:hint="请输入体重"/> </GridLayout> <CheckBox android:id="@+id/ck_married" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="已婚" android:textSize="17sp"/> <Button android:id="@+id/btn_save" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="添加" android:textSize="17sp"/> <Button android:id="@+id/btn_delete" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="删除" android:textSize="17sp"/> <Button android:id="@+id/btn_update" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="修改" android:textSize="17sp"/> <Button android:id="@+id/btn_query" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="查询" android:textSize="17sp"/> </LinearLayout>

5、清单文件
出于安全考虑,Android 11开始要求应用事先说明需要访问的其他软件包
这里服务端也要说明下访问客户端软件包,否则一直运行不出来

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android"> <queries> <package android:name="com.example.chapter07_server" /> </queries> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.MyApplication"> <activity android:name=".ContentWriteActivity" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>

6、运行日志

以添加数据为例

2026-01-12 16:10:28.223 20546-20546 sam com.example.chapter07_server D UserInfoProvider onCreate 2026-01-12 16:11:00.935 20546-20557 sam com.example.chapter07_server D UserInfoProvider insert 2026-01-12 16:11:00.935 20546-20557 sam com.example.chapter07_server D uri content://com.example.chapter07_server.provider.UserInfoProvider/user 2026-01-12 16:11:00.936 20546-20557 sam com.example.chapter07_server D values height=170.0 weight=56.0 age=12 name=qwer married=true

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

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

相关文章

如何高效做中文情感分析?StructBERT轻量镜像一键部署指南

如何高效做中文情感分析&#xff1f;StructBERT轻量镜像一键部署指南 在当前数字化运营和用户反馈管理的背景下&#xff0c;中文情感分析已成为企业洞察客户情绪、优化服务体验的核心技术之一。然而&#xff0c;传统NLP流程往往面临模型复杂、部署困难、依赖GPU等问题&#xf…

Windows异步I/O与消息循环的深度对话

序幕&#xff1a;两个程序员的对话 小王&#xff1a;老张&#xff0c;我最近写了个管道通信程序&#xff0c;异步I/O发送数据&#xff0c;但UI会冻结&#xff0c;怎么办&#xff1f; 老张&#xff1a;哦&#xff0c;这是经典的Windows编程问题。你用了MsgWaitForMultipleObject…

安卓基础之《(16)—内容提供者(2)使用内容组件获取通讯信息》

一、运行时动态申请权限1、Android系统为了防止某些App滥用权限&#xff0c;从6.0开始引入了运行时权限管理机制&#xff0c;允许App在运行过程中动态检查是否拥有某些权限&#xff0c;一旦发现缺少某种必需的权限&#xff0c;则系统会自动弹出小窗提示用户去开启该权限

从LSTM到StructBERT|升级你的中文情感分析工具链

从LSTM到StructBERT&#xff5c;升级你的中文情感分析工具链 1. 背景与挑战&#xff1a;传统LSTM的局限性 1.1 情感分析的技术演进路径 中文情感分析作为自然语言处理&#xff08;NLP&#xff09;中的经典任务&#xff0c;其技术路线经历了从规则匹配 → 机器学习 → 深度学…

AutoGLM-Phone-9B-GGUF部署全解析|解决mmproj缺失与调用难题

AutoGLM-Phone-9B-GGUF部署全解析&#xff5c;解决mmproj缺失与调用难题 1. 背景与挑战&#xff1a;从GGUF部署痛点说起 随着多模态大模型在移动端的广泛应用&#xff0c;AutoGLM-Phone-9B 凭借其90亿参数的轻量化设计和跨模态融合能力&#xff0c;成为边缘设备推理的理想选择…

从零训练到部署的跨越|StructBERT镜像简化中文情感分析落地流程

从零训练到部署的跨越&#xff5c;StructBERT镜像简化中文情感分析落地流程 1. 引言&#xff1a;中文情感分析的工程化挑战 在自然语言处理&#xff08;NLP&#xff09;的实际应用中&#xff0c;中文情感分析是一项高频且关键的任务。无论是电商平台的用户评论、社交媒体舆情…

CTF入门基础知识总结(赶紧收藏)

CTF入门基础知识总结&#xff08;赶紧收藏&#xff09; CTF&#xff0c;中文一般译作夺旗赛&#xff0c;是网络安全技术人员之间进行技术竞技的一种比赛形式。它起源于1996年的DEFCON全球黑客大会&#xff0c;旨在以更安全、更文明的方式展示黑客技术&#xff0c;推动网络安全…

AI分类器终身学习方案:云端弹性资源,适应业务增长

AI分类器终身学习方案&#xff1a;云端弹性资源&#xff0c;适应业务增长 引言 想象一下&#xff0c;你经营着一家初创公司&#xff0c;业务量每天都在快速增长。最初搭建的AI分类系统还能勉强应付&#xff0c;但随着用户量激增&#xff0c;服务器开始频繁报警&#xff0c;新…

轻量级CPU友好型中文情感分析方案|镜像部署全解析

轻量级CPU友好型中文情感分析方案&#xff5c;镜像部署全解析 1. 引言&#xff1a;为什么需要轻量级中文情感分析&#xff1f; 在当前AI大模型动辄依赖GPU、显存消耗动辄数GB的背景下&#xff0c;许多中小企业和开发者面临一个现实问题&#xff1a;如何在无GPU或低资源环境下…

基于CV-UNet的WebUI抠图工具实测|快速上手并提升图像处理效率

基于CV-UNet的WebUI抠图工具实测&#xff5c;快速上手并提升图像处理效率 1. 引言&#xff1a;为什么需要高效的自动抠图工具&#xff1f; 在电商、设计、影视后期等场景中&#xff0c;图像抠图&#xff08;Image Matting&#xff09;是一项高频且耗时的基础任务。传统手动抠…

从零部署AutoGLM-Phone-9B|打通移动端多模态推理最后一公里

从零部署AutoGLM-Phone-9B&#xff5c;打通移动端多模态推理最后一公里 随着大模型在移动端的落地需求日益增长&#xff0c;如何在资源受限设备上实现高效、低延迟的多模态推理成为关键挑战。AutoGLM-Phone-9B 正是在这一背景下应运而生——一款专为移动端优化的轻量化多模态大…

吐血推荐专科生必用8款AI论文平台

吐血推荐专科生必用8款AI论文平台 一、不同维度核心推荐&#xff1a;8款AI工具各有所长 对于专科生而言&#xff0c;撰写论文是一项既复杂又需要高效支持的任务。从选题到开题、初稿撰写、查重降重&#xff0c;再到最终排版&#xff0c;每一个环节都可能成为困扰学生的难点。而…

2024最火分类模型推荐:0配置云端体验,10块钱试遍TOP5算法

2024最火分类模型推荐&#xff1a;0配置云端体验&#xff0c;10块钱试遍TOP5算法 引言&#xff1a;分类模型的黄金时代 当你在淘宝搜索"适合30岁男士的休闲鞋"时&#xff0c;AI能精准推荐符合年龄、风格和预算的商品&#xff1b;当企业需要从海量邮件中筛选重要客户…

轻量多模态模型实践|AutoGLM-Phone-9B的GGUF本地化部署

轻量多模态模型实践&#xff5c;AutoGLM-Phone-9B的GGUF本地化部署 1. 引言&#xff1a;移动端多模态推理的现实挑战 随着大语言模型在文本、视觉、语音等多模态任务中的广泛应用&#xff0c;如何在资源受限的设备上实现高效推理成为工程落地的关键瓶颈。传统大模型往往依赖高…

Debug模式下unique_ptr的性能开销真相

本文将深入分析Debug构建中unique_ptr的性能开销来源。 一、Debug构建的特殊性 1.1 编译器优化被禁用 // GCC/Clang: -O0 (默认Debug选项) // MSVC: /Od (禁用优化)禁用所有优化包括&#xff1a; 内联展开被禁用无用代码消除被禁用常量传播被禁用循环优化被禁用函数调用不优化 …

亲测好用10个AI论文平台,继续教育学生高效写作必备!

亲测好用10个AI论文平台&#xff0c;继续教育学生高效写作必备&#xff01; AI 工具如何助力论文写作&#xff1f; 在当前的学术环境中&#xff0c;越来越多的学生和科研人员开始借助 AI 工具来提升论文写作效率。尤其是在继续教育领域&#xff0c;面对繁重的学习任务和严格的论…

AI分类模型省钱攻略:云端按需付费比买显卡省90%

AI分类模型省钱攻略&#xff1a;云端按需付费比买显卡省90% 1. 为什么初创团队应该选择云端AI算力 对于初创团队来说&#xff0c;测试AI分类模型处理用户反馈是一个常见需求。传统做法是直接购买高端显卡&#xff08;比如RTX 4090&#xff09;&#xff0c;但这会带来两个问题…

中文情感分析实战|基于StructBERT镜像快速部署情绪识别

中文情感分析实战&#xff5c;基于StructBERT镜像快速部署情绪识别 1. 引言&#xff1a;为什么需要轻量级中文情感分析方案&#xff1f; 在当前AI应用快速落地的背景下&#xff0c;中文情感分析已成为智能客服、舆情监控、用户反馈处理等场景的核心技术之一。尽管BERT类模型在…

StructBERT中文情感分析镜像:一键部署API与可视化界面

StructBERT中文情感分析镜像&#xff1a;一键部署API与可视化界面 1. 背景与需求&#xff1a;为什么需要轻量级中文情感分析服务&#xff1f; 在当前自然语言处理&#xff08;NLP&#xff09;广泛应用的背景下&#xff0c;中文情感分析已成为舆情监控、用户反馈挖掘、客服系统…

网工接私活竟比工资还高?工资1.5万,私活2万!同事:辞职干票大的!

网工接私活竟比工资还高&#xff1f;工资1.5万&#xff0c;私活2万&#xff01;同事&#xff1a;辞职干票大的&#xff01; 小编作为一名在职的网络安全工程师行业的小小一员&#xff0c;在平时的工作中洞察到一线技术工程师其实还是有很多机会和时间去做一下私活。加上最近就…