翻開擒猿寶典,Content Provider 提供了一個中央控管的資料庫,可以讓其他的 app 可以購過 API 方便存取本身的資料,以下介紹 Content Provider 的原理與實作:
Content Provider 將資料以 Table 的方式儲存,其中一個 row 表示一筆資料,每個 row 會有多個 column,Table 內容如下:
word | app_id | frequency | locale | _ID |
---|---|---|---|---|
mapreduce | user1 | 100 | en_US | 1 |
precompiler | user14 | 200 | fr_FR | 2 |
applet | user2 | 225 | fr_CA | 3 |
const | user1 | 255 | pt_BR | 4 |
int | user5 | 100 | en_UK | 5 |
鏡頭一轉,來到安卓大陸的戰場上,火爆猿王肆虐,打得眾人潰不成軍,一位武功強大的老前輩挺身而出,利用獅吼功向眾人發出訊息:幹你娘!大家快來用我的 Content Provider 打王!
這時候身為擒猿手的你,該怎麼提取前輩的內力,借力對邪惡猿王打出致命一擊呢?噎,這時候就要透過 ContentResolver 這個物件,透過他就可以對前輩的 Content Provider 進行 CRUD 操作 (C: Create、R: Retrieve、U: Update、D: Delete)。
Query Data from Content Provider
欲取得 Content Provider 分享資料的 app 必須在 manifest 中宣告 permission,而欲存取資料的 app 則需在 manifest 中去 use 這個 permission。在程式中可以利用以下寫法得到指定 Content Provider 的 Table 中的資料:// Queries the user dictionary and returns results
Cursor mCursor = getContentResolver().query(
CONTENT_URI, // The content URI of the words table
mProjection, // The columns to return for each row
mSelectionClause // Selection criteria
mSelectionArgs, // Selection criteria
mSortOrder); // The sort order for the returned rows
- CONTENT_URI 以 URI 的形式直接指向 Content Provider 的 Table,形如 content://user_dictionary/words,其中 user_diction 為 Content Provider authority,而 words 為 Table name。
- mProjecttion 定義取出的資料要有那些欄位,寫法如下:
String[] mProjection = { "_ID", "word", "locale" };
- mSelectionClause 可定義的篩選資料的條件,寫法如下:
String mSelectionClause = "frequency = 200";
但這樣的寫法非常危險,因為他直接對應到 SQL 語言,譬如 user 可能輸入 "nothing; DROP TABLE *;" ,導致 Table 被清空。 - 更好的寫法是 mSelectionArgs 與 mSelectionClause 搭配使用,能避免上述的惡意破壞情形,寫法如下,注意那個問號很玄:
// Constructs a selection clause with a replaceable parameter String mSelectionClause = "frequency = ?"; // Defines an array to contain the selection arguments String[] selectionArgs = {""}; // Sets the selection argument to the user's input selectionArgs[0] = mUserInput;
- 最後,可以利用 mSortOrder 去控制取回資料的排序方式,寫法如下:
mSortOrder = "ORDER BY _ID";
Getting data from query results
使用上述的 ContentResolver.query() 會傳回一個 Cursor 元件,以下為從 Cursor 中取得我們要的資料的方法:
// Determine the column index of the column named "word" int index = mCursor.getColumnIndex("world"); if (mCursor != null) { while (mCursor.moveToNext()) { // Gets the value from the column. newWord = mCursor.getString(index); Log.d("Lotus", newWord); } }
此外可以直接將 Cursor 與 ListView 做連結,如以下寫法:
// Creates a new SimpleCursorAdapter mCursorAdapter = new SimpleCursorAdapter( getApplicationContext(), // The application's Context object R.layout.wordlistrow, // A layout in XML for one row in the ListView mCursor, // The result from the query new Steing[] {"word" "locale"}, // A string array of column names in the cursor new int[] { R.id.dictWord, R.id.locale}, // view IDs in the row layout 0); // Flags (usually none are needed) // Sets the adapter for the ListView mListview.setAdapter(mCursorAdapter);
Inserting data
利用 ContentResolver.insert() 可達成插入一筆新資料至 Content Provider 的動作,寫法如下 :
// Defines a new Uri object that receives the result of the insertion Uri mNewUri; // Defines an object to contain the new values to insert ContentValues mNewValues = new ContentValues(); /* * Sets the values of each column and inserts the word. The arguments to the "put" * method are "column name" and "value" */ mNewValues.put("app_id", "example.user"); mNewValues.put("local", "en_US"); mNewValues.put("word", "insert"); mNewValues.put("frequency", "100"); mNewUri = getContentResolver().insert( CONTENT_URI, // the user dictionary content URI mNewValues // the values to insert );
Updating data
利用 ContentResolver.update() 可達成對 Content Provider 的資料做更新動作,寫法如下 :
// Defines an object to contain the updated values
ContentValues mUpdateValues = new ContentValues();
// Defines selection criteria for the rows you want to update
String mSelectionClause = "locale" + " LIKE ?";
String[] mSelectionArgs = {"en_%"};
// Defines a variable to contain the number of updated rows
int mRowsUpdated = 0;
/*
* Sets the updated value and updates the selected words.
*/
mUpdateValues.putNull("local");
mRowsUpdated = getContentResolver().update(
CONTENT_URI, // the user dictionary content URI
mUpdateValues // the columns to update
mSelectionClause // the column to select on
mSelectionArgs // the value to compare to
);
Deleting data
利用 ContentResolver.delete() 可達成對 Content Provider 的資料做刪除動作,寫法如下 :
// Defines selection criteria for the rows you want to delete
String mSelectionClause = "app_id" + " LIKE ?";
String[] mSelectionArgs = {"user"};
// Defines a variable to contain the number of rows deleted
int mRowsDeleted = 0;
// Deletes the words that match the selection criteria
mRowsDeleted = getContentResolver().delete(
CONTENT_URI, // the user dictionary content URI
mSelectionClause // the column to select on
mSelectionArgs // the value to compare to
);
Reference: http://developer.android.com/guide/topics/providers/content-provider-basics.html
Your Affiliate Profit Machine is ready -
回覆刪除And getting it set up is as simple as 1-2-3!
Here are the steps to make it work...
STEP 1. Input into the system which affiliate products the system will push
STEP 2. Add PUSH BUTTON traffic (this LITERALLY takes 2 minutes)
STEP 3. See how the affiliate system explode your list and sell your affiliate products on it's own!
So, do you want to start making money??
Check it out here