[转]大话企业级Android应用开发实战 文件I/O
20 文件:普通文件的I/O
20.1 文件存储数据
3.配置测试环境
编写AndroidManifest.xml:
package="com.sharpandroid.file" android:versionCode="1" android:versionName="1.0"> android:label="@string/app_name"> android:targetPackage="com.sharpandroid.file" android:label="Tests for My App" />
4.创建测试
添加testSave测试方法,FileServiceTest测试类代码如下:
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.test.AndroidTestCase;
import android.util.Log;
public class FileServiceTest extends AndroidTestCase {
public void testSave() throws Throwable{
FileService fileService = new FileService(getContext());
fileService.save("我们是sharpandroid!");
}
}
6.读取文件
在FileService.java文件中增加read方法和readFile方法,其代码如下:
/**
* 读取内容
*/
public String read() throws Throwable{
FileInputStream inStream = context.openFileInput
("sharpandroid.txt");
byte[] data = readFile(inStream);
return new String(data);
}
/**
* 读取文件数据
*/
public byte[] readFile(InputStream inStream) throws Throwable{
int len = 0;
byte[] buffer = new byte[1024];
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
while((len = inStream.read(buffer)) != -1){
outStream.write(buffer, 0, len);
}
outStream.close();
return outStream.toByteArray();
}
9.测试Context.MODE_WORLD_READABLE模式
接着在other应用中配置单元测试环境,其功能清单文件内容如下。
package="com.sharpandroid.other" android:versionCode="1" android:versionName="1.0"> android:targetPackage="com.sharpandroid.other" android:label="Tests for My App" />
完成之后,创建testAccessOtherAppFile方法,OtherTest.java内容如下。
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.test.AndroidTestCase;
import android.util.Log;
public class OhterTest extends AndroidTestCase {
private static final String TAG = "OtherTest";
/**
* 读取其他应用中的文件
*/
public void testAccessOtherAppFile() throws Throwable{
File file = new File("/data/data/ com.sharpandroid.file/files/
sharp.txt");
FileInputStream inStream = new FileInputStream(file);
byte[] data = readFile(inStream);
String content = new String(data);
Log.i(TAG, content);
}
/**
* 读取文件数据
*/
public byte[] readFile(InputStream inStream) throws Throwable{
int len = 0;
byte[] buffer = new byte[1024];
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
while((len = inStream.read(buffer)) != -1){
outStream.write(buffer, 0, len);
}
outStream.close();
return outStream.toByteArray();
}
}
20.2 SD Card数据存取
2.文件保存业务
完成save方法之后,FileService.java代码如下:
import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
public class FileService {
private Context context;
public FileService(Context context) {
this.context = context;
}
/**
* 保存内容
*/
public void saveToSDCard(String content) throws Exception{
File file = new File(Environment.getExternalStorageDirectory(),
"SDCard.txt");
FileOutputStream outStream = new FileOutputStream(file);
outStream.write(content.getBytes());
outStream.close();
}
}
3.测试保存方法
添加testSave测试方法,之后FileServiceTest测试类代码如下。
import java.io.InputStream;
import java.io.OutputStream;
import android.content.Context;
import android.test.AndroidTestCase;
import android.util.Log;
public class FileServiceTest extends AndroidTestCase {
private static final String TAG = "FileServiceTest";
public void testSaveToSDCard() throws Throwable{
if(Environment.getExternalStorageState().equals(Environment.MEDIA_M
OUNTED)){
//该状态代表SDCard已经安装在手机上,并且可以进行读写访问
FileService fileService = new FileService(getContext());
fileService.saveToSDCard("明天会更好!");
}else{
Log.i(TAG, "sdcard不存在或者写保护了");
}
}
}
4.执行测试
配置单元测试环境,配置后代码如下。
AndroidManifest.xml
package="com.sharpandroid.sdcard" android:versionCode="1" android:versionName="1.0"> android:icon="@drawable/icon" android:label="@string/app_name"> android:targetPackage="com.sharpandroid.sdcard" android:label="Tests for My App" />
20.3 SharedPreferences(共享参数)
20.3.3 界面设计
编写Main.xml:
android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > android:layout_width="fill_parent" android:layout_height="wrap_content" > android:id="@+id/nameView" android:layout_width="60px" android:layout_height="wrap_content" android:text="name:" /> android:id="@+id/name" android:layout_width="60px" android:layout_height="wrap_content" android:layout_alignTop="@id/nameView" android:layout_toRightOf="@id/nameView" /> android:layout_width="fill_parent" android:layout_height="wrap_content" > android:id="@+id/ageView" android:layout_width="60px" android:layout_height="wrap_content" android:text="age:" /> android:id="@+id/age" android:layout_width="60px" android:layout_height="wrap_content" android:layout_alignTop="@id/ageView" android:layout_toRightOf="@id/ageView" /> android:layout_width="fill_parent" android:layout_height="wrap_content" > android:id="@+id/text01" android:layout_width="fill_parent" android:layout_height="wrap_content" >
20.3.4 代码处理
部分代码如下。
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
nameText = (EditText)findViewById(R.id.name);
ageText = (EditText)findViewById(R.id.age);
Button setbutton = (Button)findViewById(R.id.setbutton);
setbutton.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
//获得输入框的内容
SharedPreferences sharedPreferences = getSharedPreferences("sharpandroid
", Context.MODE_PRIVATE);
String name = nameText.getText().toString();
String age = ageText.getText().toString();
Editor editor = sharedPreferences.edit();
editor.putString("name", name);
editor.putInt("age", Integer.parseInt(age));
editor.commit();
//添加一个提示,当添加成功可以看到该提示
Toast.makeText(PreferencesActivity.this, "保存成功。", Toast.
LENGTH_LONG).show();
}
});
}
下面我们将使用另外一种形式,更好地解决这个问题,代码如下。
package cn.sharpandroid.sharedPTest;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class SharedPreferenceTest extends Activity {
EditText nameEdit ;
EditText ageEdit;
TextView text;
Button button01;
Button button02;
String info = "提交成功";
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
nameEdit = (EditText)findViewById(R.id.name);
ageEdit = (EditText)findViewById(R.id.age);
text = (TextView)findViewById(R.id.text01);
button01 = (Button)findViewById(R.id.save);
button02 = (Button)findViewById(R.id.load);
button01.setOnClickListener(listener);
button02.setOnClickListener(listener);
}
private View.OnClickListener listener = new View.OnClickListener() {
public void onClick(View v) {
SharedPreferences sp = getSharedPreferences("preferences",
Context.MODE_WORLD_WRITEABLE);
Button button = (Button)v;
switch (button.getId()) {
case R.id.save:
Editor editor = sp.edit();
editor.putString("name", nameEdit.getText().toString());
try {editor.putInt("age", Integer.
parseInt(ageEdit.getText().toString()));
} catch (Exception e) {info = "提交失败";}
editor.commit();
DisplayToast(info);
break;
case R.id.load:
sp.getString("name", null);
sp.getInt("age", 0);
text.setText(sp.getString("name", null)+sp.getInt("age",
0));
break;
}
}
};
public void DisplayToast(String context){
Toast.makeText(SharedPreferenceTest.this, context, 200).show();
}
}
21 数据管家——SQLite数据库
21.3 常用的数据库添、删、改、查操作
21.3.1 实现添、删、改、查操作
然后为Person类添加字段和set、get方法,代码如下:
package com.sharpandroid.domain;
public class Person {
private Integer id;
private String name;
private Integer age;
public Person(){}
public Person(String name, Integer age) {
this.name = name;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Person [age=" + age + ", id=" + id + ", name=" + name + "]";
}
}
在PersonService类中,先实例化DatabaseHelper工具类,然后再由外部调用PersonService类传入上下文,代码如下:
private DatabaseHelper databaseHelper;
private Context context;
public PersonService(Context context) {
this.context=context;
databaseHelper = new DatabaseHelper(context);
}
1.添加方法
下面我们要实现保存操作,代码如下:
public void save(Person person){
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.execSQL("insert into person(name, age) values('Tom',21)");
}
如上图所示,用户输入了单引号,在程序组拼之后的SQL语句为insert into person(name, age)values(‘tom’s',21)"),那么程序就会出错,所以我们要这样做,代码如下:
public void save(Person person){
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.execSQL("insert into person(name, age) values(?,?)",
new Object[]{person.getName(), person.getAge()});
}
2.更新方法
我们继续实现更新操作,代码如下:
public void update(Person person){
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.execSQL("update person set name=?,age=? where personid=?",
new Object[]{person.getName(), person.getAge(), person.
getId()});
}
3.查询方法
实现查找操作,注意查找用到的是rawQuary()方法执行查找操作,代码如下:
public Person find(Integer id){
SQLiteDatabase db = databaseHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select personid,name,age from person
where personid=?", new String[]{String.valueOf(id)});
if(cursor.moveToNext()){ //迭代记录集
Person person = new Person();//实例化person
person.setId(cursor.getInt(cursor.getColumnIndex("personid")));
person.setName(cursor.getString(1));
person.setAge(cursor.getInt(2)); //将查到的字段,放入person,
return person;
}
cursor.close();//游标关闭
return null;
}
4.删除方法
删除操作大致和保存操作相似,代码如下:
public void delete(Integer id){
SQLiteDatabase db = databaseHelper.getWritableDatabase();
db.execSQL("delete from person where personid=?", new Object[]{id});
}
5.分页方法
分页操作,代码如下:
public List
List
SQLiteDatabase db = databaseHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select personid,name,age from person
limit ?,?",
new String[]{String.valueOf(firstResult), String.
valueOf(maxResult)}); //firstResult开始索引
while(cursor.moveToNext()){ //maxResult每页获取的记录数
Person person = new Person();
person.setId(cursor.getInt(cursor.getColumnIndex("personid")));
person.setName(cursor.getString(1));
person.setAge(cursor.getInt(2));
persons.add(person);
}
cursor.close();
return persons;
}
21.4 另一种实现添、删、改、查的方法
21.4.1 实现添、删、改、查操作
OtherPersonService类,和之前讲过的PersonService一样,先实例化DatabaseHelper工具类,然后由外部调用OtherPersonService类传入上下文,代码如下:
private DatabaseHelper databaseHelper;
private Context context;
public OtherPersonService(Context context) {
this.context=context;
databaseHelper = new DatabaseHelper(context);
}
1.添加
实现添加操作,代码如下:
public void save(Person person){
SQLiteDatabase database = databaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", person.getName());
values.put("age", person.getAge());
database.insert("person", "name", values);
//database.close();
}
2.更新
实现更新操作,代码如下:
public void update(Person person){
SQLiteDatabase database = databaseHelper.getWritableDatabase();
ContentValues values = new ContentValues();
values.put("name", person.getName());
values.put("age", person.getAge());
database.update("person", values, "personid=?" , new String[]
{String.valueOf(person.getId())});
}
3.查找
实现查找操作,代码如下:
public Person find(Integer id){
SQLiteDatabase database = databaseHelper.getWritableDatabase();
Cursor cursor = database.query("person", new String[]
{"personid","name","age"},"personid=?", new String[]{String.valueOf(id)},
null, null, null);
if(cursor.moveToNext()){
Person person= new Person();
person.setId(cursor.getInt(0));
person.setName(cursor.getString(1));
person.setAge(cursor.getInt(2));
return person;
}
return null;
}
4.删除
实现删除操作,代码如下:
public void delete(Integer id){
SQLiteDatabase database = databaseHelper.getWritableDatabase();
database.delete("person", "personid=?", new String[]{String.valueOf(id)});
}
5.分页
实现分页操作,代码如下:
public List
List
SQLiteDatabase database = databaseHelper.getWritableDatabase();
Cursor cursor = database.query("person", new String[]{"personid", "name",
"age"},null, null, null, null, "personid desc", startResult+ ","+ maxResult);
while(cursor.moveToNext()){ //迭代添加到persons
Person person= new Person();
person.setId(cursor.getInt(0));
person.setName(cursor.getString(1));
person.setAge(cursor.getInt(2));
persons.add(person);
}
return persons;
}
6.获取记录总数
实现获取记录总数的操作,代码如下:
public long getCount(){
SQLiteDatabase database = databaseHelper.getWritableDatabase();
Cursor cursor = database.query("person", new String[]{"count(*)"}, null,
null, null, null, null);
if(cursor.moveToNext()){
return cursor.getLong(0);
}
return 0;
}
21.4.2 测试业务
这个类和之前的测试类PersonServiceTest内容几乎一样,只是把PersonService类名换成OtherPersonService类名,然后测试各个方法是否成功,OtherPersonServiceTest测试类代码如下:
package com.sharpandroid.activity;
import java.util.List;
import android.test.AndroidTestCase;
import android.util.Log;
import com.sharpandroid.domain.Person;
import com.sharpandroid.service.OtherPersonService;
import com.sharpandroid.service.PersonService;
public class OtherPersonServiceTest extends AndroidTestCase {
private static final String TAG = "OtherPersonServiceTest";
public void testSave() throws Throwable{ //测试保存方法
OtherPersonService otherPersonService = new OtherPersonService
(this.getContext());//传入上下文
for(int i=0;i<10;i++)
{
Person person = new Person("Tom"+i, 21);
otherPersonService.save(person); //添加十条记录
}
}
public void testFind() throws Throwable{ //测试查找方法
OtherPersonService otherPersonService = new OtherPersonService
(this.getContext());
Person person = otherPersonService.find(1);
Log.i(TAG, person.toString());
}
public void testUpdate() throws Throwable{//测试更新方法
OtherPersonService otherPersonService = new OtherPersonService
(this.getContext());
Person person =
otherPersonService.find(1); //把第一条记录名字改为Jim
person.setName("Jim");
otherPersonService.update(person);
}
public void testCount() throws Throwable{//测试记录总数
OtherPersonService otherPersonService = new OtherPersonService
(this.getContext());
Log.i(TAG, otherPersonService.getCount()+ "");
}
public void testGetScrollData() throws Throwable{ //测试分页
OtherPersonService otherPersonService = new OtherPersonService
(this.getContext());
List
for(Person person : persons){
Log.i(TAG, person.toString());
}
}
public void testDelete() throws Throwable{ //测试删除
OtherPersonService otherPersonService = new OtherPersonService
(this.getContext());
otherPersonService.delete(1);
}
}
21.6 使用ListView显示表中的数据
1.编写personitem.xml文件
创建成功之后,它的代码如下:
Personitem.xml
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="wrap_content"> android:layout_width="60px" android:layout_height="wrap_content" android:id="@+id/personid" > android:layout_width="160px" android:layout_height="wrap_content" android:layout_toRightOf="@id/personid " android:layout_alignTop="@id/personid " android:gravity="center_horizontal" android:id="@+id/name" > android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/name" android:layout_alignTop="@id/name" android:id="@+id/age" >
2.编写main.xml文件
因为PersonActivity中,它显示的主界面为main.xml,所以我们打开main.xml,为它加入一个ListView组件,代码如下:
android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > android:id="@+id/personList" android:layout_width="fill_parent" android:layout_height="wrap_content" >
在Android系统中我们常用的适配器有ArrayAdapter,我们这次用到的适配器SimpleAdapter,以及采用查询结果集作为数据来源的适配器SimpleCursorAdapter。实例化一个SimpleAdapter,然后为它绑定数据,代码如下:
PersonActivity.java
public class PersonActivity extends Activity {
/** Called when the activity is first created. */
private final static String TAG="PersonActivity";
private ListView listView;
private PersonService personService;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ListView = (ListView)findViewById(R.id.personList);
List String>>(); HashMap title.put("personid","编号"); title.put("name", "姓名"); title.put("age", "年龄"); data.add(title); SimpleAdapter adapter = new SimpleAdapter(PersonActivity.this, data, R.layout.personitem, new String[]{"personid", "name", "age"}, new int[]{R.id.personid, R.id.name, R.id.age}); listView.setAdapter(adapter); } } 得用业务类Person Service,调用它的数据分页getScrollData()方法来得到数据,然后用迭代将数据都加入到data中,代码如下: PersonActivity.java public class PersonActivity extends Activity { /** Called when the activity is first created. */ private final static String TAG="PersonActivity"; private ListView listView; private PersonService personService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); listView = (ListView)findViewById(R.id.personList); personService = new PersonService(this); List 条数据 List String>>(); HashMap title.put("personid","编号"); title.put("name", "姓名"); title.put("age", "年龄"); data.add(title); //标题 for(Person person : persons){ HashMap map.put("personid", String.valueOf(person.getId())); map.put("name", person.getName()); map.put("age", String.valueOf(person.getAge())); data.add(map); //显示各个数据 } SimpleAdapter adapter = new SimpleAdapter(PersonActivity.this, data, R.layout.personitem, new String[]{"personid", "name", "age"}, new int[]{R.id.personid, R.id.name, R.id.age}); listView.setAdapter(adapter); } } 在onItemClick()方法中加入代码如下: public void onItemClick(AdapterView> parent, View view, int position, long id) { // TODO Auto-generated method stub ListView listView = (ListView)parent; HashMap getItemAtPosition(position); String personid = itemData.get("personid"); String name = itemData.get("name"); String age = itemData.get("age"); Log.i(TAG, "className="+ view.getClass().getName()); //打印view的类名 Log.i(TAG, "personid="+ personid+ "name="+name + "age"+ age); Log.i(TAG, "result="+ (position==id)); } }); 我们可以将它固定放到main.xml文件中,代码如下所示。 main.xml android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" > android:layout_width="fill_parent" android:layout_height="wrap_content"> android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/positionid" android:id="@+id/idTitle" > android:layout_width="200px" android:layout_height="wrap_content" android:layout_toRightOf="@id/idTitle" android:layout_alignTop="@id/idTitle" android:gravity="center_horizontal" android:text="@string/name" android:id="@+id/nameTitle" > android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_toRightOf="@id/nameTitle" android:layout_alignTop="@id/nameTitle" android:text="@string/age" android:id="@+id/ageTitle" > android:id="@+id/personList" android:layout_width="fill_parent" android:layout_height="wrap_content" > String.xml 然后,把PersonActivity中加入标题的代码去掉,就变为如下代码: PersonActivity.java public class PersonActivity extends Activity { /** Called when the activity is first created. */ private final static String TAG="PersonActivity"; private ListView listView; private PersonService personService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); listView = (ListView)findViewById(R.id.personList); personService = new PersonService(this); List 十条数据 List String>>(); for(Person person : persons){ HashMap map.put("personid", String.valueOf(person.getId())); map.put("name", person.getName()); map.put("age", String.valueOf(person.getAge())); data.add(map); //显示各个数据 } SimpleAdapter adapter = new SimpleAdapter(PersonActivity.this, data, R.layout.personitem, new "age"}, new int[]{R.id.personid, R.id.name, R.id.age}); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView. OnItemClickListener() { @Override public void onItemClick(AdapterView> parent, View view, int position, long id) { // TODO Auto-generated method stub ListView listView = (ListView)parent; HashMap listView.getItemAtPosition(position); String personid = itemData.get("personid"); String name = itemData.get("name"); String age = itemData.get("age"); Log.i(TAG, "className="+ view.getClass().getName());//打 印view的类名 Log.i(TAG, "personid="+ personid+ "name="+name + "age"+ age); Log.i(TAG, "result="+ (position==id)); } }); } } 首先,在业务类PersonService中加入返回游标的方法getRawScrollData(),代码如下: PersonService.java public Cursor getRawScrollData(int startResult, int maxResult){ List SQLiteDatabase database = databaseHelper.getWritableDatabase(); return database.rawQuery("select personid , name, age from person limit ?,?", new String[]{String.valueOf(startResult), String.valueOf(maxResult)}); } 然后在PersonActivity类中使用SimpleCursorAdapter绑定数据,代码如下: PersonActivity.java public class PersonActivity extends Activity { /** Called when the activity is first created. */ private final static String TAG="PersonActivity"; private ListView listView; private PersonService personService; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); listView = (ListView)findViewById(R.id.personList); personService = new PersonService(this); /* 使用SimpleCursorAdapter绑定数据*/ Cursor cursor = personService.getRawScrollData(0, 10);//得到游标 SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.personitem, cursor, new String[]{"personid", "name", "age"}, new int[]{R.id. personid, R.id.name, R.id.age}); listView.setAdapter(adapter); listView.setOnItemClickListener(new AdapterView. OnItemClickListener() { @Override public void onItemClick(AdapterView> parent, View view, int position, long id) { // TODO Auto-generated method stub ListView listView = (ListView)parent; HashMap String>)listView.getItemAtPosition(position); String personid = itemData.get("personid"); String name = itemData.get("name"); String age = itemData.get("age"); Log.i(TAG, "className="+ view.getClass().getName());//打 印view的类名 Log.i(TAG, "personid="+ personid+ "name="+name + "age"+ age); Log.i(TAG, "result="+ (position==id)); } }); } } 22.1.1 配置PersonProvider 配置后的代码如下: AndroidManifest.xml package="com.sharpandroid.activity" android:versionCode="1" android:versionName="1.0"> "@string/app_name"> "com.sharpandroid.providers.personprovider"/> android:label="@string/app_name"> android:targetPackage="com.sharpandroid.activity" android:label="Tests for My App" /> 1.添加insert 代码如下: PersonProvider.java private static UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH); private static final int PERSONS = 1; private static final int PERSON = 2; private DatabaseHelperdatabaseHelper; static{ matcher.addURI("com.sharpandroid.providers.personprovider", "person", PERSONS); matcher.addURI("com.sharpandroid.providers.personprovider", "person/#", PERSON); } 用户传入的Uri为代码如下: PersonProvider.java public boolean onCreate() { databaseHelper = new DatabaseHelper(this.getContext()); //实例化DatabaseHelper return true; } @Override //允许外部应用通过此方法在db应用中的person表添加数据 public Uri insert(Uri uri, ContentValues values) {//返回的Uri代表添加 后的这条记录的Uri SQLiteDatabase db = databaseHelper.getWritableDatabase(); long num;//标记 switch (matcher.match(uri)) { case PERSONS: num = db.insert("person", "personid", values); return ContentUris.withAppendedId(uri, num); case PERSON: num = db.insert("person", "personid", values); String struri = uri.toString(); return ContentUris.withAppendedId(Uri.parse(struri. substring(0, struri.lastIndexOf('/'))), num);//截取"/"前面的字符串 default : throw new IllegalArgumentException("Unknown Uri:"+ uri); //告诉用户传入了一个非法的Uri } } 2.更新update 允许外部应用通过此方法在db应用中的person表更新数据,代码如下: public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) { SQLiteDatabase db = databaseHelper.getWritableDatabase(); switch (matcher.match(uri)) { case PERSONS: // Uri = content://com.sharpandroid.providers. personprovider/person 代表的业务是更新表中的所有记录 return db.update("person", values, selection, selectionArgs); case PERSON:// Uri = content://com.sharpandroid. providers.personprovider/person/90 代表的业务是更新表中指定id的记录 long personid = ContentUris.parseId(uri);//从Uri中提取id String whereClause = "personid="+ personid; // perosnid=90 and age=? if(selection!=null && !"".equals(selection.trim())){ whereClause = whereClause+ " and "+ selection; } //组配条件语句 return db.update("person", values, whereClause, selectionArgs); default : throw new IllegalArgumentException("Unknown Uri:"+ uri); } } 3.删除delete 允许外部应用通过此方法删除db应用中的person表的数据,代码如下: public int delete(Uri uri, String selection, String[] selectionArgs) { SQLiteDatabase db = databaseHelper.getWritableDatabase(); switch (matcher.match(uri)) { case PERSONS: // Uri = content://com.sharpandroid.providers.personprovider/person 代表 的业务是删除表中的所有记录 return db.delete("person", selection, selectionArgs); case PERSON: // Uri = content://com.sharpandroid.providers.personprovider/person/90 代 表的业务是删除表中指定id的记录 long personid = ContentUris.parseId(uri); //从Uri中提取id String whereClause = "personid="+ personid; // perosnid=90 and age=? if(selection!=null && !"".equals(selection.trim())){ whereClause = whereClause+ " and "+ selection; } return db.delete("person", whereClause, selectionArgs); default : throw new IllegalArgumentException("Unknown Uri:"+ uri); } } 4.查找query 允许外部应用通过此方法查找db应用中的person表的数据,代码如下: public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) { SQLiteDatabase db = databaseHelper.getReadableDatabase(); switch (matcher.match(uri)) { case PERSONS: // Uri = content://com.sharpandroid.providers.personprovider/person 代表 的业务是获取表中的所有记录 return db.query("person", projection, selection, selectionArgs, null, null, sortOrder); case PERSON: // Uri = content://com.sharpandroid.providers.personprovider/person/90 代 表的业务是获取表中指定id的记录 long personid = ContentUris.parseId(uri); //从Uri中提取id String whereClause = "personid="+ personid; // perosnid=90 and age=? if(selection!=null && !"".equals(selection.trim())){ whereClause = whereClause+ " and "+ selection; } return db.query("person", projection, whereClause, selectionArgs, null, null, sortOrder); default : throw new IllegalArgumentException("Unknown Uri:"+ uri); } } 如果操作的数据属于集合类型,那么MIME类型字符串应该以“vnd.android.cursor.dir/”开头,如果属于非集合类型数据,那么MIME类型字符串应该以“vnd.android.cursor.item/”开头,那么返回的MIME类型字符串应该为“vnd.android.cursor.item/person”,代码如下: public String getType(Uri uri) { //返回要操作数据的内容类型 switch (matcher.match(uri)) { case PERSONS: // Uri = content://com.sharpandroid.providers.personprovider/person 代表 操作数据是集合性质的 return "vnd.android.cursor.dir/personprovider.persons"; case PERSON: // Uri = content://com.sharpandroid.providers.personprovider/person/90 代 表操作数据是非集合性质的(即单条记录) return "vnd.android.cursor.item/personprovider.person"; default : throw new IllegalArgumentException("Unknown Uri:"+ uri); } } 22.6.1 使用ContentResolver操作ContentProvider中的数据 在AndroidManifest.xml文件中加入测试权限,代码如下: AndroidManifest.xml package="com.sharpandroid.activity" android:versionCode="1" android:versionName="1.0"> android:label="@string/app_name"> android:targetPackage="com.sharpandroid.activity" android:label="Tests for My App" /> 22.6.2 测试业务 AccessContentProviderTest的具体代码如下: AccessContentProviderTest.java import android.content.ContentResolver; import android.content.ContentValues; import android.database.Cursor; import android.net.Uri; import android.provider.ContactsContract; import android.test.AndroidTestCase; import android.util.Log; public class AccessContentProviderTest extends AndroidTestCase { private static final String TAG = "AccessContentProviderTet"; public void testAccessContentProvider() throws Throwable{ ContentResolver contentResolver = this.getContext(). getContentResolver(); //获取ContentResolver对象 Uri uri = Uri.parse("content://com.sharpandroid.providers. personprovider/person"); //定义Uri Cursor cursor = contentResolver.query(uri, null, null, null, null); while(cursor.moveToNext()){ int personidIndex = cursor.getColumnIndex("personid"); int nameIndex = cursor.getColumnIndex("name"); int ageIndex = cursor.getColumnIndex("age"); Log.i(TAG, "personid="+ cursor.getInt(personidIndex)+", name="+ cursor.getString(nameIndex) + ",age="+ cursor. getInt(ageIndex)); //显示访问结果 } cursor.close(); //关闭游标 } } 如果我们要获得所有的联系人,首先在visitor项目的AndroidManifest.xml中加入访问联系人的权限,代码如下: package="com.sharpandroid.test" android:versionCode="1" android:versionName="1.0"> android:label="@string/app_name"> android:targetPackage="com.sharpandroid.test" android:label="Tests for My App" /> 然后在AccessContentProviderTest测试类中加入testAccessContactContentProvider()方法,先取得所有联系人的姓名,代码如下: //访问android自带的联系人应用中的联系人信息 public void testAccessContactContentProvider() throws Throwable{ ContentResolver contentResolver = this.getContext(). getContentResolver(); //获取所有联系人 Cursor cursor = contentResolver.query(ContactsContract.Contacts. CONTENT_URI, null, null, null, null); while(cursor.moveToNext()){ int contactid = cursor.getInt(cursor.getColumnIndex("_id")); String name = cursor.getString(cursor.getColumnIndex ("display_name")); Log.i("tel:", name); //获取联系人的姓名 } cursor.close(); } 查询联系人电话,代码如下: //访问android自带的联系人应用中的联系人信息 public void testAccessContactContentProvider() throws Throwable{ ContentResolver contentResolver = this.getContext(). getContentResolver(); //获取所有联系人 Cursor cursor = contentResolver.query(ContactsContract.Contacts. CONTENT_URI, null, null, null, null); while(cursor.moveToNext()){ int contactid = cursor.getInt(cursor.getColumnIndex("_id")); String name = cursor.getString(cursor.getColumnIndex ("display_name")); Log.i(TAG, name); //获取联系人的姓名 Cursor phones = contentResolver.query(ContactsContract. CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +"=?", new String[]{String.valueOf(contactid)}, null); StringBuilder sb = new StringBuilder(); while(phones.moveToNext()){ int phoneIndex = phones.getColumnIndex("data1"); String phone = phones.getString(phoneIndex); sb.append(phone).append(","); } phones.close(); Log.i(TAG, name+"'tel:"+ sb.toString()); //联系人的电话 } cursor.close(); } 查询联系人的E-mail信息,代码如下: //访问android自带的联系人应用中的联系人信息 public void testAccessContactContentProvider() throws Throwable{ ContentResolver contentResolver = this.getContext(). getContentResolver(); //获取所有联系人 Cursor cursor = contentResolver.query(ContactsContract.Contacts. CONTENT_URI, null, null, null, null); while(cursor.moveToNext()){ int contactid = cursor.getInt(cursor.getColumnIndex("_id")); String name = cursor.getString(cursor.getColumnIndex ("display_name")); Log.i(TAG, name); //获取联系人的姓名 Cursor phones = contentResolver.query(ContactsContract. CommonDataKinds.Phone.CONTENT_URI, null, ContactsContract.CommonDataKinds.Phone.CONTACT_ID +"=?", new String[]{String.valueOf(contactid)}, null); StringBuilder sb = new StringBuilder(); while(phones.moveToNext()){ int phoneIndex = phones.getColumnIndex("data1"); String phone = phones.getString(phoneIndex); sb.append(phone).append(","); } phones.close(); Log.i(TAG, name+"'tel:"+ sb.toString());//联系人的电话 Cursor emails = contentResolver.query(ContactsContract. CommonDataKinds.Email.CONTENT_URI, null, ContactsContract.CommonDataKinds.Email.CONTACT_ID + " =?", new String[]{String.valueOf(contactid)}, null); StringBuilder emailsb = new StringBuilder(); while(emails.moveToNext()){ int emailIndex = emails.getColumnIndex("data1"); String email = emails.getString(emailIndex); emailsb.append(email).append(","); } emails.close(); Log.i(TAG, name+" email:"+ emailsb.toString()); //查询联系人 的短信 } cursor.close(); } 23.1.1 SAX解析XML 1.创建项目 编写Person.java: package com.sharpandroid.domain; public class Person { private Integer id; private String name; private Short age; public Person(){} public Person(Integer id, String name, Short age) { this.id = id; this.name = name; this.age = age; } public Person(String name, Short age) { this.name = name; this.age = age; ······set,get方法。 @Override public String toString() { return "id="+ id+ ",name="+ name+ ",age="+ age; } } 编写SAXforHandler.java: package com.sharpandroid.service; import java.util.ArrayList; import java.util.List; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; import android.util.Log; import com.sharpandroid.domain.Person; public class SAXforHandler extends DefaultHandler { private static final String TAG = "SAXforHandler"; private List private String perTag ;//通过此变量,记录前一个标签的名称 Person person;//记录当前Person public List return persons; } //适合在此事件中触发初始化行为 public void startDocument() throws SAXException { persons = new ArrayList Log.i(TAG , "***startDocument()***"); } public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if("person".equals(localName)){ for ( int i = 0; i < attributes.getLength(); i++ ) { Log.i(TAG ,"attributeName:" + attributes.getLocalName(i) + "_attribute_Value:" + attributes.getValue(i)); person = new Person(); person.setId(Integer.valueOf(attributes.getValue(i))); } } perTag = localName; Log.i(TAG , qName+"***startElement()***"); } public void characters(char[] ch, int start, int length) throws SAXException { String data = new String(ch, start, length).trim(); if(!"".equals(data.trim())){ Log.i(TAG ,"content: " + data.trim()); } if("name".equals(perTag)){ person.setName(data); }else if("age".equals(perTag)){ person.setAge(new Short(data)); } } public void endElement(String uri, String localName, String qName) throws SAXException { Log.i(TAG , qName+"***endElement()***"); if("person".equals(perTag)&&person != null){ persons.add(person); person = null; } perTag = null; } public void endDocument() throws SAXException { Log.i(TAG , "***endDocument()***"); } } 在应用中添加如下代码: public static List InputStream is = XMLactivity.class.getClassLoader(). getResourceAsStream("sharpandroid.xml"); SAXforHandler handler = new SAXforHandler(); SAXParserFactory spf = SAXParserFactory.newInstance(); SAXParser saxParser = spf.newSAXParser(); saxParser.parse(is, handler); List is.close(); return list; } 23.2.1 示例一:DOM解析XML 编写DomPersonService.java,具体代码如下: package com.sharpandroid.service; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import com.sharpandroid.domain.Person; public class DomPersonService { public static List Exception { List DocumentBuilderFactory factory = DocumentBuilderFactory. newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.parse(inStream); Element root = document.getDocumentElement(); NodeList nodes = root.getElementsByTagName("person"); for(int i=0; i < nodes.getLength(); i++){ Element personElement = (Element)nodes.item(i); // Element / Text ==Node Person person = new Person(); person.setId(new Integer(personElement.getAttribute("id"))); NodeList childNodes = personElement.getChildNodes(); for(int y=0; y < childNodes.getLength(); y++){ Node childNode = (Node)childNodes.item(y); if(childNode.getNodeType()==Node.ELEMENT_NODE){ Element childElement = (Element)childNode; if("name".equals(childElement.getNodeName())){ person.setName(childElement.getFirstChild(). getNodeValue()); }else if("age".equals(childElement.getNodeName())){ person.setAge(new Short(childElement. getFirstChild().getNodeValue())); } } } persons.add(person); } return persons; } } 23.3.1 示例二:Pull解析XML 编写PullPersonService.java,代码如下: package com.sharpandroid.service; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; import java.io.Writer; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlSerializer; import android.os.Environment; import android.util.Log; import android.util.Xml; import com.sharpandroid.domain.Person; public class PullPersonService { public static List throws Exception { List //获得一个Pull解析的实例 XmlPullParser parser = Xml.newPullParser(); parser.setInput(inStream, "UTF-8"); //获得当前事件的代码 int eventCode = parser.getEventType(); Person person = null; //使用while循环,如果获得的事件码如果是文档结束,那么结束解析 while( eventCode != XmlPullParser.END_DOCUMENT ){ switch (eventCode) { case XmlPullParser.START_DOCUMENT://文档开始事件 persons = new ArrayList break; case XmlPullParser.START_TAG://开始元素 //判断当前元素是否是需要检索的元素 if("person".equals(parser.getName())){ person = new Person(); person.setId(new Integer(parser. getAttributeValue(0))); }else if(person!=null){ if("name".equals(parser.getName())){ person.setName(parser.nextText()); }else if("age".equals(parser.getName())){ person.setAge(new Short(parser.nextText())); } } break; case XmlPullParser.END_TAG://结束元素 if("person".equals(parser.getName()) && person !=null){ persons.add(person); person = null; } break; } eventCode = parser.next(); } return persons; } 在类PullPersonService中,添加以下代码: public static void writeXml(List throws Exception{ XmlSerializer serializer = Xml.newSerializer(); //获得存储卡的路径,在该路径下生成一个sharpandroid.xml文件 File file = new File(Environment.getExternalStorageDirectory(), "sharpandroid.xml"); FileOutputStream outStream = new FileOutputStream(file); serializer.setOutput(outStream,"UTF-8"); //作用等同于: serializer.startDocument("UTF-8", true); serializer.startTag(null, "persons"); for(Person person : persons){ serializer.startTag(null, "person"); serializer.attribute(null, "id", String.valueOf(person. getId())); serializer.startTag(null, "name"); serializer.text(person.getName()); serializer.endTag(null, "name"); serializer.startTag(null, "age"); serializer.text(String.valueOf(person.getAge())); serializer.endTag(null, "age"); serializer.endTag(null, "person"); } serializer.endTag(null, "persons"); serializer.endDocument(); writer.flush(); writer.close(); } News.java代码如下: public class News { private String title; private String link; private String pubDate; private String description; public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getLink() { return link; } public void setLink(String link) { this.link = link; } public String getPubDate() { return pubDate; } public void setPubDate(String pubDate) { this.pubDate = pubDate; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } } 在servier层下新建一个XML处理类,PullParserServier代码如下: package com.sharpandroid.servier; import java.io.InputStream; import java.util.ArrayList; import java.util.List; import org.xmlpull.v1.XmlPullParser; import com.sharpandroid.domain.News; import android.util.Xml; public class PullParserServier { public static List boolean flog = false; List XmlPullParser parser = Xml.newPullParser(); parser.setInput(inStream, "UTF-8"); int eventCode = parser.getEventType(); News news = null; while( eventCode != XmlPullParser.END_DOCUMENT ){ switch (eventCode) { case XmlPullParser.START_DOCUMENT://文档开始事件 news_list = new ArrayList break; case XmlPullParser.START_TAG://开始元素 if("item".equals(parser.getName())){ flog = true; news = new News(); } if(flog){ if("title".equals(parser.getName())) news.setTitle(parser.nextText()); else if("description".equals(parser.getName())) news.setDescription(parser.nextText()); else if("link".equals(parser.getName())) news.setLink(parser.nextText()); else if("pubDate".equals(parser.getName())) news.setPubDate(parser.nextText()); } break; case XmlPullParser.END_TAG://结束元素 if("item".equals(parser.getName())){ flog = false; news_list.add(news); news = null; } break; } eventCode = parser.next(); } return news_list; } } Activity的代码如下: package com.sharpandroid.rss; import java.util.List; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; import android.widget.AdapterView.OnItemClickListener; import com.sharpandroid.domain.News; import com.sharpandroid.servier.PullParserServier; import com.sharpandroid.util.NetTool; public class Rssactivity extends Activity { private ListView contentView; //http://rss.sina.com.cn/games/djyx.xml private String path = "http://rss.sina.com.cn/sports/global/focus. xml"; private String[] content ; private int count = 0; private List public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); contentView = (ListView)findViewById(R.id.content); try { list = PullParserServier.readXml(NetTool.getStream(path, "UTF-8")); } catch (Exception e) { e.printStackTrace(); } content = new String[list.size()]; for(News ne:list){ content[count] = ne.getTitle().trim(); count++; } contentView.setOnItemClickListener(new OnItemClickListener() { @Override public void onItemClick(AdapterView> parent, View view, int position, long id) { News temp = list.get(position); Intent intent = new Intent(Rssactivity.this, showNewsActivity.class); intent.putExtra("title", temp.getTitle()); intent.putExtra("pubDate", temp.getPubDate()); intent.putExtra("description", temp.getDescription()); intent.putExtra("link", temp.getLink()); startActivity(intent); } }); contentView.setAdapter(new ArrayAdapter android.R.layout.simple_list_item_1, content)); } @Override public boolean onCreateOptionsMenu(android.view.Menu menu) { super.onCreateOptionsMenu(menu); menu.add(0, 0, 0, "继续"); menu.add(0, 1, 1, "退出"); return true; } @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case 1: Rssactivity.this.finish(); break; } return super.onOptionsItemSelected(item); } } 数据已经传递到showNewsActivity,那么剩下我们要做的就是取得数据和显示数据。showNewsActivity.java代码如下: package com.sharpandroid.rss; import java.util.regex.Matcher; import java.util.regex.Pattern; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.widget.TextView; public class showNewsActivity extends Activity { private TextView descriptionView,pubDateView,titleView,linkView; protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.shownews); titleView = (TextView)findViewById(R.id.titleView); pubDateView = (TextView)findViewById(R.id.pubDateView); descriptionView = (TextView)findViewById(R.id.descriptionView); linkView = (TextView)findViewById(R.id.linkView); Intent intent = getIntent(); //获取相应数据 String title = intent.getStringExtra("title"); String pubDate = intent.getStringExtra("pubDate"); String description = intent.getStringExtra("description"); String link = intent.getStringExtra("link"); titleView.setText(FormatString(title)); pubDateView.setText(pubDate); descriptionView.setText(FormatString(description)); linkView.setText(link); } /** * 利用正则表达式,格式化字符串 * @param content * @return */ public static String FormatString(String content){ Pattern p = Pattern.compile("\\s*|\t|\r|\n"); Matcher m = p.matcher(content); return content.trim(); } } 转载于:https://www.cnblogs.com/fx2008/archive/2013/06/11/3132162.html
String[]{"personid", "name",21.7 使用SimpleCursorAdapter绑定数据
22 内容提供者(ContentProvider)
22.1 开发一个ContentProvider
22.3 ContentProvider类主要方法的作用
22.5 按照业务需求共享数据
22.6 操作db应用中的共享数据
22.7 操作联系人
23 订阅你感兴趣的信息——XML应用
23.1 SAX解析器
23.2 DOM(文档对象模型)
23.3 Pull解析器
23.5 XML文件的生成
23.6 综合示例:RSS_Pull
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
