zoukankan      html  css  js  c++  java
  • 内容提供者实现应用访问另一个应用的数据库

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

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

    昔日我曾苍老,如今风华正茂(ง •̀_•́)ง
  • 相关阅读:
    2-Rsync备份-全网备份
    1-Rsync备份-备份概述
    复杂声明学习总结
    EasyExcel的用法
    listvue
    解决Error: Cannot find module 'node-sass'问题
    Webpack
    babel的使用
    nodejs的使用
    vue入门
  • 原文地址:https://www.cnblogs.com/lgqrlchinese/p/10104411.html
Copyright © 2011-2022 走看看