一:创立主界面增删改查
/** * @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>
六:遇到的问题
不晓得什么起因,有大神晓得吗,须要领导一下