一:创立主界面增删改查

/** * @author zhiqiangRuan * @ClassName * @Date  2022/7/4 */class FiveActivity : BaseActivity(), View.OnClickListener {    lateinit var addData: Button    lateinit var deleteData: Button    lateinit var queryData: Button    lateinit var updataData: Button    var bookId: String? = null    override fun initView() {        addData = findViewById<Button>(R.id.add_data)        deleteData = findViewById<Button>(R.id.delete_data)        queryData = findViewById<Button>(R.id.query_data)        updataData = findViewById<Button>(R.id.update_data)        addData.setOnClickListener(this)        deleteData.setOnClickListener(this)        queryData.setOnClickListener(this)        updataData.setOnClickListener(this)    }    override fun initData() {    }    override fun getLayoutId(): Int {        return R.layout.activity_five    }    override fun onClick(v: View?) {        when (v?.id) {            R.id.add_data -> {                //增加数据                val uri = Uri.parse("content://com.cnstrong.leke.helloworld.provider/book")                val values = contentValuesOf(                    "author" to "George Martin",                    "price" to 22.85,                    "pages" to 1040,                    "name" to "A Clash of King"                )                val newUri = contentResolver.insert(uri, values)                bookId = newUri?.pathSegments?.get(1)            }            /**             * apply函数扩大了所有的泛型对象,在闭包范畴内能够任意调用该对象的任意办法,并在最初返回该对象.            次要的作用:是能够用来简化初始化对象的性能。            特地须要留神的是apply函数中示意对象自身应用的是this关键字而不是it。*/            R.id.query_data -> {                //查问数据                val uri = Uri.parse("content://com.cnstrong.leke.helloworld.provider/book")                contentResolver.query(uri, null, null, null, null)?.apply {                    while (moveToNext()) {                        val name = getString(getColumnIndex("name"))                        val author = getString(getColumnIndex("author"))                        val pages = getInt(getColumnIndex("pages"))                        val price = getDouble(getColumnIndex("price"))                        Log.d("FiveActivity", "book name is $name")                        Log.d("FiveActivity", "book author is $author")                        Log.d("FiveActivity", "book pages is $pages")                        Log.d("FiveActivity", "book price is $price")                    }                    close()                }            }            R.id.update_data -> {                //更新数据                bookId?.let {                    val uri = Uri.parse("content://com.cnstrong.leke.helloworld.provider/book/$it")                    val values = contentValuesOf(                        "name" to "A Storm of Swords",                        "pages" to 1216,                        "price" to 24.05                    )                    contentResolver.update(uri,values,null,null)                }            }            R.id.delete_data->{                bookId?.let{                    val uri = Uri.parse("content://com.cnstrong.leke.helloworld.provider/book/$it")                    contentResolver.delete(uri,null,null)                }            }        }    }}


二:Xml文件

<?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical">    <Button        android:id="@+id/add_data"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Add To Book" />    <Button        android:id="@+id/query_data"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Query From Book" />    <Button        android:id="@+id/update_data"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Update Book" />    <Button        android:id="@+id/delete_data"        android:layout_width="match_parent"        android:layout_height="wrap_content"        android:text="Delete From Book" /></LinearLayout>

三:自定义的MyProvider

package com.cnstrong.leke.helloworldimport android.content.ContentProviderimport android.content.ContentValuesimport android.content.UriMatcherimport android.net.Uriimport java.lang.RuntimeException/** * @author zhiqiangRuan * @ClassName 自定义ContentProvider * @Date  2022/7/4 */class MyProvider : ContentProvider() {    private val bookDir = 0    private val bookItem = 1    private val categoryDir = 2    private val categoryItem = 3    /**     * 每一个ContentProvider定义惟一标识URI  URI*/    private var dbHelper: MySqliteDataHelper? = null    private val authority = "com.cnstrong.leke.helloworld.provider"    /**UriMatcher实质上是一个文本过滤器,用在contentProvider中帮忙咱们过滤,分辨出查问者想要查问哪个数据表。*/    private val uriMatcher by lazy {        //常量UriMatcher.NO_MATCH示意不匹配任何门路的返回码        val mathcher = UriMatcher(UriMatcher.NO_MATCH)        //如果match()办法匹配content://com.cnstrong.leke.helloworld.provider/book门路,返回匹配码为1        mathcher.addURI(authority, "book", bookDir)        //如果match()办法匹配content://com.cnstrong.leke.helloworld.provider/book/通配符 门路,返回匹配码为2        mathcher.addURI(authority, "book/#", bookItem)        mathcher.addURI(authority, "category", categoryDir)        mathcher.addURI(authority, "category/#", categoryItem)        mathcher    }    /**创立数据*/    /**     * override fun onCreate(): Boolean {    dbHelper = context?.let {    MySqliteDataHelper(it, "BookStore.db", 1)    return true    }    return false    ------------------------------    这里用到了Kotlin let操作符    obj.let{} 或obj?.let{}    第一种写法,如果确定obj不为null,能够应用,    第二种写法相当于java的非空判断,当obj不为空时,才执行大括号内的代码段,绝对java的空判断来说简洁一些,值得应用。    //在函数体内应用it代替object对象去拜访其私有的属性和办法    } */    override fun onCreate() = context?.let {        MySqliteDataHelper(it, "BookStore.db", 1)        true    } ?: false    /**查问数据*/    override fun query(        uri: Uri,        projection: Array<out String>?,        selection: String?,        selectionArgs: Array<out String>?,        sortOrder: String?    ) = dbHelper?.let {        //查问数据        val db = it.writableDatabase        val cursor = when (uriMatcher.match(uri)) {            bookDir -> db.query("Book", projection, selection, selectionArgs, null, null, sortOrder)            bookItem -> {                val bookId = uri.pathSegments[1]                db.query("Book", projection, "id=?", arrayOf(bookId), null, null, sortOrder)            }            categoryDir -> db.query(                "Category",                projection,                selection,                selectionArgs,                null,                null,                sortOrder            )            categoryItem -> {                val categoryId = uri.pathSegments[1]                db.query("Category", projection, "id=?", arrayOf(categoryId), null, null, sortOrder)            }            else->null        }        cursor    }    /**     * 失去数据类型*/    override fun getType(uri: Uri) = when (uriMatcher.match(uri)) {        bookDir -> "vnd.android.cursor.dir/vnd.com.cnstrong.leke.helloworld.provider.book"        bookItem -> "vnd.android.cursor.item/vnd.com.cnstrong.leke.helloworld.provider.book"        categoryDir -> "vnd.android.cursor.dir/vnd.com.cnstrong.leke.helloworld.provider.category"        categoryItem -> "vnd.android.cursor.item/vnd.com.cnstrong.leke.helloworld.provider.category"        else -> null    }    /**插入数据     *     *  override fun insert(uri: Uri, values: ContentValues?): Uri? {    //获取到SQLiteDatabase 对象    val db = dbHelper?.writableDatabase    val uriReturn = when (uriMatcher.match(uri)) {    bookDir, bookItem -> {    val newBookId = db?.insert("Book", null, values)    Uri.parse("content://$authority/book/$newBookId")    }    categoryDir, categoryItem -> {    val newCategoryId = db?.insert("Category", null, values)    Uri.parse("content://$authority/category/$newCategoryId")    }    else -> null    }    return uriReturn    }*/    override fun insert(uri: Uri, values: ContentValues?) = dbHelper?.let {        //获取到SQLiteDatabase 对象        val db = it.writableDatabase        val uriReturn = when (uriMatcher.match(uri)) {            bookDir, bookItem -> {                val newBookId = db.insert("Book", null, values)                Uri.parse("content://$authority/book/$newBookId")            }            categoryDir, categoryItem -> {                val newCategoryId = db.insert("Category", null, values)                Uri.parse("content://$authority/category/$newCategoryId")            }            else ->null        }        uriReturn    }    /**删除数据*/    override fun delete(uri: Uri, selection: String?, selectionArgs: Array<out String>?) =        dbHelper?.let {            //删除数据            val db = it.writableDatabase            val deleteRows = when (uriMatcher.match(uri)) {                bookDir -> db.delete("Book", selection, selectionArgs)                bookItem -> {                    //筛选条件参数                    val bookId = uri.pathSegments[1]                    db.delete("Book", "id=?", arrayOf(bookId))                }                categoryDir -> db.delete("Category", selection, selectionArgs)                categoryItem -> {                    val categoryId = uri.pathSegments[1]                    db.delete("Category", "id=?", arrayOf(categoryId))                }                else -> 0            }            deleteRows        } ?: 0    /**更新数据*/    override fun update(        uri: Uri,        values: ContentValues?,        selection: String?,        selectionArgs: Array<out String>?    ) = dbHelper?.let {        val db = it.writableDatabase        val updateRows = when (uriMatcher.match(uri)) {            bookDir -> db.update("Book", values, selection, selectionArgs)            bookItem -> {                val bookId = uri.pathSegments[1]                db.update("Book", values, "id=?", arrayOf(bookId))            }            categoryDir -> db.update("Category", values, selection, selectionArgs)            categoryItem -> {                val categoryId = uri.pathSegments[1]                db.update("Category", values, "id=?", arrayOf(categoryId))            }            else -> 0        }        updateRows    } ?: 0}

四:MySqliteDataHelper 数据库创立的帮忙类

package com.cnstrong.leke.helloworldimport android.content.Contextimport android.database.sqlite.SQLiteDatabaseimport android.database.sqlite.SQLiteOpenHelperimport android.widget.Toast/** * @author zhiqiangRuan * @ClassName * kotlin 构造函数 参数 * val context: Context 上下文 * name: String  数据库名,库名 xxx.db * version: Int 版本号,用来数据库降级的 * @Date  2022/7/4 */class MySqliteDataHelper(val context: Context, name: String, version: Int) :    SQLiteOpenHelper(context, name, null, version) {    private val book = "create table Book( " +            "id integer primary key autoincrement," +            "author text," +            "price real," +            "pages integer," +            "name text)"    private val category = "create table Category( " +            "id integer primary key autoincrement," +            "category_name text," +            "category_code integer)"    /**应用SQliteDatabase创立数据表     *     * 1.这个办法,第一次关上数据库时候才会走     * 2.在革除数据之后再一次运行-->关上数据库,这个办法会走     * 3.没有革除数据,不会走这个办法     * 4.数据库降级的时候这个办法不会走     * */    override fun onCreate(db: SQLiteDatabase?) {        db?.execSQL(book)        db?.execSQL(category)        Toast.makeText(context, "create books success", Toast.LENGTH_SHORT).show()    }    /**     * 1.第一次创立数据库的时候,这个办法不会走     *     *2.革除数据再次运行(相当于第一次创立)这个办法不会走     *     * 3.数据库曾经存在,而且版本升高的时候,这个办法才会调用*/    override fun onUpgrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {        //依据版本号判断        if (oldVersion <= 1) {            db?.execSQL("alter table Book add column category_id")        }    }    /**这个办法是数据库降级操作     *     * 1.新版本比旧版本低时候才会执行     *     * 2.如果不执行降级操作会抛出异样*/    override fun onDowngrade(db: SQLiteDatabase?, oldVersion: Int, newVersion: Int) {        super.onDowngrade(db, oldVersion, newVersion)    }}

五:MyProvider的AndroidManifest配置

<?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.cnstrong.leke.helloworld">    <uses-permission android:name="android.permission.INTERNET" />    <uses-permission android:name="android.permission.READ_CONTACTS" />    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>    <application        android:allowBackup="true"        android:icon="@mipmap/ic_launcher"        android:label="@string/app_name"        android:roundIcon="@mipmap/ic_launcher_round"        android:supportsRtl="true"        android:theme="@style/Theme.MyApplication"        android:usesCleartextTraffic="true">        <activity android:name=".FiveActivity">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <activity android:name=".FirstActivity" />        <activity            android:name=".ThirdActivity"            android:screenOrientation="landscape" />        <provider            android:name=".MyProvider"            android:authorities="com.cnstrong.leke.helloworld.provider"            android:enabled="true"            android:exported="true">        </provider>    </application></manifest>

六:遇到的问题

不晓得什么起因,有大神晓得吗,须要领导一下