zoukankan      html  css  js  c++  java
  • [转]大话企业级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();

        }

    }

  • 相关阅读:
    解决IE下a标签点击有虚线边框的问题
    解决IE8下opacity属性失效问题
    用Vue.js开发微信小程序:开源框架mpvue解析
    使用pie.htc时Border-radius的兼容
    解决IE8下CSS3选择器 :nth-child() 不兼容的问题
    jQuery兼容浏览器IE8方法
    css3兼容IE8的方案 各个ie的hack
    JavaScript之旅(DOM)
    JavaScript之旅(三)
    JavaScript之旅(二)
  • 原文地址:https://www.cnblogs.com/fx2008/p/3132162.html
Copyright © 2011-2022 走看看