大家好 我是akira 今天我们来讲解前面剩下的一点东西 关于andriod文件存储方法
首先我们先回顾一下上期我们讲了什么 如果你没有看上期的话 不要紧
http://blog.youkuaiyun.com/mtgodd/article/details/40081941 这我已经帮朋友们把链接找好了
前面说 andriod存储的五点 是内容提供者 sqllite 网络 文件 和首选项 顺序无所谓
这次我们就来说下剩下的三个也就是 内容提供者 sqllite和网络部分
其实 内容提供者 和sqlite原理都差不多 都是crud 这里有些人要问 什么是内容提供者
其实 内容提供者简单的来说就是andriod开发必备的四大组件之一 前面我们已经知道了actvity 也就是活动
而内容提供者 它的作用是查询andriod手机内部的一些信息 原文是共享数据 比如我们要查询或者添加一个手机电话号码联系人或者查询自定义的数据
这个时候就要用到内容提供者 而提到四大组件 你应该要了解一点就是andriod的四大组件要么进行清单文件配置 要么进行代码配置 或者叫代码注册 也叫广播 前面的有一张我已经提到了一个服务service 那么四大组件就全了 也就是 活动 actvity 服务 service 广播接受者
broadcastreviever 和接下来要说的内容提供者 contentprovider 。
OK 回到正题 我们来说下内容提供者 前面说了 内容提供者是实现数据共享用的
我们建立一个工程简单的先适应一下内容提供者
先看下Ui 很简单 就是一个按钮
<RelativeLayout 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"
tools:context=".MainActivity" >
<Button
android:id="@+id/bt_fun"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/fun" />
</RelativeLayout>
这里实在没什么看的
看下 想实现效果的act
public class MainActivity extends Activity implements OnClickListener {
private Button bt_fun;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findview();
setlistener();
}
private void setlistener() {
bt_fun.setOnClickListener(this);
}
private void findview() {
bt_fun = (Button) findViewById(R.id.bt_fun);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
@Override
public void onClick(View v) {
if(v.getId()==R.id.bt_fun){
//进行访问
}
}
}
这里进行访问后先留一点 但是其实也没什么看的
关键的来了 我们知道 contentprovider是要进行数据访问的 那么它怎么知道 我想访问的哪些数据 这个时候就要依照一个东西 Uri 也就是统一资源标识符
OK 这里提到了uri 不妨看看我们在清单文件中是怎么注册我们自定义的内容提供者的
<provider android:name="com.akira.contentdemo.MyContent"
android:authorities="akira"
/>
我们关键看后一个 auth什么的 这个就是一个授权 这就好比一个代理 我只有拿到了官方的授权才允许进行运营
看完了这个 我们看下自己的contentProvider的写法
public class MyContent extends ContentProvider {
private static final String TAG = "akira";
private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
private final static String authority= "akira" ;
static{
matcher.addURI(authority, "aaa", 200);
}
@Override
public boolean onCreate() {
Log.i(TAG, "访问到");
return false;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
int code = matcher.match(uri);//匹配的uricode
if(code==200){
//一些事情
}
return null;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Uri insert(Uri uri, ContentValues values) {
// TODO Auto-generated method stub
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
// TODO Auto-generated method stub
return 0;
}
}
这里我简单解释一下 继承不用多说 我说了 这个是有crud的 看到override了么 那几个方法就是证明 当然还有onCreate和getType这两方法
这里引用一个UriMatcher类 用来匹配我们的Uri路径 由于是初次匹配 所以选择UriMatcher给的常量即可
而在生成的匹配者中有添加Uri的方法 这里面有三个参数 auth就是清单文件中的那个 写法任意
path比如你建立Db也就是数据库里要用到的表名 如果你还不清楚数据库是什么 建议可以看看数据库方面的知识 这里我就不赘述了
而最后的code你可以理解为一种返回码
Ok 说完了上述还有一点是关于日志 简单的来说 日志是和debug进行配合帮助开发人员找到bug或者开发的一种类
也就是Log类 而这个类提供了几个方法 比如 i w 等
但你要知道 andriod日志是有级别的 从低到高为
v d i w e
即 verbose debug info warm 和error 如果你不清楚这几个没关系 在你用的开发工具 比如eclipse中会有相应的
在菜单project showview有个logcat 打开就可以了
主Act的补充代码
//进行访问
MyContent mContent = new MyContent();
Cursor c = mContent.query(Uri.parse("content://akira/aaa/200"), null, null, null, null);
while(c.moveToNext()){
//做一些事情
}
因为我们写好了 自定义的提供者 所以先new一个 然后query调用api 这里面有几个参数说下
Uri就是匹配的Uri 而Uri类中有一个parse方法专门去做匹配 提供者uri的格式前缀都为content:// 这个格式跟http协议的格式太像了
而后面第一部分就是授权 第二部分是表 或者说路径 最后一部分是路径中的参数
知道了这个 我们很容易理解content://akira/aaa/200 后面四个为 列 条件 条件为 和排序 这里会返回一个游标 而这个游标它会帮助我们去查询
下面利用while循环 然后做一些事情 关于提供者的初步入门就先介绍到这 后期咱还会继续说。
然后因为前面提到了联系人 我们就来添加一个联系人 我们知道联系人靠的就是提供者 那么我们就来按照需求添加一个联系人
看下代码
//获取联系人
ContentResolver cr = this.getContentResolver();
ContentValues values = new ContentValues();
Uri insert = cr.insert(Uri.parse("content://com.andriod.contacts/raw_contacts"), values);
long parseId = ContentUris.parseId(insert);
//name
values.put("raw_contact_id", parseId);
values.put("data1", "哈哈");
values.put("mimetype", "vnd.android.cursor.item/name");
cr.insert(Uri.parse("content://com.andriod.contacts/data"), values);
//number
values.put("raw_contact_id", parseId);
values.put("data1", "12345");
values.put("mimetype", "vnd.android.cursor.item/phone_v2");
values.put("data2", "1");
cr.insert(Uri.parse("content://com.andriod.contacts/data"), values);
前面我只是做了添加另外一个按钮的操作 关键的来了 这里面看起来代码比较多 实际上很容易 先看书我们获取到一个提供者
因为要利用插入的api 所以用到一个类是ContentValues 这个类 你看到put方法就知道 它也可以看称一个map 那么既然是map肯定有key 我们利用key值插入即可
唯一麻烦的是找Uri 这里如果你有andriod源码的话 就可以发现实际上源码的ContentProvider中提供了匹配
那么它是按照 数据库Contact2.db拿到的 这个数据库如果在进行真机操作的时候 必须要root 然后就是找表过程 有个软件是Sqlite ExcerptXXX(具体名字记不清了)
去找即可
而表这里 刚开始是插入raw_contacts表 后面利用到姓名和号码的时候利用data表 然后去匹配相应的内容和mimeType即可
最后调用insert 关键一点是加入读写联系人的权限 OK 大功告成
下次我们讲下sqlite的CRUD用法