内容提供者实现应用访问另一个应用的数据库

实现这么个需求:应用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 }

这样就实现了第二个应用访问第一个应用的数据库。

posted @ 2018-12-10 19:16  龙谷情Sinoam  阅读(763)  评论(0编辑  收藏  举报
Smiley face