赞
踩
我们在安卓日常开发和学习过程中,contentProvider是个很常见的概念,毕竟是四大组件之一。不过可能工作和学习过程中涉及到contentProvider的场景有时候不是很多。本文先初步介绍下contentProvider的基本使用。
话不多说,直接上代码,代码主要可以分为两大部分,一个是内容提供者,提供contentProvider给其他客户端访问,一个是内容访问者,通过访问第三方APP提供的contentProvider,去对第三方数据进行增删改查等各类操作。
(1)借助SQLiteOpenHelper,新建数据库管理类,代码如下:
- import android.content.Context;
- import android.database.sqlite.SQLiteDatabase;
- import android.database.sqlite.SQLiteOpenHelper;
-
- import androidx.annotation.Nullable;
-
- /**
- * 数据库管理类,创建和管理数据库
- *
- * @author baorant
- */
- public class MySqlHelper extends SQLiteOpenHelper {
-
- public MySqlHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {
- super(context, name, factory, version);
- }
- @Override
- public void onCreate(SQLiteDatabase sqLiteDatabase) {
- // 创建student数据表
- sqLiteDatabase.execSQL("create table student ("+
- "id integer primary key autoincrement,name varchar,age integer)");
- }
- @Override
- public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
-
- }
- }
(2)新建数据库增删改查具体操作类,暂时先实现查询和插入操作,代码如下:
- import android.content.ContentUris;
- import android.content.ContentValues;
- import android.content.Context;
- import android.database.Cursor;
- import android.database.sqlite.SQLiteDatabase;
- import android.net.Uri;
- import android.util.Log;
-
- /**
- * 数据库操作类,增删改查操作
- *
- * @author baorant
- */
- public class MyDataBase {
- private Context context;
- private SQLiteDatabase database;
-
- private static String TAG = "TestResolver";
-
- public MyDataBase(Context context){
- this.context = context;
- MySqlHelper dbHelper = new MySqlHelper(context,"db",null,1);
- database = dbHelper.getWritableDatabase();
- }
-
- /**
- * 数据插入操作
- */
- public Uri insertDao(ContentValues contentValues){
- Log.d(TAG, contentValues.toString());
- long rowid = database.insert("student",null, contentValues);
- Uri uri = Uri.parse("content://com.baorant.provider.MyContentProvider/student");
- Uri inserturi = ContentUris.withAppendedId(uri,rowid);
- context.getContentResolver().notifyChange(inserturi,null);
- return inserturi;
- }
-
- /**
- * 数据查询操作
- */
- public Cursor queryDao(String[] whichone, String selection, String[] selectionArgs, String sortOrder) {
- return database.query("student",whichone,selection,selectionArgs, null,null,sortOrder);
- }
- }
(3)新建自定义的ContentProvider类,代码如下:
- import android.content.ContentProvider;
- import android.content.ContentValues;
- import android.database.Cursor;
- import android.net.Uri;
-
- import androidx.annotation.NonNull;
- import androidx.annotation.Nullable;
-
- /**
- * MyContentProvider 自定义内容提供者类
- *
- * @author baorant
- */
- public class MyContentProvider extends ContentProvider {
- private MyDataBase myDataBase;
-
- @Override
- public String getType(Uri uri) {
- return "1";
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return myDataBase.insertDao(values);
- }
-
- @Override
- public boolean onCreate() {
- myDataBase =new MyDataBase(this.getContext());
- return false;
- }
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
- return myDataBase.queryDao(projection,selection,selectionArgs,sortOrder);
- }
-
- @Override
- public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) {
- return 0;
- }
- }
(4)manifest文件中配置自定义的contentProvider类,代码如下:
- <provider
- android:name=".MyContentProvider"
- android:authorities="com.baorant.provider.MyContentProvider"
- android:enabled="true"
- android:exported="true">
- </provider>
到此为止,contentProvider内容提供方的代码基本OK,我们下面一起看下内容访问者APP的代码。
(1)manifest文件中对要访问的APP的包名进行一个query权限的配置,代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <manifest xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:tools="http://schemas.android.com/tools">
- <queries>
- <package android:name="com.baorant.providerapplication"/>
- </queries>
- ...
(2)新建activity执行contentProvider的访问操作,代码如下:
- import androidx.appcompat.app.AppCompatActivity;
-
- import android.annotation.SuppressLint;
- import android.content.ContentResolver;
- import android.content.ContentValues;
- import android.database.Cursor;
- import android.net.Uri;
- import android.os.Bundle;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.TextView;
-
- /**
- * @author baorant
- */
- public class MainActivity extends AppCompatActivity {
- private final StringBuffer stringBuffer = new StringBuffer();
- Button resovlerQueryBtn;
- Button resovlerInsertBtn;
- TextView resovlerText;
-
- final int[] count = {0};
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
-
- resovlerQueryBtn = findViewById(R.id.queryBtn);
- resovlerInsertBtn = findViewById(R.id.insertBtn);
- resovlerText = findViewById(R.id.text);
-
- ContentResolver resolver = getContentResolver();
- ContentValues values = new ContentValues();
- values.put("name", "sb");
- values.put("age", "20");
-
- Uri uri = Uri.parse("content://com.baorant.provider.MyContentProvider/student");
-
- resovlerQueryBtn.setOnClickListener(v -> {
- Cursor cursor = resolver.query(uri, null, null, null, null);
- // 清除之前的数据
- stringBuffer.delete(0, stringBuffer.toString().length());
- while (cursor.moveToNext()) {
- @SuppressLint("Range") String name = cursor.getString(cursor.
- getColumnIndex("name"));
- @SuppressLint("Range") int age = cursor.getInt(cursor.
- getColumnIndex("age"));
- @SuppressLint("Range") int id = cursor.getInt(cursor.
- getColumnIndex("id"));
- Log.d("db", "id=" + id + "|name=" + name + "|age=" + age);
- stringBuffer.append("id=").append(id).append("|name=").append(name).append("|age=").append(age);
- }
- resovlerText.setText(stringBuffer.toString());
- }
- );
-
- ContentValues contentValues = new ContentValues();
- resovlerInsertBtn.setOnClickListener(v -> {
- // 先清空之前已经插入的数据
- contentValues.clear();
- contentValues.put("name", "name" + count[0]);
- contentValues.put("age", count[0]);
- count[0]++;
- resolver.insert(uri, contentValues);
- });
- }
- }
(3)activity对应的layout布局文件,代码如下:
- <?xml version="1.0" encoding="utf-8"?>
- <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:app="http://schemas.android.com/apk/res-auto"
- xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- tools:context=".MainActivity">
-
- <TextView
- android:id="@+id/text"
- android:layout_margin="10dp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:text="resolver text!"
- app:layout_constraintTop_toTopOf="parent" />
-
- <Button
- android:id="@+id/queryBtn"
- android:layout_margin="10dp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:text="查询结果!"
- app:layout_constraintTop_toBottomOf="@id/text" />
-
- <Button
- android:id="@+id/insertBtn"
- android:layout_margin="10dp"
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:gravity="center_horizontal"
- android:text="插入一条数据!"
- app:layout_constraintTop_toBottomOf="@id/queryBtn" />
-
- </androidx.constraintlayout.widget.ConstraintLayout>
到此,内容提供方APP和内容访问方APP的代码基本OK,现在先运行内容提供方APP的代码,让内容提供方APP先跑起来。然后运行内容访问方APP的代码。内容访问方页面提供了两个按钮,一个用来查询,一个用来插入数,还有一个textView显示内容查询结果。我们点击几次插入按钮后,再点击查询按钮进行结果的查询,运行结果如下所示:
本文先初步介绍下contentProvider的基本使用,后面会继续介绍contentProvider的源码执行逻辑以及应用启动过程contentProvider的执行流程,有兴趣的同学可以进一步深入研究。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。