[转]大话企业级Android应用开发实战 文件I/O

                      20  文件:普通文件的I/O 

20.1  文件存储数据

3.配置测试环境

编写AndroidManifest.xml:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="com.sharpandroid.file"

      android:versionCode="1"

      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/

app_name">

        <uses-library android:name="android.test.runner" />

        <activity android:name=".FileActivity"

                  android:label="@string/app_name">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>

    <uses-sdk android:minSdkVersion="7" />

    <instrumentation android:name="android.test.InstrumentationTestRunner"

  android:targetPackage="com.sharpandroid.file" android:label="Tests for

My App" />

</manifest>

 

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应用中配置单元测试环境,其功能清单文件内容如下。

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="com.sharpandroid.other"

      android:versionCode="1"

      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/

app_name">

    <uses-library android:name="android.test.runner" />

 

    </application>

    <uses-sdk android:minSdkVersion="7" />

    <instrumentation android:name="android.test.InstrumentationTestRunner"

  android:targetPackage="com.sharpandroid.other" android:label="Tests

for My App" />

</manifest>

 

完成之后,创建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

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="com.sharpandroid.sdcard"

      android:versionCode="1"

      android:versionName="1.0">

<application

android:icon="@drawable/icon"

android:label="@string/app_name">

    <uses-library android:name="android.test.runner" />

    </application>

    <uses-sdk android:minSdkVersion="7" />

 <instrumentation android:name="android.test.InstrumentationTestRunner"

  android:targetPackage="com.sharpandroid.sdcard" android:label="Tests

for My App" />

</manifest>

20.3  SharedPreferences(共享参数)

20.3.3  界面设计

编写Main.xml:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

    <RelativeLayout

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    >

    <TextView

    android:id="@+id/nameView"

    android:layout_width="60px"

    android:layout_height="wrap_content"

    android:text="name:"

    />

    <EditText

    android:id="@+id/name"

    android:layout_width="60px"

    android:layout_height="wrap_content"

    android:layout_alignTop="@id/nameView"

    android:layout_toRightOf="@id/nameView"

    />

    </RelativeLayout>

    <RelativeLayout

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    >

    <TextView

    android:id="@+id/ageView"

    android:layout_width="60px"

    android:layout_height="wrap_content"

    android:text="age:"

    />

    <EditText

    android:id="@+id/age"

    android:layout_width="60px"

    android:layout_height="wrap_content"

    android:layout_alignTop="@id/ageView"

    android:layout_toRightOf="@id/ageView"

    />

    </RelativeLayout>

    <RelativeLayout

    android:layout_width="fill_parent"

    android:layout_height="wrap_content"

    >

    <Button

    android:id="@+id/save"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:text="保存"

    />

    <Button

    android:id="@+id/load"

    android:layout_width="wrap_content"

    android:layout_height="wrap_content"

    android:layout_alignTop="@id/save"

    android:layout_toRightOf="@id/save"

    android:text="读取"

    />

    </RelativeLayout>

<TextView

android:id="@+id/text01"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

</TextView>

</LinearLayout>

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<Person> getScrollData(int firstResult, int maxResult){

        List<Person> persons = new ArrayList<Person>();

        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<Person> getScrollData(int startResult, int maxResult){

List<Person> persons = new ArrayList<Person>();

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<Person> persons = otherPersonService.getScrollData(0, 3);

        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

<?xml version="1.0" encoding="utf-8"?>

<RelativeLayout

  xmlns:android="http://schemas.android.com/apk/res/android"

  android:layout_width="fill_parent"

  android:layout_height="wrap_content">

  <TextView

     android:layout_width="60px"

     android:layout_height="wrap_content"

     android:id="@+id/personid"

     >

  </TextView>

   <TextView

     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"

     >

  </TextView>

  <TextView

     android:layout_width="wrap_content"

     android:layout_height="wrap_content"

     android:layout_toRightOf="@id/name"

     android:layout_alignTop="@id/name"

     android:id="@+id/age"

     >

  </TextView>

</RelativeLayout>

 

2.编写main.xml文件

因为PersonActivity中,它显示的主界面为main.xml,所以我们打开main.xml,为它加入一个ListView组件,代码如下:

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

<ListView

     android:id="@+id/personList"

     android:layout_width="fill_parent"

     android:layout_height="wrap_content"

 ></ListView>

</LinearLayout>

在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<HashMap<String, String>> data = new ArrayList<HashMap<String,

String>>();

     HashMap<String, String>title = new HashMap<String, String>();

        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<Person> persons = personService.getScrollData(0, 10);//前十

条数据       

        List<HashMap<String, String>> data = new ArrayList<HashMap<String,

String>>();

    HashMap<String, String>title = new HashMap<String, String>();

    title.put("personid","编号");

    title.put("name", "姓名");

    title.put("age", "年龄");

    data.add(title);        //标题

        for(Person person : persons){

        HashMap<String, String> map = new HashMap<String, String>();

        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<String, String> itemData = (HashMap<String, 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));

 

            }

        });

我们可以将它固定放到main.xml文件中,代码如下所示。

main.xml

<?xml version="1.0" encoding="utf-8"?>

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:orientation="vertical"

    android:layout_width="fill_parent"

    android:layout_height="fill_parent"

    >

    <RelativeLayout

        android:layout_width="fill_parent"

        android:layout_height="wrap_content">

  <TextView

     android:layout_width="wrap_content"

     android:layout_height="wrap_content"

     android:text="@string/positionid"

     android:id="@+id/idTitle"

     >

  </TextView>

   <TextView

     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"

     >

  </TextView>

  <TextView

     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"

     >

  </TextView>

  </RelativeLayout>

<ListView

     android:id="@+id/personList"

     android:layout_width="fill_parent"

     android:layout_height="wrap_content"

 ></ListView>

</LinearLayout>

String.xml

<?xml version="1.0" encoding="utf-8"?>

<resources>

    <string name="hello">Hello World, PersonActivity!</string>

    <string name="app_name">数据库应用</string>

    <string name="positionid">编号</string>

    <string name="name">姓名</string>

    <string name="age">年龄</string>

</resources>

然后,把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<Person> persons = personService.getScrollData(0, 10);  //前

十条数据     

        List<HashMap<String, String>> data = new ArrayList<HashMap<String,

String>>();

       for(Person person : persons){

        HashMap<String, String> map = new HashMap<String, String>();

        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);

       

        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, String> itemData = (HashMap<String, 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));

 

            }

        });

    }

}

21.7  使用SimpleCursorAdapter绑定数据

首先,在业务类PersonService中加入返回游标的方法getRawScrollData(),代码如下:

PersonService.java

public Cursor getRawScrollData(int startResult, int maxResult){

    List<Person> persons = new ArrayList<Person>();

        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, String> itemData = (HashMap<String,

 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  内容提供者(ContentProvider) 

22.1  开发一个ContentProvider

22.1.1  配置PersonProvider

配置后的代码如下:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="com.sharpandroid.activity"

      android:versionCode="1"

      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label=

"@string/app_name">

       <provider android:name=".PersonProvider" android:authorities=

"com.sharpandroid.providers.personprovider"/>

      <uses-library android:name="android.test.runner" />

        <activity android:name=".PersonActivity"

                  android:label="@string/app_name">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>

    <uses-sdk android:minSdkVersion="7" />

 <instrumentation android:name="android.test.InstrumentationTestRunner"

  android:targetPackage="com.sharpandroid.activity" android:label="Tests

for My App" />

</manifest>

22.3  ContentProvider类主要方法的作用

22.5  按照业务需求共享数据

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  操作db应用中的共享数据

 

22.6.1  使用ContentResolver操作ContentProvider中的数据

在AndroidManifest.xml文件中加入测试权限,代码如下:

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<manifest  xmlns:android="http://schemas.android.com/apk/res/android"

      package="com.sharpandroid.activity"

      android:versionCode="1"

      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/

app_name">

    <uses-library android:name="android.test.runner" />

        <activity android:name=".VisitorActivity"

                  android:label="@string/app_name">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

 

    </application>

    <uses-sdk android:minSdkVersion="7" />

 <instrumentation android:name="android.test.InstrumentationTestRunner"

     android:targetPackage="com.sharpandroid.activity"

android:label="Tests for My App" />

</manifest>

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();

//关闭游标

    }

}

22.7  操作联系人

如果我们要获得所有的联系人,首先在visitor项目的AndroidManifest.xml中加入访问联系人的权限,代码如下:

<?xml version="1.0" encoding="utf-8"?>

<manifest xmlns:android="http://schemas.android.com/apk/res/android"

      package="com.sharpandroid.test"

      android:versionCode="1"

      android:versionName="1.0">

    <application android:icon="@drawable/icon" android:label="@string/

app_name">

     <uses-library android:name="android.test.runner" />

        <activity android:name=".VisitorActivity"

                  android:label="@string/app_name">

            <intent-filter>

                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />

            </intent-filter>

        </activity>

    </application>

    <uses-sdk android:minSdkVersion="7" />

    <!--访问联系人的权限-->

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

 <instrumentation android:name="android.test.InstrumentationTestRunner"

  android:targetPackage="com.sharpandroid.test" android:label="Tests for

My App" />

</manifest>

然后在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  订阅你感兴趣的信息——XML应用 

23.1  SAX解析器

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<Person> persons;

    private String perTag ;//通过此变量,记录前一个标签的名称

    Person person;//记录当前Person

   

    public List<Person> getPersons() {

        return persons;

    }

 

    //适合在此事件中触发初始化行为

    public void startDocument() throws SAXException {

        persons = new ArrayList<Person>();

        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<Person> sax_XML() throws Exception{

        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<Person> list = handler.getPersons();

    is.close();

    return list;

         }

23.2  DOM(文档对象模型)

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<Person> readXml(InputStream inStream) throws

Exception {

        List<Person> persons = new ArrayList<Person>();

        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  Pull解析器

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<Person> readXml(InputStream inStream)

throws Exception {

        List<Person> persons = null;

        //获得一个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<Person>();

                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;

    }

23.5  XML文件的生成

在类PullPersonService中,添加以下代码:

    public static void writeXml(List<Person> persons, Writer writer)

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");

        //作用等同于:<?xml version="1.0" encoding="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();   

    }

23.6  综合示例:RSS_Pull

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<News> readXml(InputStream inStream) throws Exception {

        boolean flog = false

        List<News> news_list = null

        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<News>();

                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<News> 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<String>(Rssactivity.this,

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();

    }

}

 

posted @ 2013-06-11 22:21  火腿骑士  阅读(183)  评论(0编辑  收藏  举报