Android 学习笔记之ContentProvider实现数据共享....
PS:最近听老师说打算让我参与企业的app制作,让我加快学习的进度...好吧,貌似下周还有考试...貌似实验室这个app也要做...暂时不管了...那就只能加快进度了,感觉略微的有点激动和紧张,总算是可以开始对项目进行着手操作了...学的东西还是很少,还要继续努力啊...搞定Android的网络通信后就可以正式的进入项目开发了...不说废话了...
学习内容:
1.使用ContentProvider存储数据
2.操作联系人的ContentProvider...
3.多媒体信息的ContentProvider...
ContentProvider:
ContentProvider类是一个实现数据共享的一个类,它将共享的数据进行包装,然后对外暴露接口,外界的应用程序就能通过接口来访问被封装的数据,从而达到数据共享的目的...使用这个类需要了解一些其他的东西...
Uri:
在使用ContentProvider对数据进行操作的时候,以Uri的形式进行数据交换...Uri包含两个部分,一部分包含着我们要操作的ContentProvider..另一部分包括的是对ContentProvider中哪一个数据进行操作...
Uri uri=Uri.parse("content://com.example.contentprovider/person");//这个Uri表示访问person表中的所有记录...
UriMatcher:
在使用ContentProvider类操作某一种方法的时候有可能传递多种Uri,必须对这些传递的Uri进行相应的判断才能够决定如何去操作...可以使用switch语句进行判断...
UriMatcher match =new UriMatcher(No_MATCH);//对象的实例化操作...NO_MATCH表示-1...
match.addURI("包名","表名",匹配码)..
match.addURI("content://com.example.contentprovider","person",1);//增加一个URI值
/* 如果match方法匹配content://content.example.contentprovider/person/5
* 那么返回值就是2...
*/
mathc.addURI("content://com.example.contentprovider","person/#",2);//#为通配符......
ContentUris:
由于所有的数据操作都要通过Uri的形式进行传递,那么当执行完增加操作之后,我们往往想要返回我们增加后数据的ID以Uri的形式进行返回,那么就可以使用这个类来完成操作...
数据共享:
如果想实现数据共享,我们可以自己定义自己的ContentProvider...定义以后重写其内部的方法,不过这种方式一般都是没有任何的必要的..因为Android提供了多种类型的ContentProvider(图片,音频,视频,联系人等)...这些类都是它所提供的,因此我们只需要把数据封装这些类中,然后就可以完成数据的共享...因此一般我们都是将数据写入到系统提供的类中,完成数据的共享....
联系人的ContentProvider...
一般当我们在打电话或者是发短信的时候会使用到联系人这一数据信息,因此这个联系人内部的数据信息必须要进行共享,才使得其他的应用程序获取联系人信息...因此我们需要把数据写入到ContentProvider中....我们在模拟器中或者是自己的手机中也可以,添加几条联系人...然后我们通过触发按钮的形式来获取我们保存的数据信息...这个还需要配置一下权限,在AndroidManifest.xml文件中加入<user-permission android:name="android.permission.READ_CONTACTS"/>....布局文件一个按钮,一个文本显示控件...很简单....主要还是实现过程...
import android.net.Uri;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.ContentValues;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;
import android.widget.TextView; public class MainActivity extends Activity implements View.OnClickListener { private TextView tv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewById(R.id.but).setOnClickListener(this);
findViewById(R.id.but_1).setOnClickListener(this);
tv=(TextView) findViewById(R.id.text);
} @Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} @Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch(v.getId()){
case R.id.but:
StringBuilder st=getContents();//定义一个StringBuilder对象...表示st是一个可变的字符串...这里也可以使用StringBuffered...但是使用StringBuider更快...
tv.setText(st.toString());
break;
}
}
private StringBuilder getContents(){
StringBuilder stlog=new StringBuilder();
ContentResolver cr=this.getContentResolver();//操作ContentProvider首先要利用getContentResolver()获取ContentResolver实例..
Cursor cursor=cr.query(ContactsContract.Contacts.CONTENT_URI, null, null, null, null);//用Cursor来保存结果...
/* cr.query(uri, projection, selection, selectionArgs, sortOrder)
* uri参数:表示的是对哪个数据表进行操作..
* projection参数:表示在表中需要选取的列值..
* selection参数:表示的是查询的条件...相当于where子句..
* selectionArgs参数:表示语句中是否有?...
* sortorder参数:表示查询的结果按照什么形式进行排列...
* 查询的结果返回给Cursor对象...按行进行排列数据...
* */
for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToNext()){
//这里cr按行来保存每一条获取的数据...我们可以对想要的数据进行一一获取..
int nameIndex=cursor.getColumnIndex(ContactsContract.Contacts.DISPLAY_NAME);//这句话的意思表示获取联系人的名字...内容在ContactsContract.Contacts中...
String name=cursor.getString(nameIndex);
stlog.append("name= "+name+";");
String contentid=cursor.getString(cursor.getColumnIndex(ContactsContract.Contacts._ID));//获取联系人的ID信息...
//由于一个人可能有多个手机号码...因此还需要Cursor对多个号码进行保存...ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = "+contenti 这一参数来限制必须是同一个ID下的电话号码..说白了就是限制号码必须是一个人的...
Cursor phonecursor=cr.query(ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID + " = "+contentid, null, null);
while(phonecursor.moveToNext()){
String strphone=phonecursor.getString(phonecursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
stlog.append("phone="+ strphone+";");
}
// phonecursor.close(); 这句话在模拟器上可以使用...我们动态关闭...
//这个也一样可能有多个email....
Cursor email=cr.query(ContactsContract.CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " = "+contentid, null, null);
while(email.moveToNext()){
String stremail=email.getString(email.getColumnIndex(ContactsContract.CommonDataKinds.Email.DATA));
stlog.append("email="+stremail+";");
}
/*
* if(Build.VERSION.SDK_INT < 14) {
* cursor.close();
* }
* Android真机超过4.0以后的版本无法使用close()方法来关闭程序...否则会出现崩溃现象... 但是在模拟器上可以运行... 可以使用上面的函数进行判断是否已经超过4.0版本...
* */
// email.close();
// cursor.close();
}
return stlog; } }
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" > <TextView
android:id="@+id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/but"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="获取信息..."/>
<Button
android:id="@+id/but_1"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="增加信息..."/> </LinearLayout>
这里我们只是获取我们保存的数据信息,同时我们可以添加联系人,然后将数据保存在联系人中...插入数据就需要使用到ContentValues这个类,将插入的数据信息保存在其中...最后通过insert方法来完成数据的插入操作...这样就完成了数据的插入操作...
Uri uri=Uri.parse("content://com.android.contacts/raw_contacts");
ContentResolver resolver_1=this.getContentResolver();
ContentValues values=new ContentValues();
//获取主键值...
long contactid=ContentUris.parseId(resolver_1.insert(uri, values));
uri=Uri.parse("content://com.android.contacts/data");
values.put("raw_contact_id",contactid);
values.put("mimetype", "vnd.android.cursor.item/name");
values.put("data2", "aa");
resolver_1.insert(uri, values);
values.clear();
values.put("raw_contact_id", contactid);
values.put("mimetype", "vnd.andoroid.cursor.item/phone_v2");
values.put("data2", "2");
values.put("data1", "1131313");
resolver_1.insert(uri, values);
values.clear();
values.put("raw_contact_id", contactid);
values.put("mimetype", "vnd.android.cursor.item/email_v2");
values.put("data2", "2");
values.put("data1", "sa@qq.com");
resolver_1.insert(uri, values);
多媒体信息的ContentProvider...
多媒体的ContentProvider和联系人的基本都差不多,基本的模式都差不多,多媒体的ContentProvider也是需要首先获取ContentValues实例..然后才能进行增删改查等操作...查询一般使用query(uri,Prjs,Selections,selectArgs,Order)..方法来查询然后进行保存...查询的URI接收几个系统参数...这几个系统参数表示的是几个URI,这几个URI分别表示的是存储在手机内部或者是外部的图片内容,音频内容,或者是视频内容的URI...通过传递参数,我们就可以获取到手机里的图片,音频,或者是视频...
通过一个简单的例子来说一下多媒体信息的ContentProvider...然后实现多媒体数据信息的共享...这个例子就是获取手机里的音乐的基本信息...主布局...
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical"
tools:context=".MainActivity" > <TextView
android:id="@+id/msg"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:text="所有音乐"
android:textSize="20dp"
android:gravity="center"/>
<TableLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TableRow >
<TextView
android:layout_height="wrap_content"
android:layout_width="150px"
android:textSize="15px"
android:text="歌曲名"/>
<TextView
android:layout_height="wrap_content"
android:layout_width="100px"
android:textSize="15px"
android:text="歌手"/>
<TextView
android:layout_width="50px"
android:layout_height="wrap_content"
android:textSize="15px"
android:text="时间"/>
</TableRow>
</TableLayout>
<ListView
android:id="@+id/songlist"
android:layout_width="wrap_content"
android:layout_height="wrap_content"> </ListView> </LinearLayout>
这个布局没什么好说的...重点还是如何实现获取音乐的基本信息...这是实现的过程...在这里调用了另一个布局文件...调用另一个布局文件来显示获取到的数据信息...这种方式非常的常用...另一个布局文件...
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<TableRow >
<TextView
android:id="@+id/title"
android:layout_height="wrap_content"
android:layout_width="150px"
android:textSize="15px"/>
<TextView
android:id="@+id/name"
android:layout_height="wrap_content"
android:layout_width="100px"
android:textSize="15px"/>
<TextView
android:id="@+id/time"
android:layout_width="50px"
android:layout_height="wrap_content"
android:textSize="15px"/> </TableRow> </TableLayout>
package com.example.contentprovidermedia; import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map; import android.media.MediaPlayer;
import android.os.Bundle;
import android.provider.MediaStore;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.view.Menu;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.Toast; public class MainActivity extends Activity { private List<Map<String,String>>list=new ArrayList<Map<String,String>>();
private SimpleAdapter simpleadapter;
private ListView listview;
private String songname;
private String songtime;
private String songwriter;
private int Alltime;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listview=(ListView) findViewById(R.id.songlist);
listview.setOnItemClickListener(new OnItemClickListener() { private MediaPlayer media;
@Override
public void onItemClick(AdapterView<?> parent, View view,
int position, long id) {
/*
* 这个实现方法简单的说一下...parent表示的这个整体的列表,这个列表保存在适配器中...
* view表示的是列表中被选择的子选项...position表示被点击的定位...id表示的是被点击的行数...
* 这里表示的是当列表的某一行没触发时需要进行的操作...我定义的操作是,当点击到列表的某一行的时候
* 这个音乐将进行播放操作...
* */
// TODO Auto-generated method stub
Map<String,String>map=(Map<String, String>) MainActivity.this.simpleadapter.getItem(position);
String songtitle=map.get("title");
String songname=map.get("name");
String songtime=map.get("time");
String songpath=map.get("path");
palysong(songpath);
}
private void palysong(String songpath) {
// TODO Auto-generated method stub
this.media=new MediaPlayer();
media.reset();
try {
media.setDataSource(songpath);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
media.prepare();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
media.start();
}
}); ContentResolver resolver=this.getContentResolver();
/* resolver.query(uri, projection, selection, selectionArgs, sortOrder)
* uri参数:表示的是对哪个数据表进行操作..
* projection参数:表示在表中需要选取的列值..
* selection参数:表示的是查询的条件...相当于where子句..
* selectionArgs参数:表示语句中是否有?...
* sortorder参数:表示查询的结果按照什么形式进行排列...
* 查询的结果返回给Cursor对象...按行进行排列数据...
* */
Cursor cursor=resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, null, null, null, MediaStore.Audio.Media.DEFAULT_SORT_ORDER);
if(cursor==null){
Toast.makeText(MainActivity.this, "没有找到相应的数据", Toast.LENGTH_SHORT).show();
}else{
for(cursor.moveToFirst();!cursor.isAfterLast();cursor.moveToLast()){
songname=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));//获取音乐的名字信息..
songwriter=cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));//获取音乐的作者...
Alltime=cursor.getInt(cursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));//获取音乐的时长...以毫秒为单位...
songtime=settime(Alltime);
Map<String,String>map=new HashMap<String, String>();//用一个Map来保存数据...
map.put("title", songname);
map.put("songwriter", songwriter);
map.put("maptime", songtime);
list.add(map);//将map存入到List中...
/*
* 这里使用了一个简单的适配器...
* new SimpleAdapter(context,data,resource,from,to);这是适配器的构造方法...
* context SimpleAdapter关联的View的运行环境
* data 一个Map组成的List。在列表中的每个条目对应列表中的一行,每一个map中应该包含所有在from参数中指定的键
* resource 一个定义列表项的布局文件的资源ID。布局文件将至少应包含那些在to中定义了的ID
* from 一个将被添加到Map映射上的键名
* to 将绑定数据的视图的ID,跟from参数对应,这些应该全是TextView
*
* */
this.simpleadapter=new SimpleAdapter(this,list, R.layout.songlist, new String[]{"title","name","time"},new int[]{R.id.title,R.id.name,R.id.time});
listview.setAdapter(simpleadapter);//设置适配器...
}
}
} private String settime(int time){
time/=1000;
int minute=time/60;
int second=time%60;
minute %=60;
return String.format("%02d:%02d", minute,second); }
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
} }
ContentProvider的东西很多,也很杂,其重要的作用还是实现数据的共享,掌握了如何使用这个类来完成数据共享,那么目的就达到了...主要还是掌握如何去实现应用之间去调用共享的数据...
Android 学习笔记之ContentProvider实现数据共享....的更多相关文章
- android学习笔记54——ContentProvider
ContentProvider ContentProvider用于实现数据共享. ContentProvider是不同应用程序之间进行数据交换的标准API,其以某种Uri的形式对外提供数据,允许其他应 ...
- Android学习笔记之ContentProvider
读取其他应用程序共享的数据 以下示例为读取联系人信息 package com.jiahemeikang.helloandroid; import com.jiahemikang.service.Ech ...
- udacity android 学习笔记: lesson 4 part b
udacity android 学习笔记: lesson 4 part b 作者:干货店打杂的 /titer1 /Archimedes 出处:https://code.csdn.net/titer1 ...
- Android学习笔记36:使用SQLite方式存储数据
在Android中一共提供了5种数据存储方式,分别为: (1)Files:通过FileInputStream和FileOutputStream对文件进行操作.具体使用方法可以参阅博文<Andro ...
- 【转】Pro Android学习笔记(七):了解Content Provider(下上)
我们通过一个Content Provider小例子进行详细说明.数据源是一个SQLite数据库,名字为books.db,该数据库只含有一个表格,名字为books.表格中含有name,isbn,auth ...
- 【转】Pro Android学习笔记(五):了解Content Provider(上)
Content Provider是抽象数据封装和数据访问机制,例如SQLite是Android设备带有的数据源,可以封装到一个content provider中.要通过content provider ...
- 【转】Pro Android学习笔记(二):开发环境:基础概念、连接真实设备、生命周期
在Android学习笔记(二):安装环境中已经有相应的内容.看看何为新.这是在source网站上的Android架构图,和标准图没有区别,只是这张图颜色好看多了,录之.本笔记主要讲述Android开发 ...
- Android 学习笔记之Volley(七)实现Json数据加载和解析...
学习内容: 1.使用Volley实现异步加载Json数据... Volley的第二大请求就是通过发送请求异步实现Json数据信息的加载,加载Json数据有两种方式,一种是通过获取Json对象,然后 ...
- Android学习笔记进阶之在图片上涂鸦(能清屏)
Android学习笔记进阶之在图片上涂鸦(能清屏) 2013-11-19 10:52 117人阅读 评论(0) 收藏 举报 HandWritingActivity.java package xiaos ...
随机推荐
- VS2010 win7 QT4.8.0,实现VS2010编译调试Qt程序,QtCreator静态发布程序
下载源代码,注意一定是源码压缩包如qt-everywhere-opensource-src-4.8.0.zip, 不是Qt发布的已编译的不同版本的标准库如qt-win-opensource-4.8.0 ...
- 解决Visual Studio 2010/2012在调试时lock文件的方法
调试3dsmax插件,有一个避免每次修改插件代码都需要重启3dsmax的方法,就是将导出的核心代码写在一个独立的DLL中,然后在插件代码需要导出时LoadLibrary这个DLL,导出之后再FreeL ...
- SqlServer数据库备份与还原
http://v.youku.com/v_show/id_XMjA4NzcyNzUy.html http://v.youku.com/v_show/id_XMjA4Nzc0NDQw.html
- java中的==和equals
1,==用于比较基本数据类型,和引用类型.而equals是Object上的方法,可以被子类重写,用于判断内容一致. 比较奇葩的是,java基本数据类型(byte,short,int,long,floa ...
- C++中文件按行读取和逐词读取 backup
http://blog.csdn.net/zhangchao3322218/article/details/7930857 #include <iostream>#include &l ...
- java之接口interface
接口 1.多个无关的类可以实现同一个接口 2.一个类可以实现多个无关的接口 3.与继承关系类似,接口与实现类之间存在多态性 4.定义java类的语法格式 < modifier> class ...
- 图文安装Windows Template Library - WTL Version 9.0
从http://wtl.sourceforge.net/下载 WTL 9.0,或者点此链接下载:WTL90_4140_Final.zip,然后解压到你的VC目录下面, 我的地址是:C:\Program ...
- js类(继承)(一)
//call() //调用一个对象的一个方法,以另一个对象替换当前对象. //call([thisObj[,arg1[, arg2[, [,.argN]]]]]) //参数 //thisObj / ...
- Could not get BatchedBridge, make sure your bundle is packaged correctly
react-native 运行android项目的时候运行成功但是模拟器上会提示: Could not get BatchedBridge, make sure your bundle is pack ...
- Log4net对数据库的支持
记录到Oracle数据库中 <appender name="AdoNetAppender_Oracle" type="log4net.Appender.AdoNet ...