Android 应用间数据共享:使用 ContentProvider 实现 SQLite 数据库操作

本教程将展示如何使用 ContentProvider 在 Android 应用程序之间共享 SQLite 数据库数据。我们将创建两个应用程序:

  • 应用 A (appa):包含 SQLite 数据库,其中有一个图书表,包含书名、作者、页数和价格等字段。应用 A 将创建 ContentProvider 以提供对数据库的访问接口。
  • 应用 B (appb):通过应用 A 的 ContentProvider 接口对数据库进行增删改查操作,并将操作结果实时显示在 ListView 或 RecyclerView 上。

三、实验要求

  1. 应用 A (appa) 及其界面:

    • 包含相应的数据库创建、增删改查等功能按钮,实现对应用 A 数据库图书表数据的相应操作。
    • 操作后结果以 Log 日志的方式输出。
  2. 应用 B (appb) 及其界面:

    • 包含增删改查等功能按钮,实现对应用 A 数据库图书表数据的相应操作。
    • 操作后结果以 ListView 或 RecyclerView 方式实时呈现在应用界面上。

应用 A 代码

  1. 创建数据库和图书表的 SQLiteOpenHelper 类:
public class BookDatabaseHelper extends SQLiteOpenHelper {
    private static final String DATABASE_NAME = "book.db";
    private static final int DATABASE_VERSION = 1;

    public BookDatabaseHelper(Context context) {
        super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
        db.execSQL("CREATE TABLE book (_id INTEGER PRIMARY KEY AUTOINCREMENT, title TEXT, author TEXT, pages INTEGER, price REAL)");
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
        db.execSQL("DROP TABLE IF EXISTS book");
        onCreate(db);
    }
}
  1. 创建内容提供器类:
public class BookProvider extends ContentProvider {
    private static final String AUTHORITY = "com.example.appa.bookprovider";
    private static final UriMatcher uriMatcher;
    private static final int BOOK_DIR = 0;
    private static final int BOOK_ITEM = 1;

    private static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.com.example.appa.book";
    private static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.com.example.appa.book";

    private BookDatabaseHelper dbHelper;

    static {
        uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
        uriMatcher.addURI(AUTHORITY, "book", BOOK_DIR);
        uriMatcher.addURI(AUTHORITY, "book/#", BOOK_ITEM);
    }

    @Override
    public boolean onCreate() {
        dbHelper = new BookDatabaseHelper(getContext());
        return true;
    }

    @Override
    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
        SQLiteDatabase db = dbHelper.getReadableDatabase();
        Cursor cursor = null;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                cursor = db.query("book", projection, selection, selectionArgs, null, null, sortOrder);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                cursor = db.query("book", projection, "_id = ?", new String[]{bookId}, null, null, sortOrder);
                break;
            default:
                break;
        }
        return cursor;
    }

    @Override
    public Uri insert(Uri uri, ContentValues values) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        Uri uriReturn = null;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
            case BOOK_ITEM:
                long newBookId = db.insert("book", null, values);
                uriReturn = Uri.parse("content://" + AUTHORITY + "/book/" + newBookId);
                break;
            default:
                break;
        }
        return uriReturn;
    }

    @Override
    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int updatedRows = 0;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                updatedRows = db.update("book", values, selection, selectionArgs);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                updatedRows = db.update("book", values, "_id = ?", new String[]{bookId});
                break;
            default:
                break;
        }
        return updatedRows;
    }

    @Override
    public int delete(Uri uri, String selection, String[] selectionArgs) {
        SQLiteDatabase db = dbHelper.getWritableDatabase();
        int deletedRows = 0;
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                deletedRows = db.delete("book", selection, selectionArgs);
                break;
            case BOOK_ITEM:
                String bookId = uri.getPathSegments().get(1);
                deletedRows = db.delete("book", "_id = ?", new String[]{bookId});
                break;
            default:
                break;
        }
        return deletedRows;
    }

    @Override
    public String getType(Uri uri) {
        switch (uriMatcher.match(uri)) {
            case BOOK_DIR:
                return CONTENT_TYPE;
            case BOOK_ITEM:
                return CONTENT_ITEM_TYPE;
            default:
                throw new IllegalArgumentException("Unknown URI: " + uri);
        }
    }
}
  1. 在 AndroidManifest.xml 中注册内容提供器:
<provider
    android:name=".BookProvider"
    android:authorities="com.example.appa.bookprovider"
    android:exported="true" />
  1. 在应用 A 的界面中添加相应的按钮和事件处理逻辑,实现对数据库的增删改查操作:
public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    private Button insertButton;
    private Button updateButton;
    private Button deleteButton;
    private Button queryButton;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        insertButton = findViewById(R.id.insert_button);
        updateButton = findViewById(R.id.update_button);
        deleteButton = findViewById(R.id.delete_button);
        queryButton = findViewById(R.id.query_button);

        insertButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                insertData();
            }
        });

        updateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateData();
            }
        });

        deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                deleteData();
            }
        });

        queryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                queryData();
            }
        });
    }

    private void insertData() {
        Uri uri = Uri.parse("content://com.example.appa.bookprovider/book");
        ContentValues values = new ContentValues();
        values.put("title", "Book A");
        values.put("author", "Author A");
        values.put("pages", 100);
        values.put("price", 10.99);
        Uri newUri = getContentResolver().insert(uri, values);
        Log.d(TAG, "insertData: " + newUri.toString());
    }

    private void updateData() {
        Uri uri = Uri.parse("content://com.example.appa.bookprovider/book/1");
        ContentValues values = new ContentValues();
        values.put("price", 9.99);
        int updatedRows = getContentResolver().update(uri, values, null, null);
        Log.d(TAG, "updateData: " + updatedRows);
    }

    private void deleteData() {
        Uri uri = Uri.parse("content://com.example.appa.bookprovider/book/1");
        int deletedRows = getContentResolver().delete(uri, null, null);
        Log.d(TAG, "deleteData: " + deletedRows);
    }

    private void queryData() {
        Uri uri = Uri.parse("content://com.example.appa.bookprovider/book");
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        if (cursor != null) {
            while (cursor.moveToNext()) {
                String title = cursor.getString(cursor.getColumnIndex("title"));
                String author = cursor.getString(cursor.getColumnIndex("author"));
                int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                double price = cursor.getDouble(cursor.getColumnIndex("price"));
                Log.d(TAG, "queryData: " + title + " - " + author + " - " + pages + " - " + price);
            }
            cursor.close();
        }
    }
}

应用 B 代码

  1. 创建 ListView 或 RecyclerView 的布局文件,例如 activity_main.xml。

  2. 在应用 B 的界面中添加相应的按钮和事件处理逻辑,实现对应用 A 数据库图书表数据的增删改查操作,并将操作后的结果实时显示在 ListView 或 RecyclerView 上:

public class MainActivity extends AppCompatActivity {
    private static final String TAG = "MainActivity";

    private ListView listView;
    private Button insertButton;
    private Button updateButton;
    private Button deleteButton;
    private Button queryButton;

    private ArrayAdapter<String> adapter;
    private List<String> bookList = new ArrayList<>();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        listView = findViewById(R.id.list_view);
        insertButton = findViewById(R.id.insert_button);
        updateButton = findViewById(R.id.update_button);
        deleteButton = findViewById(R.id.delete_button);
        queryButton = findViewById(R.id.query_button);

        adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, bookList);
        listView.setAdapter(adapter);

        insertButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                insertData();
            }
        });

        updateButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                updateData();
            }
        });

        deleteButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                deleteData();
            }
        });

        queryButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                queryData();
            }
        });
    }

    private void insertData() {
        Uri uri = Uri.parse("content://com.example.appa.bookprovider/book");
        ContentValues values = new ContentValues();
        values.put("title", "Book B");
        values.put("author", "Author B");
        values.put("pages", 200);
        values.put("price", 20.99);
        Uri newUri = getContentResolver().insert(uri, values);
        Log.d(TAG, "insertData: " + newUri.toString());
    }

    private void updateData() {
        Uri uri = Uri.parse("content://com.example.appa.bookprovider/book/2");
        ContentValues values = new ContentValues();
        values.put("price", 19.99);
        int updatedRows = getContentResolver().update(uri, values, null, null);
        Log.d(TAG, "updateData: " + updatedRows);
    }

    private void deleteData() {
        Uri uri = Uri.parse("content://com.example.appa.bookprovider/book/2");
        int deletedRows = getContentResolver().delete(uri, null, null);
        Log.d(TAG, "deleteData: " + deletedRows);
    }

    private void queryData() {
        Uri uri = Uri.parse("content://com.example.appa.bookprovider/book");
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);
        if (cursor != null) {
            bookList.clear();
            while (cursor.moveToNext()) {
                String title = cursor.getString(cursor.getColumnIndex("title"));
                String author = cursor.getString(cursor.getColumnIndex("author"));
                int pages = cursor.getInt(cursor.getColumnIndex("pages"));
                double price = cursor.getDouble(cursor.getColumnIndex("price"));
                bookList.add(title + " - " + author + " - " + pages + " - " + price);
            }
            adapter.notifyDataSetChanged();
            cursor.close();
        }
    }
}

总结

以上代码示例展示了如何使用 ContentProvider 在 Android 应用程序之间共享 SQLite 数据库数据。应用 A 提供数据访问接口,应用 B 通过接口访问数据并进行操作。该方法可以方便地实现跨应用程序的数据共享,提升应用程序的灵活性和可扩展性。

注意: 应用 A 和应用 B 需要在同一个设备上安装和运行,且应用 A 先于应用 B 运行。

更多信息:

希望本教程能够帮助您理解并应用 ContentProvider 实现 Android 应用间的数据共享!

Android 应用间数据共享:使用 ContentProvider 实现 SQLite 数据库操作

原文地址: http://www.cveoy.top/t/topic/dl2 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录