一,将外部工程导入的到IDE中的两种方式
1,将外部工程的整体工程导入时
1)鼠标右键-->import-->next-->选择你要导入的工程
(图1)![](https://img-blog.csdn.net/20130822182050625?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvYmFpeHVleWl5aW52aXA=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
注意:此时出现:(图2)
时要右键-->android Tools-->fix project prpoperties
2,只有工程的code代码时
1)new -->project-->android-->android project from Existing Code
二,操作数据库的第二种方式:
好处:1,可以避免因为书写操作数据库的sql语句不正确而造成的bug
2,在每次操作完数据库时都会返回一个结果,方便判断操作数据库是否有效,及其影响的结果
建议使用******
代码示例:
package cn.guoqing.userLoginSYS.dao;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import cn.guoqing.userLoginSYS.UserDBOpenHelper;
import cn.guoqing.userLoginSYS.domain.User;
public class UserDao {
//在一创建此类对象的时候就,就要拥有一个helper
UserDBOpenHelper helper=null;
Context context=null;
public UserDao(Context context) {
super();
this.context=context;
helper=new UserDBOpenHelper(context);
}
/**
* 向数据库中添加用户信息
* @param username
* @param password
*/
public Long addUser(String username,String password){
SQLiteDatabase database = helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("username", username);
values.put("password", password);
long result = database.insert("users", null, values);
database.close();
return result;
}
/**
* 从数据库中删除指定用户名的用户
* @param username
*/
public int deletetUser(String username){
SQLiteDatabase database = helper.getWritableDatabase();
int result = database.delete("users", "username=?", new String[]{username});
database.close();
return result;
}
/**
* 修改表中用户的密码
* @param username
* @param password
*/
public int updateUser(String username,String password){
SQLiteDatabase database = helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("username", username);
values.put("password", password);
int result = database.update("users", values, "username=?", new String[]{username});
database.close();
return result;
}
/**
* 查询指定的用户
* @param name
* @return
*/
public boolean find(String username){
SQLiteDatabase database = helper.getWritableDatabase();
Cursor cursor = database.query("users", new String[]{"username"}, "username=?", new String[]{username}, null, null, null);
if(cursor.moveToNext()){
database.close();
return true;
}
else{
database.close();
return false;
}
}
/**
* 获取数据库中所有的用户
* @return
*/
public List<User> findAll(String username){
SQLiteDatabase database = helper.getWritableDatabase();
Cursor cursor = database.query("username", new String[]{"id","username","password"}, "username=?", new String[]{username}, null, null, null);
List<User> list=new ArrayList<User>();
while(cursor.moveToNext()){
User user = new User();
int id=cursor.getInt(0);
String name=cursor.getString(1);
String pass=cursor.getString(2);
user.setId(id);
user.setUsername(name);
user.setPassword(pass);
list.add(user);
}
database.close();
return list;
}
}
三,使用sqlite3在命令行中打开android系统中数据库:
使用的步骤示例:
C:\Users\Administrator>adb shell
# cd data
cd data
# cd data
cd data
# ls
ls
cn.guoqing.userLoginSYS
com.android.contacts
com.android.music
com.android.speechrecorder
jp.co.omronsoft.openwnn
com.android.inputmethod.latin
com.android.protips
com.android.quicksearchbox
com.android.phone
com.android.calculator2
com.android.browser
com.android.sdksetup
com.android.development
com.android.providers.applications
com.android.wallpaper.livepicker
com.android.fallback
com.svox.pico
android.tts
com.android.soundrecorder
com.android.providers.downloads.ui
com.android.gallery
com.android.providers.subscribedfeeds
com.android.providers.drm
com.android.customlocale
com.android.spare_parts
com.android.term
com.android.packageinstaller
com.android.certinstaller
com.android.netspeed
com.android.systemui
com.android.htmlviewer
com.android.defcontainer
com.android.server.vpn
com.android.providers.contacts
com.android.mms
com.android.providers.telephony
com.android.launcher
com.android.inputmethod.pinyin
com.android.email
com.android.providers.media
com.android.providers.settings
com.android.providers.downloads
com.android.camera
cn.guoqing.mysms
cn.guoqing.wangyiNews
cn.guoqing.message
cn.guoqing.IPdialer
cn.guoqing.broswer
cn.guoqing.rpcalculator
cn.guoqing.taskandmodle
cn.guoqing.openBaiDu
com.android.gesture.builder
com.example.android.softkeyboard
com.example.android.livecubes
com.example.android.apis
cn.guoqing.eavesdrop
cn.guoqing.senter
com.android.settings
com.android.deskclock
com.android.providers.userdictionary
cn.guoqing.receiver
# cd cn.guoqing.userLoginSYS
cd cn.guoqing.userLoginSYS
# ls
ls
databases
lib
# cd databases
cd databases
# ls
ls
users.db
# sqlite3 users.db
sqlite3 users.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables;
.tables;
sqlite> .tables
.tables
android_metadata users
sqlite> select * from users;
select * from users;
1|wangwu1|1101
2|wangwu2|1102
3|wangwu3|1103
4|wangwu4|1104
5|wangwu5|1105
6|wangwu6|1106
7|wangwu7|1107
8|wangwu8|1108
9|wangwu9|1109
10|wangwu10|11010
11|wangwu11|11011
sqlite>
四,动态生成布局文件:就是根据返回的结果,向一个view中添加文本内容,有多少个结果就动态的向
一个布局文件中添加多少个已经填写好文本内容的view对象
1,listView :原理
listview 列表view
1.知道一共要显示有多少个条目
2.知道一个屏幕上最多能显示多个条目
3.创建一个集合 双向链表
4.滑动界面的时候 最上面条目移除屏幕 双向链表移除对象. 双向链表添加对象.
m : model 数据模型 Person
v : view 展示视图 ListView
c : controller 控制器 adapter
Code1:BaseAdapter适配器
package cn.guoqing.studentlist;
import java.util.List;
import cn.guoqing.userLoginSYS.dao.UserDao;
import cn.guoqing.userLoginSYS.domain.Student;
import cn.guoqing.userLoginSYS.service.LoginService;
import cn.guoqing.userLoginSYS.service.UserService;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
@SuppressWarnings("all")
public class MainActivity extends Activity {
//定义集合用于存储得到的学生信息对象的集合
List<Student> students =null;
ListView lv=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取ListView对象
lv=(ListView) findViewById(R.id.lv_list);
UserDao dao=new UserDao(this);
//查询所有的学生
students = dao.findAll();
//为ListView添加一个适配器
lv.setAdapter(new MyAdapter());
}
private class MyAdapter extends BaseAdapter{
//手机页面中每显示一个条目,就调用一次这个方法
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//每个条目设置一个特定同一风格的TestView对象(吹,吹,吹个大气球)
View view = View.inflate(getApplicationContext(), R.layout.lv_list, null);
TextView tvname=(TextView) view.findViewById(R.id.tv_name);
TextView tvid=(TextView) view.findViewById(R.id.tv_id);
TextView tvtel=(TextView) view.findViewById(R.id.tv_tel);
//获取当前提条目的student对象
Student student=students.get(position);
String name=student.getName();
int id = student.getId();
String phone = student.getPhone();
//将学生对象的信息填充到每个特定布局的相关的TextView中
tvname.setText("姓名:"+name);
tvid.setText("联系人ID:"+id);
tvtel.setText("电话"+phone);
return view;
}
//指定listView对象中一共要显示的条目个数
@Override
public int getCount() {
return students.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
}
Code2:ArrayAdapter适配器 只能更改指定魔板中的TextView中text中的内容
图;![](https://img-blog.csdn.net/20130822182334031)
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item,
R.id.tv_info, new String[] { "功能1", "功能2", "功能3", "功能4", "功能5",
"功能1", "功能2", "功能3", "功能4", "功能5" }));
}
}
3,public SimpleAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
Added in API level 1
Constructor
Parameters
context The context where the View associated with this SimpleAdapter is running
data A List of Maps. Each entry in the List corresponds to one row in the list. The Maps contain the data for each row, and should include all the entries specified in "from"
resource Resource identifier of a view layout that defines the views for this list item. The layout file should include at least those named views defined in "to"
from A list of column names that will be added to the Map associated with each item.
to The views that should display column in the "from" parameter. These should all be TextViews. The first N views in this list are given the values of the first N columns in the from parameter.
code3:
package com.itheima.simpleadapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class MainActivity extends Activity {
private ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
// 准备第一个map对象 第一个要显示条目对应的数据
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("image", R.drawable.app);
map1.put("text", "功能1");
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("image", R.drawable.atools);
map2.put("text", "功能2");
Map<String, Object> map3 = new HashMap<String, Object>();
map3.put("image", R.drawable.safe);
map3.put("text", "功能3");
Map<String, Object> map4 = new HashMap<String, Object>();
map4.put("image", R.drawable.settings);
map4.put("text", "功能4");
data.add(map1);
data.add(map2);
data.add(map3);
data.add(map4);
lv.setAdapter(new SimpleAdapter(this, data, R.layout.list_item,
new String[] { "image", "text" }, new int[]{R.id.iv_icon,R.id.tv_info}));
}
}
五,通过修改数据库的版本号,修改数据库的表结构
public class PersonDBOpenHelper extends SQLiteOpenHelper {
private static final String TAG = "PersonDBOpenHelper";
/**
*
* @param context上下文
* "person.db" 数据库名称 null 采用默认游标工厂 1 数据库的版本号 >=1
*/
public PersonDBOpenHelper(Context context) {
super(context, "person.db", null, 2);
}
/**
* 数据库第一次被创建的时候 调用,如果数据库已经存在 就不会调用这个方法.
* 数据库表结构的初始化.
*/
@Override
public void onCreate(SQLiteDatabase db) {
// 当数据库在第一次被创建的时候 调用 的方法
Log.i(TAG, "数据库被创建了..");
//执行一个sql语句
db.execSQL("create table person (id integer primary key autoincrement, name varchar(20),phone varchar(20)) ");
}
/**
* 当数据库的版本号发生增加的时候调用.
* 适合在升级的时候 更新数据库的表结构
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "数据库需要被更新了...");
db.execSQL("alter table person add money varchar(20)");
}
}
六,使用事务操作SQLite数据库
使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。使用例子如下: SQLiteDatabase db = ....;
db.beginTransaction();//开始事务
try {
db.execSQL("insert into person(name, age) values(?,?)", new Object[]{"传智播客", 4});
db.execSQL("update person set name=? where personid=?", new Object[]{"传智", 1});
db.setTransactionSuccessful();//调用此方法会在执行到endTransaction() 时提交当前事务,如果不调用此方法会回滚事务
} finally {
db.endTransaction();//由事务的标志决定是提交事务,还是回滚事务
}
db.close();
上面两条SQL语句在同一个事务中执行。
七,使用ContentProvider(内容提供者)共享数据
1,ContentProvider 在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。关于数据共享,以前我们学习过文件操作模式,知道通过指定文件的操作模式为Context.MODE_WORLD_READABLE 或Context.MODE_WORLD_WRITEABLE同样也可以对外共享数据。那么,这里为何要使用ContentProvider 对外共享数据呢?是这样的,如果采用文件操作模式对外共享数据,数据的访问方式会因数据存储的方式而不同,导致数据的访问方式无法统一,如:采用xml文件对外共享数据,需要进行xml解析才能读取数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读取数据。
使用ContentProvider对外共享数据的好处是统一了数据的访问方式。
当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法:
public class PersonContentProvider extends ContentProvider{
public boolean onCreate()
public Uri insert(Uri uri, ContentValues values)
public int delete(Uri uri, String selection, String[] selectionArgs)
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
public String getType(Uri uri)}
第二步需要在AndroidManifest.xml使用<provider>对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider , ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:
<manifest .... >
<application android:icon="@drawable/icon" android:label="@string/app_name">
<provider android:name=".PersonContentProvider" android:authorities="cn.itcast.providers.personprovider"/>
</application>
</manifest>
2,Uri代表了要操作的数据,Uri主要包含了两部分信息:1》需要操作的ContentProvider ,2》对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:
图:uri![](https://img-blog.csdn.net/20130822182447484)
ContentProvider(内容提供者)的scheme已经由Android所规定, scheme为:content://
主机名(或叫Authority)用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
要操作person表中id为10的记录,可以构建这样的路径:/person/10
要操作person表中id为10的记录的name字段, person/10/name
要操作person表中的所有记录,可以构建这样的路径:/person
要操作xxx表中的记录,可以构建这样的路径:/xxx
当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")
3,UriMatcher类使用介绍
因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的开发工作。
UriMatcher类用于匹配Uri,它的用法如下:
首先第一步把你需要匹配Uri路径全部给注册上,如下:
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//如果match()方法匹配content://cn.itcast.provider.personprovider/person路径,返回匹配码为1
sMatcher.addURI(“cn.itcast.provider.personprovider”, “person”, 1);//添加需要匹配uri,如果匹配就会返回匹配码
//如果match()方法匹配content://cn.itcast.provider.personprovider/person/230路径,返回匹配码为2
sMatcher.addURI(“cn.itcast.provider.personprovider”, “person/#”, 2);//#号为通配符
switch (sMatcher.match(Uri.parse("content://cn.itcast.provider.personprovider/person/10"))) {
case 1
break;
case 2
break;
default://不匹配
break;
}
注册完需要匹配的Uri后,就可以使用sMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,假设匹配content://cn.itcast.provider.personprovider/person路径,返回的匹配码为1
4,ContentUris类使用介绍
ContentUris类用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
withAppendedId(uri, id)用于为路径加上ID部分:
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")
Uri resultUri = ContentUris.withAppendedId(uri, 10);
//生成后的Uri为:content://cn.itcast.provider.personprovider/person/10
parseId(uri)方法用于从路径中获取ID部分:
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person/10")
long personid = ContentUris.parseId(uri);//获取的结果为:10
八,使用ContentResolver操作ContentProvider中的数据
1,当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中获取数据。
这些方法的第一个参数为Uri,代表要操作的ContentProvider和对其中的什么数据进行操作,假设给定的是: Uri.parse(“content://cn.itcast.providers.personprovider/person/10”),那么将会对主机名为cn.itcast.providers.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。
2,使用ContentResolver对ContentProvider中的数据进行添加、删除、修改和查询操作:
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person");
//添加一条记录
ContentValues values = new ContentValues();
values.put("name", "itcast");
values.put("age", 25);
resolver.insert(uri, values);
//获取person表中所有记录
Cursor cursor = resolver.query(uri, null, null, null, "personid desc");
while(cursor.moveToNext()){
Log.i("ContentTest", "personid="+ cursor.getInt(0)+ ",name="+ cursor.getString(1));
}
//把id为1的记录的name字段值更改新为liming
ContentValues updateValues = new ContentValues();
updateValues.put("name", "liming");
Uri updateIdUri = ContentUris.withAppendedId(uri, 2);
resolver.update(updateIdUri, updateValues, null, null);
//删除id为2的记录
Uri deleteIdUri = ContentUris.withAppendedId(uri, 2);
resolver.delete(deleteIdUri, null, null);
3,ContentResolver对ContentProvider在代码中具体时候情况
1)内容提供者在清单列表中的配置:
<provider
android:name="cn.guoqing.studentlist.StudentDBProvider"
android:authorities="cn.guoqing.studentlist.student"> --->相当于:天王盖地虎(暗号的前半句),后半句在内容提供者中的static代码块中进行预先录制
</provider>
2)内容提供者:
package cn.guoqing.studentlist;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
public class StudentDBProvider extends ContentProvider {
private static final int STUDENT = 1;
private static final int AAAAA = 2;
private static final int BBBBB = 3;
UserDBOpenHelper helper=null;
//1,获取电话号码的匹配器
private static UriMatcher uriMatcher =new UriMatcher(UriMatcher.NO_MATCH);
//2,规定电话号码的匹配规则 (相当于为指纹机收取指纹)
static{
uriMatcher.addURI("cn.guoqing.studentlist.student", "student", STUDENT); ---->"student"代表要操作的哪个表
uriMatcher.addURI("cn.guoqing.studentlist.student", "student/#", AAAAA);
uriMatcher.addURI("cn.guoqing.studentlist.student", "aaaaa", BBBBB);
}
@Override
public boolean onCreate() {
helper=new UserDBOpenHelper(this.getContext());
return false;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
if(uriMatcher.match(uri)==STUDENT){
System.out.println("满足STUDENT匹配规则");
SQLiteDatabase database = helper.getReadableDatabase();
Cursor cursor = database.query("student", projection, selection, selectionArgs, null, null, null);
return cursor;
}
else if(uriMatcher.match(uri)==AAAAA){
System.out.println("满足AAAAA匹配规则");
//获取指定的id
String path =uri.toString();
String id=path.substring(path.lastIndexOf("/")+1);
SQLiteDatabase database = helper.getReadableDatabase();
Cursor cursor = database.query("student", projection, "id=?", new String[]{id}, null, null, null);
return cursor;
}
else{
throw new IllegalArgumentException("暗号不对,好好想想!!!");
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if(uriMatcher.match(uri)==STUDENT){
System.out.println("满足STUDENT匹配规则");
SQLiteDatabase database = helper.getWritableDatabase();
database.insert("student", null, values);
}
else{
throw new IllegalArgumentException("暗号不对,好好想想!!!");
}
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
if(uriMatcher.match(uri)==STUDENT){
System.out.println("满足STUDENT匹配规则");
SQLiteDatabase database = helper.getWritableDatabase();
int result = database.delete("student", selection, selectionArgs);
return result;
}
else{
throw new IllegalArgumentException("暗号不对,好好想想!!!");
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
if(uriMatcher.match(uri)==STUDENT){
System.out.println("满足STUDENT匹配规则");
SQLiteDatabase database = helper.getWritableDatabase();
int result = database.update("student", values, selection, selectionArgs);
return result;
}
else{
throw new IllegalArgumentException("暗号不对,好好想想!!!");
}
}
}
3)通过内容提供者(中间代理人)访问应用程序的私有数据库
package cn.guoqing.visitPrivateDB;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
ContentResolver contentResolver = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contentResolver=this.getContentResolver();
}
/**
* 获取
* @param view
*/
public void get(View view){
Uri uri = Uri.parse("content://cn.guoqing.studentlist.student/student");
Cursor cursor = contentResolver.query(uri, null, null, null, null);
while(cursor.moveToNext()){
int id = cursor.getInt(0);
String name = cursor.getString(1);
String phone = cursor.getString(2);
String money = cursor.getString(3);
System.out.println(id+">>>"+name+">>>"+phone+">>>"+money);
}
}
/**
* 按id获取
*/
public void getByID(View view ){
Uri uri = Uri.parse("content://cn.guoqing.studentlist.student/student/4");
Cursor cursor = contentResolver.query(uri, null, null, null, null);
while(cursor.moveToNext()){
int id = cursor.getInt(0);
String name = cursor.getString(1);
String phone = cursor.getString(2);
String money = cursor.getString(3);
System.out.println(id+">>>"+name+">>>"+phone+">>>"+money);
}
}
/**
* 增加新的记录
*/
public void insert(View view){
Uri url = Uri.parse("content://cn.guoqing.studentlist.student/student");
ContentValues values =new ContentValues();
values.put("name", "zhaoliu");
values.put("phone", "120");
values.put("money", "$9999999");
Uri uri = contentResolver.insert(url, values);
System.out.println(uri);
}
/**
* 更新表中数据
*/
public void update(View view){
Uri url = Uri.parse("content://cn.guoqing.studentlist.student/student");
ContentValues values =new ContentValues();
values.put("money", "$58585895");
int result = contentResolver.update(url, values, "name=?", new String[]{"wangwu3"});
System.out.println(result);
}
/**
* 删除表中记录
*/
public void delete(View view){
Uri url = Uri.parse("content://cn.guoqing.studentlist.student/student");
int result = contentResolver.delete(url, "name=?", new String[]{"wangwu6"});
System.out.println(result);
}
}
九,一些小案例代码
1,短信的备份与还原:
package cn.guoqing.readSms;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Xml;
import android.view.View;
import android.widget.Toast;
import cn.guoqing.readSms.domian.Sms;
public class MainActivity extends Activity {
ContentResolver resolver=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取广播者的内容解析者
resolver=getContentResolver();
}
public void Smsbackup(View view){
Uri uri = Uri.parse("content://sms/");
Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, null);
try {
//将系统中短信信息进行数据备份
//1,获取将XML文件进行持久化的序列器
XmlSerializer xmlSerializer = Xml.newSerializer();
//2,指定备份文件的地址
File file=new File(getFilesDir(), "Sms.xml");
FileOutputStream fos=new FileOutputStream(file);
xmlSerializer.setOutput(fos, "UTF-8");
xmlSerializer.startDocument("utf-8", true);
xmlSerializer.startTag(null, "smss");
while(cursor.moveToNext()){
xmlSerializer.startTag(null, "sms");
String address = cursor.getString(0);
xmlSerializer.startTag(null, "address");
xmlSerializer.text(address);
xmlSerializer.endTag(null, "address");
String date = cursor.getString(1);
xmlSerializer.startTag(null, "date");
xmlSerializer.text(date);
xmlSerializer.endTag(null, "date");
String type = cursor.getString(2);
xmlSerializer.startTag(null, "type");
xmlSerializer.text(type);
xmlSerializer.endTag(null, "type");
String body = cursor.getString(3);
xmlSerializer.startTag(null, "body");
xmlSerializer.text(body);
xmlSerializer.endTag(null, "body");
xmlSerializer.endTag(null, "sms");
}
xmlSerializer.endTag(null, "smss");
xmlSerializer.endDocument();
Toast.makeText(this, "短信备份成功!", 0).show();
} catch (Exception e) {
Toast.makeText(this, "短信备份失败!", 0).show();
e.printStackTrace();
}
}
//短信还原
public void Smsrestore(View view){
List<Sms> list=null;
Sms sms = null;
//1,获取解析xml文件的解析器
XmlPullParser xmlPullParser = Xml.newPullParser();
//2,设置解析器要解析的额xml文件
try{
xmlPullParser.setInput(new FileInputStream(new File(getFilesDir(),"Sms.xml")), "utf-8");
System.out.println(new File(getFilesDir(),"Sms.xml").getAbsolutePath());
int eventType = xmlPullParser.getEventType();
System.out.println(eventType==xmlPullParser.END_DOCUMENT);
//3,解析xml文件
while(eventType!=xmlPullParser.END_DOCUMENT){
switch(eventType){
case XmlPullParser.START_TAG:
if("smss".equals(xmlPullParser.getName())){
list=new ArrayList<Sms>();
}
else if("sms".equals(xmlPullParser.getName())){
sms=new Sms();
}
else if("address".equals(xmlPullParser.getName())){
String address = xmlPullParser.nextText();
sms.setAddress(address);
}
else if("date".equals(xmlPullParser.getName())){
String date = xmlPullParser.nextText();
sms.setDate(date);
}
else if("type".equals(xmlPullParser.getName())){
String type = xmlPullParser.nextText();
sms.setType(type);
}
else if("body".equals(xmlPullParser.getName())){
String body = xmlPullParser.nextText();
sms.setBody(body);
}
break;
case XmlPullParser.END_TAG:
if("sms".equals(xmlPullParser.getName())){
list.add(sms);
sms=null;
}
break;
}
//解析下一个元素
eventType=xmlPullParser.next();
}
//将list中信息数据还原到sms表中
Uri uri = Uri.parse("content://sms/");
ContentValues values =null;
for(Sms s:list){
values=new ContentValues();
values.put("address", s.getAddress());
values.put("date", s.getDate());
values.put("type", s.getType());
values.put("body", s.getBody());
resolver.insert(uri, values);
}
Toast.makeText(this, "短信还原成功!", 0).show();
}catch(Exception e){
Toast.makeText(this, "短信还原失败!", 0).show();
e.printStackTrace();
}
}
}
2)Smsdomain:
package cn.guoqing.readSms.domian;
public class Sms {
private String address;
private String date;
private String type;
private String body;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
2,虚拟短信发送器:
package cn.guoqing.virtrueSms;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void senSms(View view){
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
try {
sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms/");
ContentValues values=new ContentValues();
values.put("address", "88888");
values.put("date", System.currentTimeMillis());
values.put("type", 1);
values.put("body","你好,你的账户余额为:888888888888888.99元整");
Uri uri2 = resolver.insert(uri, values);
System.out.println(uri2);
}
}.start();
}
}
1,将外部工程的整体工程导入时
1)鼠标右键-->import-->next-->选择你要导入的工程
(图1)
注意:此时出现:(图2)
2,只有工程的code代码时
1)new -->project-->android-->android project from Existing Code
二,操作数据库的第二种方式:
好处:1,可以避免因为书写操作数据库的sql语句不正确而造成的bug
2,在每次操作完数据库时都会返回一个结果,方便判断操作数据库是否有效,及其影响的结果
建议使用******
代码示例:
package cn.guoqing.userLoginSYS.dao;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import cn.guoqing.userLoginSYS.UserDBOpenHelper;
import cn.guoqing.userLoginSYS.domain.User;
public class UserDao {
//在一创建此类对象的时候就,就要拥有一个helper
UserDBOpenHelper helper=null;
Context context=null;
public UserDao(Context context) {
super();
this.context=context;
helper=new UserDBOpenHelper(context);
}
/**
* 向数据库中添加用户信息
* @param username
* @param password
*/
public Long addUser(String username,String password){
SQLiteDatabase database = helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("username", username);
values.put("password", password);
long result = database.insert("users", null, values);
database.close();
return result;
}
/**
* 从数据库中删除指定用户名的用户
* @param username
*/
public int deletetUser(String username){
SQLiteDatabase database = helper.getWritableDatabase();
int result = database.delete("users", "username=?", new String[]{username});
database.close();
return result;
}
/**
* 修改表中用户的密码
* @param username
* @param password
*/
public int updateUser(String username,String password){
SQLiteDatabase database = helper.getWritableDatabase();
ContentValues values=new ContentValues();
values.put("username", username);
values.put("password", password);
int result = database.update("users", values, "username=?", new String[]{username});
database.close();
return result;
}
/**
* 查询指定的用户
* @param name
* @return
*/
public boolean find(String username){
SQLiteDatabase database = helper.getWritableDatabase();
Cursor cursor = database.query("users", new String[]{"username"}, "username=?", new String[]{username}, null, null, null);
if(cursor.moveToNext()){
database.close();
return true;
}
else{
database.close();
return false;
}
}
/**
* 获取数据库中所有的用户
* @return
*/
public List<User> findAll(String username){
SQLiteDatabase database = helper.getWritableDatabase();
Cursor cursor = database.query("username", new String[]{"id","username","password"}, "username=?", new String[]{username}, null, null, null);
List<User> list=new ArrayList<User>();
while(cursor.moveToNext()){
User user = new User();
int id=cursor.getInt(0);
String name=cursor.getString(1);
String pass=cursor.getString(2);
user.setId(id);
user.setUsername(name);
user.setPassword(pass);
list.add(user);
}
database.close();
return list;
}
}
三,使用sqlite3在命令行中打开android系统中数据库:
使用的步骤示例:
C:\Users\Administrator>adb shell
# cd data
cd data
# cd data
cd data
# ls
ls
cn.guoqing.userLoginSYS
com.android.contacts
com.android.music
com.android.speechrecorder
jp.co.omronsoft.openwnn
com.android.inputmethod.latin
com.android.protips
com.android.quicksearchbox
com.android.phone
com.android.calculator2
com.android.browser
com.android.sdksetup
com.android.development
com.android.providers.applications
com.android.wallpaper.livepicker
com.android.fallback
com.svox.pico
android.tts
com.android.soundrecorder
com.android.providers.downloads.ui
com.android.gallery
com.android.providers.subscribedfeeds
com.android.providers.drm
com.android.customlocale
com.android.spare_parts
com.android.term
com.android.packageinstaller
com.android.certinstaller
com.android.netspeed
com.android.systemui
com.android.htmlviewer
com.android.defcontainer
com.android.server.vpn
com.android.providers.contacts
com.android.mms
com.android.providers.telephony
com.android.launcher
com.android.inputmethod.pinyin
com.android.email
com.android.providers.media
com.android.providers.settings
com.android.providers.downloads
com.android.camera
cn.guoqing.mysms
cn.guoqing.wangyiNews
cn.guoqing.message
cn.guoqing.IPdialer
cn.guoqing.broswer
cn.guoqing.rpcalculator
cn.guoqing.taskandmodle
cn.guoqing.openBaiDu
com.android.gesture.builder
com.example.android.softkeyboard
com.example.android.livecubes
com.example.android.apis
cn.guoqing.eavesdrop
cn.guoqing.senter
com.android.settings
com.android.deskclock
com.android.providers.userdictionary
cn.guoqing.receiver
# cd cn.guoqing.userLoginSYS
cd cn.guoqing.userLoginSYS
# ls
ls
databases
lib
# cd databases
cd databases
# ls
ls
users.db
# sqlite3 users.db
sqlite3 users.db
SQLite version 3.6.22
Enter ".help" for instructions
Enter SQL statements terminated with a ";"
sqlite> .tables;
.tables;
sqlite> .tables
.tables
android_metadata users
sqlite> select * from users;
select * from users;
1|wangwu1|1101
2|wangwu2|1102
3|wangwu3|1103
4|wangwu4|1104
5|wangwu5|1105
6|wangwu6|1106
7|wangwu7|1107
8|wangwu8|1108
9|wangwu9|1109
10|wangwu10|11010
11|wangwu11|11011
sqlite>
四,动态生成布局文件:就是根据返回的结果,向一个view中添加文本内容,有多少个结果就动态的向
一个布局文件中添加多少个已经填写好文本内容的view对象
1,listView :原理
listview 列表view
1.知道一共要显示有多少个条目
2.知道一个屏幕上最多能显示多个条目
3.创建一个集合 双向链表
4.滑动界面的时候 最上面条目移除屏幕 双向链表移除对象. 双向链表添加对象.
m : model 数据模型 Person
v : view 展示视图 ListView
c : controller 控制器 adapter
Code1:BaseAdapter适配器
package cn.guoqing.studentlist;
import java.util.List;
import cn.guoqing.userLoginSYS.dao.UserDao;
import cn.guoqing.userLoginSYS.domain.Student;
import cn.guoqing.userLoginSYS.service.LoginService;
import cn.guoqing.userLoginSYS.service.UserService;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.CheckBox;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
@SuppressWarnings("all")
public class MainActivity extends Activity {
//定义集合用于存储得到的学生信息对象的集合
List<Student> students =null;
ListView lv=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取ListView对象
lv=(ListView) findViewById(R.id.lv_list);
UserDao dao=new UserDao(this);
//查询所有的学生
students = dao.findAll();
//为ListView添加一个适配器
lv.setAdapter(new MyAdapter());
}
private class MyAdapter extends BaseAdapter{
//手机页面中每显示一个条目,就调用一次这个方法
@Override
public View getView(int position, View convertView, ViewGroup parent) {
//每个条目设置一个特定同一风格的TestView对象(吹,吹,吹个大气球)
View view = View.inflate(getApplicationContext(), R.layout.lv_list, null);
TextView tvname=(TextView) view.findViewById(R.id.tv_name);
TextView tvid=(TextView) view.findViewById(R.id.tv_id);
TextView tvtel=(TextView) view.findViewById(R.id.tv_tel);
//获取当前提条目的student对象
Student student=students.get(position);
String name=student.getName();
int id = student.getId();
String phone = student.getPhone();
//将学生对象的信息填充到每个特定布局的相关的TextView中
tvname.setText("姓名:"+name);
tvid.setText("联系人ID:"+id);
tvtel.setText("电话"+phone);
return view;
}
//指定listView对象中一共要显示的条目个数
@Override
public int getCount() {
return students.size();
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
}
Code2:ArrayAdapter适配器 只能更改指定魔板中的TextView中text中的内容
图;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ListView lv = (ListView) findViewById(R.id.lv);
lv.setAdapter(new ArrayAdapter<String>(this, R.layout.list_item,
R.id.tv_info, new String[] { "功能1", "功能2", "功能3", "功能4", "功能5",
"功能1", "功能2", "功能3", "功能4", "功能5" }));
}
}
3,public SimpleAdapter (Context context, List<? extends Map<String, ?>> data, int resource, String[] from, int[] to)
Added in API level 1
Constructor
Parameters
context The context where the View associated with this SimpleAdapter is running
data A List of Maps. Each entry in the List corresponds to one row in the list. The Maps contain the data for each row, and should include all the entries specified in "from"
resource Resource identifier of a view layout that defines the views for this list item. The layout file should include at least those named views defined in "to"
from A list of column names that will be added to the Map associated with each item.
to The views that should display column in the "from" parameter. These should all be TextViews. The first N views in this list are given the values of the first N columns in the from parameter.
code3:
package com.itheima.simpleadapter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import android.app.Activity;
import android.os.Bundle;
import android.widget.ListView;
import android.widget.SimpleAdapter;
public class MainActivity extends Activity {
private ListView lv;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv = (ListView) findViewById(R.id.lv);
List<Map<String, Object>> data = new ArrayList<Map<String, Object>>();
// 准备第一个map对象 第一个要显示条目对应的数据
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("image", R.drawable.app);
map1.put("text", "功能1");
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("image", R.drawable.atools);
map2.put("text", "功能2");
Map<String, Object> map3 = new HashMap<String, Object>();
map3.put("image", R.drawable.safe);
map3.put("text", "功能3");
Map<String, Object> map4 = new HashMap<String, Object>();
map4.put("image", R.drawable.settings);
map4.put("text", "功能4");
data.add(map1);
data.add(map2);
data.add(map3);
data.add(map4);
lv.setAdapter(new SimpleAdapter(this, data, R.layout.list_item,
new String[] { "image", "text" }, new int[]{R.id.iv_icon,R.id.tv_info}));
}
}
五,通过修改数据库的版本号,修改数据库的表结构
public class PersonDBOpenHelper extends SQLiteOpenHelper {
private static final String TAG = "PersonDBOpenHelper";
/**
*
* @param context上下文
* "person.db" 数据库名称 null 采用默认游标工厂 1 数据库的版本号 >=1
*/
public PersonDBOpenHelper(Context context) {
super(context, "person.db", null, 2);
}
/**
* 数据库第一次被创建的时候 调用,如果数据库已经存在 就不会调用这个方法.
* 数据库表结构的初始化.
*/
@Override
public void onCreate(SQLiteDatabase db) {
// 当数据库在第一次被创建的时候 调用 的方法
Log.i(TAG, "数据库被创建了..");
//执行一个sql语句
db.execSQL("create table person (id integer primary key autoincrement, name varchar(20),phone varchar(20)) ");
}
/**
* 当数据库的版本号发生增加的时候调用.
* 适合在升级的时候 更新数据库的表结构
*/
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
Log.i(TAG, "数据库需要被更新了...");
db.execSQL("alter table person add money varchar(20)");
}
}
六,使用事务操作SQLite数据库
使用SQLiteDatabase的beginTransaction()方法可以开启一个事务,程序执行到endTransaction() 方法时会检查事务的标志是否为成功,如果程序执行到endTransaction()之前调用了setTransactionSuccessful() 方法设置事务的标志为成功则提交事务,如果没有调用setTransactionSuccessful() 方法则回滚事务。使用例子如下: SQLiteDatabase db = ....;
db.beginTransaction();//开始事务
try {
db.execSQL("insert into person(name, age) values(?,?)", new Object[]{"传智播客", 4});
db.execSQL("update person set name=? where personid=?", new Object[]{"传智", 1});
db.setTransactionSuccessful();//调用此方法会在执行到endTransaction() 时提交当前事务,如果不调用此方法会回滚事务
} finally {
db.endTransaction();//由事务的标志决定是提交事务,还是回滚事务
}
db.close();
上面两条SQL语句在同一个事务中执行。
七,使用ContentProvider(内容提供者)共享数据
1,ContentProvider 在android中的作用是对外共享数据,也就是说你可以通过ContentProvider把应用中的数据共享给其他应用访问,其他应用可以通过ContentProvider 对你应用中的数据进行添删改查。关于数据共享,以前我们学习过文件操作模式,知道通过指定文件的操作模式为Context.MODE_WORLD_READABLE 或Context.MODE_WORLD_WRITEABLE同样也可以对外共享数据。那么,这里为何要使用ContentProvider 对外共享数据呢?是这样的,如果采用文件操作模式对外共享数据,数据的访问方式会因数据存储的方式而不同,导致数据的访问方式无法统一,如:采用xml文件对外共享数据,需要进行xml解析才能读取数据;采用sharedpreferences共享数据,需要使用sharedpreferences API读取数据。
使用ContentProvider对外共享数据的好处是统一了数据的访问方式。
当应用需要通过ContentProvider对外共享数据时,第一步需要继承ContentProvider并重写下面方法:
public class PersonContentProvider extends ContentProvider{
public boolean onCreate()
public Uri insert(Uri uri, ContentValues values)
public int delete(Uri uri, String selection, String[] selectionArgs)
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
public String getType(Uri uri)}
第二步需要在AndroidManifest.xml使用<provider>对该ContentProvider进行配置,为了能让其他应用找到该ContentProvider , ContentProvider 采用了authorities(主机名/域名)对它进行唯一标识,你可以把 ContentProvider看作是一个网站(想想,网站也是提供数据者),authorities 就是他的域名:
<manifest .... >
<application android:icon="@drawable/icon" android:label="@string/app_name">
<provider android:name=".PersonContentProvider" android:authorities="cn.itcast.providers.personprovider"/>
</application>
</manifest>
2,Uri代表了要操作的数据,Uri主要包含了两部分信息:1》需要操作的ContentProvider ,2》对ContentProvider中的什么数据进行操作,一个Uri由以下几部分组成:
图:uri
ContentProvider(内容提供者)的scheme已经由Android所规定, scheme为:content://
主机名(或叫Authority)用于唯一标识这个ContentProvider,外部调用者可以根据这个标识来找到它。
路径(path)可以用来表示我们要操作的数据,路径的构建应根据业务而定,如下:
要操作person表中id为10的记录,可以构建这样的路径:/person/10
要操作person表中id为10的记录的name字段, person/10/name
要操作person表中的所有记录,可以构建这样的路径:/person
要操作xxx表中的记录,可以构建这样的路径:/xxx
当然要操作的数据不一定来自数据库,也可以是文件、xml或网络等其他存储方式,如下:
要操作xml文件中person节点下的name节点,可以构建这样的路径:/person/name
如果要把一个字符串转换成Uri,可以使用Uri类中的parse()方法,如下:
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")
3,UriMatcher类使用介绍
因为Uri代表了要操作的数据,所以我们经常需要解析Uri,并从Uri中获取数据。Android系统提供了两个用于操作Uri的工具类,分别为UriMatcher 和ContentUris 。掌握它们的使用,会便于我们的开发工作。
UriMatcher类用于匹配Uri,它的用法如下:
首先第一步把你需要匹配Uri路径全部给注册上,如下:
//常量UriMatcher.NO_MATCH表示不匹配任何路径的返回码
UriMatcher sMatcher = new UriMatcher(UriMatcher.NO_MATCH);
//如果match()方法匹配content://cn.itcast.provider.personprovider/person路径,返回匹配码为1
sMatcher.addURI(“cn.itcast.provider.personprovider”, “person”, 1);//添加需要匹配uri,如果匹配就会返回匹配码
//如果match()方法匹配content://cn.itcast.provider.personprovider/person/230路径,返回匹配码为2
sMatcher.addURI(“cn.itcast.provider.personprovider”, “person/#”, 2);//#号为通配符
switch (sMatcher.match(Uri.parse("content://cn.itcast.provider.personprovider/person/10"))) {
case 1
break;
case 2
break;
default://不匹配
break;
}
注册完需要匹配的Uri后,就可以使用sMatcher.match(uri)方法对输入的Uri进行匹配,如果匹配就返回匹配码,匹配码是调用addURI()方法传入的第三个参数,假设匹配content://cn.itcast.provider.personprovider/person路径,返回的匹配码为1
4,ContentUris类使用介绍
ContentUris类用于获取Uri路径后面的ID部分,它有两个比较实用的方法:
withAppendedId(uri, id)用于为路径加上ID部分:
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person")
Uri resultUri = ContentUris.withAppendedId(uri, 10);
//生成后的Uri为:content://cn.itcast.provider.personprovider/person/10
parseId(uri)方法用于从路径中获取ID部分:
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person/10")
long personid = ContentUris.parseId(uri);//获取的结果为:10
八,使用ContentResolver操作ContentProvider中的数据
1,当外部应用需要对ContentProvider中的数据进行添加、删除、修改和查询操作时,可以使用ContentResolver 类来完成,要获取ContentResolver 对象,可以使用Activity提供的getContentResolver()方法。 ContentResolver 类提供了与ContentProvider类相同签名的四个方法:
public Uri insert(Uri uri, ContentValues values)
该方法用于往ContentProvider添加数据。
public int delete(Uri uri, String selection, String[] selectionArgs)
该方法用于从ContentProvider删除数据。
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs)
该方法用于更新ContentProvider中的数据。
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder)
该方法用于从ContentProvider中获取数据。
这些方法的第一个参数为Uri,代表要操作的ContentProvider和对其中的什么数据进行操作,假设给定的是: Uri.parse(“content://cn.itcast.providers.personprovider/person/10”),那么将会对主机名为cn.itcast.providers.personprovider的ContentProvider进行操作,操作的数据为person表中id为10的记录。
2,使用ContentResolver对ContentProvider中的数据进行添加、删除、修改和查询操作:
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://cn.itcast.provider.personprovider/person");
//添加一条记录
ContentValues values = new ContentValues();
values.put("name", "itcast");
values.put("age", 25);
resolver.insert(uri, values);
//获取person表中所有记录
Cursor cursor = resolver.query(uri, null, null, null, "personid desc");
while(cursor.moveToNext()){
Log.i("ContentTest", "personid="+ cursor.getInt(0)+ ",name="+ cursor.getString(1));
}
//把id为1的记录的name字段值更改新为liming
ContentValues updateValues = new ContentValues();
updateValues.put("name", "liming");
Uri updateIdUri = ContentUris.withAppendedId(uri, 2);
resolver.update(updateIdUri, updateValues, null, null);
//删除id为2的记录
Uri deleteIdUri = ContentUris.withAppendedId(uri, 2);
resolver.delete(deleteIdUri, null, null);
3,ContentResolver对ContentProvider在代码中具体时候情况
1)内容提供者在清单列表中的配置:
<provider
android:name="cn.guoqing.studentlist.StudentDBProvider"
android:authorities="cn.guoqing.studentlist.student"> --->相当于:天王盖地虎(暗号的前半句),后半句在内容提供者中的static代码块中进行预先录制
</provider>
2)内容提供者:
package cn.guoqing.studentlist;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.net.Uri;
public class StudentDBProvider extends ContentProvider {
private static final int STUDENT = 1;
private static final int AAAAA = 2;
private static final int BBBBB = 3;
UserDBOpenHelper helper=null;
//1,获取电话号码的匹配器
private static UriMatcher uriMatcher =new UriMatcher(UriMatcher.NO_MATCH);
//2,规定电话号码的匹配规则 (相当于为指纹机收取指纹)
static{
uriMatcher.addURI("cn.guoqing.studentlist.student", "student", STUDENT); ---->"student"代表要操作的哪个表
uriMatcher.addURI("cn.guoqing.studentlist.student", "student/#", AAAAA);
uriMatcher.addURI("cn.guoqing.studentlist.student", "aaaaa", BBBBB);
}
@Override
public boolean onCreate() {
helper=new UserDBOpenHelper(this.getContext());
return false;
}
@Override
public String getType(Uri uri) {
// TODO Auto-generated method stub
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
if(uriMatcher.match(uri)==STUDENT){
System.out.println("满足STUDENT匹配规则");
SQLiteDatabase database = helper.getReadableDatabase();
Cursor cursor = database.query("student", projection, selection, selectionArgs, null, null, null);
return cursor;
}
else if(uriMatcher.match(uri)==AAAAA){
System.out.println("满足AAAAA匹配规则");
//获取指定的id
String path =uri.toString();
String id=path.substring(path.lastIndexOf("/")+1);
SQLiteDatabase database = helper.getReadableDatabase();
Cursor cursor = database.query("student", projection, "id=?", new String[]{id}, null, null, null);
return cursor;
}
else{
throw new IllegalArgumentException("暗号不对,好好想想!!!");
}
}
@Override
public Uri insert(Uri uri, ContentValues values) {
if(uriMatcher.match(uri)==STUDENT){
System.out.println("满足STUDENT匹配规则");
SQLiteDatabase database = helper.getWritableDatabase();
database.insert("student", null, values);
}
else{
throw new IllegalArgumentException("暗号不对,好好想想!!!");
}
return null;
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
if(uriMatcher.match(uri)==STUDENT){
System.out.println("满足STUDENT匹配规则");
SQLiteDatabase database = helper.getWritableDatabase();
int result = database.delete("student", selection, selectionArgs);
return result;
}
else{
throw new IllegalArgumentException("暗号不对,好好想想!!!");
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
if(uriMatcher.match(uri)==STUDENT){
System.out.println("满足STUDENT匹配规则");
SQLiteDatabase database = helper.getWritableDatabase();
int result = database.update("student", values, selection, selectionArgs);
return result;
}
else{
throw new IllegalArgumentException("暗号不对,好好想想!!!");
}
}
}
3)通过内容提供者(中间代理人)访问应用程序的私有数据库
package cn.guoqing.visitPrivateDB;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
ContentResolver contentResolver = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
contentResolver=this.getContentResolver();
}
/**
* 获取
* @param view
*/
public void get(View view){
Uri uri = Uri.parse("content://cn.guoqing.studentlist.student/student");
Cursor cursor = contentResolver.query(uri, null, null, null, null);
while(cursor.moveToNext()){
int id = cursor.getInt(0);
String name = cursor.getString(1);
String phone = cursor.getString(2);
String money = cursor.getString(3);
System.out.println(id+">>>"+name+">>>"+phone+">>>"+money);
}
}
/**
* 按id获取
*/
public void getByID(View view ){
Uri uri = Uri.parse("content://cn.guoqing.studentlist.student/student/4");
Cursor cursor = contentResolver.query(uri, null, null, null, null);
while(cursor.moveToNext()){
int id = cursor.getInt(0);
String name = cursor.getString(1);
String phone = cursor.getString(2);
String money = cursor.getString(3);
System.out.println(id+">>>"+name+">>>"+phone+">>>"+money);
}
}
/**
* 增加新的记录
*/
public void insert(View view){
Uri url = Uri.parse("content://cn.guoqing.studentlist.student/student");
ContentValues values =new ContentValues();
values.put("name", "zhaoliu");
values.put("phone", "120");
values.put("money", "$9999999");
Uri uri = contentResolver.insert(url, values);
System.out.println(uri);
}
/**
* 更新表中数据
*/
public void update(View view){
Uri url = Uri.parse("content://cn.guoqing.studentlist.student/student");
ContentValues values =new ContentValues();
values.put("money", "$58585895");
int result = contentResolver.update(url, values, "name=?", new String[]{"wangwu3"});
System.out.println(result);
}
/**
* 删除表中记录
*/
public void delete(View view){
Uri url = Uri.parse("content://cn.guoqing.studentlist.student/student");
int result = contentResolver.delete(url, "name=?", new String[]{"wangwu6"});
System.out.println(result);
}
}
九,一些小案例代码
1,短信的备份与还原:
package cn.guoqing.readSms;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlSerializer;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.util.Xml;
import android.view.View;
import android.widget.Toast;
import cn.guoqing.readSms.domian.Sms;
public class MainActivity extends Activity {
ContentResolver resolver=null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//获取广播者的内容解析者
resolver=getContentResolver();
}
public void Smsbackup(View view){
Uri uri = Uri.parse("content://sms/");
Cursor cursor = resolver.query(uri, new String[]{"address","date","type","body"}, null, null, null);
try {
//将系统中短信信息进行数据备份
//1,获取将XML文件进行持久化的序列器
XmlSerializer xmlSerializer = Xml.newSerializer();
//2,指定备份文件的地址
File file=new File(getFilesDir(), "Sms.xml");
FileOutputStream fos=new FileOutputStream(file);
xmlSerializer.setOutput(fos, "UTF-8");
xmlSerializer.startDocument("utf-8", true);
xmlSerializer.startTag(null, "smss");
while(cursor.moveToNext()){
xmlSerializer.startTag(null, "sms");
String address = cursor.getString(0);
xmlSerializer.startTag(null, "address");
xmlSerializer.text(address);
xmlSerializer.endTag(null, "address");
String date = cursor.getString(1);
xmlSerializer.startTag(null, "date");
xmlSerializer.text(date);
xmlSerializer.endTag(null, "date");
String type = cursor.getString(2);
xmlSerializer.startTag(null, "type");
xmlSerializer.text(type);
xmlSerializer.endTag(null, "type");
String body = cursor.getString(3);
xmlSerializer.startTag(null, "body");
xmlSerializer.text(body);
xmlSerializer.endTag(null, "body");
xmlSerializer.endTag(null, "sms");
}
xmlSerializer.endTag(null, "smss");
xmlSerializer.endDocument();
Toast.makeText(this, "短信备份成功!", 0).show();
} catch (Exception e) {
Toast.makeText(this, "短信备份失败!", 0).show();
e.printStackTrace();
}
}
//短信还原
public void Smsrestore(View view){
List<Sms> list=null;
Sms sms = null;
//1,获取解析xml文件的解析器
XmlPullParser xmlPullParser = Xml.newPullParser();
//2,设置解析器要解析的额xml文件
try{
xmlPullParser.setInput(new FileInputStream(new File(getFilesDir(),"Sms.xml")), "utf-8");
System.out.println(new File(getFilesDir(),"Sms.xml").getAbsolutePath());
int eventType = xmlPullParser.getEventType();
System.out.println(eventType==xmlPullParser.END_DOCUMENT);
//3,解析xml文件
while(eventType!=xmlPullParser.END_DOCUMENT){
switch(eventType){
case XmlPullParser.START_TAG:
if("smss".equals(xmlPullParser.getName())){
list=new ArrayList<Sms>();
}
else if("sms".equals(xmlPullParser.getName())){
sms=new Sms();
}
else if("address".equals(xmlPullParser.getName())){
String address = xmlPullParser.nextText();
sms.setAddress(address);
}
else if("date".equals(xmlPullParser.getName())){
String date = xmlPullParser.nextText();
sms.setDate(date);
}
else if("type".equals(xmlPullParser.getName())){
String type = xmlPullParser.nextText();
sms.setType(type);
}
else if("body".equals(xmlPullParser.getName())){
String body = xmlPullParser.nextText();
sms.setBody(body);
}
break;
case XmlPullParser.END_TAG:
if("sms".equals(xmlPullParser.getName())){
list.add(sms);
sms=null;
}
break;
}
//解析下一个元素
eventType=xmlPullParser.next();
}
//将list中信息数据还原到sms表中
Uri uri = Uri.parse("content://sms/");
ContentValues values =null;
for(Sms s:list){
values=new ContentValues();
values.put("address", s.getAddress());
values.put("date", s.getDate());
values.put("type", s.getType());
values.put("body", s.getBody());
resolver.insert(uri, values);
}
Toast.makeText(this, "短信还原成功!", 0).show();
}catch(Exception e){
Toast.makeText(this, "短信还原失败!", 0).show();
e.printStackTrace();
}
}
}
2)Smsdomain:
package cn.guoqing.readSms.domian;
public class Sms {
private String address;
private String date;
private String type;
private String body;
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getDate() {
return date;
}
public void setDate(String date) {
this.date = date;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body;
}
}
2,虚拟短信发送器:
package cn.guoqing.virtrueSms;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void senSms(View view){
new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
try {
sleep(5000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ContentResolver resolver = getContentResolver();
Uri uri = Uri.parse("content://sms/");
ContentValues values=new ContentValues();
values.put("address", "88888");
values.put("date", System.currentTimeMillis());
values.put("type", 1);
values.put("body","你好,你的账户余额为:888888888888888.99元整");
Uri uri2 = resolver.insert(uri, values);
System.out.println(uri2);
}
}.start();
}
}