android学习日记13--数据存储之ContentProvide

3、ContentProvider
  数据在Android当中是私有的,当然这些数据包括文件数据和数据库数据以及一些其他类型的数据。ContentProvider实现多应用程序间的数据共享类
一般利用ContentProvider为需要共享的数据定义一个URI(统一资源定位符)
然后其他程序通过Context获得ContentResolver并将数据的URI传入即可

Android已为一些常用的数据创建ContentProvider,这些ContentProvider位于
android.provider包下,常用的就是手机上联系人信息,但是要取得相应的权限自己的应用程序才能访问
具体设置是在AndroidManifest.xml

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

对于ContentProvide重要的是数据模型和URI
数据模型:ContentProvide为所需要的数据创建表,每行代表一条记录,每条记录有唯一的'_ID'标识
URI:每个ContentProvide对外提供一个URI来标识自己的数据集

URI特点:
1、无法改变的标准前缀,包括;"content://"、"tel://"等。当前缀是"content://"时,说明通过一个Content Provider控制这些数据
2、URI的标识,它通过authorities属性声明,用于定义了是哪个ContentProvider提供这些数据。对于第三方应用程序,为了保证URI标识的唯一性,它必须是一个完整的类名(数据路径)。例如;"content://com.example.contentprovide.myprovider"
3、如果URI中包含表示需要获取的记录的_ID;则就返回该id对应的数据,如果没有_ID,就表示返回全部

举个例子,如: 

所有联系人的URI: content://contacts/people

某个联系人的URI: content://contacts/people/5

 

具体使用步骤:
1、在当前应用程序中定义一个ContentProvider

 1 public class MyProvider extends ContentProvider {
 2 
 3     @Override
 4     public int delete(Uri arg0, String arg1, String[] arg2) {
 5         // TODO Auto-generated method stub
 6         return 0;
 7     }
 8 
 9     @Override
10     public String getType(Uri arg0) {
11         // TODO Auto-generated method stub
12         return null;
13     }
14 
15     @Override
16     public Uri insert(Uri arg0, ContentValues arg1) {
17         // TODO Auto-generated method stub
18         return null;
19     }
20 
21     // 创建数据库,建表和插入数据
22     @Override
23     public boolean onCreate() {
24         // TODO Auto-generated method stub
25         SQLiteDatabase db =this.getContext().openOrCreateDatabase("mydb.db", Context.MODE_PRIVATE, null);
26         db.execSQL("create table tab(_id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL)");
27         ContentValues values =new ContentValues();
28         values.put("name", "Hello ContentProvider!");
29         db.insert("tab", "_id", values);
30         db.close();
31         return true;
32     }
33     
34     // 查询
35     @Override
36     public Cursor query(Uri arg0, String[] arg1, String arg2, String[] arg3,
37             String arg4) {
38         // TODO Auto-generated method stub
39          SQLiteDatabase db =this.getContext().openOrCreateDatabase("mydb.db", Context.MODE_PRIVATE, null);
40          Cursor c = db.query("tab", null, null, null, null, null,null);
41          return c;
42     }
43 
44     @Override
45     public int update(Uri arg0, ContentValues arg1, String arg2, String[] arg3) {
46         // TODO Auto-generated method stub
47         return 0;
48     }

 这里为了演示方便只实现创建和查询两个简单的方法

 

2、在当前应用程序的AndroidManifest.xml中注册此ContentProvider

1 <provider android:name=".MyProvider" android:authorities="com.example.contentprovider.MyProvider"/>

 

3、其他应用程序通过ContentResolver和Uri来获取此ContentProvider的数据

 1 protected void onCreate(Bundle savedInstanceState) {
 2         super.onCreate(savedInstanceState);
 3         setContentView(R.layout.activity_main);
 4         
 5         // 获取当前context
 6         Context context = MainActivity.this;
 7         
 8         // 得到ContentResolver对象
 9         ContentResolver resolver = context.getContentResolver();
10         
11         // uri格式 "content://"、数据的路径、标示ID(可选)
12         Uri uri = Uri.parse("content://com.example.contentprovider.MyProvider");
13         Cursor c = resolver.query(uri, null, null, null, null);
14         
15         // 打印获取数据
16         c.moveToFirst();
17         for(int i=0; i<c.getCount(); i++){
18         int index = c.getColumnIndexOrThrow("name");
19                      String src = c.getString(index);
20                      Log.d("", src);
21                      c.moveToNext();
22                  }
23         }

日志打印:

 

 

  上面MyProvider代码和应用程序MainActivity代码不放在同一个包下是想说明ContentProvider不同程序间的数据共享,

但是注册获取权限那段代码要放在调用的程序包里。

  其实通过代码可以看出为了共享数据库.可以让数据库披上ContentProvider外衣,主要还是通过SQLiteDatabase去操作数据库。

当然对于已封装的共享数据。我们只要设置获取权限,通过ContentResolver就可以直接调用。

 

4、获取系统的联系人、媒体库信息

  对于系统程序的联系人、多媒体等信息可通过指定的Uri来获取。

  数据附录是获取本地联系人信息代码:

 1 public String getContactInfo(){
 2         String result="";
 3         ContentResolver resolver=getContentResolver();
 4         //查询联系人
 5         Cursor cursor=resolver.query(Contacts.CONTENT_URI, null, null, null, null);
 6         int idIndex=cursor.getColumnIndex(Contacts._ID);
 7         // 取得联系人名字 (显示出来的名字),实际内容在 ContactsContract.Contacts中
 8         int nameIndex=cursor.getColumnIndex(Contacts.DISPLAY_NAME);
 9         for (cursor.moveToFirst();(!cursor.isAfterLast());cursor.moveToNext()) {
10             //获取联系人ID
11             String contactId =cursor.getString(idIndex);
12             result=result+contactId+"\t\t\t";
13             result=result+cursor.getString(nameIndex)+"\t\t\t";
14              // 根据联系人ID查询对应的电话号码  
15             Cursor phoneNumbers = resolver.query(CommonDataKinds.Phone.CONTENT_URI, null,
16                     CommonDataKinds.Phone.CONTACT_ID + " = " + contactId, null, null);   
17             // 取得电话号码(可能存在多个号码)    
18             while (phoneNumbers.moveToNext())     
19             {  
20                 String strPhoneNumber = phoneNumbers.getString(phoneNumbers.getColumnIndex(CommonDataKinds.Phone.NUMBER));     
21                 result=result+strPhoneNumber+"\t\t\t";
22             }
23             phoneNumbers.close();
24             
25             // 根据联系人ID查询对应的email  
26             Cursor emails = resolver.query(CommonDataKinds.Email.CONTENT_URI, null, 
27                     CommonDataKinds.Email.CONTACT_ID + " = " + contactId, null, null);               
28             // 取得email(可能存在多个email)    
29             while (emails.moveToNext())     
30             {  
31                 String strEmail = emails.getString(emails.getColumnIndex(CommonDataKinds.Email.DATA));     
32                 result=result+strEmail+"\t\t\t";
33             }     
34             emails.close(); 
35             result=result+"\n";
36         }
37         cursor.close();
38         return result;
39     }

 

5、监听ContentProvider的数据改变

  随着ContentProvider的共享数据可能发生改变,要提供给有使用该共享数据的相应,具体步骤如下:

1).在ContentProvider类的insert\update\delete方法加入this.getContext().getContentResolver().notifyChange(URI,null);
其中URI表示监听的URI
null表示发送消息给任何人;
2).在访问者的类中调用如下方法:
context.getContentResolver().registerContentObserver(uri,true,new ContentObserver(new Handler()));
3).创建内部类继承ContentObserver并重写下面两个方法:
(1)带有Handler的构造函数;
(2)public void onChange(boolean selfChange); 此函数在内容提供者发出改变信号时就会被调用
参数selfChange为如果是自己改变的原因,则为true;如果不是自己改变的,则为false;

 

 

转载于:https://www.cnblogs.com/aiguozhe/p/3587881.html

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

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

相关文章

cin,cin.get(),getline()

我势必扫清我对c的各种疑惑&#xff0c;重拾csdn水文之任 结论&#xff1a;cin在获得需要接受的东西之前&#xff0c;对缓冲区里的空格和换行符不会理睬(但是会把它们从缓冲区删去)&#xff0c;但如果达到了可以结束接受的时候&#xff0c;空格和换行符都会让cin不再接 收,并且…

1067. 试密码(20)

1067. 试密码(20) 时间限制400 ms内存限制65536 kB代码长度限制8000 B判题程序Standard作者CHEN, Yue当你试图登录某个系统却忘了密码时&#xff0c;系统一般只会允许你尝试有限多次&#xff0c;当超出允许次数时&#xff0c;账号就会被锁死。本题就请你实现这个小功能。 输入格…

Map接口的实现类HashMap的操作

3中遍历HashMap方式 package C12_21;import java.util.Collection; import java.util.HashMap; import java.util.Set; import java.util.Map.Entry;public class testHashMap {public static void main(String[] args) {//定义两个HashMap 集合HashMap<Integer, Integer&g…

1068. 万绿丛中一点红(20)

1068. 万绿丛中一点红(20) 时间限制500 ms内存限制65536 kB代码长度限制8000 B判题程序Standard作者CHEN, Yue对于计算机而言&#xff0c;颜色不过是像素点对应的一个24位的数值。现给定一幅分辨率为MxN的画&#xff0c;要求你找出万绿丛中的一点红&#xff0c;即有独一无二颜色…

MapReduce 作业调试

1. 最经典的方法通过打印语句来调试程序 System.err.println("Bad Data"value.toString()); 这些输出错误都会记录到一个标准错误中&#xff0c;可以通过WebUI进行查看 2.可以创建一个自定义计数器来统计整个数据集中不合理的数据的数量。 首先创建一个enum enum BA…

寻找边界值,二分模板,简洁凝练

二分模板 class Solution {public static void main(String[] args) {int[] arr{1,2,2,2,2,4,5,6};int l0,rarr.length-1;while(l<r){int midl(r-l)/2;if(arr[mid]>2) rmid;else lmid1;}System.out.println("l:"l"r:"r);System.out.println("le…

Java 字节和字符流的读写+Buffered

一个关于IO流的导图 IO流字节的读写&#xff0c;实现复制 import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException;public class TestCopy {public static void main(String[] args) throws IOException {copyT…

1069. 微博转发抽奖(20)

1069. 微博转发抽奖(20) 时间限制400 ms内存限制65536 kB代码长度限制8000 B判题程序Standard作者CHEN, Yue小明PAT考了满分&#xff0c;高兴之余决定发起微博转发抽奖活动&#xff0c;从转发的网友中按顺序每隔N个人就发出一个红包。请你编写程序帮助他确定中奖名单。 输入格式…

jdbc 连接 Oracle 进行基本的增删改查

package api8;import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement;public class UpdateSelect {public static void main(String[] args) {// jdbc 连接 OracleselectAll();}//…

1070. 结绳(25)

1070. 结绳(25) 时间限制200 ms内存限制65536 kB代码长度限制8000 B判题程序Standard作者CHEN, Yue给定一段一段的绳子&#xff0c;你需要把它们串成一条绳。每次串连的时候&#xff0c;是把两段绳子对折&#xff0c;再如下图所示套接在一起。这样得到的绳子又被当成是另一段绳…

近期的随笔

有一段时间没有更新博客了&#xff0c;这一段时间确实忙&#xff0c;换工作&#xff0c;过年&#xff0c;适应新工作&#xff0c;培训&#xff0c;搬家等等。今天积累了一点想法想写写。 1.关于博客 在运营了独立博客一段时间后&#xff0c;有了比较深的感受就是为了高大上而高…

Java预编译和批处理

预编译 package csdn.prepare.take;import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;public class TestCompiling {public static void main(String[] args) {prep…

1028. 人口普查(20)

1028. 人口普查(20) 时间限制200 ms内存限制65536 kB代码长度限制8000 B判题程序Standard作者CHEN, Yue某城镇进行人口普查&#xff0c;得到了全体居民的生日。现请你写个程序&#xff0c;找出镇上最年长和最年轻的人。 这里确保每个输入的日期都是合法的&#xff0c;但不一定是…

结对项目开发-电梯调度

结对项目开发-电梯调度n设计和实现一个电梯调度瞄准两个正确性和性能&#xff0c;在托管代码。n技能训练&#xff1a;na&#xff09;需求分析nb&#xff09;高层次设计&#xff08;界面&#xff0c;信息隐藏&#xff0c;松耦合&#xff09;nc&#xff09;设计文档nd&#xff09…

1030. 完美数列(25)

1030. 完美数列(25) 时间限制300 ms内存限制65536 kB代码长度限制8000 B判题程序Standard作者CAO, Peng给定一个正整数数列&#xff0c;和正整数p&#xff0c;设这个数列中的最大值是M&#xff0c;最小值是m&#xff0c;如果M < m * p&#xff0c;则称这个数列是完美数列。 …

Java模拟事务Demo

Java操作Oracle事务&#xff0c;以转账为例。 转账之前 package translate.commit;import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException;public class CommitRollback…

关于 block的一些浅识

block的定义&#xff1a;“带自动变量的匿名函数” &#xff08;一&#xff09;写法&#xff1a; ^ void (int iAge){ NSLog("%d", iAge);}; 和C函数写法区别在于: 1) :以插入符号 ^ 开始. 2):没有函数名字 当block声明变量时候的写法 void (^blk)(int iAge) block …

1025. 反转链表 (25)

1025. 反转链表 (25) 时间限制300 ms内存限制65536 kB代码长度限制8000 B判题程序Standard作者CHEN, Yue给定一个常数K以及一个单链表L&#xff0c;请编写程序将L中每K个结点反转。例如&#xff1a;给定L为1→2→3→4→5→6&#xff0c;K为3&#xff0c;则输出应该为3→2→1→6…

手机连接电脑win10热点,手机显示无IP分配

hhhh&#xff0c;下面是我从csdn以及百度上查到的&#xff0c;对于我解决这个问题没什么luan用。 在C:\Windows\System32\drivers\etc GitHub不能上&#xff0c;可能我改了host文件的。 //创建一个热点对象 账号为lovely 密码为key netsh wlan set hostednetwork modeallow ss…