【重生之我在学Android原生】ContentProvider(Java)

本文详细介绍了如何在Android应用中使用ContentProvider与SQLite数据库进行数据共享,包括创建DatabaseHelper、定义ContentProvider的insert和query方法,以及在其他应用中访问数据的过程。
摘要由CSDN通过智能技术生成

相关文章

【重生之我在学Android原生】ContentProvider(Java)
【重生之我在学Android原生】Media3

ContentProvider

参考资料

参考资料
官方文档

ContentProvider 和 SqliteDataBase

实现效果

【1】Content Provider + Sqlite Database 共享数据
【2】APP可以访问另一个APP的Provider

创建

Empty View Activity
在这里插入图片描述
在这里插入图片描述

创建ContentProvider

在这里插入图片描述
在这里插入图片描述

创建DatabaseHelper

创建表存储

package com.test.contentproviderexample;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

import androidx.annotation.Nullable;

public class DatabaseHelper extends SQLiteOpenHelper {
    static final String DATABASE_NAME = "UserDB";
    static final String TABLE_NAME = "Users";
    static final int DATABASE_VERSION = 1;

    static final String CREATE_DB_TABLE = "CREATE TABLE " + TABLE_NAME
            + " (id INTEGER PRIMARY KEY AUTOINCREMENT, "
            + " name TEXT NOT NULL);";

    public DatabaseHelper(@Nullable Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL(CREATE_DB_TABLE);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS " + TABLE_NAME);
    }
}

new 一个 database

@Override
    public boolean onCreate() {
        Context context = getContext();
        DatabaseHelper databaseHelper = new DatabaseHelper(context);
        db = databaseHelper.getWritableDatabase();
        return false;
    }

构建界面

<?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">

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dp"
            android:layout_marginBottom="70dp"
            android:fontFamily="sans-serif"
            android:text="@string/heading"
            android:textAlignment="center" />

        <EditText
            android:id="@+id/textName"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:layout_marginBottom="40dp"
            android:autofillHints=""
            android:fontFamily="@font/"
            android:hint="@string/hint_text"
            android:inputType="text|textMultiLine"
            android:minHeight="48dp"
            android:textColorHint="#546E7A" />

        <Button
            android:id="@+id/insertButton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="20dp"
            android:layout_marginBottom="20dp"
            android:background="#F44336"
            android:onClick="onClickAddDetails"
            android:text="@string/insertButtonText"
            android:textAlignment="center"
            android:textStyle="bold" />

        <Button
            android:id="@+id/loadButton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="20dp"
            android:layout_marginBottom="20dp"
            android:background="#F44336"
            android:onClick="onClickShowDetail"
            android:text="@string/load_text"
            android:textAlignment="center"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/res"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:clickable="false"
            android:ems="10"
            android:fontFamily="sans-serif"
            android:textColor="@android:color/holo_green_dark"
            android:textSize="18sp"
            android:textStyle="bold" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

插入数据

定义URL

    static final String authorities = "com.contentprovider.example";
    static final String URL = "content://" + authorities + "/users";
    static final Uri CONTENT_URI = Uri.parse(URL);
    static final String name = "name";

在contentProvider中重写insert方法

    @Override
    public Uri insert(@NonNull Uri uri, ContentValues values) {
        final long rowId = db.insert(DatabaseHelper.TABLE_NAME, null, values);
        if (rowId > 0) {
            Uri _uri = ContentUris.withAppendedId(uri, rowId);
            Objects.requireNonNull(getContext()).getContentResolver().notifyChange(_uri, null);
            return _uri;
        }
        throw new SQLiteException("Failed to add a record into " + uri);
    }

在MainActivity.java中定义插入方法

    public void onClickAddDetails(View view) {
        EditText editText = findViewById(R.id.textName);
        String text = editText.getText().toString();
        ContentValues values = new ContentValues();
        values.put(MyContentProvider.name, text);
        getContentResolver().insert(MyContentProvider.CONTENT_URI, values);
        Toast.makeText(this, "insert text", Toast.LENGTH_LONG).show();
    }

测试插入数据

在这里插入图片描述
在这里插入图片描述
运行过程:
【1】DatabaseHelper 创建了数据库UserDB
【2】利用MyContentProvider重写insert方法
在这里插入图片描述
【3】MainActivity点击insert
在这里插入图片描述

查询数据

重写ContentProvider - query方法

@Override
    public Cursor query(@NonNull Uri uri, String[] prxojection, String selection,
                        String[] selectionArgs, String sortOrder) {
        SQLiteQueryBuilder builder = new SQLiteQueryBuilder();
        builder.setTables(DatabaseHelper.TABLE_NAME);
        Cursor cursor = builder.query(db, prxojection, selection, selectionArgs, null, null, sortOrder);
        ContentResolver provider = Objects.requireNonNull(getContext()).getContentResolver();
        cursor.setNotificationUri(provider, uri);
        return cursor;
    }

定义MainActivity的查询方法

    public void onClickShowDetail(View view) {
        Cursor cursor = getContentResolver().query(MyContentProvider.CONTENT_URI, null, null, null, null);
        TextView res = findViewById(R.id.res);
        StringBuilder builder = new StringBuilder();
        if (cursor != null && cursor.moveToFirst()) {
            do {
                int iName = cursor.getColumnIndex(DatabaseHelper.COLUMN_NAME);
                int iId = cursor.getColumnIndex(DatabaseHelper.COLUMN_ID);
                String name = cursor.getString(iName);
                String id = cursor.getString(iId);
                builder.append("\n").append(id).append(" - ").append(name);
            } while (cursor.moveToNext());
        }
        res.setText(builder.toString());
    }

测试查询数据

在这里插入图片描述
在这里插入图片描述

共享数据

创建另一个应用,通过provider可以访问到之前创建的应用的数据

构建界面

<?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">

    <LinearLayout
        android:id="@+id/linearLayout"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginBottom="338dp"
        android:orientation="vertical"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent">

        <TextView
            android:id="@+id/textView"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginTop="40dp"
            android:layout_marginBottom="70dp"
            android:fontFamily="sans-serif"
            android:text="@string/heading"
            android:textAlignment="center" />

        <Button
            android:id="@+id/loadButton"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginTop="10dp"
            android:layout_marginEnd="20dp"
            android:layout_marginBottom="20dp"
            android:background="#F44336"
            android:onClick="onClickShowDetails"
            android:text="@string/load_text"
            android:textAlignment="center"
            android:textStyle="bold" />

        <TextView
            android:id="@+id/res"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_marginStart="20dp"
            android:layout_marginEnd="20dp"
            android:clickable="false"
            android:ems="10"
            android:fontFamily="sans-serif"
            android:textColor="@android:color/holo_green_dark"
            android:textSize="18sp"
            android:textStyle="bold" />

    </LinearLayout>

</androidx.constraintlayout.widget.ConstraintLayout>

在这里插入图片描述

定义查询方法

复制之前定义的查询方法,但是在另一个新的应用中

public void onClickShowDetails(View view) {
        Cursor cursor = getContentResolver().query(CONTENT_URI, null, null, null, null);
        TextView res = findViewById(R.id.res);
        StringBuilder builder = new StringBuilder();
        if (cursor != null && cursor.moveToFirst()) {
            do {
                int iName = cursor.getColumnIndex(COLUMN_NAME);
                int iId = cursor.getColumnIndex(COLUMN_ID);
                String name = cursor.getString(iName);
                String id = cursor.getString(iId);
                builder.append("\n").append(id).append(" - ").append(name);
            } while (cursor.moveToNext());
        }
        res.setText(builder.toString());
    }

AndroidManifest定义queries

在AndroidMainifest.xml中添加

    <queries>
        <provider android:authorities="com.contentprovider.example"/>
    </queries>

authorities需要与之前定义的一致
获取的一方
在这里插入图片描述
之前定义的provider,提供的一方
在这里插入图片描述

运行测试

在这里插入图片描述
获取到另一个应用定义的contentProvider中的数据

相关概念

参考官方文档

URL格式

  • content:// 固定在前面
  • authority 中间是程序的授权标志
  • table 表名
  • 18
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sheng_er_sheng

打赏是什么?好吃么

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值