相关文章
【重生之我在学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 表名