1. 程式人生 > >內容提供者實現應用訪問另一個應用的資料庫

內容提供者實現應用訪問另一個應用的資料庫

實現這麼個需求:應用1建立資料庫Account.db,應用2對Account.db進行操作

有兩個辦法。

首先記錄第一個不合常理的方法:將建立的資料庫的許可權改為公開的可讀可寫的,然後其他應用就可以訪問了。當然沒人會這麼做,太不安全還麻煩。在這裡就不詳細說了,之提供一個方法可以在程式碼裡寫shell命令:

 1 public void myChmod() {
 2 
 3         try {
 4             String command = "chmod 777 /data/data/com.lgqrlchinese.createprdb/databases/Account.db ";//
這裡是shell命令,我修改資料庫許可權為777 5 Runtime runtime = Runtime.getRuntime(); 6 runtime.exec(command); 7 } catch (IOException e) { 8 e.printStackTrace(); 9 } 10 11 }

記錄一下作為小白所學的方法。用到內容提供者ContentProvider:

新建一個類MyOpenHelper.java來建立資料庫Account.db:

 1 package com.lgqrlchinese.createprdb;
 2 
 3 import android.content.Context;
 4 import android.database.sqlite.SQLiteDatabase;
 5 import android.database.sqlite.SQLiteOpenHelper;
 6 
 7 public class MyOpenHelper extends SQLiteOpenHelper {
 8     /**
 9      * context 上下文
10      * name 資料庫名字
11 * factory 遊標工廠 12 * version 版本 13 */ 14 public MyOpenHelper(Context context) { 15 super(context, "Account.db", null, 1); 16 } 17 18 @Override 19 public void onCreate(SQLiteDatabase db) { 20 db.execSQL("create table info(_id integer primary key autoincrement,name varchar(20),phone varchar(20))"); 21 db.execSQL("insert into info(name,phone) values(?,?)", new String[]{"張三", "17865649855"}); 22 db.execSQL("insert into info(name,phone) values(?,?)", new String[]{"李四", "15364987564"}); 23 24 } 25 26 @Override 27 public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { 28 29 } 30 }

首先實現在本應用中操作資料庫,不妨直接查一查:MainActivity.java:

 1 package com.lgqrlchinese.createprdb;
 2 
 3 import android.database.Cursor;
 4 import android.database.sqlite.SQLiteDatabase;
 5 import android.support.v7.app.AppCompatActivity;
 6 import android.os.Bundle;
 7 
 8 import java.io.IOException;
 9 
10 public class MainActivity extends AppCompatActivity {
11 
12     @Override
13     protected void onCreate(Bundle savedInstanceState) {
14         super.onCreate(savedInstanceState);
15         setContentView(R.layout.activity_main);
16 
17         MyOpenHelper myOpenHelper = new MyOpenHelper(getApplicationContext());
18         SQLiteDatabase db = myOpenHelper.getReadableDatabase();
19         Cursor cursor = db.query("info", null, null, null, null, null, null);
20         if (cursor != null && cursor.getCount() > 0) {
21             while (cursor.moveToNext()) {
22                 String name = cursor.getString(1);
23                 String phone = cursor.getString(2);
24                 System.out.println(name + phone);
25             }
26         }
27 
28     }
29 
30 }

只是檢驗下資料庫有木有問題,通過檢測,沒有問題,然後我們開始寫內容提供者AccountContentProvider.java,其中有四個方法正好是對資料庫的四個操作:增刪改查。

  1 package com.lgqrlchinese.createprdb;
  2 
  3 import android.content.ContentProvider;
  4 import android.content.ContentValues;
  5 import android.content.UriMatcher;
  6 import android.database.Cursor;
  7 import android.database.sqlite.SQLiteDatabase;
  8 import android.net.Uri;
  9 
 10 public class AccountContentProvider extends ContentProvider {
 11     //定義一個uriMathcher,路徑匹配器
 12     private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
 13 
 14     private static final int QUERYSUCESS = 0;
 15     private static final int INSERTSUCESS = 0;
 16     private static final int UPDATESUCESS = 0;
 17     private static final int DELETESUCESS = 0;
 18 
 19     //靜態程式碼塊,新增匹配規則
 20     static {
 21         /**
 22          * authority 注意和清單檔案裡面配置的一樣
 23          * path
 24          * code 一個常量
 25          */
 26         sURIMatcher.addURI("AccountContentProvider", "query", QUERYSUCESS);
 27         sURIMatcher.addURI("AccountContentProvider", "insert", INSERTSUCESS);
 28         sURIMatcher.addURI("AccountContentProvider", "update", UPDATESUCESS);
 29         sURIMatcher.addURI("AccountContentProvider", "delete", DELETESUCESS);
 30 
 31     }
 32 
 33     private MyOpenHelper myOpenHelper;
 34 
 35     public AccountContentProvider() {
 36     }
 37 
 38     @Override
 39     public boolean onCreate() {
 40         // TODO: Implement this to initialize your content provider on startup.
 41 
 42         myOpenHelper = new MyOpenHelper(getContext());
 43 
 44         return false;
 45     }
 46 
 47     @Override
 48     public int delete(Uri uri, String selection, String[] selectionArgs) {
 49         // Implement this to handle requests to delete one or more rows.
 50         int code = sURIMatcher.match(uri);
 51         if (code == DELETESUCESS) {
 52             SQLiteDatabase db = myOpenHelper.getReadableDatabase();
 53             int delete = db.delete("info", selection, selectionArgs);
 54             return delete;
 55         } else {
 56             throw new IllegalArgumentException("delete您的路徑不匹配,請檢查路徑");
 57 
 58         }
 59     }
 60 
 61     @Override
 62     public String getType(Uri uri) {
 63         // TODO: Implement this to handle requests for the MIME type of the data
 64         // at the given URI.
 65         throw new UnsupportedOperationException("Not yet implemented");
 66     }
 67 
 68     @Override
 69     public Uri insert(Uri uri, ContentValues values) {
 70         // TODO: Implement this to handle requests to insert a new row.
 71         int code = sURIMatcher.match(uri);
 72         if (code == INSERTSUCESS) {
 73             SQLiteDatabase db = myOpenHelper.getReadableDatabase();
 74             long insert = db.insert("info", null, values);
 75             Uri uri2 = Uri.parse("com.lgqrlchinese.insert" + insert);
 76             return uri2;
 77         } else {
 78             throw new IllegalArgumentException("insert您的路徑不匹配,請檢查路徑");
 79 
 80         }
 81     }
 82 
 83     @Override
 84     public Cursor query(Uri uri, String[] projection, String selection,
 85                         String[] selectionArgs, String sortOrder) {
 86         // TODO: Implement this to handle query requests from clients.
 87         int code = sURIMatcher.match(uri);
 88         if (code == QUERYSUCESS) {
 89             //路徑匹配成功,把query方法實現(資料庫查詢方法),造作資料庫必須獲得SQLiteDatabase物件
 90             SQLiteDatabase db = myOpenHelper.getReadableDatabase();
 91             Cursor cursor = db.query("info", projection, selection, selectionArgs, null, null, sortOrder);
 92             //cursor不能關閉
 93             return cursor;
 94 
 95 
 96         } else {
 97             //路徑不匹配
 98             throw new IllegalArgumentException("您的路徑不匹配,請檢查路徑");
 99         }
100     }
101 
102     @Override
103     public int update(Uri uri, ContentValues values, String selection,
104                       String[] selectionArgs) {
105         // TODO: Implement this to handle requests to update one or more rows.
106         int code = sURIMatcher.match(uri);
107         if (code == UPDATESUCESS) {
108             SQLiteDatabase db = myOpenHelper.getReadableDatabase();
109             int update = db.update("info", values, selection, selectionArgs);
110             return update;
111         } else {
112             throw new IllegalArgumentException("update您的路徑不匹配,請檢查路徑");
113 
114         }
115     }
116 }

當然要在清單檔案中配置內容提供者

1         <provider
2                 android:name=".AccountContentProvider"
3                 android:authorities="AccountContentProvider"
4                 android:enabled="true"
5                 android:exported="true">
6         </provider>

此時新建一個專案,開始第二個應用

在佈局檔案activity_main.xml中加入四個按鈕分別是增刪改查:

 1 <?xml version="1.0" encoding="utf-8"?>
 2 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 3     xmlns:tools="http://schemas.android.com/tools"
 4     android:layout_width="match_parent"
 5     android:layout_height="match_parent"
 6     android:orientation="vertical"
 7     tools:context=".MainActivity">
 8 
 9     <Button
10         android:layout_width="wrap_content"
11         android:layout_height="wrap_content"
12         android:onClick="click1"
13         android:text="add" />
14 
15     <Button
16         android:layout_width="wrap_content"
17         android:layout_height="wrap_content"
18         android:onClick="click2"
19         android:text="delete" />
20 
21     <Button
22         android:layout_width="wrap_content"
23         android:layout_height="wrap_content"
24         android:onClick="click3"
25         android:text="update" />
26 
27     <Button
28         android:layout_width="wrap_content"
29         android:layout_height="wrap_content"
30         android:onClick="click4"
31         android:text="query" />
32 
33 </LinearLayout>

在MainActivity.java中實現按鈕的點選事件:

 1 package com.lgqrlchinese.readdb;
 2 
 3 import android.content.ContentValues;
 4 import android.database.Cursor;
 5 import android.database.sqlite.SQLiteDatabase;
 6 import android.net.Uri;
 7 import android.support.v7.app.AppCompatActivity;
 8 import android.os.Bundle;
 9 import android.view.View;
10 import android.widget.Toast;
11 
12 public class MainActivity extends AppCompatActivity {
13 
14     @Override
15     protected void onCreate(Bundle savedInstanceState) {
16         super.onCreate(savedInstanceState);
17         setContentView(R.layout.activity_main);
18 
19     }
20 
21     //add
22     public void click1(View view) {
23         Uri uri = Uri.parse("content://AccountContentProvider/insert");//路徑和定義的路徑一樣
24         ContentValues values = new ContentValues();
25         /**
26          * key 欄位名
27          * name 值
28          */
29         values.put("name", "趙六");
30         values.put("phone", "15445896458");
31         Uri insert = getContentResolver().insert(uri, values);
32         System.out.println("insert:" + insert);
33 
34 
35     }
36 
37     //delete
38     public void click2(View view) {
39         Uri uri = Uri.parse("content://AccountContentProvider/delete");//路徑和定義的路徑一樣
40         int delete = getContentResolver().delete(uri, "name=?", new String[]{"趙六"});
41         Toast.makeText(getApplicationContext(), "刪除了" + delete + "行", Toast.LENGTH_SHORT).show();
42 
43 
44     }
45 
46     //update
47     public void click3(View view) {
48         Uri uri = Uri.parse("content://AccountContentProvider/update");//路徑和定義的路徑一樣
49         ContentValues values = new ContentValues();
50         values.put("phone", 10086);
51         int update = getContentResolver().update(uri, values, "name=?", new String[]{"張三"});
52         Toast.makeText(getApplicationContext(), "更改了" + update + "行", Toast.LENGTH_SHORT).show();
53 
54     }
55 
56     //query
57     public void click4(View view) {
58         //拿到內容解析者,直接通過上下文拿取
59         Uri uri = Uri.parse("content://AccountContentProvider/query");//路徑和定義的路徑一樣
60         Cursor cursor = getContentResolver().query(uri, null, null, null, null);
61         if (cursor != null && cursor.getCount() > 0) {
62             while (cursor.moveToNext()) {
63                 String name = cursor.getString(1);
64                 String phone = cursor.getString(2);
65                 System.out.println("應用二" + name + phone);
66 
67             }
68         }
69     }
70 }

這樣就實現了第二個應用訪問第一個應用的資料庫。

 

 

 

ContentProvider