text:
Các điều kiện cần có trước
Để đồng hành cùng bài viết này, bạn cần những kỹ năng và các công cụ sau đây:
- Kiến thức cơ bản về công nghệ Java™ và cách sử dụng Eclipse (hoặc IDE yêu thích của bạn).
- JDK (phiên bản cần thiết là 5 hoặc 6).
- Eclipse (phiên bản 3.4 hoặc 3.5).
- SDK của Android và Trình cắm thêm ADT.
Để tải về và có thông tin thiết lập, hãy xem Tài nguyên ở cuối bài viết này.
Ứng dụng mẫu
Để làm nổi bật các khía cạnh lưu trữ cục bộ về việc phát triển ứng dụng Android, tôi trình bày một ứng dụng mẫu cho phép bạn thử nghiệm việc thực hiện các kiểu API. Mã nguồn có sẵn để tải về. Ứng dụng này hỗ trợ các hành động trong Hình 1.
Hình 1. Các trường hợp sử dụng (use cases)
Hình 1 liệt kê các trường hợp sử dụng sau:
- Quản lý và lưu trữ các sở thích.
- Nạp thông tin từ các tài sản ứng dụng.
- Xuất khẩu thông tin vào bộ nhớ trong, bộ nhớ ngoài và cơ sở dữ liệu cục bộ.
- Đọc thông tin từ bộ nhớ trong và cơ sở dữ liệu cục bộ.
- Xóa thông tin đã lưu trữ.
- Xem thông tin trên màn hình.
Bạn sử dụng lưu trữ cục bộ trong ứng dụng xuyên suốt bài viết này, như sau:
- Các sở thích được nắm bắt từ người sử dụng, được lưu trữ cục bộ và được sử dụng trong toàn bộ ứng dụng.
- Một hình ảnh của người sử dụng được lấy ra từ các tài sản của ứng dụng nội bộ, được lưu trữ trong bộ nhớ trong và bộ nhớ ngoài cục bộ và được biểu hiện trên màn hình.
- Một danh sách những người bạn trong JSON được lấy từ các tài sản của ứng dụng. Nó được phân tích cú pháp và được lưu trữ trong bộ nhớ trong cục bộ, bộ nhớ ngoài và cơ sở dữ liệu quan hệ và được biểu hiện trên màn hình.
Ứng dụng mẫu định nghĩa các lớp trong Bảng 1.
Bảng 1. Các lớp của ứng dụng mẫu
Ứng dụng ví dụ sử dụng hai kiểu dữ liệu. Kiểu đầu tiên là các sở thích của ứng dụng được lưu trữ như các cặp giá trị tên. Đối với các sở thích, hãy định nghĩa các thông tin sau đây:
- Một tên tệp, được dùng để nạp và lưu trữ danh sách các tên của những người bạn.
- Một tên tệp, được dùng để nạp và lưu trữ một hình ảnh cho người sử dụng.
- Một cờ, nếu được đặt, chỉ báo tự động xóa tất cả dữ liệu được lưu khi khởi động ứng dụng.
Kiểu dữ liệu thứ hai là một danh sách những người bạn. Ban đầu danh sách những người bạn được trình bày theo định dạng JSON API biểu đồ của Facebook (Facebook Graph API JSON), bao gồm một mảng các đối tượng name (tên) và friend (người bạn) (xem Liệt kê 1).
Liệt kê 1. Danh sách những người bạn (theo định dạng Facebook Graph API JSON)
{ "data": [ { "name": "Edmund Troche", "id": "500067699" } ] }
Định dạng đơn giản ở trên làm cho đối tượng
Friend (người bạn) và lược đồ cơ sở dữ liệu đơn
giản. Liệt kê 2 cho thấy lớp
Friend.
Liệt kê 2. Lớp
Friend
package com.cenriqueortiz.tutorials.datastore; import android.graphics.Bitmap; /** * Represents a Friend */ public class Friend { public String id; public String name; public byte[] picture; public Bitmap pictureBitmap;; }
Ngoài ID (mã định danh) và tên, ứng dụng mẫu cũng duy trì các tham chiếu tới hình ảnh người bạn. Mặc dù ứng dụng mẫu chưa sử dụng các tham chiếu đó, bạn có thể dễ dàng mở rộng ứng dụng mẫu để lấy hình ảnh từ Facebook và hiển thị nó trong màn hình chính.
Lược đồ cơ sở dữ liệu bao gồm một bảng duy nhất để lưu trữ thông tin của người bạn. Bảng này có ba cột:
- ID hoặc khóa duy nhất.
- ID của Facebook.
- Tên của người bạn.
Liệt kê 3 cho thấy câu lệnh SQL để khai báo bảng quan hệ tương ứng.
Liệt kê 3. Bảng cơ sở dữ liệu người bạn
db.execSQL("create table " + TABLE_NAME + " (_id integer primary key autoincrement, " + " fid text not null, name text not null) ");
Dựa trên thông tin này, bạn có thể hiển thị tên của trên màn hình chính và bằng cách sử dụng ID, bạn có thể lấy thêm thông tin chi tiết cho người dùng được chọn. Trong ứng dụng mẫu này, bạn chỉ hiển thị tên. Việc lấy thêm thông tin còn dành lại cho bạn tự thử nghiệm. Lưu ý rằng bạn có thể dễ dàng thay đổi mã để trực tiếp đi vào Facebook.
Lưu trữ các sở thích của ứng dụng
Phần này trình bày API các sở thích (API Preferences) và các màn hình. API
Android cung cấp một số cách để xử lý các sở thích. Có một cách tiếp cận
là trực tiếp sử dụng
SharedPreferences (Các sở
thích chia sẻ) và sử dụng thiết kế màn hình riêng của bạn và quản lý của
các sở thích. Cách tiếp cận thứ hai là sử dụng một
PreferenceActivity (Hoạt động các sở thích). Một
PreferenceActivity tự động chăm lo về các sở
thích được hiển thị trên màn hình như thế nào (theo mặc định chúng trông
giống như các sở thích của hệ thống) và tự động lưu trữ hoặc sao lưu các
sở thích khi người dùng tương tác với từng sở thích thông qua việc sử dụng
SharedPreferences.
Để đơn giản hóa ứng dụng mẫu, hãy sử dụng một
PreferenceActivity để quản lý các sở thích và
màn hình sở thích (xem Hình 2). Màn hình các sở thích
hiển thị hai phần: Các tài sản và các giá trị cài đặt tự động. Trong Các
tài sản, bạn có thể nhập các tên tệp cho cả hai tùy chọn Danh sách những
người bạn và Hình ảnh. Trong Các giá trị cài đặt tự động, bạn có thể đánh
dấu chọn một hộp kiểm tra để xóa thông tin lúc khởi động.
Hình 2. Màn hình Các sở thích khi được cài đặt
Trong Hình 2, cách bố trí đã được định nghĩa bằng cách sử dụng cách tiếp cận khai báo thông qua XML (thay vì lập trình); XML khai báo được ưa thích vì nó giữ mã nguồn sạch sẽ và dễ đọc.Liệt kê 4 cho thấy khai báo XML cho giao diện người dùng Các sở thích (Preferences UI).
Liệt kê 4. Khai báo XML của màn hình Các sở thích
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/prefs_screen" android:key="preferencescreen" > <PreferenceCategory android:title="Assets"> <EditTextPreference android:key="@string/prefs_assetname_friendslist_key" android:title="Friends List" android:summary="Please enter filename" android:defaultValue="friends.txt" /> <EditTextPreference android:key="@string/prefs_assetname_picture_key" android:title="Picture" android:summary="Please enter filename" android:defaultValue="pict2.jpg" /> </PreferenceCategory> <PreferenceCategory android:title="Auto Settings"> <CheckBoxPreference android:key="@string/prefs_autodelete_key" android:title="Delete at Startup" android:summary="Check to clear at startup" android:defaultValue="false" /> </PreferenceCategory> </PreferenceScreen>
PreferenceScreen (Màn hình các sở thích) bao gồm
hai cá thể
EditTextPreference, một là
CheckBoxPreference và hai nhóm thể loại theo
như định nghĩa của
PreferenceCategory (một cho
Asset và một cho
Auto Settings).
Trong ứng dụng mẫu này, thiết kế yêu cầu màn hình các sở thích được gọi ra
bằng cách sử dụng một mục trình đơn. Để làm việc này, hãy sử dụng một
thông báo Intent để gọi Hoạt động của Màn hình Các sở thích (Preference
Screen Activity) có tên là
AppPreferenceActivity (xem Liệt kê 5). Lưu ý rằng tôi không trình bày Intent hoạt động cụ
thể như thế nào. Xem phần Tài nguyên để biết thêm
thông tin về các Intent.
Liệt kê 5.
AppPreferenceActivity
/* * AppPreferenceActivity is a basic PreferenceActivity * C. Enrique Ortiz | http://CEnriqueOrtiz.com */ package com.cenriqueortiz.tutorials.datastore; import android.os.Bundle; import android.preference.PreferenceActivity; public class AppPreferenceActivity extends PreferenceActivity { /** * Default Constructor */ public AppPreferenceActivity() {} /** * Called when the activity is first created. * Inflate the Preferences Screen XML declaration. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.prefs); // Inflate the XML declaration } }
Trong ứng dụng mẫu này, hãy gọi Intent như trong Liệt kê 6, từ bên trong trình xử lý mục Trình đơn.
Liệt kê 6. Gọi hoạt động Preferences bằng cách sử dụng một Intent
/** * Invoked when a menu item has been selected */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Case: Bring up the Preferences Screen case R.id.menu_prefs: // Preferences // Launch the Preference Activity Intent i = new Intent(this, AppPreferenceActivity.class); startActivity(i); break; case R.id.menu...: : break; } return true; }
Ngoài ra, bạn phải định nghĩa tất cả các Intent trong tệp XML AndroidManifest như trong Liệt kê 7.
Liệt kê 7. Định nghĩa Intent trong tệp AndroidManifest.xml
: <application android:icon="@drawable/icon" android:label="@string/app_name"> : : <activity android:name="AppPreferenceActivity" android:label="Preferences"> </activity> : </application>
Nhớ lại rằng
PreferenceActivity sử dụng
SharedPreferences để lưu trữ tự động các sở
thích khi người dùng tương tác với màn hình các sở thích. Sau đó ứng dụng
sử dụng các sở thích này khi nó thực thi để thực hiện các nhiệm vụ khác
nhau của nó. Liệt kê 8 cho thấy cách sử dụng trực
tiếp
SharedPreferences để nạp các sở thích đã
lưu, bạn có thể tham khảo mã mẫu đi kèm về cách sử dụng các sở thích đã
nạp trong xuyên suốt toàn bộ mã mẫu như thế nào. Ngoài ra, Liệt kê 8 cũng cho thấy cách lưu trữ trực tiếp các
sở thích bằng
SharedPreferences khi sử dụng một
Editor (trình soạn thảo) trong trường hợp bạn
thích tự quản lý các sở thích của mình (và không thông qua
PrefenceActivity).
Liệt kê 8 cho thấy cách sử dụng
SharedPreferences để nạp các sở thích đã lưu
trữ và cách thay đổi các sở thích đã lưu bằng cách sử dụng một
Editor.
Liệt kê 8. Sử dụng
SharedPreferences
///////////////////////////////////////////////////////////// // The following methods show how to use the SharedPreferences ///////////////////////////////////////////////////////////// /** * Retrieves the Auto delete preference * @return the value of auto delete */ public boolean prefsGetAutoDelete() { boolean v = false; SharedPreferences sprefs = PreferenceManager.getDefaultSharedPreferences(appContext); String key = appContext.getString(R.string.prefs_autodelete_key); try { v = sprefs.getBoolean(key, false); } catch (ClassCastException e) { } return v; } /** * Sets the auto delete preference * @param v the value to set */ public void prefsSetAutoDelete(boolean v) { SharedPreferences sprefs = PreferenceManager.getDefaultSharedPreferences(appContext); Editor e = sprefs.edit(); String key = appContext.getString(R.string.prefs_autodelete_key); e.putBoolean(key, v); e.commit(); }
Tiếp theo, bạn sẽ thấy cách sử dụng một cơ sở dữ liệu để lưu dữ liệu.
Sử dụng các cơ sở dữ liệu SQLite
Android cung cấp sự hỗ trợ cho cơ sở dữ liệu quan hệ cục bộ thông qua SQLite. Bảng này (được định nghĩa trong các liệt kê sau đây) tóm tắt các lớp cơ sở dữ liệu quan trọng được sử dụng trong ứng dụng mẫu.
Đối với ứng dụng mẫu, một lớp
DBHelper được dùng
để gói một số phép toán của cơ sở dữ liệu (xem Liệt kê
9).
Liệt kê 9. Lớp
DBHelper
package com.cenriqueortiz.tutorials.datastore; import java.util.ArrayList; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DBHelper extends SQLiteOpenHelper {
Một số hằng số được định nghĩa cho phiên bản cơ sở dữ liệu, tên cơ sở dữ liệu và tên bảng (xem Liệt kê 10).
Liệt kê 10. Khởi tạo lớp
DBHelper
private SQLiteDatabase db; private static final int DATABASE_VERSION = 1; private static final String DB_NAME = "sample.db"; private static final String TABLE_NAME = "friends"; /** * Constructor * @param context the application context */ public DBHelper(Context context) { super(context, DB_NAME, null, DATABASE_VERSION); db = getWritableDatabase(); }
Phương thức
onCreate() được gọi khi đã sẵn sàng
để tạo ra cơ sở dữ liệu. Trong phương thức này, các bảng được tạo ra (xem
Liệt kê 11).
Liệt kê 11. Tạo bảng cơ sở dữ liệu
/** * Called at the time to create the DB. * The create DB statement * @param the SQLite DB */ @Override public void onCreate(SQLiteDatabase db) { db.execSQL( "create table " + TABLE_NAME + " (_id integer primary key autoincrement, " + " fid text not null, name text not null) "); }
Phương thức
insert() được
MainActivity gọi ra khi xuất khẩu thông tin tới
cơ sở dữ liệu (xem Liệt kê 12).
Liệt kê 12. Chèn một hàng
/** * The Insert DB statement * @param id the friends id to insert * @param name the friend's name to insert */ public void insert(String id, String name) { db.execSQL("INSERT INTO friends('fid', 'name') values ('" + id + "', '" + name + "')"); }
Phương thức
deleteAll() được
MainActivity gọi ra khi xóa cơ sở dữ liệu. Nó
xóa bảng (xem Liệt kê 13).
Liệt kê 13. Xóa bảng cơ sở dữ liệu
/** * Wipe out the DB */ public void clearAll() { db.delete(TABLE_NAME, null, null); }
Hai phương thức
SELECT ALL (Chọn tất cả) được
cung cấp:
cursorSelectAll(), trả về một con trỏ
và
listSelectAll(), trả về một
ArrayList của các đối tượng
Friend. Các phương thức này được
MainActivity gọi ra khi nạp thông tin từ cơ sở
dữ liệu (xem Liệt kê 14).
Liệt kê 14. Chạy một phương thức
Select All để trả về một
ArrayList
/** * Select All returns a cursor * @return the cursor for the DB selection */ public Cursor cursorSelectAll() { Cursor cursor = this.db.query( TABLE_NAME, // Table Name new String[] { "fid", "name" }, // Columns to return null, // SQL WHERE null, // Selection Args null, // SQL GROUP BY null, // SQL HAVING "name"); // SQL ORDER BY return cursor; }
Phương thức
listSelectAll() trả về hàng đã chọn
trong một thùng chứa
ArrayList được
MainActivity sử dụng để ràng buộc nó vào
MainScreen
ListView (xem Liệt kê 15).
Liệt kê 15. Chạy một phương thức
Select All để trả về một con trỏ
/** * Select All that returns an ArrayList * @return the ArrayList for the DB selection */ public ArrayList<Friend> listSelectAll() { ArrayList<Friend> list = new ArrayList<Friend>(); Cursor cursor = this.db.query(TABLE_NAME, new String[] { "fid", "name" }, null, null, null, null, "name"); if (cursor.moveToFirst()) { do { Friend f = new Friend(); f.id = cursor.getString(0); f.name = cursor.getString(1); list.add(f); } while (cursor.moveToNext()); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } return list; }
Phương thức
onUpgrade() được gọi nếu phát hiện
ra một phiên bản cơ sở dữ liệu thay đổi (xem Liệt kê
16).
Liệt kê 16. Phát hiện xem có thay đổi phiên bản cơ sở dữ liệu không
/** * Invoked if a DB upgrade (version change) has been detected */ @Override /** * Invoked if a DB upgrade (version change) has been detected */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Here add any steps needed due to version upgrade // for example, data format conversions, old tables // no longer needed, etc } }
Xuyên suốt
MainActivity,
DBHelper được sử dụng khi bạn xuất khẩu thông
tin đến cơ sở dữ liệu, nạp thông tin từ cơ sở dữ liệu và khi bạn xóa cơ sở
dữ liệu. Việc đầu tiên là khởi tạo
DBHelper khi
đã tạo
MainActivity. Các nhiệm vụ khác được
thực hiện tại phương thức
onCreate() bao gồm
việc khởi tạo các khung nhìn màn hình khác nhau (xem Liệt kê 17).
Liệt kê 17. Phương thức
MainActivity onCreate() khởi tạo cơ sở dữ liệu
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); appContext = this; setContentView(R.layout.main); dbHelper = new DBHelper(this); listView = (ListView) findViewById(R.id.friendsview); friendsArrayAdapter = new FriendsArrayAdapter( this, R.layout.rowlayout, friends); listView.setAdapter(friendsArrayAdapter); : : }
Liệt kê 18 cho thấy cách nạp danh sách những người bạn từ các tài sản và cách phân tích cú pháp và chèn nó vào trong cơ sở dữ liệu.
Liệt kê 18.
MainActivity đang chèn vào trong cơ sở dữ liệu
String fname = prefsGetFilename(); if (fname != null && fname.length() > 0) { buffer = getAsset(fname); // Parse the JSON file String friendslist = new String(buffer); final JSONObject json = new JSONObject(friendslist); JSONArray d = json.getJSONArray("data"); int l = d.length(); for (int i2=0; i2<l; i2++) { JSONObject o = d.getJSONObject(i2); String n = o.getString("name"); String id = o.getString("id"); dbHelper.insert(id, n); } // Only the original owner thread can touch its views MainActivity.this.runOnUiThread(new Runnable() { public void run() { friendsArrayAdapter.notifyDataSetChanged(); } }); }
Liệt kê 19 cho thấy cách thực hiện một
SELECT ALL (Chọn tất cả) và cách ràng buộc dữ
liệu vào
ListView của màn hình chính.
Liệt kê 19.
Select All của
MainActivity và ràng buộc dữ liệu vào
ListView
final ArrayList<Friend> dbFriends = dbHelper.listSelectAll(); if (dbFriends != null) { // Only the original owner thread can touch its views MainActivity.this.runOnUiThread(new Runnable() { public void run() { friendsArrayAdapter = new FriendsArrayAdapter( MainActivity.this, R.layout.rowlayout, dbFriends); listView.setAdapter(friendsArrayAdapter); friendsArrayAdapter.notifyDataSetChanged(); } }); }
Tiếp theo, hãy xem xét việc sử dụng API lưu trữ trong với ứng dụng ví dụ.
Sử dụng lưu trữ trong của thiết bị cho dữ liệu riêng tư
Với API lưu trữ dữ liệu, bạn có thể lưu trữ dữ liệu bằng cách sử dụng lưu
trữ trong. Thông tin có thể riêng tư và bạn có tùy chọn cho phép các ứng
dụng khác có quyền đọc hoặc viết vào nó. Phần này trình bày API để lưu trữ
dữ liệu cá nhân khi sử dụng
android.content.Context.openFileInput,
openFileOutput, và
getCacheDir() để lưu dữ liệu vào bộ nhớ nhanh
(cache) thay vì lưu trữ nó lâu bền.
Đoạn mã được hiển thị trong Liệt kê 20 cho thấy cách
đọc từ bộ nhớ riêng bên trong. Việc sử dụng phương thức
openFileOutput() với
MODE_PRIVATE (Chế độ_ riêng tư) để làm cho lưu
trữ thành riêng tư.
Liệt kê 20. Đọc từ lưu trữ riêng cục bộ
/** * Writes content to internal storage making the content private to * the application. The method can be easily changed to take the MODE * as argument and let the caller dictate the visibility: * MODE_PRIVATE, MODE_WORLD_WRITEABLE, MODE_WORLD_READABLE, etc. * * @param filename - the name of the file to create * @param content - the content to write */ public void writeInternalStoragePrivate( String filename, byte[] content) { try { //MODE_PRIVATE creates/replaces a file and makes // it private to your application. Other modes: // MODE_WORLD_WRITEABLE // MODE_WORLD_READABLE // MODE_APPEND FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE); fos.write(content); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
Đoạn mã trong Liệt kê 21 cho thấy cách đọc từ lưu trữ
riêng bên trong; hãy xem cách sử dụng phương thức
openFileInput().
Liệt kê 21. Đọc từ lưu trữ riêng bên trong
/** * Reads a file from internal storage * @param filename the file to read from * @return the file content */ public byte[] readInternalStoragePrivate(String filename) { int len = 1024; byte[] buffer = new byte[len]; try { FileInputStream fis = openFileInput(filename); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int nrb = fis.read(buffer, 0, len); // read up to len bytes while (nrb != -1) { baos.write(buffer, 0, nrb); nrb = fis.read(buffer, 0, len); } buffer = baos.toByteArray(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return buffer; }
Liệt kê 22 cho thấy cách xóa khỏi lưu trữ riêng bên trong.
Liệt kê 22. Xóa khỏi lưu trữ riêng bên trong
/** * Delete internal private file * @param filename - the filename to delete */ public void deleteInternalStoragePrivate(String filename) { File file = getFileStreamPath(filename); if (file != null) { file.delete(); } }
Bây giờ bạn có thể thấy cách sử dụng lưu trữ ngoài cho dữ liệu công cộng.
Sử dụng lưu trữ ngoài cho dữ liệu công cộng
Với các API lưu trữ dữ liệu, bạn có thể lưu trữ dữ liệu bằng cách sử dụng
lưu trữ ngoài. Thông tin có thể là riêng tư và bạn có tùy chọn cho phép
các ứng dụng khác có quyền đọc hoặc viết vào nó. Trong phần này, bạn viết
mã lệnh API để lưu trữ dữ liệu công cộng bằng cách sử dụng một số trong
các API bao gồm
getExternalStorageState(),
getExternalFilesDir(),
getExternalStorageDirectory() và
getExternalStoragePublicDirectory(). Bạn sử
dụng đường dẫn sau đây cho dữ liệu công cộng:
/Android/data/<package_name>/files/.
Trước khi sử dụng lưu trữ ngoài, bạn phải xem nó có sẵn chưa và có cho phép ghi vào không. Hai đoạn mã sau đây cho thấy các phương thức của trình trợ giúp để kiểm tra các điều kiện như vậy. Liệt kê 23 kiểm tra xem liệu lưu trữ ngoài đã có sẵn chưa.
Liệt kê 23. Kiểm tra xem lưu trữ ngoài đã có sẵn chưa
/** * Helper Method to Test if external Storage is Available */ public boolean isExternalStorageAvailable() { boolean state = false; String extStorageState = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(extStorageState)) { state = true; } return state; }
Liệt kê 24 kiểm tra xem lưu trữ ngoài là chỉ đọc hay không.
Liệt kê 24. Kiểm tra xem lưu trữ ngoài là chỉ đọc hay không
/** * Helper Method to Test if external Storage is read only */ public boolean isExternalStorageReadOnly() { boolean state = false; String extStorageState = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) { state = true; } return state; }
Liệt kê 25 cho thấy cách ghi vào lưu trữ ngoài để lưu trữ dữ liệu công cộng.
Liệt kê 25. Viết vào bộ nhớ ngoài
/** * Write to external public directory * @param filename - the filename to write to * @param content - the content to write */ public void writeToExternalStoragePublic(String filename, byte[] content) { // API Level 7 or lower, use getExternalStorageDirectory() // to open a File that represents the root of the external // storage, but writing to root is not recommended, and instead // application should write to application-specific directory, as shown below. String packageName = this.getPackageName(); String path = "/Android/data/" + packageName + "/files/"; if (isExternalStorageAvailable() && !isExternalStorageReadOnly()) { try { File file = new File(path, filename); file.mkdirs(); FileOutputStream fos = new FileOutputStream(file); fos.write(content); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
Liệt kê 26 cho thấy cách đọc từ bộ nhớ ngoài.
Liệt kê 26. Đọc từ bộ nhớ ngoài
/** * Reads a file from internal storage * @param filename - the filename to read from * @return the file contents */ public byte[] readExternallStoragePublic(String filename) { int len = 1024; byte[] buffer = new byte[len]; String packageName = this.getPackageName(); String path = "/Android/data/" + packageName + "/files/"; if (!isExternalStorageReadOnly()) { try { File file = new File(path, filename); FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int nrb = fis.read(buffer, 0, len); //read up to len bytes while (nrb != -1) { baos.write(buffer, 0, nrb); nrb = fis.read(buffer, 0, len); } buffer = baos.toByteArray(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return buffer; }
Đoạn mã trong Liệt kê 27 cho thấy cách xóa một tệp khỏi bộ nhớ ngoài.
Liệt kê 27. Xóa một tệp khỏi bộ nhớ ngoài
/** * Delete external public file * @param filename - the filename to write to */ void deleteExternalStoragePublicFile(String filename) { String packageName = this.getPackageName(); String path = "/Android/data/" + packageName + "/files/"+filename; File file = new File(path, filename); if (file != null) { file.delete(); } }
Làm việc với bộ nhớ ngoài đòi hỏi phải có quyền hạn đặc biệt, cần phải yêu
cầu
WRITE_EXTERNAL_STORAGE, thông qua tệp
AndroidManifest.xml (xem Liệt kê 28).
Liệt kê 28.
WRITE_EXTERNAL_STORAGE
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
API lưu trữ ngoài cho phép bạn lưu trữ công cộng các tệp bằng cách lưu trữ các tệp trong các thư mục được xác định trước dựa vào các kiểu của chúng như các hình ảnh, các nhạc chuông và v.v. Cách tiếp cận này không được trình bày trong bài viết này, nhưng bạn nên biết rõ về nó. Ngoài ra, hãy nhớ rằng các tệp trong lưu trữ ngoài có thể bị xóa bất cứ lúc nào.
Các phương thức có liên quan
Nếu bạn có các tệp tạm thời không cần lưu giữ lâu dài, bạn có thể lưu trữ các tệp đó trong một bộ nhớ nhanh (cache) . Cache là một bộ nhớ đặc biệt có ích để lưu trữ dữ liệu cỡ vừa hoặc nhỏ (ít hơn một megabyte), nhưng bạn phải nhận thức được rằng nội dung của bộ nhớ cache có thể bị xóa bất cứ lúc nào tùy thuộc vào có sẵn bao nhiêu bộ nhớ.
Liệt kê 29 cho thấy một phương thức của trình trợ giúp để trả về đường dẫn đến bộ nhớ lưu trữ nhanh trong bộ nhớ trong.
Liệt kê 29. Lấy ra đường dẫn đến bộ nhớ lưu trữ nhanh của bộ nhớ trong
/** * Helper method to retrieve the absolute path to the application * specific internal cache directory on the file system. These files * will be ones that get deleted when the application is uninstalled or when * the device runs low on storage. There is no guarantee when these * files will be deleted. * * Note: This uses a Level 8+ API. * * @return the absolute path to the application specific cache * directory */ public String getInternalCacheDirectory() { String cacheDirPath = null; File cacheDir = getCacheDir(); if (cacheDir != null) { cacheDirPath = cacheDir.getPath(); } return cacheDirPath; }
Liệt kê 30 cho thấy một phương thức của trình trợ giúp để trả về đường dẫn đến bộ nhớ lưu trữ nhanh trong bộ nhớ ngoài.
Liệt kê 30. Lấy ra đường dẫn đến bộ nhớ lưu trữ nhanh của bộ nhớ ngoài
/** * Helper method to retrieve the absolute path to the application * specific external cache directory on the file system. These files * will be ones that get deleted when the application is uninstalled or when * the device runs low on storage. There is no guarantee when these * files will be deleted. * * Note: This uses a Level 8+ API. * * @return the absolute path to the application specific cache * directory */ public String getExternalCacheDirectory() { String extCacheDirPath = null; File cacheDir = getExternalCacheDir(); if (cacheDir != null) { extCacheDirPath = cacheDir.getPath(); } return extCacheDirPath; }
Thông qua cách sử dụng ứng dụng ví dụ này, bây giờ bạn đã có một sự hiểu biết tốt về cách sử dụng lưu trữ ngoài của thiết bị cho dữ liệu công cộng.
Kết luận
Bài viết này đã trình bày các API lưu trữ của Android, từ các sở thích đến việc sử dụng SQLite và bộ nhớ trong và bộ nhớ ngoài. Với API các sở thích, bạn có thể cho ứng dụng của bạn để thu thập và lưu trữ thông tin sở thích đơn giản. Khi sử dụng API SQLite, bạn có thể lưu trữ nhiều dữ liệu phức tạp hơn và với lưu trữ trong và lưu trữ ngoài, bạn có thể lưu trữ các tệp riêng tư với ứng dụng hoặc lưu trữ các tệp công cộng có sẵn tới các ứng dụng khác. Dữ liệu đã lưu trữ vẫn còn tồn tại trên các phiên làm việc cho phép ứng dụng của bạn làm việc ngay cả khi ngắt kết nối khỏi mạng. Bây giờ bạn sẽ có chuyên môn để tận dụng lợi thế của tất cả các loại thiết bị lưu trữ khi bạn phát triển ứng dụng Android.
Tải về
Tài nguyên
Học tập
- Trang web di động Facebook: Tìm hiểu cách kết hợp Facebook vào ứng dụng di động riêng của bạn bằng cách sử dụng các API tương tự như các API được cung cấp cho tất cả các trang web, được định dạng cho phù hợp với điện thoại di động.
- Tạo một ứng dụng - Các nhà phát triển Facebook: Đăng ký ứng dụng Facebook của bạn.
- Các quyền hạn mở rộng - Các nhà phát triển Facebook: Yêu cầu các quyền hạn mở rộng khi ứng dụng của bạn cần phải truy cập vào các phần khác của hồ sơ người dùng có thể có tính riêng tư hoặc khi ứng dụng của bạn cần xuất bản nội dung đến Facebook nhân danh người dùng.
- Tài liệu chính thức của nhà phát triển Facebook: Tìm hiểu các API mạnh mẽ cho phép bạn tạo ra những kinh nghiệm xã hội để thúc đẩy tăng trưởng và sự tham gia vào trang web của bạn.
- Xác thực Facebook: Tìm hiểu về xác thực và cấp phép khi sử dụng nền tảng Facebook để phát triển các ứng dụng của bạn.
- Lộ trình của nhà phát triển Facebook: Sử dụng lộ trình này để lên kế hoạch cho những thay đổi có thể đòi hỏi những sự sửa đổi mã lệnh.
- Phát triển các ứng dụng Android với Eclipse (Frank Ableson, developerWorks, 02.2008): Cách dễ dàng nhất để phát triển các ứng dụng Android là sử dụng với Eclipse. Hãy tìm hiểu tất cả về chủ đề này trong hướng dẫn này của developerWorks.
- Giới thiệu về phát triển Android (Frank Ableson, developerWorks, 05.2009): Xem phần mở đầu về nền tảng Android và tìm hiểu cách mã hóa một ứng dụng Android cơ bản.
- Kết nối mạng với Android (Frank Ableson, developerWorks, 06.2009): Tìm hiểu các khả năng nối mạng của Android.
- Làm việc với XML trên Android (Michael Galpin, developerWorks, 06.2009): Tìm hiểu về các tùy chọn khác nhau để làm việc với XML trên Android và cách sử dụng chúng để xây dựng các ứng dụng của Android riêng của bạn.
- Dưới Mái che của các ứng dụng Web được thiết kế riêng cho Android: Tìm hiểu về các ứng dụng lai trong Android.
- Mở khóa Android (Frank Ableson, Manning Publications, 2010): Trình bày tất cả các khía cạnh về phát triển Android trong cuốn sách này của tác giả.
- Thiết kế và Phát triển di động (Brian Fling, O'Reilly Media, 2009): Tìm hiểu về các hướng dẫn thực hành, các tiêu chuẩn, các kỹ thuật và các thực hành tốt nhất để xây dựng các sản phẩm di động trong cuốn sách này.
- Đọc Hướng dẫn phát triển lưu trữ dữ liệu: Chọn giải pháp đúng để lưu dữ liệu ứng dụng lâu bền như được lưu ý trên trang web chính thức của nhà phát triển Android.
- Intents: Tìm hiểu về mô tả trừu tượng này của một hoạt động được thực hiện từ trang web của nhà phát triển Android.
- Tài liệu SDK của Android: Thu thập các thông tin mới nhất trong tài liệu tham khảo API của Android.
- The Open Handset Alliance: Truy cập nhà tài trợ của Android.
- Thêm nhiều bài báo của tác giả này (C. Enrique Ortiz, developerWorks, 04.2002 đến nay): Đọc các bài viết về các ứng dụng Android, các ứng dụng di động, các dịch vụ web và các công nghệ khác.
- Vùng XML trên developerWorks: Thu thập các tài nguyên mà bạn cần để nâng cao các kỹ năng của bạn trong lĩnh vực XML.
- My developerWorks: Cá nhân hoá kinh nghiệm developerWorks của bạn.
- Chứng chỉ XML của IBM: Tìm hiểu cách bạn có thể trở thành một nhà phát triển có chứng chỉ IBM về XML và các công nghệ có liên quan.
- Thư viện kỹ thuật XML: Xem Vùng XML của developerWorks với một loạt các bài báo và thủ thuật kỹ thuật, các hướng dẫn, các tiêu chuẩn và các sách Đỏ của IBM. Ngoài ra, hãy xem chi tiết các thủ thuật XML.
- Các sự kiện kỹ thuật và Webcast: Theo sát với công nghệ trong các phiên này.
- developerWorks trên Twitter: Tham gia ngày hôm nay để theo sát các bài viết ngắn (tweets) của developerWorks.
- developerWorks podcasts: Nghe các cuộc phỏng vấn và các cuộc thảo luận thú vị dành cho các nhà phát triển phần mềm.
- Các chương trình trình diễn theo yêu cầu của developerWorks: Xem một dải từ cài đặt và thiết lập sản phẩm cho nhưng người mới bắt đầu đến chức năng cao cấp cho các nhà phát triển có kinh nghiệm.
Lấy sản phẩm và công nghệ
- Facebook Android SDK (Hiện nay có bản phát hành Alpha): Làm việc với thư viện này để tích hợp Facebook vào ứng dụng di động Android của bạn.
- Nền tảng Facebook: Mở rộng khả năng của bạn để xây dựng các ứng dụng xã hội trên Facebook và các trang web.
- Các API còn lại trước kia của Facebook (Phiên bản trước của API biểu đồ): Tương tác với các trang web Facebook bằng lập trình thông qua các yêu cầu HTTP đơn giản.
- API Biểu đồ Facebook (phiên bản hiện hành): Đi sâu vào API nền tảng lõi Facebook này.
- Đặc tả kỹ thuật giao thức OAuth 2.0 (07.2010): Làm việc với việc xác thực OAuth, được nền tảng Facebook hỗ trợ.
- Android SDK: Tải về SDK, truy cập tài liệu tham khảo API và nhận các tin tức mới nhất về Android từ trang Web chính thức của các nhà phát triển Android. Phiên bản 1.5 và mới hơn sẽ hoạt động.
- Dự án nguồn mở Android: Tìm các thông tin nguồn mở và mã nguồn mà bạn cần để xây dựng một thiết bị tương thích với Android.
- Bản cập nhật 21 của JDK 6: Nhận nền tảng Java, ấn bản tiêu chuẩn.
- Eclipse: Nhận lấy bản IDE của Eclipse mới nhất.
- Các phiên bản đánh giá sản phẩm của IBM: Tải về hoặc khám phá các thử nghiệm trực tuyến trong SOA Sandbox của IBM và nhận các công cụ phát triển ứng dụng thực hành của bạn và các sản phẩm phần mềm trung gian từ DB2®, Lotus®, Rational®, Tivoli® và WebSphere®.
Thảo luận
- Các diễn đàn thảo vùng XML: Tham gia vào bất kỳ trong số các cuộc thảo luận có liên quan đến XML.
- developerWorks blogs: Đọc các blog này và dành tâm trí cho nó.
Bình luận
-
Vùng dữ liệu trên developerWorks
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
-
Vùng mã nguồn mở trên developerWorks
Xem các bài viết về HTML, CSS, JavaScript,...
-
Điện toán đám mây
Tìm hiểu về điện toán đám mây

markdown:
## Các điều kiện cần có trước
Để đồng hành cùng bài viết này, bạn cần những kỹ năng và các công cụ sau đây:
- Kiến thức cơ bản về công nghệ Java™ và cách sử dụng Eclipse (hoặc IDE yêu thích của bạn).
- JDK (phiên bản cần thiết là 5 hoặc 6).
- Eclipse (phiên bản 3.4 hoặc 3.5).
- SDK của Android và Trình cắm thêm ADT.
Để tải về và có thông tin thiết lập, hãy xem
[Tài
nguyên](#resources) ở cuối bài viết này.
## Ứng dụng mẫu
Để làm nổi bật các khía cạnh lưu trữ cục bộ về việc phát triển ứng dụng
Android, tôi trình bày một ứng dụng mẫu cho phép bạn thử nghiệm việc thực
hiện các kiểu API.
[Mã nguồn](#download) có sẵn để tải về. Ứng
dụng này hỗ trợ các hành động trong [Hình 1](#fig1).
##### Hình 1. Các trường hợp sử dụng (use cases)
![ Biểu đồ các trường hợp sử dụng trong ứng dụng mẫu](fig01.gif)
[Hình 1](#fig1) liệt kê các trường hợp sử dụng sau:
- Quản lý và lưu trữ các sở thích.
- Nạp thông tin từ các tài sản ứng dụng.
- Xuất khẩu thông tin vào bộ nhớ trong, bộ nhớ ngoài và cơ sở dữ liệu cục bộ.
- Đọc thông tin từ bộ nhớ trong và cơ sở dữ liệu cục bộ.
- Xóa thông tin đã lưu trữ.
- Xem thông tin trên màn hình.
Bạn sử dụng lưu trữ cục bộ trong ứng dụng xuyên suốt bài viết này, như sau:
- Các sở thích được nắm bắt từ người sử dụng, được lưu trữ cục bộ và được sử dụng trong toàn bộ ứng dụng.
- Một hình ảnh của người sử dụng được lấy ra từ các tài sản của ứng dụng nội bộ, được lưu trữ trong bộ nhớ trong và bộ nhớ ngoài cục bộ và được biểu hiện trên màn hình.
- Một danh sách những người bạn trong JSON được lấy từ các tài sản của ứng dụng. Nó được phân tích cú pháp và được lưu trữ trong bộ nhớ trong cục bộ, bộ nhớ ngoài và cơ sở dữ liệu quan hệ và được biểu hiện trên màn hình.
Ứng dụng mẫu định nghĩa các lớp trong
[Bảng 1](#table1).
##### Bảng 1. Các lớp của ứng dụng mẫu
|Lớp||Mô tả|
|Hoạt động chính; hầu hết các mã mẫu tập trung ở đây.|
|Biểu diễn một người bạn.|
|Màn hình và Hoạt động Các sở thích.|
|Một lớp trợ giúp để quản lý cơ sở dữ liệu SQLite.|
Ứng dụng ví dụ sử dụng hai kiểu dữ liệu. Kiểu đầu tiên là các sở thích của ứng dụng được lưu trữ như các cặp giá trị tên. Đối với các sở thích, hãy định nghĩa các thông tin sau đây:
- Một
*tên tệp*, được dùng để nạp và lưu trữ danh sách các tên của những người bạn.
- Một
*tên tệp*, được dùng để nạp và lưu trữ một hình ảnh cho người sử dụng.
- Một
*cờ*, nếu được đặt, chỉ báo tự động xóa tất cả dữ liệu được lưu khi khởi động ứng dụng.
Kiểu dữ liệu thứ hai là một danh sách những người bạn. Ban đầu danh sách
những người bạn được trình bày theo định dạng JSON API biểu đồ của
Facebook (Facebook Graph API JSON), bao gồm một mảng các đối tượng name
(tên) và friend (người bạn) (xem
[Liệt kê 1](#list1)).
##### Liệt kê 1. Danh sách những người bạn (theo định dạng Facebook Graph API JSON)
{ "data": [ { "name": "Edmund Troche", "id": "500067699" } ] }
Định dạng đơn giản ở trên làm cho đối tượng
Friend (người bạn) và lược đồ cơ sở dữ liệu đơn
giản.
[Liệt kê 2](#list2) cho thấy lớp
Friend.
##### Liệt kê 2. Lớp
Friend
package com.cenriqueortiz.tutorials.datastore; import android.graphics.Bitmap; /** * Represents a Friend */ public class Friend { public String id; public String name; public byte[] picture; public Bitmap pictureBitmap;; }
Ngoài ID (mã định danh) và tên, ứng dụng mẫu cũng duy trì các tham chiếu tới hình ảnh người bạn. Mặc dù ứng dụng mẫu chưa sử dụng các tham chiếu đó, bạn có thể dễ dàng mở rộng ứng dụng mẫu để lấy hình ảnh từ Facebook và hiển thị nó trong màn hình chính.
Lược đồ cơ sở dữ liệu bao gồm một bảng duy nhất để lưu trữ thông tin của người bạn. Bảng này có ba cột:
- ID hoặc khóa duy nhất.
- ID của Facebook.
- Tên của người bạn.
[Liệt kê 3](#list3) cho thấy câu lệnh SQL để khai báo bảng quan
hệ tương ứng.
##### Liệt kê 3. Bảng cơ sở dữ liệu người bạn
db.execSQL("create table " + TABLE_NAME + " (_id integer primary key autoincrement, " + " fid text not null, name text not null) ");
Dựa trên thông tin này, bạn có thể hiển thị tên của trên màn hình chính và bằng cách sử dụng ID, bạn có thể lấy thêm thông tin chi tiết cho người dùng được chọn. Trong ứng dụng mẫu này, bạn chỉ hiển thị tên. Việc lấy thêm thông tin còn dành lại cho bạn tự thử nghiệm. Lưu ý rằng bạn có thể dễ dàng thay đổi mã để trực tiếp đi vào Facebook.
## Lưu trữ các sở thích của ứng dụng
Phần này trình bày API các sở thích (API Preferences) và các màn hình. API
Android cung cấp một số cách để xử lý các sở thích. Có một cách tiếp cận
là trực tiếp sử dụng
SharedPreferences (Các sở
thích chia sẻ) và sử dụng thiết kế màn hình riêng của bạn và quản lý của
các sở thích. Cách tiếp cận thứ hai là sử dụng một
PreferenceActivity (Hoạt động các sở thích). Một
PreferenceActivity tự động chăm lo về các sở
thích được hiển thị trên màn hình như thế nào (theo mặc định chúng trông
giống như các sở thích của hệ thống) và tự động lưu trữ hoặc sao lưu các
sở thích khi người dùng tương tác với từng sở thích thông qua việc sử dụng
SharedPreferences.
Để đơn giản hóa ứng dụng mẫu, hãy sử dụng một
PreferenceActivity để quản lý các sở thích và
màn hình sở thích (xem
[Hình 2](#fig2)). Màn hình các sở thích
hiển thị hai phần: Các tài sản và các giá trị cài đặt tự động. Trong Các
tài sản, bạn có thể nhập các tên tệp cho cả hai tùy chọn Danh sách những
người bạn và Hình ảnh. Trong Các giá trị cài đặt tự động, bạn có thể đánh
dấu chọn một hộp kiểm tra để xóa thông tin lúc khởi động.
##### Hình 2. Màn hình Các sở thích khi được cài đặt
![ Ảnh chụp màn hình của màn hình Các sở thích khi được triển khai thực hiện](fig02.jpg)
Trong
[Hình 2](#fig2), cách bố trí đã được định nghĩa bằng cách
sử dụng cách tiếp cận khai báo thông qua XML (thay vì lập trình); XML khai
báo được ưa thích vì nó giữ mã nguồn sạch sẽ và dễ đọc. [Liệt kê 4](#list4) cho thấy khai báo XML cho giao diện người dùng Các sở
thích (Preferences UI).
##### Liệt kê 4. Khai báo XML của màn hình Các sở thích
<?xml version="1.0" encoding="utf-8"?> <PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/prefs_screen" android:key="preferencescreen" > <PreferenceCategory android:title="Assets"> <EditTextPreference android:key="@string/prefs_assetname_friendslist_key" android:title="Friends List" android:summary="Please enter filename" android:defaultValue="friends.txt" /> <EditTextPreference android:key="@string/prefs_assetname_picture_key" android:title="Picture" android:summary="Please enter filename" android:defaultValue="pict2.jpg" /> </PreferenceCategory> <PreferenceCategory android:title="Auto Settings"> <CheckBoxPreference android:key="@string/prefs_autodelete_key" android:title="Delete at Startup" android:summary="Check to clear at startup" android:defaultValue="false" /> </PreferenceCategory> </PreferenceScreen>
PreferenceScreen (Màn hình các sở thích) bao gồm
hai cá thể
EditTextPreference, một là
CheckBoxPreference và hai nhóm thể loại theo
như định nghĩa của
PreferenceCategory (một cho
Asset và một cho
Auto Settings).
Trong ứng dụng mẫu này, thiết kế yêu cầu màn hình các sở thích được gọi ra
bằng cách sử dụng một mục trình đơn. Để làm việc này, hãy sử dụng một
thông báo Intent để gọi Hoạt động của Màn hình Các sở thích (Preference
Screen Activity) có tên là
AppPreferenceActivity (xem
[Liệt kê 5](#list5)). Lưu ý rằng tôi không trình bày Intent hoạt động cụ
thể như thế nào. Xem phần [Tài nguyên](#resources) để biết thêm
thông tin về các Intent.
##### Liệt kê 5.
AppPreferenceActivity
/* * AppPreferenceActivity is a basic PreferenceActivity * C. Enrique Ortiz | http://CEnriqueOrtiz.com */ package com.cenriqueortiz.tutorials.datastore; import android.os.Bundle; import android.preference.PreferenceActivity; public class AppPreferenceActivity extends PreferenceActivity { /** * Default Constructor */ public AppPreferenceActivity() {} /** * Called when the activity is first created. * Inflate the Preferences Screen XML declaration. */ @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); addPreferencesFromResource(R.xml.prefs); // Inflate the XML declaration } }
Trong ứng dụng mẫu này, hãy gọi Intent như trong
[Liệt kê
6](#list6), từ bên trong trình xử lý mục Trình đơn.
##### Liệt kê 6. Gọi hoạt động Preferences bằng cách sử dụng một Intent
/** * Invoked when a menu item has been selected */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { // Case: Bring up the Preferences Screen case R.id.menu_prefs: // Preferences // Launch the Preference Activity Intent i = new Intent(this, AppPreferenceActivity.class); startActivity(i); break; case R.id.menu...: : break; } return true; }
Ngoài ra, bạn phải định nghĩa tất cả các Intent trong tệp XML
AndroidManifest như trong
[Liệt kê 7](#list7).
##### Liệt kê 7. Định nghĩa Intent trong tệp AndroidManifest.xml
: <application android:icon="@drawable/icon" android:label="@string/app_name"> : : <activity android:name="AppPreferenceActivity" android:label="Preferences"> </activity> : </application>
Nhớ lại rằng
PreferenceActivity sử dụng
SharedPreferences để lưu trữ tự động các sở
thích khi người dùng tương tác với màn hình các sở thích. Sau đó ứng dụng
sử dụng các sở thích này khi nó thực thi để thực hiện các nhiệm vụ khác
nhau của nó.
[Liệt kê 8](#list8) cho thấy cách sử dụng trực
tiếp
SharedPreferences để nạp các sở thích đã
lưu, bạn có thể tham khảo mã mẫu đi kèm về cách sử dụng các sở thích đã
nạp trong xuyên suốt toàn bộ mã mẫu như thế nào. Ngoài ra,
[Liệt kê 8](#list8) cũng cho thấy cách lưu trữ trực tiếp các
sở thích bằng
SharedPreferences khi sử dụng một
Editor (trình soạn thảo) trong trường hợp bạn
thích tự quản lý các sở thích của mình (và không thông qua
PrefenceActivity).
[Liệt kê 8](#list8) cho thấy cách sử dụng
SharedPreferences để nạp các sở thích đã lưu
trữ và cách thay đổi các sở thích đã lưu bằng cách sử dụng một
Editor.
##### Liệt kê 8. Sử dụng
SharedPreferences
///////////////////////////////////////////////////////////// // The following methods show how to use the SharedPreferences ///////////////////////////////////////////////////////////// /** * Retrieves the Auto delete preference * @return the value of auto delete */ public boolean prefsGetAutoDelete() { boolean v = false; SharedPreferences sprefs = PreferenceManager.getDefaultSharedPreferences(appContext); String key = appContext.getString(R.string.prefs_autodelete_key); try { v = sprefs.getBoolean(key, false); } catch (ClassCastException e) { } return v; } /** * Sets the auto delete preference * @param v the value to set */ public void prefsSetAutoDelete(boolean v) { SharedPreferences sprefs = PreferenceManager.getDefaultSharedPreferences(appContext); Editor e = sprefs.edit(); String key = appContext.getString(R.string.prefs_autodelete_key); e.putBoolean(key, v); e.commit(); }
Tiếp theo, bạn sẽ thấy cách sử dụng một cơ sở dữ liệu để lưu dữ liệu.
## Sử dụng các cơ sở dữ liệu SQLite
Android cung cấp sự hỗ trợ cho cơ sở dữ liệu quan hệ cục bộ thông qua SQLite. Bảng này (được định nghĩa trong các liệt kê sau đây) tóm tắt các lớp cơ sở dữ liệu quan trọng được sử dụng trong ứng dụng mẫu.
Đối với ứng dụng mẫu, một lớp
DBHelper được dùng
để gói một số phép toán của cơ sở dữ liệu (xem
[Liệt kê
9](#list9)).
##### Liệt kê 9. Lớp
DBHelper
package com.cenriqueortiz.tutorials.datastore; import java.util.ArrayList; import android.content.Context; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; public class DBHelper extends SQLiteOpenHelper {
Một số hằng số được định nghĩa cho phiên bản cơ sở dữ liệu, tên cơ sở dữ
liệu và tên bảng (xem
[Liệt kê 10](#list10)).
##### Liệt kê 10. Khởi tạo lớp
DBHelper
private SQLiteDatabase db; private static final int DATABASE_VERSION = 1; private static final String DB_NAME = "sample.db"; private static final String TABLE_NAME = "friends"; /** * Constructor * @param context the application context */ public DBHelper(Context context) { super(context, DB_NAME, null, DATABASE_VERSION); db = getWritableDatabase(); }
Phương thức
onCreate() được gọi khi đã sẵn sàng
để tạo ra cơ sở dữ liệu. Trong phương thức này, các bảng được tạo ra (xem
[Liệt kê 11](#list11)).
##### Liệt kê 11. Tạo bảng cơ sở dữ liệu
/** * Called at the time to create the DB. * The create DB statement * @param the SQLite DB */ @Override public void onCreate(SQLiteDatabase db) { db.execSQL( "create table " + TABLE_NAME + " (_id integer primary key autoincrement, " + " fid text not null, name text not null) "); }
Phương thức
insert() được
MainActivity gọi ra khi xuất khẩu thông tin tới
cơ sở dữ liệu (xem
[Liệt kê 12](#list12)).
##### Liệt kê 12. Chèn một hàng
/** * The Insert DB statement * @param id the friends id to insert * @param name the friend's name to insert */ public void insert(String id, String name) { db.execSQL("INSERT INTO friends('fid', 'name') values ('" + id + "', '" + name + "')"); }
Phương thức
deleteAll() được
MainActivity gọi ra khi xóa cơ sở dữ liệu. Nó
xóa bảng (xem
[Liệt kê 13](#list13)).
##### Liệt kê 13. Xóa bảng cơ sở dữ liệu
/** * Wipe out the DB */ public void clearAll() { db.delete(TABLE_NAME, null, null); }
Hai phương thức
SELECT ALL (Chọn tất cả) được
cung cấp:
cursorSelectAll(), trả về một con trỏ
và
listSelectAll(), trả về một
ArrayList của các đối tượng
Friend. Các phương thức này được
MainActivity gọi ra khi nạp thông tin từ cơ sở
dữ liệu (xem
[Liệt kê 14](#list14)).
##### Liệt kê 14. Chạy một phương thức
Select All để trả về một
ArrayList
/** * Select All returns a cursor * @return the cursor for the DB selection */ public Cursor cursorSelectAll() { Cursor cursor = this.db.query( TABLE_NAME, // Table Name new String[] { "fid", "name" }, // Columns to return null, // SQL WHERE null, // Selection Args null, // SQL GROUP BY null, // SQL HAVING "name"); // SQL ORDER BY return cursor; }
Phương thức
listSelectAll() trả về hàng đã chọn
trong một thùng chứa
ArrayList được
MainActivity sử dụng để ràng buộc nó vào
MainScreen
ListView (xem
[Liệt kê 15](#list15)).
##### Liệt kê 15. Chạy một phương thức
Select All để trả về một con trỏ
/** * Select All that returns an ArrayList * @return the ArrayList for the DB selection */ public ArrayList<Friend> listSelectAll() { ArrayList<Friend> list = new ArrayList<Friend>(); Cursor cursor = this.db.query(TABLE_NAME, new String[] { "fid", "name" }, null, null, null, null, "name"); if (cursor.moveToFirst()) { do { Friend f = new Friend(); f.id = cursor.getString(0); f.name = cursor.getString(1); list.add(f); } while (cursor.moveToNext()); } if (cursor != null && !cursor.isClosed()) { cursor.close(); } return list; }
Phương thức
onUpgrade() được gọi nếu phát hiện
ra một phiên bản cơ sở dữ liệu thay đổi (xem
[Liệt kê
16](#list16)).
##### Liệt kê 16. Phát hiện xem có thay đổi phiên bản cơ sở dữ liệu không
/** * Invoked if a DB upgrade (version change) has been detected */ @Override /** * Invoked if a DB upgrade (version change) has been detected */ @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { // Here add any steps needed due to version upgrade // for example, data format conversions, old tables // no longer needed, etc } }
Xuyên suốt
MainActivity,
DBHelper được sử dụng khi bạn xuất khẩu thông
tin đến cơ sở dữ liệu, nạp thông tin từ cơ sở dữ liệu và khi bạn xóa cơ sở
dữ liệu. Việc đầu tiên là khởi tạo
DBHelper khi
đã tạo
MainActivity. Các nhiệm vụ khác được
thực hiện tại phương thức
onCreate() bao gồm
việc khởi tạo các khung nhìn màn hình khác nhau (xem
[Liệt kê 17](#list17)).
##### Liệt kê 17. Phương thức
MainActivity onCreate() khởi tạo cơ sở dữ liệu
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); appContext = this; setContentView(R.layout.main); dbHelper = new DBHelper(this); listView = (ListView) findViewById(R.id.friendsview); friendsArrayAdapter = new FriendsArrayAdapter( this, R.layout.rowlayout, friends); listView.setAdapter(friendsArrayAdapter); : : }
[Liệt kê 18](#list18) cho thấy cách nạp danh sách những người
bạn từ các tài sản và cách phân tích cú pháp và chèn nó vào trong cơ sở dữ
liệu.
##### Liệt kê 18.
MainActivity đang chèn vào trong cơ sở dữ liệu
String fname = prefsGetFilename(); if (fname != null && fname.length() > 0) { buffer = getAsset(fname); // Parse the JSON file String friendslist = new String(buffer); final JSONObject json = new JSONObject(friendslist); JSONArray d = json.getJSONArray("data"); int l = d.length(); for (int i2=0; i2<l; i2++) { JSONObject o = d.getJSONObject(i2); String n = o.getString("name"); String id = o.getString("id"); dbHelper.insert(id, n); } // Only the original owner thread can touch its views MainActivity.this.runOnUiThread(new Runnable() { public void run() { friendsArrayAdapter.notifyDataSetChanged(); } }); }
[Liệt kê 19](#list19) cho thấy cách thực hiện một
SELECT ALL (Chọn tất cả) và cách ràng buộc dữ
liệu vào
ListView của màn hình chính.
##### Liệt kê 19.
Select All của
MainActivity và ràng buộc dữ liệu vào
ListView
final ArrayList<Friend> dbFriends = dbHelper.listSelectAll(); if (dbFriends != null) { // Only the original owner thread can touch its views MainActivity.this.runOnUiThread(new Runnable() { public void run() { friendsArrayAdapter = new FriendsArrayAdapter( MainActivity.this, R.layout.rowlayout, dbFriends); listView.setAdapter(friendsArrayAdapter); friendsArrayAdapter.notifyDataSetChanged(); } }); }
Tiếp theo, hãy xem xét việc sử dụng API lưu trữ trong với ứng dụng ví dụ.
## Sử dụng lưu trữ trong của thiết bị cho dữ liệu riêng tư
Với API lưu trữ dữ liệu, bạn có thể lưu trữ dữ liệu bằng cách sử dụng lưu
trữ trong. Thông tin có thể riêng tư và bạn có tùy chọn cho phép các ứng
dụng khác có quyền đọc hoặc viết vào nó. Phần này trình bày API để lưu trữ
dữ liệu cá nhân khi sử dụng
android.content.Context.openFileInput,
openFileOutput, và
getCacheDir() để lưu dữ liệu vào bộ nhớ nhanh
(cache) thay vì lưu trữ nó lâu bền.
Đoạn mã được hiển thị trong
[Liệt kê 20](#list20) cho thấy cách
đọc từ bộ nhớ riêng bên trong. Việc sử dụng phương thức
openFileOutput() với
MODE_PRIVATE (Chế độ_ riêng tư) để làm cho lưu
trữ thành riêng tư.
##### Liệt kê 20. Đọc từ lưu trữ riêng cục bộ
/** * Writes content to internal storage making the content private to * the application. The method can be easily changed to take the MODE * as argument and let the caller dictate the visibility: * MODE_PRIVATE, MODE_WORLD_WRITEABLE, MODE_WORLD_READABLE, etc. * * @param filename - the name of the file to create * @param content - the content to write */ public void writeInternalStoragePrivate( String filename, byte[] content) { try { //MODE_PRIVATE creates/replaces a file and makes // it private to your application. Other modes: // MODE_WORLD_WRITEABLE // MODE_WORLD_READABLE // MODE_APPEND FileOutputStream fos = openFileOutput(filename, Context.MODE_PRIVATE); fos.write(content); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
Đoạn mã trong
[Liệt kê 21](#list21) cho thấy cách đọc từ lưu trữ
riêng bên trong; hãy xem cách sử dụng phương thức
openFileInput().
##### Liệt kê 21. Đọc từ lưu trữ riêng bên trong
/** * Reads a file from internal storage * @param filename the file to read from * @return the file content */ public byte[] readInternalStoragePrivate(String filename) { int len = 1024; byte[] buffer = new byte[len]; try { FileInputStream fis = openFileInput(filename); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int nrb = fis.read(buffer, 0, len); // read up to len bytes while (nrb != -1) { baos.write(buffer, 0, nrb); nrb = fis.read(buffer, 0, len); } buffer = baos.toByteArray(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return buffer; }
[Liệt kê 22](#list22) cho thấy cách xóa khỏi lưu trữ riêng bên
trong.
##### Liệt kê 22. Xóa khỏi lưu trữ riêng bên trong
/** * Delete internal private file * @param filename - the filename to delete */ public void deleteInternalStoragePrivate(String filename) { File file = getFileStreamPath(filename); if (file != null) { file.delete(); } }
Bây giờ bạn có thể thấy cách sử dụng lưu trữ ngoài cho dữ liệu công cộng.
## Sử dụng lưu trữ ngoài cho dữ liệu công cộng
Với các API lưu trữ dữ liệu, bạn có thể lưu trữ dữ liệu bằng cách sử dụng
lưu trữ ngoài. Thông tin có thể là riêng tư và bạn có tùy chọn cho phép
các ứng dụng khác có quyền đọc hoặc viết vào nó. Trong phần này, bạn viết
mã lệnh API để lưu trữ dữ liệu công cộng bằng cách sử dụng một số trong
các API bao gồm
getExternalStorageState(),
getExternalFilesDir(),
getExternalStorageDirectory() và
getExternalStoragePublicDirectory(). Bạn sử
dụng đường dẫn sau đây cho dữ liệu công cộng:
/Android/data/<package_name>/files/.
Trước khi sử dụng lưu trữ ngoài, bạn phải xem nó có sẵn chưa và có cho phép
ghi vào không. Hai đoạn mã sau đây cho thấy các phương thức của trình trợ
giúp để kiểm tra các điều kiện như vậy.
[Liệt kê 23](#list23)
kiểm tra xem liệu lưu trữ ngoài đã có sẵn chưa.
##### Liệt kê 23. Kiểm tra xem lưu trữ ngoài đã có sẵn chưa
/** * Helper Method to Test if external Storage is Available */ public boolean isExternalStorageAvailable() { boolean state = false; String extStorageState = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED.equals(extStorageState)) { state = true; } return state; }
[Liệt kê 24](#list24) kiểm tra xem lưu trữ ngoài là chỉ đọc hay
không.
##### Liệt kê 24. Kiểm tra xem lưu trữ ngoài là chỉ đọc hay không
/** * Helper Method to Test if external Storage is read only */ public boolean isExternalStorageReadOnly() { boolean state = false; String extStorageState = Environment.getExternalStorageState(); if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(extStorageState)) { state = true; } return state; }
[Liệt kê 25](#list25) cho thấy cách ghi vào lưu trữ ngoài để lưu
trữ dữ liệu công cộng.
##### Liệt kê 25. Viết vào bộ nhớ ngoài
/** * Write to external public directory * @param filename - the filename to write to * @param content - the content to write */ public void writeToExternalStoragePublic(String filename, byte[] content) { // API Level 7 or lower, use getExternalStorageDirectory() // to open a File that represents the root of the external // storage, but writing to root is not recommended, and instead // application should write to application-specific directory, as shown below. String packageName = this.getPackageName(); String path = "/Android/data/" + packageName + "/files/"; if (isExternalStorageAvailable() && !isExternalStorageReadOnly()) { try { File file = new File(path, filename); file.mkdirs(); FileOutputStream fos = new FileOutputStream(file); fos.write(content); fos.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } }
[Liệt kê 26](#list26) cho thấy cách đọc từ bộ nhớ ngoài.
##### Liệt kê 26. Đọc từ bộ nhớ ngoài
/** * Reads a file from internal storage * @param filename - the filename to read from * @return the file contents */ public byte[] readExternallStoragePublic(String filename) { int len = 1024; byte[] buffer = new byte[len]; String packageName = this.getPackageName(); String path = "/Android/data/" + packageName + "/files/"; if (!isExternalStorageReadOnly()) { try { File file = new File(path, filename); FileInputStream fis = new FileInputStream(file); ByteArrayOutputStream baos = new ByteArrayOutputStream(); int nrb = fis.read(buffer, 0, len); //read up to len bytes while (nrb != -1) { baos.write(buffer, 0, nrb); nrb = fis.read(buffer, 0, len); } buffer = baos.toByteArray(); fis.close(); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } return buffer; }
Đoạn mã trong
[Liệt kê 27](#list27) cho thấy cách xóa một tệp
khỏi bộ nhớ ngoài.
##### Liệt kê 27. Xóa một tệp khỏi bộ nhớ ngoài
/** * Delete external public file * @param filename - the filename to write to */ void deleteExternalStoragePublicFile(String filename) { String packageName = this.getPackageName(); String path = "/Android/data/" + packageName + "/files/"+filename; File file = new File(path, filename); if (file != null) { file.delete(); } }
Làm việc với bộ nhớ ngoài đòi hỏi phải có quyền hạn đặc biệt, cần phải yêu
cầu
WRITE_EXTERNAL_STORAGE, thông qua tệp
AndroidManifest.xml (xem
[Liệt kê 28](#list28)).
##### Liệt kê 28.
WRITE_EXTERNAL_STORAGE
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
API lưu trữ ngoài cho phép bạn lưu trữ công cộng các tệp bằng cách lưu trữ các tệp trong các thư mục được xác định trước dựa vào các kiểu của chúng như các hình ảnh, các nhạc chuông và v.v. Cách tiếp cận này không được trình bày trong bài viết này, nhưng bạn nên biết rõ về nó. Ngoài ra, hãy nhớ rằng các tệp trong lưu trữ ngoài có thể bị xóa bất cứ lúc nào.
## Các phương thức có liên quan
Nếu bạn có các tệp tạm thời không cần lưu giữ lâu dài, bạn có thể lưu trữ các tệp đó trong một bộ nhớ nhanh (cache) . Cache là một bộ nhớ đặc biệt có ích để lưu trữ dữ liệu cỡ vừa hoặc nhỏ (ít hơn một megabyte), nhưng bạn phải nhận thức được rằng nội dung của bộ nhớ cache có thể bị xóa bất cứ lúc nào tùy thuộc vào có sẵn bao nhiêu bộ nhớ.
[Liệt kê 29](#list29) cho thấy một phương thức của trình trợ
giúp để trả về đường dẫn đến bộ nhớ lưu trữ nhanh trong bộ nhớ trong.
##### Liệt kê 29. Lấy ra đường dẫn đến bộ nhớ lưu trữ nhanh của bộ nhớ trong
/** * Helper method to retrieve the absolute path to the application * specific internal cache directory on the file system. These files * will be ones that get deleted when the application is uninstalled or when * the device runs low on storage. There is no guarantee when these * files will be deleted. * * Note: This uses a Level 8+ API. * * @return the absolute path to the application specific cache * directory */ public String getInternalCacheDirectory() { String cacheDirPath = null; File cacheDir = getCacheDir(); if (cacheDir != null) { cacheDirPath = cacheDir.getPath(); } return cacheDirPath; }
[Liệt kê 30](#list30) cho thấy một phương thức của trình trợ
giúp để trả về đường dẫn đến bộ nhớ lưu trữ nhanh trong bộ nhớ ngoài.
##### Liệt kê 30. Lấy ra đường dẫn đến bộ nhớ lưu trữ nhanh của bộ nhớ ngoài
/** * Helper method to retrieve the absolute path to the application * specific external cache directory on the file system. These files * will be ones that get deleted when the application is uninstalled or when * the device runs low on storage. There is no guarantee when these * files will be deleted. * * Note: This uses a Level 8+ API. * * @return the absolute path to the application specific cache * directory */ public String getExternalCacheDirectory() { String extCacheDirPath = null; File cacheDir = getExternalCacheDir(); if (cacheDir != null) { extCacheDirPath = cacheDir.getPath(); } return extCacheDirPath; }
Thông qua cách sử dụng ứng dụng ví dụ này, bây giờ bạn đã có một sự hiểu biết tốt về cách sử dụng lưu trữ ngoài của thiết bị cho dữ liệu công cộng.
## Kết luận
Bài viết này đã trình bày các API lưu trữ của Android, từ các sở thích đến việc sử dụng SQLite và bộ nhớ trong và bộ nhớ ngoài. Với API các sở thích, bạn có thể cho ứng dụng của bạn để thu thập và lưu trữ thông tin sở thích đơn giản. Khi sử dụng API SQLite, bạn có thể lưu trữ nhiều dữ liệu phức tạp hơn và với lưu trữ trong và lưu trữ ngoài, bạn có thể lưu trữ các tệp riêng tư với ứng dụng hoặc lưu trữ các tệp công cộng có sẵn tới các ứng dụng khác. Dữ liệu đã lưu trữ vẫn còn tồn tại trên các phiên làm việc cho phép ứng dụng của bạn làm việc ngay cả khi ngắt kết nối khỏi mạng. Bây giờ bạn sẽ có chuyên môn để tận dụng lợi thế của tất cả các loại thiết bị lưu trữ khi bạn phát triển ứng dụng Android.
## Tải về
|Mô tả||Tên||Kích thước|
|Article source code|
## Tài nguyên
### Học tập
[Trang web di động Facebook](http://developers.facebook.com/docs/guides/mobile/): Tìm hiểu cách kết hợp Facebook vào ứng dụng di động riêng của bạn bằng cách sử dụng các API tương tự như các API được cung cấp cho tất cả các trang web, được định dạng cho phù hợp với điện thoại di động. [Tạo một ứng dụng - Các nhà phát triển Facebook](http://developers.facebook.com/setup/): Đăng ký ứng dụng Facebook của bạn. [Các quyền hạn mở rộng - Các nhà phát triển Facebook](http://developers.facebook.com/docs/authentication/permissions): Yêu cầu các quyền hạn mở rộng khi ứng dụng của bạn cần phải truy cập vào các phần khác của hồ sơ người dùng có thể có tính riêng tư hoặc khi ứng dụng của bạn cần xuất bản nội dung đến Facebook nhân danh người dùng. [Tài liệu chính thức của nhà phát triển Facebook](http://developers.facebook.com/docs/): Tìm hiểu các API mạnh mẽ cho phép bạn tạo ra những kinh nghiệm xã hội để thúc đẩy tăng trưởng và sự tham gia vào trang web của bạn. [Xác thực Facebook](http://developers.facebook.com/docs/authentication): Tìm hiểu về xác thực và cấp phép khi sử dụng nền tảng Facebook để phát triển các ứng dụng của bạn. [Lộ trình của nhà phát triển Facebook](http://developers.facebook.com/roadmap): Sử dụng lộ trình này để lên kế hoạch cho những thay đổi có thể đòi hỏi những sự sửa đổi mã lệnh. [Phát triển các ứng dụng Android với Eclipse](http://www.ibm.com/developerworks/edu/os-dw-os-eclipse-android.html?S_TACT=105AGY75)(Frank Ableson, developerWorks, 02.2008): Cách dễ dàng nhất để phát triển các ứng dụng Android là sử dụng với Eclipse. Hãy tìm hiểu tất cả về chủ đề này trong hướng dẫn này của developerWorks. [Giới thiệu về phát triển Android](http://www.ibm.com/developerworks/vn/library/os-android-devel/)(Frank Ableson, developerWorks, 05.2009): Xem phần mở đầu về nền tảng Android và tìm hiểu cách mã hóa một ứng dụng Android cơ bản. [Kết nối mạng với Android](http://www.ibm.com/developerworks/opensource/library/os-android-networking/?S_TACT=105AGY75)(Frank Ableson, developerWorks, 06.2009): Tìm hiểu các khả năng nối mạng của Android. [Làm việc với XML trên Android](http://www.ibm.com/developerworks/xml/library/x-android/?S_TACT=105AGY75)(Michael Galpin, developerWorks, 06.2009): Tìm hiểu về các tùy chọn khác nhau để làm việc với XML trên Android và cách sử dụng chúng để xây dựng các ứng dụng của Android riêng của bạn. [Dưới Mái che của các ứng dụng Web được thiết kế riêng cho Android](http://www.linux-mag.com/id/7633): Tìm hiểu về các ứng dụng lai trong Android. [Mở khóa Android](http://manning.com/ableson2)(Frank Ableson, Manning Publications, 2010): Trình bày tất cả các khía cạnh về phát triển Android trong cuốn sách này của tác giả. [Thiết kế và Phát triển di động](http://oreilly.com/catalog/9780596155445/)(Brian Fling, O'Reilly Media, 2009): Tìm hiểu về các hướng dẫn thực hành, các tiêu chuẩn, các kỹ thuật và các thực hành tốt nhất để xây dựng các sản phẩm di động trong cuốn sách này.
- Đọc
[Hướng dẫn phát triển lưu trữ dữ liệu](http://developer.android.com/guide/topics/data/data-storage.html): Chọn giải pháp đúng để lưu dữ liệu ứng dụng lâu bền như được lưu ý trên trang web chính thức của nhà phát triển Android. [Intents](http://developer.android.com/reference/android/content/Intent.html): Tìm hiểu về mô tả trừu tượng này của một hoạt động được thực hiện từ trang web của nhà phát triển Android. [Tài liệu SDK của Android](http://developer.android.com/reference/packages.html): Thu thập các thông tin mới nhất trong tài liệu tham khảo API của Android. [The Open Handset Alliance](http://www.openhandsetalliance.com/): Truy cập nhà tài trợ của Android. [Thêm nhiều bài báo của tác giả này](http://www.ibm.com/developerworks/views/xml/libraryview.jsp?sort_by=&show_abstract=true &show_all=&search_flag=&contentarea_by=All+Zones&search_by=C.+Enrique+Ortiz &product_by=All++Products&topic_by=All++Topics&industry_by=All++Industries &type_by=All++Types&ibm-search=Search&S_TACT=105AGY75)(C. Enrique Ortiz, developerWorks, 04.2002 đến nay): Đọc các bài viết về các ứng dụng Android, các ứng dụng di động, các dịch vụ web và các công nghệ khác. [Vùng XML trên developerWorks](http://www.ibm.com/developerworks/xml?S_TACT=105AGY75): Thu thập các tài nguyên mà bạn cần để nâng cao các kỹ năng của bạn trong lĩnh vực XML. [My developerWorks](http://www.ibm.com/developerworks/mydeveloperworks?S_TACT=105AGY75): Cá nhân hoá kinh nghiệm developerWorks của bạn. [Chứng chỉ XML của IBM](http://www.ibm.com/certify/certs/01001503.shtml): Tìm hiểu cách bạn có thể trở thành một nhà phát triển có chứng chỉ IBM về XML và các công nghệ có liên quan. [Thư viện kỹ thuật XML](http://www.ibm.com/developerworks/views/xml/library.jsp?S_TACT=105AGY75): Xem Vùng XML của developerWorks với một loạt các bài báo và thủ thuật kỹ thuật, các hướng dẫn, các tiêu chuẩn và các sách Đỏ của IBM. Ngoài ra, hãy xem chi tiết [các thủ thuật XML](http://www.ibm.com/developerworks/views/xml/libraryview.jsp?search_by=tip:&S_TACT=105AGY75). [Các sự kiện kỹ thuật và Webcast](http://www.ibm.com/developerworks/offers/techbriefings/?S_TACT=105AGY75): Theo sát với công nghệ trong các phiên này. [developerWorks trên Twitter](http://twitter.com/developerworks/): Tham gia ngày hôm nay để theo sát các bài viết ngắn (tweets) của developerWorks. [developerWorks podcasts](http://www.ibm.com/developerworks/podcast/?S_TACT=105AGY75): Nghe các cuộc phỏng vấn và các cuộc thảo luận thú vị dành cho các nhà phát triển phần mềm. [Các chương trình trình diễn theo yêu cầu của developerWorks](http://www.ibm.com/developerworks/offers/lp/demos/?S_TACT=105AGY75): Xem một dải từ cài đặt và thiết lập sản phẩm cho nhưng người mới bắt đầu đến chức năng cao cấp cho các nhà phát triển có kinh nghiệm.
### Lấy sản phẩm và công nghệ
[Facebook Android SDK](http://github.com/facebook/facebook-android-sdk)(Hiện nay có bản phát hành Alpha): Làm việc với thư viện này để tích hợp Facebook vào ứng dụng di động Android của bạn. [Nền tảng Facebook](http://www.facebook.com/platform): Mở rộng khả năng của bạn để xây dựng các ứng dụng xã hội trên Facebook và các trang web. [Các API còn lại trước kia của Facebook](http://developers.facebook.com/docs/reference/rest/)(Phiên bản trước của API biểu đồ): Tương tác với các trang web Facebook bằng lập trình thông qua các yêu cầu HTTP đơn giản. [API Biểu đồ Facebook](http://developers.facebook.com/docs/api)(phiên bản hiện hành): Đi sâu vào API nền tảng lõi Facebook này. [Đặc tả kỹ thuật giao thức OAuth 2.0](http://tools.ietf.org/html/draft-ietf-oauth-v2-10)(07.2010): Làm việc với việc xác thực OAuth, được nền tảng Facebook hỗ trợ. [Android SDK](http://developer.android.com): Tải về SDK, truy cập tài liệu tham khảo API và nhận các tin tức mới nhất về Android từ trang Web chính thức của các nhà phát triển Android. Phiên bản 1.5 và mới hơn sẽ hoạt động. [Dự án nguồn mở Android](http://source.android.com/): Tìm các thông tin nguồn mở và mã nguồn mà bạn cần để xây dựng một thiết bị tương thích với Android. [Bản cập nhật 21 của JDK 6](http://www.oracle.com/technetwork/java/javase/downloads/index.html): Nhận nền tảng Java, ấn bản tiêu chuẩn. [Eclipse](http://eclipse.org): Nhận lấy bản IDE của Eclipse mới nhất. [Các phiên bản đánh giá sản phẩm của IBM](http://www.ibm.com/developerworks/downloads/?S_TACT=105AGY75): Tải về hoặc [khám phá các thử nghiệm trực tuyến trong SOA Sandbox của IBM](http://www.ibm.com/developerworks/downloads/soasandbox/?S_TACT=105AGY75)và nhận các công cụ phát triển ứng dụng thực hành của bạn và các sản phẩm phần mềm trung gian từ DB2®, Lotus®, Rational®, Tivoli® và WebSphere®.
### Thảo luận
[Các diễn đàn thảo vùng XML](http://www.ibm.com/developerworks/forums/dw_xforums.jsp?S_TACT=105AGY75): Tham gia vào bất kỳ trong số các cuộc thảo luận có liên quan đến XML. [developerWorks blogs](http://www.ibm.com/developerworks/blogs/?S_TACT=105AGY75): Đọc các blog này và dành tâm trí cho nó.
## Bình luận
[Vùng dữ liệu trên developerWorks](http://www.ibm.com/developerworks/vn/views/data/libraryview.jsp)
Khám phá các bài viết xoay quanh lĩnh vực dữ liệu, Quản lý hệ thống thông tin
[Vùng mã nguồn mở trên developerWorks](http://www.ibm.com/developerworks/vn/views/opensource/libraryview.jsp)
Xem các bài viết về HTML, CSS, JavaScript,...
[Điện toán đám mây](http://www.ibm.com/developerworks/vn/views/cloud/libraryview.jsp)
Tìm hiểu về điện toán đám mây

Content-Language: en-US


text:
Dùng cho công ty có nhu cầu mượn nhà để làm trụ sở chính, chi nhánh, VPĐD
mauhopdongmuonnha.doc (dowload văn bản tại đây)
Phòng 442, Tòa nhà VP5 Linh Đàm, đường Nguyễn Duy Trinh, Hoàng Mai, Hà Nội
Đặt LuatTrucTuyen.net làm trang chủ
Tiện ích pháp lý - Mạng tư vấn luật trực tuyến miễn phí cho cộng đồng
Bản quyền thuộc về Tư Vấn Việt Group - Ghi rõ nguồn khi sử dụng lại thông tin từ website này.

markdown:
|
|
Tư vấn thương hiệu
Tư vấn doanh nghiệp
Hỗ trợ dịch vụ
|
|
|
|
|
|
|
|
|
|![]()
|
|
|
|
|:
|Hỗ trợ trực tuyến: Bản quyền thuộc về Tư Vấn Việt Group - Ghi rõ nguồn khi sử dụng lại thông tin từ website này.
|
|

WARC-Type: response

Content-Type: application/http; msgtype=response

Connection: close

X-Powered-By: PleskWin

Content-Type: text/html

Cache-control: private


text:
a) Học hát
b) Phát triển khả năng âm nhạc
-Nghe nhạc.
-Kể chuyện âm nhạc: Cá heo với âm nhạc; Du Bá- Tử Kì (truyện cổ Trung Quốc); Chàng Oóc-phê và cây đàn Lia (truyện thần thoại Hi-lạp)
-Giới thiệu một vài nhạc cụ dân tộc: đàn bầu, đàn nguyệt, đàn tranh
-Làm quen tên nốt nhạc qua trò chơi
-Khuông nhạc và khóa Son; một số hình nốt nhạc; Tập nhận biết tên một số nốt nhạc trên khuông; Tập viết các nốt nhạc trên khuông nhạc.
-Trò chơi âm nhạc.
Nội dung dạy học trong 35 tuần (35 tiết) của chương trình Âm nhạc lớp 3:
Bài hát Con chim non (Se Canto, que canto)
Sở hữu và quản lý Website: Lê Anh Tuấn (Viện Khoa học Giáo dục Việt Nam - Bộ Giáo dục và Đào tạo)
Ý kiến bạn đọc

markdown:
**a) Học hát**
|
||
||
|
|
|
-
-
-
-
-
-
-
|
|
-
-
|
|
**b) Phát triển khả năng âm nhạc**
-Nghe nhạc.
-Kể chuyện âm nhạc: Cá heo với âm nhạc; Du Bá- Tử Kì (truyện cổ Trung Quốc); Chàng Oóc-phê và cây đàn Lia (truyện thần thoại Hi-lạp)
-Giới thiệu một vài nhạc cụ dân tộc: đàn bầu, đàn nguyệt, đàn tranh
-Làm quen tên nốt nhạc qua trò chơi
-Khuông nhạc và khóa Son; một số hình nốt nhạc; Tập nhận biết tên một số nốt nhạc trên khuông; Tập viết các nốt nhạc trên khuông nhạc.
-Trò chơi âm nhạc.
**Nội dung dạy học trong 35 tuần (35 tiết) của chương trình Âm nhạc lớp 3:**
|
||
|
|
|
1
|
|
Học hát: Bài
|
|
2
|
|
Học hát: Bài
|
|
3
|
|
Học hát: Bài
|
|
4
|
|
Học hát: Bài
|
|
5
|
|
Học hát: Bài
|
|
6
|
|
-Ôn tập bài hát:
-Trò chơi âm nhạc
|
|
7
|
|
Học hát: Bài
|
|
8
|
|
Ôn tập bài hát:
|
|
9
|
|
Ôn tập 3 bài hát:
|
|
10
|
|
Học hát: Bài
|
|
11
|
|
Ôn tập bài hát:
|
|
12
|
|
Học hát: Bài
|
|
13
|
|
Ôn tập bài hát:
|
|
14
|
|
Học hát: Bài
|
|
15
|
|
-Học hát: Bài
-Giới thiệu một vài nhạc cụ dân tộc
-Nghe nhạc
|
|
16
|
|
-Kể chuyện âm nhạc: Cá heo với âm nhạc
-Giới thiệu tên nốt nhạc qua trò chơi
|
|
17
|
|
Ôn tập 3 bài hát:
|
|
18
|
|
Kiểm tra học kì I
|
|
19
|
|
Học hát: Bài
|
|
20
|
|
-Học hát: Bài
-Ôn tập tên nốt nhạc
|
|
21
|
|
Học hát: Bài
|
|
22
|
|
-Ôn tập bài hát:
-Giới thiệu khuông nhạc và khóa Son
|
|
23
|
|
-Giới thiệu một số hình nốt nhạc
-Kể chuyện âm nhạc: Bá Nha- Tử Kì
|
|
24
|
|
-Ôn tập 2 bài hát:
-Tập nhận biết tên một số nốt nhạc trên khuông
|
|
25
|
|
Học hát: Bài
|
|
26
|
|
-Ôn tập bài hát:
-Nghe nhạc
|
|
27
|
|
Học hát: Bài
|
|
28
|
|
-Ôn tập bài hát:
-Tập kẻ khuông nhạc và viết khóa Son
|
|
29
|
|
Tập viết các nốt nhạc trên khuông nhạc
|
|
30
|
|
-Kể chuyện âm nhạc: Chàng Oóc-phê và cây đàn Lia
-Nghe nhạc
|
|
31
|
|
-Ôn tập 2 bài hát:
-Ôn tập các nốt nhạc
|
|
32
|
|
-Học hát: Bài do địa phương tự chọn
-Trò chơi âm nhạc
|
|
33
|
|
-Ôn tập các nốt nhạc
-Tập biểu diễn các bài hát
-Nghe nhạc
|
|
34
|
|
Kiểm tra cuối năm
|
|
35
|
|
Kiểm tra cuối năm
Bài hát
*Con chim non (Se Canto, que canto)*
Sở hữu và quản lý Website: Lê Anh Tuấn (Viện Khoa học Giáo dục Việt Nam - Bộ Giáo dục và Đào tạo)
## Ý kiến bạn đọc

WARC-Truncated: length

Server: Apache

Content-Language: vi

Cache-Control: private, pre-check=0, post-check=0, max-age=0

Pragma: no-cache

Content-Encoding: x-gzip

Vary: Accept-Encoding

Set-Cookie: nv3c_Kyw0f_sess=fc0bff37a705d0ead0be01e3178e5848911824359; path=/; domain=.music.edu.vn; HttpOnly

Content-Type: text/html; charset=utf-8


text:
Ngày yêu thương tri ân khách hàng nữĐăng ngày: 8/3/12
Trong ngày 07 và 08/3/2012, Ngân hàng Á châu (ACB) triển khai chương trình “Ngày yêu thương” dành cho tất cả các khách hàng nữ tham gia chương trình tiết kiệm dự thưởng “Xuân phát tài”.
Trong ngày 07 và 08/3/2012, Ngân hàng Á châu (ACB) triển khai chương trình “Ngày yêu thương” dành cho tất cả các khách hàng nữ tham gia chương trình tiết kiệm dự thưởng “Xuân phát tài”.
Khi tham gia chương trình “Ngày yêu thương”, khách hàng sẽ được tặng chiếc móc khóa ACB mạ vàng xinh xắn thay cho lời chúc tốt lành của ACB triển khai từ ngày 16/01/2012 với tổng giá trị giải thưởng trên 5 tỉ đồng. Khi giao dịch Tiền gửi tiết kiệm và tham gia chương trình này, khách hàng sẽ có cơ hội trúng giải đặc biệt 1kg Vàng.
Để biết thêm thông tin chi tiết về những chương trình chăm sóc khách hàng cũng như các sản phẩm, dịch vụ của ACB, khách hàng tham khảo tại website www.acb.com.vn; các chi nhánh, phòng giao dịch gần nhất hoặc gọi đến Trung tâm dịch vụ khách hàng 247 (CallCenter 247): (08) 38 247 247 hoặc 1800 577 775 (phục vụ 24/24, miễn phí cuộc gọi).
Từ Khóa: Chương Trình, Chương Trình CT, Khuyến Mại, Khuyến Mại, Ưu Đãi, Ưu Đãi, Vàng,
Ý Kiến Mới Nhất

markdown:
# Ngày yêu thương tri ân khách hàng nữĐăng ngày: 8/3/12
Trong ngày 07 và 08/3/2012, Ngân hàng Á châu (ACB) triển khai chương trình “Ngày yêu thương” dành cho tất cả các khách hàng nữ tham gia chương trình tiết kiệm dự thưởng “Xuân phát tài”.
Trong ngày 07 và 08/3/2012, Ngân hàng Á châu (ACB) triển khai chương trình “Ngày yêu thương” dành cho tất cả các khách hàng nữ tham gia chương trình tiết kiệm dự thưởng “Xuân phát tài”.
Khi tham gia chương trình “Ngày yêu thương”, khách hàng sẽ được tặng chiếc móc khóa
[ ACB ](http://nganhangonline.com/ngan-hang-a-chau-acb.html)mạ vàng xinh xắn thay cho lời chúc tốt lành của [ ACB ](http://nganhangonline.com/ngan-hang-a-chau-acb.html)triển khai từ ngày 16/01/2012 với tổng giá trị giải thưởng trên 5 tỉ đồng. Khi giao dịch Tiền gửi tiết kiệm và tham gia chương trình này, khách hàng sẽ có cơ hội trúng giải đặc biệt 1kg Vàng.
Để biết thêm thông tin chi tiết về những chương trình chăm sóc khách hàng cũng như các sản phẩm, dịch vụ của ACB, khách hàng tham khảo tại website www.acb.com.vn; các chi nhánh, phòng giao dịch gần nhất hoặc gọi đến Trung tâm dịch vụ khách hàng 247 (CallCenter 247): (08) 38 247 247 hoặc 1800 577 775 (phục vụ 24/24, miễn phí cuộc gọi).
**Từ Khóa: ** [ Chương Trình](/tags/chuong-trinh/), [ Chương Trình CT](/tags/chuong-trinh-ct/), [ Khuyến Mại](/tags/khuyen-mai/), [ Khuyến Mại](/tags/khuyen-mai/), [ Ưu Đãi](/tags/uu-dai/), [ Ưu Đãi](/tags/uu-dai/), [ Vàng](/tags/vang/),

Set-Cookie: visisted=1; expires=Thu, 05-Feb-2015 16:15:09 GMT

P3P: CP="NOI ADM DEV PSAi COM NAV OUR OTRo STP IND DEM"

Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0

Server: Dong Cam Caching Engine 12.3 build 3.456.234.2600


text:
NDĐT - Bất chấp việc chính phủ của Tổng thống Viktor Yanukovyck ban bố lệnh ân xá những người biểu tình chống chính phủ, trong ngày hôm qua, ít nhất 25 người chết, trong đó có bảy cảnh sát khi các cuộc biểu tình biến thành bạo lực, nhấn chìm cả thủ đô Kiev trong “ngày thứ ba đẫm máu”.
Kéo dài gần bốn tháng qua, cuộc giằng co giữa chính phủ của Tổng thống Yanukovyck và phe đối lập vẫn không thể tìm ra được hồi kết. Nói cách khác, bài toán đối đầu giữa Nga và EU với Mỹ tại khu vực vùng đệm Đông-Tây vẫn không thể tìm ra lời giải.
Làn sóng bạo lực leo thang tại Kiev trong ngày thứ ba đẫm máu đã buộc Tổng thư ký LHQ Ban Ki-moon phải lên tiếng kêu gọi chính phủ và phe đối lập phải kiềm chế, cũng như cần có cuộc “đối thoại thẳng thắn”. Song, lời kêu gọi của cộng đồng quốc tế có giá trị hay không khi mà các bên liên quan vẫn giữ một “cái đầu nóng” để xử lý tình trạng hiện tại?
Bộ trưởng Bộ Tư pháp Yelena Lukask đã cáo buộc các thủ lĩnh đối lập đã gây ra tình trạng bất ổn ngày càng tồi tệ hơn, và tuyên bố sẽ quy trách nhiệm cá nhân trong các vụ bạo lực này.
Ngay trong khi quốc hội Ucraina họp phiên toàn thể thảo luận kế hoạch cải cách Hiến pháp, thì bên ngoài tòa nhà quốc hội, các cuộc mít-tinh, biểu tình của những người ủng hộ và phản đối chính phủ vẫn diễn ra rầm rộ, thậm chí cảnh sát đã phải sử dụng tới các biện pháp mạnh để trấn áp sự quá khích của những người biểu tình. Ngay cả trong phiên họp quốc hội, những nghị sĩ đối lập cũng phong tỏa diễn đàn nhằm phản đối việc các nghị sĩ ủng hộ chính phủ bác bỏ ký kết một dự luật sửa đổi hiến pháp.
Nội bộ là thế, còn bên ngoài, Nga và các nước phương Tây cũng không ngừng “ăn miếng, trả miếng” lẫn nhau.
Hồi đầu tháng, trên mạng Youtube xuất hiện một đoạn hội thoại về khủng hoảng tại Ucraine giữa trợ lý ngoại trưởng Mỹ Victoria Nuland và đại sứ Mỹ tại Ucraina Geoffrey Pyatt. Trong đoạn ghi âm dài hơn 4 phút, các quan chức ngoại giao Mỹ đã nói xấu đồng minh EU và trao đổi thẳng thắn về chiến lược của Mỹ trong cách làm việc cùng các lãnh đạo phe đối lập tại Ucraina. Ngay lập tức, Mỹ đã lên án rằng Nga đứng sau việc do thám và tung đoạn băng ghi âm này lên YouTube. Chỉ hai ngày sau, một đoạn băng ghi âm giữa hai quan chức EU nói về những bất đồng với Mỹ trong vấn đề Ucraina lại được tung lên mạng.
Hiện không rõ ai đứng đằng sau vụ việc này, nhưng điều đó cũng đủ cho thấy, các nước bên ngoài đang can thiệp ngày càng sâu vào chính trường Ucraina.
Sau “ngày thứ ba đẫm máu” và “gây sốc” với cộng đồng quốc tế như lời của Ngoại trưởng Đức Frank-Walter Steinmeier vào tối qua, Bộ Ngoại giao Nga khẳng định: “Những gì đang xảy ra là kết quả trực tiếp của một chính sách đồng lõa của một bộ phận các chính trị gia phương Tây và các cơ quan châu Âu, từ lúc bắt đầu cuộc khủng hoảng, cố tình làm ngơ trước các hành động hiếu chiến của các lực lượng cực đoan tại Ucraina, và sau đó khuyến khích các hành động leo thang, khiêu khích của các lực lượng này trong mối quan hệ với chính phủ hợp pháp”.
Còn về phía Mỹ, Nhà Trắng nói rằng Phó tổng thống Mỹ Joe Biden kêu gọi Tổng thống Yanukovych nên ra lệnh cho các lực lượng của chính phủ đang “càn quét” nơi cắm trại của những người biểu tình rút lui và kềm chế tối đa, nhằm xoa dịu cuộc khủng hoảng chính trị vốn đang biến thành bạo động đẫm máu ở Ukraine.
Trả lời trên kênh truyền hình CNN, Đại sứ Mỹ tại Ucraina Geoffrey Pyatt nói rằng “Mỹ muốn thấy các lực lượng chính trị rời khỏi đường phố, trở lại các thể chế dân chủ của Ucraina”. Đồng thời “cuộc khủng hoảng của Ucraina chỉ có thể được giải quyết thông qua đối thoại, nhưng những người thổi bùng ngọn lửa bạo lực sẽ phải đón nhận các biện pháp trừng phạt”.
Còn người phụ trách đối ngoại của EU Catherine Ashton thì nói rằng bà "quan ngại sâu sắc" về sự "leo thang nghiêm trọng mới" ở Kiev và lên án "mọi hình thức sử dụng bạo lực nhắm và những tòa nhà của cả chính phủ hay các đảng phái”, cũng như kêu gọi các nhà lãnh đạo chính trị của Ucraina "giải quyết nguyên nhân gốc rễ của cuộc khủng hoảng”.
Dẫu biết rằng để giải quyết bất cứ một cuộc khủng hoảng nào, việc tìm ra được nguyên nhân gốc rễ là chìa khóa quan trọng để tìm ra được cách thức giải quyết, song điều quan trọng hơn là ý chí của mỗi bên liên quan, liệu họ có đủ “một trái tim nóng, và một cái đầu lạnh” để cùng nhau ngồi lại bàn đàm phán và tìm ra cách thức xoa dịu bất đồng, hướng tới lợi ích chung của người dân hay không? Câu chuyện chính trường Ucraina gần bốn tháng qua chứa đựng quá nhiều toan tính lợi ích của trong nước và các lực lượng bên ngoài, và cái kết của câu chuyện này sẽ không thể có hậu nếu những lời kêu gọi đối thoại, đàm phán kia chỉ mang màu trách nhiệm suông.
Tổng Biên tập THUẬN HỮU. © Báo Nhân Dân thiết kế và giữ bản quyền. Mong bạn đọc góp ý kiến, phê bình.
Trụ sở Bộ biên tập: 71 Hàng Trống - Hà Nội. Tel: (84 4) 38254231/38254232 Fax:(84 4) 38255593/38289432.
E-mail: nhandandientu@nhandan.org.vn

Server: Apache/2.2.15 (CentOS)

Cache-Control: no-cache

Vary: Accept-Encoding,User-Agent

Content-Encoding: gzip

Content-Type: text/html; charset=UTF-8


text:
Email
Mật khẩu
Đăng ký thành viên
Quên mật khẩu?
Chọn Phố
Cổ Vật
Gốm Sứ
Đồng Hồ
Gỗ
Âm Thanh
Xe Máy
Sưu Tập
Thời Trang
Kỷ Vật
Đá Quý
Tìm kiếm
Bản tin này đã bị xóa hoặc không tồn tại.
Đăng tin mới
01-01-1970, 07:00 AM
Chức năng sửa/xóa
( )
Chưa được người nào xác thực
Giúp xác thực thành viên này
Điện thoại:
Địa chỉ:
bạn bè
Kết bạn
Gửi tin nhắn
45 năm trước*
Thích
Đăng tin mới
Chưa có phản hồi
Bạn cần phải
đăng nhập
mới gửi được phản hồi.
Giới thiệu Phố Mua Bán
|
Quy định sử dụng Phố Mua Bán
|
Tin tức
|
Liên hệ Ban quản trị Phố Mua Bán
Thiết kế bởi Phố Mua Bán. Bản quyền © 2005-2014 Phố Mua Bán | PhoMuaBan.com | PhoMuaBan.VN. Bảo lưu mọi quyền.
Website đang chờ xin giấy phép của Bộ Thông tin và Truyền thông.
Số người vào hôm nay :: Số thành viên :: Thời gian gọi trang 0.0307 giây.


text:
Trang Chính
| Tin Quốc tế
Trung Quốc sẵn sàng chiến tranh?
Bệnh nhân AIDS giai đoạn cuối
Tin tức nổi bật trong ngày

Server: Zope/(2.13.8, python 2.7.6, linux2) ZServer/1.1

X-Cache-Lookup: MISS from localhost:8100

Via: 1.0 localhost (squid/3.1.14)


text:
Tiếng Việt
|
English
Trang chủ
Giới thiệu
Lịch sử phát triển
Giải thưởng
Giới thiệu Công ty
Các dự án
Sản phẩm
Thiết bị điện
Ổ cắm, công tắc
Hệ thống chiếu sáng
Cầu dao tự động (MCB)/(RCCB)
Dây và cáp điện
Hệ thống tủ phân phối điện
Thiết bị điện khác
Ống nhựa & phụ kiện
Ổ cắm đa năng kéo dài
Thiết bị công nghiệp
Ổ cắm, phích cắm
Cầu dao tự động (MCCB)
Thiết bị mạng
Dây mạng
Thiết bị khác
Thiết bị ngành nước
Ống nước HDPE
Ống thoát nước u.PVC
Ống cấp nước PP-R
Đại lý phân phối
Đại lý bán hàng
Cửa hàng giới thiệu sản phẩm
Hỗ trợ
Tải Catalogues
Tải báo giá
Tin tức
Sự kiện
Tin tức
-----Lựa chọn nhãn hiệu----
SINO
VANLOCK
SP
Thiết bị điện
Ổ cắm, công tắc
Hệ thống chiếu sáng
Cầu dao tự động (MCB)/(RCCB)
Dây và cáp điện
Hệ thống tủ phân phối điện
Thiết bị điện khác
Ống nhựa & phụ kiện
Ổ cắm đa năng kéo dài
Thiết bị công nghiệp
Ổ cắm, phích cắm
Cầu dao tự động (MCCB)
Thiết bị mạng
Dây mạng
Thiết bị khác
Thiết bị ngành nước
Ống nước HDPE
Ống thoát nước u.PVC
Ống cấp nước PP-R
Tải dữ liệu
Tải Catalogues
Tải báo giá
Thống kê truy cập
Số người đã truy cập:
103051
Số người đang truy cập:
1088
Trang chủ
»
Sản phẩm
» Hệ thống chiếu sáng
Hệ thống chiếu sáng
Sản phẩm khác
Lựa chọn
Ổ cắm, công tắc
Hệ thống chiếu sáng
Cầu dao tự động (MCB)/(RCCB)
Dây và cáp điện
Hệ thống tủ phân phối điện
Thiết bị điện khác
Ống nhựa & phụ kiện
Ổ cắm đa năng kéo dài
Đèn Pha Lon (Downlight)
Xem tất cả
»
Đèn trang Trí
Xem tất cả
»
Đèn đường
Xem tất cả
»
Máng đèn tán quang - T5
Xem tất cả
»
Đèn chống thấm
Xem tất cả
»
Máng Huỳnh Quang Kiểu Batten
Xem tất cả
»
Máng đèn tán quang - T10
Xem tất cả
»
Liên hệ
|
Sơ đồ trang
2008 © Bản quyền thuộc sở hữu công ty Xuân Lộc Thọ

Vary: Content-encoding


text:
Kinh là đường thẳng đi thông mọi chỗ.
Lạc là những nhánh phân ra từ kinh.
Kinh lạc làm thành 1 mạng lưới nối tiếp, chằng chịt, phân bổ khắp toàn thân. Kinh lạc liên kết các tạng phủ, các tổ chức lại với nhau thành 1 chỉnh thể thống nhất.Xem thêm: Đại Cương
- Về sinh lý : Kinh lạc là đường tuần hành khí huyết đi nuôi dưỡng toàn thân, duy trì mọi hoạt động sinh lý của cơ thể, chống ngoại tà, bảo vệ cơ thể. Nếu chức năng vận hành khí huyết của Kinh lạc bị trở ngại, khí huyết không thông lập tức sẽ xuất hiện dấu hiệu bệnh lý.
- Về bệnh lý : Kinh lạc là nơi bệnh tà xâm nhập vào cơ thể và truyền bệnh từ nông vào sâu (khi bệnh nặng lên) hoặc từ sâu ra nông (khi bệnh nhẹ đi). Vì thế, khi tạng phủ có bệnh, bệnh sẽ thông qua Kinh lạc mà phản ảnh ra ngoài cơ thể như : Bệnh Phế, ấn thấy đau huyệt Trung phủ, Phế du. Bệnh ở Can, ấn đau huyệt Kỳ môn, Can du...Xem thêm: Tác Dụng của Hệ Thống Kinh Lạc
+ "Kinh Biệt là 1 bộ phận đi riêng biệt của 12 Kinh Mạch, nhưng nó lại khác với Lạc mạch, vì thế, nó là ?đường đi riêng rẽ của kinh chính? gọi tắt là ?Kinh Biệt? (Trung Y Học Khái Luận).
+ Kinh Biệt còn gọi là kinh Nhánh, là bộ phận đặc biệt phân ra từ 12 kinh Chính. Mỗi kinh Chính tách ra 1 kinh Biệt.
+ Tên gọi của các kinh Biệt giống tên gọi của kinh Chính chỉ khác thêm chữ Biệt ở đầu. Thí dụ : Biệt thủ Thái Âm Phế, Biệt túc Quyết âm Can...Xem thêm: Hệ Thống 12 Kinh Biệt
Kinh lạc là 1 hệ thống phong phú, gồm có :
Theo người xưa, 4 khí dương từ trên đi xuống (Thiên khí) và 4 khí âm (địa khí) từ dưới đi lên, 8 dòng khí hóa trên giao lưu qua cơ thể con người, tạo thành 8 kinh, gọi là Kỳ kinh bát mạch.
Kỳ kinh bát mạch gồm : Nhâm mạch, Đốc mạch, Dương duy mạch, Âm duy mạch, Dương Kiều (Kiểu) mạch, Âm Kiều (Kiểu) mạch, Xung mạch và Đái (Đới) mạch.
Trong 8 mạch, trừ 2 mạch Nhâm và Đốc có huyệt riêng, còn 6 mạch khác không có huyệt riêng, có thể dùng 1 số huyệt của các kinh chính (huyệt Hội với 8 mạch) để điều hòa mạch khí của 6 mạch này.Xem thêm: Kỳ Kinh Bát Bộ
Các thai phụ và người muốn có con nên tránh xa tuyệt đối bia, rượu, theo một khuyến cáo vừa được đưa ra tại Anh. Khuyến

markdown:
Kinh là đường thẳng đi thông mọi chỗ.
Lạc là những nhánh phân ra từ kinh.
Kinh lạc làm thành 1 mạng lưới nối tiếp, chằng chịt, phân bổ khắp toàn thân. Kinh lạc liên kết các tạng phủ, các tổ chức lại với nhau thành 1 chỉnh thể thống nhất.
-
**Về sinh lý : **Kinh lạc là đường tuần hành khí huyết đi nuôi dưỡng toàn thân, duy trì mọi hoạt động sinh lý của cơ thể, chống ngoại tà, bảo vệ cơ thể. Nếu chức năng vận hành khí huyết của Kinh lạc bị trở ngại, khí huyết không thông lập tức sẽ xuất hiện dấu hiệu bệnh lý. **- Về bệnh lý : **Kinh lạc là nơi bệnh tà xâm nhập vào cơ thể và truyền bệnh từ nông vào sâu (khi bệnh nặng lên) hoặc từ sâu ra nông (khi bệnh nhẹ đi). Vì thế, khi tạng phủ có bệnh, bệnh sẽ thông qua Kinh lạc mà phản ảnh ra ngoài cơ thể như : Bệnh Phế, ấn thấy đau huyệt Trung phủ, Phế du. Bệnh ở Can, ấn đau huyệt Kỳ môn, Can du...
+ "Kinh Biệt là 1 bộ phận đi riêng biệt của 12 Kinh Mạch, nhưng nó lại khác với Lạc mạch, vì thế, nó là ?đường đi riêng rẽ của kinh chính? gọi tắt là ?Kinh Biệt? (Trung Y Học Khái Luận).
+ Kinh Biệt còn gọi là kinh Nhánh, là bộ phận đặc biệt phân ra từ 12 kinh Chính. Mỗi kinh Chính tách ra 1 kinh Biệt.
+ Tên gọi của các kinh Biệt giống tên gọi của kinh Chính chỉ khác thêm chữ Biệt ở đầu. Thí dụ : Biệt thủ Thái Âm Phế, Biệt túc Quyết âm Can...
Kinh lạc là 1 hệ thống phong phú, gồm có :
Theo người xưa, 4 khí dương từ trên đi xuống (Thiên khí) và 4 khí âm (địa khí) từ dưới đi lên, 8 dòng khí hóa trên giao lưu qua cơ thể con người, tạo thành 8 kinh, gọi là Kỳ kinh bát mạch.
Kỳ kinh bát mạch gồm : Nhâm mạch, Đốc mạch, Dương duy mạch, Âm duy mạch, Dương Kiều (Kiểu) mạch, Âm Kiều (Kiểu) mạch, Xung mạch và Đái (Đới) mạch.
Trong 8 mạch, trừ 2 mạch Nhâm và Đốc có huyệt riêng, còn 6 mạch khác không có huyệt riêng, có thể dùng 1 số huyệt của các kinh chính (huyệt Hội với 8 mạch) để điều hòa mạch khí của 6 mạch này.
Các thai phụ và người muốn có con nên tránh xa tuyệt đối bia, rượu, theo một khuyến cáo vừa được đưa ra tại Anh. Khuyến


text:
Trang chủ Bếp điện, Từ Bếp điện Bếp hồng ngoại Sanaky AT-2521HGN
Bếp hồng ngoại Sanaky AT-2521HGN
Giá NY: 1.020.000 vnđ
Giá KM: 930.000 vnđ
Bảo hành: 24 Tháng
Trạng thái sản phẩm: Còn hàng
Sản phẩm cùng loại
Giá NY: 4.950.000 đ
Giá KM: 4.455.000 đ
Tặng bộ nồi Inox cao cấp
Bảo hành: 36 Tháng
Giá NY: 9.000.000 đ
Giá KM: 8.100.000 đ
Tặng bộ nồi Inox cao cấp
Bảo hành: 36 Tháng
Giá NY: 14.990.000 đ
Giá KM: 9.743.000 đ
Tặng bộ nồi Inox cao cấp 3 chiếc
Bảo hành: 36 Tháng
Giá NY: 13.800.000 đ
Giá KM: 11.800.000 đ
Tặng bộ nồi Inox cao cấp
Bảo hành: 48 tháng - 1 đổi 1 năm đầu
Giá NY: 16.800.000 đ
Giá KM: 14.800.000 đ
Tặng bộ nồi Inox cao cấp
Bảo hành: 48 tháng - 1 đổi 1 năm đầu
Giá NY: 10.000.000 đ
Giá KM: 5.900.000 đ
Tặng bộ nồi Inox cao cấp 3 chiếc
Bảo hành: 36 Tháng - 1 đổi 1 năm đầu
Kinh nghiệm và đánh giá sản phẩm
Nhận tin khuyến mại
Điền thông tin Email để nhận thông tin khuyến mại
Thủ thuật
Copyright © 2011 ThegioiBepgas.vn. All Rights Reserved.
- Các comment chỉ nói về sản phẩm và tính năng sản phẩm.
- Ngôn từ lịch sự. Tôn trọng cộng đồng, tôn trọng chính bản thân người comment
- Mọi comment không hợp lệ, không hợp lý đều bị xóa.

markdown:
![](/includes/images/homepath.jpg)
Bếp hồng ngoại Sanaky AT-2521HGN
Tặng bộ nồi Inox cao cấp
Tặng bộ nồi Inox cao cấp
Tặng bộ nồi Inox cao cấp 3 chiếc
Tặng bộ nồi Inox cao cấp
Tặng bộ nồi Inox cao cấp
Tặng bộ nồi Inox cao cấp 3 chiếc
![](/includes/images/homepath.jpg)
[Trang chủ](http://www.thegioibepgas.vn/) [Bếp điện, Từ](http://www.thegioibepgas.vn/bep-dien-tu_dm4.html) [Bếp điện](http://www.thegioibepgas.vn/bep-dien_dm134.html) ![](/includes/images/tendm.gif)
# Bếp hồng ngoại Sanaky AT-2521HGN
Giá NY: 1.020.000 vnđ
Giá KM: 930.000 vnđ
Bảo hành: 24 Tháng
Trạng thái sản phẩm: Còn hàng
|Hãng sản xuất||SANAKY|
|Số bếp||1|
|Công suất (W)||2000|
|Chức năng|| - Chất liệu mặt bếp: Kính Ceramic |
- Khóa an toàn, Tự động tắt khi nhiệt độ quá cao
- Đèn hiển thị dạ quang
- Hẹn giờ
- Bảng điều khiển cảm ứng
|Nguồn điện||220V ~ 240V 50Hz/ 60Hz|
Sản phẩm cùng loại
Giá NY: 4.950.000 đ
Giá KM: 4.455.000 đ
![](http://www.thegioibepgas.vn/includes/images/km1.gif)
**Bảo hành:**36 Tháng
Giá NY: 9.000.000 đ
Giá KM: 8.100.000 đ
![](http://www.thegioibepgas.vn/includes/images/km1.gif)
**Bảo hành:**36 Tháng
Giá NY: 14.990.000 đ
Giá KM: 9.743.000 đ
![](http://www.thegioibepgas.vn/includes/images/km1.gif)
**Bảo hành:**36 Tháng
Giá NY: 13.800.000 đ
Giá KM: 11.800.000 đ
![](http://www.thegioibepgas.vn/includes/images/km1.gif)
**Bảo hành:**48 tháng - 1 đổi 1 năm đầu
Giá NY: 16.800.000 đ
Giá KM: 14.800.000 đ
![](http://www.thegioibepgas.vn/includes/images/km1.gif)
**Bảo hành:**48 tháng - 1 đổi 1 năm đầu
Giá NY: 10.000.000 đ
Giá KM: 5.900.000 đ
![](http://www.thegioibepgas.vn/includes/images/km1.gif)
**Bảo hành:**36 Tháng - 1 đổi 1 năm đầu
Kinh nghiệm và đánh giá sản phẩm
Nhận tin khuyến mại
Điền thông tin Email để nhận thông tin khuyến mại
Thủ thuật
Copyright © 2011 ThegioiBepgas.vn. All Rights Reserved.
Bếp hồng ngoại Sanaky AT-2521HGNtheo mẫu dưới đây. Xin lưu ý:
- Các comment chỉ nói về sản phẩm và tính năng sản phẩm.
- Ngôn từ lịch sự. Tôn trọng cộng đồng, tôn trọng chính bản thân người comment
- Mọi comment không hợp lệ, không hợp lý đều bị xóa.


markdown:
**5**lượt cảm ơn)
Hiện giờ mình đang định tậu 1 con AB F1 đỏ nhưng không biết giá hiện tại trên thị trường (26/3/2010) của loại xe này trong mấy ngày gần đây như thế nào, mình có gọi điện đến hỏi 1 số Head của HN thì họ bảo đến trực tiếp HEAD để thỏa thuận. Vì mình đang tham khảo giá trên thị trường để lựa chọn xe nên mình muốn biết giá trên thị trường của dòng xe này là bao nhiêu, thấy trên vặt giá ghi là 37t (Hôm tết mình có ghé qua HEAD và giá lúc bấy giờ là 41t). Vậy ai mới mua xe hoạc biết chính xác giá của xe này trong thời gian gần đây nhất thì cho mình biết nhé ( hôm nay là 36/3/2010). Thanks
Mình muốn hỏi gần chính xác giá của xe hiện tại là bao nhiêu, tại mình thấy hình như xe đang có xu hướng giảm giá," xe dao động trong khoảng 36 -40t, gần tết xe đắt "--> cái này thì mình nghĩ ai cũng biết, vấn đề mình quan tâm là nó giảm xuống bao nhiêu và giá hiện tại là bao nhiêu, ai mới mua xe hoạc biết chính xác giá xe AB F1 ở Hà Nội or Bắc Ninh thì cho mình biết với.
mình cũng đang định mua,hum trước ra hỏi thì nó bảo 36,5 triệu.đang đi hỏi mấy chỗ khác.
Mình muốn hỏi gần chính xác giá của xe hiện tại là bao nhiêu, tại mình thấy hình như xe đang có xu hướng giảm giá," xe dao động trong khoảng 36 -40t, gần tết xe đắt "--> cái này thì mình nghĩ ai cũng biết, vấn đề mình quan tâm là nó giảm xuống bao nhiêu và giá hiện tại là bao nhiêu, ai mới mua xe hoạc biết chính xác giá xe AB F1 ở Hà Nội or Bắc Ninh thì cho mình biết với.
Bác mua xe rồi thì coi lại cách gọi tên nha. Chạy AB mà bảo là AB f1 thì người ta cười cho. Sorry vì có hơi nói quá nhưng thật sự hãy là người hiểu biết rõ với những j mình định mua.
thằng bạn mình vừa mua con ablet màu trắng,nó mua bên đường Nguyễn Trãi Hà Đông,36.5 kủ chưa giây tờ.nguồn tin chính xác đấy....
Hôm nay là 10/08/2010, Bạn mình mới mua AB màu đen làm giấy tờ biển Hà Nội + dán xe đầy đủ là hết 36 triệu. Không biết bác nào mua Nouvo LX gần đây nhất giá sao nhỉ?!
Mình mới mua xe nouvo lx 2010 và có ban so luôn tổng cộng 36,5 triệu bạn ạ.
Hôm nay ngày 25/8/2010
Bác nào biết ở HN giá bán AB Fi màu đen hiện tại là bao nhiêu nhỉ?
cung cấp cho em xin địa chỉ luôn nhé
thanks.
PS: Nhà em ở HN có người quen làm đại lý Honda Ở Ha Nam lấy giá rẻ hơn, em muốn lấy hóa đơn tiên em và đăng ký tại Hà Nội được không ah?
Honda Air Blade Thái (Màu Đen)
Honda Air Blade FI Thái
Honda Air Blade FI Đỏ
Honda Air Blade FI Thái (Đỏ)
|
|![]()

Set-Cookie: u_nologin_id=1613956796; expires=Sat, 09-May-2015 16:33:14 GMT; path=/; httponly