編輯:Android編程入門
內容提供器(Content Provider)主要用於在不同的應用程序之間實現數據共享的功能,它提供了一套完整的機制,允許一個程序訪問另一個程序中的數據,同時還能保證被訪數據的安全性。目前,使用內容提供器是Android 實現跨程序共享數據的標准方式。不同於文件存儲和SharedPreferences 存儲中的兩種全局可讀寫操作模式,內容提供器可以選擇只對哪一部分數據進行共享,從而保證我們程序中的隱私數據不會有洩漏的風險。接下來,我們開始內容提供器的學習。content provider的原理說明,參見另外一篇博客(android高級---->ContentProvider的源碼分析)
目錄導航:
一、 內容提供器的用法:
二、 ContentResolver的基本用法:
三、 內容URI的基本介紹:
創建一個簡單項目,結構如下:
一、 在activity_main.xml文件中創建一個ListView的布局:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ListView
android:id="@+id/listView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
二、 在MainActivity.java中:
package com.example.linux.getcontact;
import android.database.Cursor;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.support.v7.app.AppCompatActivity;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private ListView listView;
ArrayAdapter<String> adapter;
List<String> contactsList = new ArrayList<String>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = (ListView) findViewById(R.id.listView);
adapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, contactsList);
listView.setAdapter(adapter);
readContacts();
}
private void readContacts() {
Cursor cursor = null;
try {
// 查詢聯系人數據
cursor = getContentResolver().query(
ContactsContract.CommonDataKinds.Phone.CONTENT_URI, null, null, null, null);
while (cursor.moveToNext()) {
// 獲取聯系人姓名
String displayName = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME));
// 獲取聯系人手機號
String number = cursor.getString(cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER));
contactsList.add(displayName + "\n" + number);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (cursor != null) {
cursor.close();
}
}
}
}
三、 讀取系統聯系人是需要聲明權限的,在AndroidManifest.xml中增加權限:
<uses-permission android:name="android.permission.READ_CONTACTS" />
上一個自己的程序中訪問其他應用程序的數據。總體來說思路還是非常簡單的,只需要獲取到該應用程序的內容URI,然後借助ContentResolver進行CRUD 操作就可以了。以下我們創建自己的內容提供器。
項目結構:
一、 創建一個與數據庫表對應的Bean:Person.java:
package com.example.linux.contentproviderserver.model;
/**
* Created by Linux on 2016/3/4.
*/
public class Person {
private Integer _id;
private String name;
private String age;
public Integer get_id() {
return _id;
}
public void set_id(Integer _id) {
this._id = _id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAge() {
return age;
}
public void setAge(String age) {
this.age = age;
}
}
二、 接著建立一個關於數據庫的工具類:DBOpenHelper.java
package com.example.linux.contentproviderserver.util;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
/**
* Created by Linux on 2016/3/4.
*/
public class DBOpenHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "person.db"; //數據庫名稱
private static final int DATABASE_VERSION = 1;//數據庫版本
private static final String CREATE_TABLE_PERSON = "CREATE TABLE person (_id integer primary key autoincrement, name varchar(20), age varchar(10))";
private static final String DROP_TABLE_PERSON = "DROP TABLE IF EXISTS person";
public DBOpenHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION);
}
@Override
public void onCreate(SQLiteDatabase db) {
db.execSQL(CREATE_TABLE_PERSON);
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(DROP_TABLE_PERSON);
onCreate(db);
}
}
三、 創建一個自己的繼承了ContentProvider的內容提供器:PersonProvider.java
private final static String TAG = "PersonProvider";
private DBOpenHelper dbOpenHelper;
private static final UriMatcher MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
private static final int PERSONS = 1;
private static final int PERSON = 2;
private static final String AUTHORITY = "com.example.linux.contentproviderserver.action.PersonProvider";
private static final String PATH_1 = "person";
private static final String PATH_2 = "person/#";
static {
Log.i(TAG, "on PersonProvider static");
MATCHER.addURI(AUTHORITY, PATH_1, PERSONS);
MATCHER.addURI(AUTHORITY, PATH_2, PERSON);
}
@Override
public boolean onCreate() {
Log.i(TAG, "on PersonProvider create");
this.dbOpenHelper = new DBOpenHelper(this.getContext());
return false;
}
// 插入person表中的所有記錄 /person
// 插入person表中指定id的記錄 /person/10
@Override
public Uri insert(Uri uri, ContentValues values) {
Log.i(TAG, "uri: " + uri.getPath() + ", values: " + values.getAsString("name"));
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
switch (MATCHER.match(uri)) {
case PERSONS:
// 特別說一下第二個參數是當name字段為空時,將自動插入一個NULL。
long rowid = db.insert("person", "name", values);
Uri insertUri = ContentUris.withAppendedId(uri, rowid);// 得到代表新增記錄的Uri
this.getContext().getContentResolver().notifyChange(uri, null);
return insertUri;
case PERSON:
Log.i("some", "soem");
return null;
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int count = 0;
switch (MATCHER.match(uri)) {
case PERSONS:
count = db.delete("person", selection, selectionArgs);
return count;
case PERSON:
long id = ContentUris.parseId(uri);
String where = "_id=" + id;
if (selection != null && !"".equals(selection)) {
where = selection + " and " + where;
}
count = db.delete("person", where, selectionArgs);
return count;
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
@Override
public int update(Uri uri, ContentValues values, String selection,
String[] selectionArgs) {
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
int count = 0;
switch (MATCHER.match(uri)) {
case PERSONS:
count = db.update("person", values, selection, selectionArgs);
return count;
case PERSON:
long id = ContentUris.parseId(uri);
String where = "_id=" + id;
if (selection != null && !"".equals(selection)) {
where = selection + " and " + where;
}
count = db.update("person", values, where, selectionArgs);
return count;
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
@Override
public Cursor query(Uri uri, String[] projection, String selection,
String[] selectionArgs, String sortOrder) {
Log.i(TAG, "PersonProvider query");
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
int matchResult = MATCHER.match(uri);
switch (MATCHER.match(uri)) {
case PERSONS:
return db.query("person", projection, selection, selectionArgs,
null, null, sortOrder);
case PERSON:
long id = ContentUris.parseId(uri);
String where = "_id=" + id;
if (selection != null && !"".equals(selection)) {
where = selection + " and " + where;
}
return db.query("person", projection, where, selectionArgs, null,
null, sortOrder);
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
//返回數據的MIME類型。
@Override
public String getType(Uri uri) {
Log.i(TAG, "PersonProvider get type");
switch (MATCHER.match(uri)) {
case PERSONS:
return "vnd.android.cursor.dir/person";
case PERSON:
return "vnd.android.cursor.item/person";
default:
throw new IllegalArgumentException("Unkwon Uri:" + uri.toString());
}
}
五、 在MainActivity方法,為了方便得到數據庫中的數據,添加了查詢與增加方法:
package com.example.linux.contentproviderserver;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Toast;
import com.example.linux.contentproviderserver.util.DBOpenHelper;
/**
* writer: huhx
* 內容提供器的服務端
*/
public class MainActivity extends AppCompatActivity {
private final static String TAG = "PersonProvider";
private DBOpenHelper dbOpenHelper;
SQLiteDatabase database = null;
private StringBuffer stringBuffer = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
Log.i(TAG, "main on create.");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbOpenHelper = new DBOpenHelper(this);
database = dbOpenHelper.getWritableDatabase();
}
// 查詢所有的數據
public void queryAll(View view) {
stringBuffer = new StringBuffer();
Cursor cursor = database.rawQuery("select * from person", null);
cursor.moveToFirst();
while(cursor.moveToNext()) {
String name = cursor.getString(1);
int age = cursor.getInt(2);
stringBuffer.append("name: " + name + ", age: " + age + "\n");
}
if (stringBuffer.toString().equals("")) {
Toast.makeText(MainActivity.this, "nothing", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, stringBuffer, Toast.LENGTH_SHORT).show();
}
}
//插入數據
public void insertData(View view) {
Object[] object = new Object[]{"linux", 23};
database.execSQL("insert into person(name, age) values(?, ?)", object);
}
@Override
protected void onDestroy() {
super.onDestroy();
database.close();
}
}
項目結構:
一、在MainActivity中增加了查詢與插入功能:
package com.example.linux.contentproviderclient;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Toast;
/**
* 內容提供器的客戶端
*/
public class MainActivity extends AppCompatActivity {
private StringBuffer stringBuffer = new StringBuffer();
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
// 插入數據
public void insert(View view) {
ContentResolver contentResolver = getContentResolver();
Uri insertUri = Uri.parse("content://com.example.linux.contentproviderserver.action.PersonProvider/person");
ContentValues values = new ContentValues();
values.put("name", "wangkuifeng");
values.put("age", 23);
Uri uri = contentResolver.insert(insertUri, values);
Toast.makeText(MainActivity.this, "insert success: " + uri, Toast.LENGTH_SHORT).show();
}
// 查詢數據
public void query(View view) {
ContentResolver contentResolver = getContentResolver();
Uri queryUri = Uri.parse("content://com.example.linux.contentproviderserver.action.PersonProvider/person/5");
Cursor queryResult = contentResolver.query(queryUri, null, null, null, null);
int count = queryResult.getCount();
for (queryResult.moveToFirst(); !queryResult.isAfterLast(); queryResult.moveToNext()) {
String name = queryResult.getString(1);
int age = queryResult.getInt(2);
stringBuffer.append("name: " + name + ", age: " + age + "\n");
}
Toast.makeText(MainActivity.this, stringBuffer.toString() + "\ncount: " + count, Toast.LENGTH_SHORT).show();
queryResult.close();
}
}
Android學習筆記:ActionBar使用介紹
一、基本概念最權威和官方的介紹請看google的api文檔http://developer.android.com/training/basics/actionbar/s
java/android線程池詳解
一,簡述線程池:線程池是如何工作的:一系列任務出現後,根據自己的線程池安排任務進行。如圖: 線程池的好處:重用線程池中的線程,避免因為線程的創建和銷毀所帶來的性能開銷。能
Android 意圖(Intent)和過濾器(Filter)
Android 意圖(Intent)和過濾器(Filter)Android意圖是一個要執行的操作的抽象描述。它可以通過 startActivity 來啟動
Android 控件架構
如果說Android上的app是一個有血有肉的人的話,那麼人靠衣裝馬靠鞍,那麼控件就是把app裝扮的漂漂亮亮的“衣服”。那麼安卓的控件到底是如何架