1. Trang chủ
  2. » Công Nghệ Thông Tin

Lập trình Androi part 36 doc

8 110 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 8
Dung lượng 236,81 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

237 Chapter Accessing Files While Android offers structured storage, via preferences and databases, sometimes a simple file will suffice.. To access this file, you need to get yourself

Trang 1

237

Chapter Accessing Files

While Android offers structured storage, via preferences and databases, sometimes a

simple file will suffice Android offers two models for accessing files: one for files

prepackaged with your application and one for files created on-device by your

application Both of these models are covered in this chapter

You and the Horse You Rode in On

Let’s suppose you have some static data you want to ship with the application, such as

a list of words for a spell checker The easiest way to deploy that is to place the file in

the res/raw directory, so it will be put in the Android application APK file as part of the

packaging process as a raw resource

To access this file, you need to get yourself a Resources object From an activity, that is

as simple as calling getResources() A Resources object offers openRawResource() to get

an InputStream on the file you specify Rather than a path, openRawResource() expects

an integer identifier for the file as packaged This works just like accessing widgets via

findViewById() For example, if you put a file named words.xml in res/raw, the identifier

is accessible in Java as R.raw.words

Since you can get only an InputStream, you have no means of modifying this file Hence,

it is really useful just for static reference data Moreover, since it is unchanging until the

user installs an updated version of your application package, either the reference data

must be valid for the foreseeable future or you will need to provide some means of

updating the data The simplest way to handle that is to use the reference data to

bootstrap some other modifiable form of storage (e.g., a database), but you end up with

two copies of the data in storage

An alternative is to keep the reference data as is but keep modifications in a file or

database, and merge them together when you need a complete picture of the

information For example, if your application ships a file of URLs, you could have a

second file that tracks URLs added by the user or reference URLs that were deleted by

the user

23

Trang 2

In the Files/Static sample project, you will find a reworking of the list box example from Chapter 7, this time using a static XML file instead of a hardwired array in Java The layout is the same:

<?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" >

<TextView

android:id="@+id/selection"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

/>

<ListView

android:id="@android:id/list"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:drawSelectorOnTop="false"

/>

</LinearLayout>

In addition to that XML file, you also need an XML file with the words to show in the list:

<words>

<word value="lorem" />

<word value="ipsum" />

<word value="dolor" />

<word value="sit" />

<word value="amet" />

<word value="consectetuer" />

<word value="adipiscing" />

<word value="elit" />

<word value="morbi" />

<word value="vel" />

<word value="ligula" />

<word value="vitae" />

<word value="arcu" />

<word value="aliquet" />

<word value="mollis" />

<word value="etiam" />

<word value="vel" />

<word value="erat" />

<word value="placerat" />

<word value="ante" />

<word value="porttitor" />

<word value="sodales" />

<word value="pellentesque" />

<word value="augue" />

<word value="purus" />

</words>

While this XML structure is not exactly a model of space efficiency, it will suffice for a demo

The Java code now must read in that XML file, parse out the words, and put them someplace for the list to pick up:

Trang 3

public class StaticFileDemo extends ListActivity {

TextView selection;

ArrayList<String> items=new ArrayList<String>();

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

selection=(TextView)findViewById(R.id.selection);

try {

InputStream in=getResources().openRawResource(R.raw.words);

DocumentBuilder builder=DocumentBuilderFactory

.newInstance()

.newDocumentBuilder();

Document doc=builder.parse(in, null);

NodeList words=doc.getElementsByTagName("word");

for (int i=0;i<words.getLength();i++) {

items.add(((Element)words.item(i)).getAttribute("value"));

}

in.close();

}

catch (Throwable t) {

Toast

.makeText(this, "Exception: "+t.toString(), 2000)

.show();

}

setListAdapter(new ArrayAdapter<String>(this,

android.R.layout.simple_list_item_1,

items));

}

public void onListItemClick(ListView parent, View v, int position,

long id) {

selection.setText(items.get(position).toString());

}

}

The differences mostly lie within onCreate() We get an InputStream for the XML file

(getResources().openRawResource(R.raw.words)), then use the built-in XML parsing

logic to parse the file into a DOM Document, pick out the word elements, and then pour

the value attributes into an ArrayList for use by the ArrayAdapter

The resulting activity looks the same as before, as shown in Figure 23–1, since the list of

words is the same, just relocated

Trang 4

Figure 23–1 The StaticFileDemo sample application

Of course, there are even easier ways to have XML files available to you as prepackaged files, such as by using an XML resource, as discussed in Chapter 20 However, while this example used XML, the file could just as easily have been a simple one-word-per-line list or in some other format not handled natively by the Android resource system

Readin’ ’n Writin’

Reading or writing your own, application-specific data files is nearly identical to what you might do in a desktop Java application The key is to use openFileInput() or openFileOutput() on your Activity or other Context to get an InputStream or

OutputStream, respectively From that point forward, it is not much different from regular Java I/O logic:

 Wrap those streams as needed, such as using an InputStreamReader

or OutputStreamWriter for text-based I/O

 Read or write the data

 Use close() to release the stream when done

If two applications both try reading a notes.txt file via openFileInput(), each will access its own edition of the file If you need to have one file accessible from many places, you probably want to create a content provider, as described in Chapter 27 Note that openFileInput() and openFileOutput() do not accept file paths (e.g.,

path/to/file.txt), just simple filenames

Trang 5

Here is the layout for the world’s most trivial text editor, pulled from the Files/ReadWrite

sample application:

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

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

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:orientation="vertical">

<Button android:id="@+id/close"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="Close" />

<EditText

android:id="@+id/editor"

android:layout_width="fill_parent"

android:layout_height="fill_parent"

android:singleLine="false"

android:gravity="top"

/>

</LinearLayout>

All we have here is a large text-editing widget, with a Close button above it

The Java is only slightly more complicated:

package com.commonsware.android.readwrite;

import android.app.Activity;

import android.os.Bundle;

import android.view.View;

import android.widget.Button;

import android.widget.EditText;

import android.widget.Toast;

import java.io.BufferedReader;

import java.io.File;

import java.io.InputStream;

import java.io.InputStreamReader;

import java.io.OutputStream;

import java.io.OutputStreamWriter;

public class ReadWriteFileDemo extends Activity {

private final static String NOTES="notes.txt";

private EditText editor;

@Override

public void onCreate(Bundle icicle) {

super.onCreate(icicle);

setContentView(R.layout.main);

editor=(EditText)findViewById(R.id.editor);

Button btn=(Button)findViewById(R.id.close);

btn.setOnClickListener(new Button.OnClickListener() {

public void onClick(View v) {

finish();

}

});

Trang 6

}

public void onResume() {

super.onResume();

try {

InputStream in=openFileInput(NOTES);

if (in!=null) {

InputStreamReader tmp=new InputStreamReader(in); BufferedReader reader=new BufferedReader(tmp); String str;

StringBuffer buf=new StringBuffer();

while ((str = reader.readLine()) != null) {

buf.append(str+"\n");

}

in.close();

editor.setText(buf.toString());

}

}

catch (java.io.FileNotFoundException e) {

// that's OK, we probably haven't created it yet }

catch (Throwable t) {

Toast

.makeText(this, "Exception: "+t.toString(), 2000) .show();

}

}

public void onPause() {

super.onPause();

try {

OutputStreamWriter out=

new OutputStreamWriter(openFileOutput(NOTES, 0));

out.write(editor.getText().toString());

out.close();

}

catch (Throwable t) {

Toast

.makeText(this, "Exception: "+t.toString(), 2000) .show();

}

}

}

Trang 7

First, we wire up the button to close our activity when clicked by using

setOnClickListener() to invoke finish() on the activity

Next, we hook into onResume(), so we get control when our editor is coming back to life,

from a fresh launch or after having been frozen We use openFileInput() to read in

notes.txt and pour the contents into the text editor If the file is not found, we assume

this is the first time the activity was run (or the file was deleted by other means), and we

just leave the editor empty

Finally, we hook into onPause(), so we get control as our activity is hidden by another

activity or closed, such as via our Close button Here, we use openFileOutput() to open

notes.txt, into which we pour the contents of the text editor

The net result is that we have a persistent notepad, as shown in Figures 23–2 and 23–3

Whatever is typed in will remain until deleted, surviving our activity being closed, the

phone being turned off, or similar situations

Figure 23–2 The ReadWriteFileDemo sample application, as initially launched

Trang 8

Figure 23–3 The same application, after entering some text

You are also welcome to read and write files on external storage (a.k.a., the SD card) Use Environment.getExternalStorageDirectory() to obtain a File object at the root of the SD card Starting with Android 1.6, you will also need to hold permissions to work with external storage (e.g., WRITE_EXTERNAL_STORAGE) Permissions are covered in Chapter 28

Bear in mind that external storage is accessible by all applications, whereas

openFileInput() and openFileOutput() are in an application-private area

Ngày đăng: 01/07/2014, 21:20