当前位置:   article > 正文

Android之自定义ContentProvider的实现(Very Very 用心)_expected to find a valid contentprovider for this

expected to find a valid contentprovider for this authority

刚开始学习ContentProvider时是学的系统的ContentProvider,没碰到什么问题,但是在学习自定义ContentProvider的实现时,唉,碰到好几个问题,花了我好多时间。

 

我碰到的问题:

1.  java.lang.IllegalArgumentException: column '_id' does not exist

解决方法:创建数据表时插入一个名为_id的列,类型为自增量,因为在使用Cursor相关的Adapter时需要用到这个列

2.Failed to find provider <authority> for user 0 ; expected to find a valid ContentProvider for

解决方法:在第一个应用的AndroidManifest.xml中添加如下代码

  1. <provider
  2. android:authorities="cn.sch.myprovider"
  3. android:name=".MyProvide"
  4. android:exported="true"
  5. android:multiprocess="false"
  6. android:grantUriPermissions="true"
  7. android:writePermission="cn.sch.myprovider.Write"
  8. android:readPermission="cn.sch.myprovider.Read"
  9. >
  10. </provider>

但是当我使用API 30时却还是会报错,报空指针异常,到现在还没解决,真的菜啊,所以为了让程序运行起来,我就选择API 29 ,就能正常运行了

3.注意:在数据库类里写sql语句时,最容易出错,比如少了空格拼接起来就是错误的sql语句,英文逗号写成中文逗号,进行增删改查时表名,列名要写正确

4.Uri里的authorities也非常容易搞错,搞错了就会报 uri 找不到异常

5.还有很多小问题就不一一描述了,细心认真点,相信你们自己能解决

为了让你们(新手,包括我自己)能正确的运行起我的程序来,我把所有类,布局文件和配置信息都贴出来。如果你去看别人写的自定义ContentProvider的实现,你会发现有这几个问题,不敢说全部,大多数是这样,自定义ContentProvider的实现本来就是面向新手的,所以把信息都写全来才好去学习和模仿加创新。

1.缺少布局文件,对于我这种小白来说真的就离谱,id都不知道哪个是哪个

2.缺少一些类,不如数据库类。

3.只贴出一些重要代码片段来,对于小白来说,的确不好搞

4.缺少配置信息,这只能看看,要想模仿就难了,一大堆BUG等着你

5.完整的源码要VIP或者收费

项目里的代码详解我就不说了,大多数都有解释,实在不懂的,可以自行百度,肯定比我在这说的清楚详细易懂,我这篇给文章主要还是让各位实现自定义ContentProvider,能跑起来

先来看看我效果

20211021

注意:视频中的删除我是按序号删除的,比如表中有一条记录:

序号:1  姓名:小明  工作:Android Development

然后我在输入框中输入,只要序号是1,不管姓名和工作输的是什么,都会将

序号:1  姓名:小明  工作:Android Development 这条记录删除。

(感兴趣的可以自己去改改)

首先看一下我的项目结构,你就知道要写哪些类和布局文件了

 

模块gamedemo是第一个应用

MainActivity代码如下

  1. import android.app.Activity;
  2. import android.content.ContentResolver;
  3. import android.content.ContentValues;
  4. import android.database.Cursor;
  5. import android.database.sqlite.SQLiteDatabase;
  6. import android.net.Uri;
  7. import android.os.Bundle;
  8. import android.text.TextUtils;
  9. import android.view.View;
  10. import android.widget.Button;
  11. import android.widget.EditText;
  12. import android.widget.TextView;
  13. import android.widget.Toast;
  14. public class MainActivity extends Activity implements View.OnClickListener {
  15. private static final String TAG = "lzs";
  16. private DbHelp dbHelp;
  17. private SQLiteDatabase db;
  18. private TextView userTv;
  19. private Button btn_query;
  20. private Button btn_insert;
  21. private Button btn_delete;
  22. private Button btn_update;
  23. private int m=2;
  24. private int n=3;
  25. private EditText xuhao;
  26. private EditText xingming;
  27. private EditText zhiye;
  28. private int id;
  29. private String name;
  30. private String job;
  31. @Override
  32. protected void onCreate(Bundle savedInstanceState) {
  33. super.onCreate(savedInstanceState);
  34. setContentView(R.layout.activity_main);
  35. this.dbHelp = new DbHelp(this); //创建数据库
  36. this.db = this.dbHelp.getWritableDatabase();
  37. init(); //初始化控件
  38. }
  39. private void init() {
  40. btn_query = findViewById(R.id.btn_query);
  41. btn_insert = findViewById(R.id.btn_insert);
  42. btn_delete = findViewById(R.id.btn_delete);
  43. btn_update = findViewById(R.id.btn_update);
  44. xuhao = findViewById(R.id.xuhao);
  45. xingming = findViewById(R.id.xingming);
  46. zhiye = findViewById(R.id.zhiye);
  47. btn_query.setOnClickListener(this);
  48. btn_insert.setOnClickListener(this);
  49. btn_delete.setOnClickListener(this);
  50. btn_update.setOnClickListener(this);
  51. }
  52. @Override
  53. protected void onStart() {
  54. super.onStart();
  55. }
  56. @Override
  57. protected void onDestroy() {
  58. super.onDestroy();
  59. db.close();
  60. dbHelp.close();
  61. }
  62. @Override
  63. public void onClick(View view) {
  64. switch (view.getId()){
  65. case R.id.btn_query:
  66. btn_query();
  67. break;
  68. case R.id.btn_insert:
  69. btn_insert();
  70. break;
  71. case R.id.btn_delete:
  72. btn_delete();
  73. break;
  74. case R.id.btn_update:
  75. btn_update();
  76. break;
  77. }
  78. }
  79. //查询函数
  80. private void btn_query(){
  81. Cursor user = this.db.query("user", null, null, null, null, null, null);
  82. this.userTv = findViewById(R.id.id_user_db);
  83. //清空文本,防止重复查询而多次显示
  84. if(!TextUtils.isEmpty(this.userTv.getText()))
  85. {
  86. this.userTv.setText("");
  87. }
  88. while (user.moveToNext()){
  89. String id = user.getString(0);
  90. String name = user.getString(1);
  91. String jobs = user.getString(2);
  92. this.userTv.append("序号:"+id+" 姓名:"+name+" 工作:"+jobs+"\n");
  93. }
  94. }
  95. //插入函数(没有用SQL语句,用的是Android的方式)
  96. private void btn_insert(){
  97. if(!TextUtils.isEmpty(xuhao.getText())&&!TextUtils.isEmpty(xingming.getText())&&!TextUtils.isEmpty(zhiye.getText())){
  98. id = Integer.parseInt(xuhao.getText().toString());
  99. name = xingming.getText().toString();
  100. job = zhiye.getText().toString();
  101. Cursor result=db.rawQuery("select * from user where _id = "+id,null);
  102. if(!result.isAfterLast()){
  103. Toast.makeText(MainActivity.this,"插入失败,改记录已存在或序号重复!",Toast.LENGTH_SHORT).show();
  104. }else {
  105. Uri uri_user = Uri.parse("content://cn.sch.myprovider/user");
  106. // 向user表插入数据
  107. ContentValues values3 = new ContentValues();
  108. values3.put("_id", id);
  109. values3.put("name", name);
  110. values3.put("jobs", job);
  111. // 获取ContentResolver
  112. ContentResolver resolver3 = getContentResolver();
  113. // 通过ContentResolver 根据URI 向ContentProvider中插入数据
  114. resolver3.insert(uri_user, values3);
  115. Toast.makeText(MainActivity.this,"插入成功",Toast.LENGTH_SHORT).show();
  116. }
  117. }else {
  118. Toast.makeText(MainActivity.this,"请填写完整,不能为空!",Toast.LENGTH_SHORT).show();
  119. }
  120. }
  121. //删除函数(利用SQL语句删除,你也可以用Android的方式删除),因为序号是唯一的,所以直接根据提供的序号删除就可以了
  122. private void btn_delete(){
  123. if(!TextUtils.isEmpty(xuhao.getText())){
  124. id = Integer.parseInt(xuhao.getText().toString());
  125. Cursor result=db.rawQuery("select _id from user where _id="+id,null);
  126. if(!result.isAfterLast()){
  127. db.execSQL("delete from user where _id="+id);
  128. Toast.makeText(MainActivity.this,"删除成功",Toast.LENGTH_SHORT).show();
  129. }else {
  130. Toast.makeText(MainActivity.this,"删除失败,没有该条记录!",Toast.LENGTH_SHORT).show();
  131. }
  132. }else {
  133. Toast.makeText(MainActivity.this,"请填写完整,不能为空!",Toast.LENGTH_SHORT).show();
  134. }
  135. }
  136. //更新函数(利用SQL语句更新,你也可以用Android的方式更新),因为序号唯一,所以直接根据输入的序号更改就可以了
  137. private void btn_update(){
  138. if(!TextUtils.isEmpty(xuhao.getText())&&!TextUtils.isEmpty(xingming.getText())&&!TextUtils.isEmpty(zhiye.getText())){
  139. id = Integer.parseInt(xuhao.getText().toString());
  140. name = xingming.getText().toString();
  141. job = zhiye.getText().toString();
  142. Cursor result=db.rawQuery("select * from user where _id="+id,null);
  143. if(!result.isAfterLast()){
  144. db.execSQL("update user set _id="+id +" where _id="+id);
  145. db.execSQL("update user set name='"+name +"' where _id="+id);//注意是 set='name' 如果不清楚可以再去看看数据库的知识
  146. db.execSQL("update user set jobs='"+job +"' where _id="+id);
  147. Toast.makeText(MainActivity.this,"更新成功",Toast.LENGTH_SHORT).show();
  148. }else {
  149. Toast.makeText(MainActivity.this,"更新失败,改记录不存在!",Toast.LENGTH_SHORT).show();
  150. }
  151. }else {
  152. Toast.makeText(MainActivity.this,"请填写完整,不能为空!",Toast.LENGTH_SHORT).show();
  153. }
  154. }
  155. }

MainActivity的布局文件activity_main.xml 代码如下

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:orientation="vertical"
  8. android:gravity="center">
  9. <LinearLayout
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent"
  12. android:layout_weight="1"
  13. android:gravity="center"
  14. android:orientation="vertical">
  15. <TextView
  16. android:id="@+id/textView"
  17. android:layout_width="wrap_content"
  18. android:layout_height="wrap_content"
  19. android:layout_marginBottom="50dp"
  20. android:text="第一个应用"
  21. android:textSize="30dp"/>
  22. <TextView
  23. android:id="@+id/id_user_db"
  24. android:layout_width="wrap_content"
  25. android:layout_height="wrap_content"
  26. android:layout_marginBottom="250dp"
  27. android:text="" />
  28. </LinearLayout>
  29. <LinearLayout
  30. android:layout_width="match_parent"
  31. android:layout_height="match_parent"
  32. android:layout_weight="2"
  33. android:gravity="center"
  34. android:orientation="vertical">
  35. <EditText
  36. android:id="@+id/xuhao"
  37. android:layout_width="wrap_content"
  38. android:layout_height="wrap_content"
  39. android:ems="10"
  40. android:hint="请输入序号"
  41. android:inputType="number" />
  42. <EditText
  43. android:id="@+id/xingming"
  44. android:layout_width="wrap_content"
  45. android:layout_height="wrap_content"
  46. android:ems="10"
  47. android:hint="请输入姓名"
  48. android:inputType="textPersonName" />
  49. <EditText
  50. android:id="@+id/zhiye"
  51. android:layout_width="wrap_content"
  52. android:layout_height="wrap_content"
  53. android:ems="10"
  54. android:hint="请输入职业"
  55. android:inputType="textPersonName" />
  56. </LinearLayout>
  57. <LinearLayout
  58. android:layout_width="match_parent"
  59. android:layout_height="match_parent"
  60. android:layout_weight="2"
  61. android:orientation="vertical">
  62. <LinearLayout
  63. android:layout_width="match_parent"
  64. android:layout_height="match_parent"
  65. android:layout_weight="1"
  66. android:gravity="center"
  67. android:orientation="horizontal">
  68. <Button
  69. android:id="@+id/btn_query"
  70. android:layout_width="wrap_content"
  71. android:layout_height="wrap_content"
  72. android:layout_marginTop="20dp"
  73. android:text="查询数据" />
  74. <Button
  75. android:id="@+id/btn_insert"
  76. android:layout_width="wrap_content"
  77. android:layout_height="wrap_content"
  78. android:layout_marginLeft="20dp"
  79. android:layout_marginTop="20dp"
  80. android:text="插入数据" />
  81. </LinearLayout>
  82. <LinearLayout
  83. android:layout_width="match_parent"
  84. android:layout_height="match_parent"
  85. android:layout_weight="1"
  86. android:gravity="center_horizontal"
  87. android:orientation="horizontal">
  88. <Button
  89. android:id="@+id/btn_delete"
  90. android:layout_width="wrap_content"
  91. android:layout_height="wrap_content"
  92. android:text="删除数据" />
  93. <Button
  94. android:id="@+id/btn_update"
  95. android:layout_width="wrap_content"
  96. android:layout_height="wrap_content"
  97. android:layout_marginLeft="20dp"
  98. android:text="更新数据" />
  99. </LinearLayout>
  100. </LinearLayout>
  101. </LinearLayout>

MyProvide代码如下

  1. import android.content.ContentProvider;
  2. import android.content.ContentValues;
  3. import android.content.Context;
  4. import android.content.UriMatcher;
  5. import android.database.Cursor;
  6. import android.database.sqlite.SQLiteDatabase;
  7. import android.net.Uri;
  8. public class MyProvide extends ContentProvider {
  9. private Context mContext;
  10. private DbHelp dbHelp = null;
  11. private SQLiteDatabase db = null;
  12. public static final String AUTHORITY = "cn.sch.myprovider";
  13. public static final int User_Code = 1;
  14. private UriMatcher mMatcher;
  15. @Override
  16. public boolean onCreate() {
  17. mContext = getContext();
  18. mMatcher = new UriMatcher(UriMatcher.NO_MATCH);
  19. //初始化
  20. // 若URI资源路径 = content://cn.sch.myprovider/user ,则返回注册码User_Code
  21. mMatcher.addURI(AUTHORITY, "user", User_Code);
  22. dbHelp = new DbHelp(mContext);
  23. this.db = dbHelp.getWritableDatabase();
  24. // 初始化表的数据
  25. db.execSQL("delete from user");
  26. db.execSQL("insert into user values(1,'xiaoming','Android Development')");
  27. db.execSQL("insert into user values(2,'xiaohua','Java Development')");
  28. return true;
  29. }
  30. @Override
  31. public Cursor query( Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
  32. String tableName = getTableName(uri);
  33. return db.query(tableName,projection,selection,selectionArgs,null,null,sortOrder,null);
  34. }
  35. @Override
  36. public String getType( Uri uri) {
  37. return null;
  38. }
  39. @Override
  40. public Uri insert( Uri uri, ContentValues values) {
  41. String tableName = getTableName(uri);
  42. //向表中插入数据
  43. db.insert(tableName,null,values);
  44. mContext.getContentResolver().notifyChange(uri,null);
  45. return uri;
  46. }
  47. @Override
  48. public int delete( Uri uri, String selection, String[] selectionArgs) {
  49. String tableName = getTableName(uri);
  50. int count=db.delete(tableName, null, null);
  51. if(count>0){
  52. getContext().getContentResolver().notifyChange(uri, null);
  53. return count;
  54. }
  55. return 0;
  56. }
  57. @Override
  58. public int update( Uri uri, ContentValues values, String selection, String[] selectionArgs) {
  59. String tableName = getTableName(uri);
  60. int count = db.update(tableName, values, selection,selectionArgs);
  61. if(count>0){
  62. getContext().getContentResolver().notifyChange(uri, null);
  63. return count;
  64. }
  65. return 0;
  66. }
  67. private String getTableName(Uri uri) {
  68. String tableName = null;
  69. switch (mMatcher.match(uri)){
  70. case User_Code:
  71. tableName = DbHelp.USER_TABLE_NAME;
  72. break;
  73. }
  74. return tableName;
  75. }
  76. }

DbHelp代码如下

  1. import android.content.Context;
  2. import android.database.sqlite.SQLiteDatabase;
  3. import android.database.sqlite.SQLiteOpenHelper;
  4. public class DbHelp extends SQLiteOpenHelper {
  5. // 数据库名
  6. private static final String DATABASE_NAME = "finch.db";
  7. // 表名
  8. public static final String USER_TABLE_NAME = "user";
  9. //数据库版本号
  10. private static final int DATABASE_VERSION = 1;
  11. public DbHelp(Context context) {
  12. super(context, DATABASE_NAME, null, DATABASE_VERSION);
  13. }
  14. @Override
  15. public void onCreate(SQLiteDatabase db) {
  16. //创建数据库表
  17. //注意;如果你第一次运行后第二次又改动创建数据语句时,并且只改动了属性,没有该表名,那么当你再次运行App时会发现会报错,新改动的属性不存在
  18. //解决方法:手动将已建好的那个表删除,或者删除App重新安装,这样你改动的属性才能生效
  19. db.execSQL("CREATE TABLE IF NOT EXISTS "+USER_TABLE_NAME+"(_id INTEGER PRIMARY KEY AUTOINCREMENT,"+" name TEXT,"+"jobs TEXT)");
  20. }
  21. @Override
  22. public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
  23. }
  24. }

第一个应用的AndroidManifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. package="com.example.gamedemo">
  5. <uses-permission android:name="android.permission.READ_PERSON_DB" />
  6. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  7. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
  8. tools:ignore="ProtectedPermissions" />
  9. <uses-permission android:name="cn.sch.myprovider.Read"/>
  10. <uses-permission android:name="cn.sch.myprovider.Write"/>
  11. <permission android:name="cn.sch.myprovider.Read"
  12. android:label="Permission for read content provider"
  13. android:protectionLevel="normal"
  14. ></permission>
  15. <permission android:name="cn.sch.myprovider.Write"
  16. android:label="Permission for write content provider"
  17. android:protectionLevel="normal"
  18. ></permission>
  19. <application
  20. android:allowBackup="true"
  21. android:icon="@mipmap/ic_launcher"
  22. android:label="@string/app_name"
  23. android:roundIcon="@mipmap/ic_launcher_round"
  24. android:supportsRtl="true"
  25. android:theme="@style/Theme.MyApplication1">
  26. <activity
  27. android:name=".MainActivity"
  28. android:exported="true">
  29. <intent-filter>
  30. <action android:name="android.intent.action.MAIN" />
  31. <category android:name="android.intent.category.LAUNCHER" />
  32. </intent-filter>
  33. </activity>
  34. <provider
  35. android:authorities="cn.sch.myprovider"
  36. android:name=".MyProvide"
  37. android:exported="true"
  38. android:multiprocess="false"
  39. android:grantUriPermissions="true"
  40. android:writePermission="cn.sch.myprovider.Write"
  41. android:readPermission="cn.sch.myprovider.Read"
  42. >
  43. </provider>
  44. </application>
  45. </manifest>

第一个应用的build.gradle

  1. plugins {
  2. id 'com.android.application'
  3. }
  4. android {
  5. compileSdk 29
  6. defaultConfig {
  7. applicationId "com.example.gamedemo"
  8. minSdk 21
  9. targetSdk 29
  10. versionCode 1
  11. versionName "1.0"
  12. testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  13. }
  14. buildTypes {
  15. release {
  16. minifyEnabled false
  17. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  18. }
  19. }
  20. compileOptions {
  21. sourceCompatibility JavaVersion.VERSION_1_8
  22. targetCompatibility JavaVersion.VERSION_1_8
  23. }
  24. }
  25. dependencies {
  26. implementation 'androidx.appcompat:appcompat:1.2.0'
  27. implementation 'com.google.android.material:material:1.3.0'
  28. implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
  29. testImplementation 'junit:junit:4.+'
  30. androidTestImplementation 'androidx.test.ext:junit:1.1.2'
  31. androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
  32. }

模块contentprovidertest是第二个应用

MainActivity代码如下

  1. package com.example.contentprovidertest;
  2. import android.Manifest;
  3. import android.content.ContentResolver;
  4. import android.content.ContentValues;
  5. import android.content.pm.PackageManager;
  6. import android.database.Cursor;
  7. import android.net.Uri;
  8. import android.os.Bundle;
  9. import android.text.TextUtils;
  10. import android.view.View;
  11. import android.widget.Button;
  12. import android.widget.EditText;
  13. import android.widget.TextView;
  14. import android.widget.Toast;
  15. import androidx.appcompat.app.AppCompatActivity;
  16. import androidx.core.app.ActivityCompat;
  17. public class MainActivity extends AppCompatActivity implements View.OnClickListener {
  18. private static final String TAG = "lzs";
  19. private TextView userTv;
  20. private Button btn_query2;
  21. private Button btn_insert2;
  22. private Button btn_delete2;
  23. private Button btn_update2;
  24. private EditText xuhao2;
  25. private EditText xingming2;
  26. private EditText zhiye2;
  27. private int id;
  28. private String name;
  29. private String job;
  30. @Override
  31. protected void onCreate(Bundle savedInstanceState) {
  32. super.onCreate(savedInstanceState);
  33. setContentView(R.layout.activity_main);
  34. this.userTv = findViewById(R.id.id_tv);
  35. //动态获取权限
  36. if(ActivityCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED
  37. ||ActivityCompat.checkSelfPermission
  38. (this, Manifest.permission.WRITE_EXTERNAL_STORAGE)==PackageManager.PERMISSION_GRANTED) {
  39. init(); //初始化控件
  40. }else {
  41. ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_EXTERNAL_STORAGE},0x10);
  42. }
  43. }
  44. private void init() {
  45. xuhao2 = findViewById(R.id.xuhao2);
  46. xingming2 = findViewById(R.id.xingming2);
  47. zhiye2 = findViewById(R.id.zhiye2);
  48. btn_query2 = findViewById(R.id.btn_query2);
  49. btn_insert2 = findViewById(R.id.btn_insert2);
  50. btn_delete2 = findViewById(R.id.btn_delete2);
  51. btn_update2 = findViewById(R.id.btn_update2);
  52. btn_query2.setOnClickListener(this);
  53. btn_insert2.setOnClickListener(this);
  54. btn_delete2.setOnClickListener(this);
  55. btn_update2.setOnClickListener(this);
  56. }
  57. @Override
  58. public void onClick(View view) {
  59. switch (view.getId()){
  60. case R.id.btn_query2:
  61. btn_query2();
  62. break;
  63. case R.id.btn_insert2:
  64. btn_insert2();
  65. break;
  66. case R.id.btn_delete2:
  67. btn_delete2();
  68. break;
  69. case R.id.btn_update2:
  70. btn_update2();
  71. break;
  72. }
  73. }
  74. private void btn_update2() {
  75. id = Integer.parseInt(xuhao2.getText().toString());
  76. name = xingming2.getText().toString();
  77. job = zhiye2.getText().toString();
  78. if(!TextUtils.isEmpty(xuhao2.getText())&&!TextUtils.isEmpty(xingming2.getText())&&!TextUtils.isEmpty(zhiye2.getText())){
  79. Uri uri = Uri.parse("content://cn.sch.myprovider/user");
  80. ContentResolver resolver2 = getContentResolver();
  81. ContentValues values2 = new ContentValues();
  82. values2.put("_id", id);
  83. values2.put("name", name);
  84. values2.put("jobs", job);
  85. resolver2.update(uri,values2,"_id="+id,null);
  86. Toast.makeText(MainActivity.this, "更新成功", Toast.LENGTH_SHORT).show();
  87. }else {
  88. Toast.makeText(MainActivity.this,"请填写完整,不能为空!",Toast.LENGTH_SHORT).show();
  89. }
  90. }
  91. private void btn_delete2() {
  92. id = Integer.parseInt(xuhao2.getText().toString());
  93. if(!TextUtils.isEmpty(xuhao2.getText())){
  94. Uri uri = Uri.parse("content://cn.sch.myprovider/user");
  95. ContentResolver resolver2 = getContentResolver();
  96. resolver2.delete(uri,"_id ="+id,null);
  97. Toast.makeText(MainActivity.this, "删除成功", Toast.LENGTH_SHORT).show();
  98. }else {
  99. Toast.makeText(MainActivity.this,"请填写完整,不能为空!",Toast.LENGTH_SHORT).show();
  100. }
  101. }
  102. private void btn_insert2() {
  103. this.userTv.setText("");
  104. id = Integer.parseInt(xuhao2.getText().toString());
  105. name = xingming2.getText().toString();
  106. job = zhiye2.getText().toString();
  107. if(!TextUtils.isEmpty(xuhao2.getText())&&!TextUtils.isEmpty(xingming2.getText())&&!TextUtils.isEmpty(zhiye2.getText())){
  108. Uri uri = Uri.parse("content://cn.sch.myprovider/user");
  109. // 插入表中数据
  110. ContentValues values2 = new ContentValues();
  111. values2.put("_id", id);
  112. values2.put("name", name);
  113. values2.put("jobs", job);
  114. // 获取ContentResolver
  115. ContentResolver resolver2 = getContentResolver();
  116. // 通过ContentResolver 根据URI 向ContentProvider中插入数据
  117. resolver2.insert(uri, values2);
  118. // 通过ContentResolver 向ContentProvider中查询数据
  119. Cursor cursor2 = resolver2.query(uri, new String[]{"_id", "name","jobs"}, null, null, null);
  120. while (cursor2.moveToNext()) {
  121. // 将表中数据全部输出
  122. this.userTv.append(" 序号:" + cursor2.getInt(0) + " 姓名:" + cursor2.getString(1) +" 工作:"+cursor2.getString(2)+ "\n");
  123. }
  124. Toast.makeText(MainActivity.this,"插入成功",Toast.LENGTH_SHORT).show();
  125. // 关闭游标
  126. cursor2.close();
  127. }else {
  128. Toast.makeText(MainActivity.this,"请填写完整,不能为空!",Toast.LENGTH_SHORT).show();
  129. }
  130. }
  131. private void btn_query2() {
  132. Uri uri = Uri.parse("content://cn.sch.myprovider/user");
  133. Cursor query = getContentResolver().query(uri, null, null, null, null);
  134. //清空文本,防止重复查询而多次显示
  135. if(!TextUtils.isEmpty(this.userTv.getText()))
  136. {
  137. this.userTv.setText("");
  138. }
  139. while (query.moveToNext()) {
  140. int id = query.getInt(0);
  141. String name = query.getString(1);
  142. String job = query.getString(2);
  143. this.userTv.append(" 序号:" + id + " 姓名:" + name +" 工作:"+job+ "\n");
  144. }
  145. query.close();
  146. }
  147. }

MainActivity的activity_main.xml代码如下

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:app="http://schemas.android.com/apk/res-auto"
  4. xmlns:tools="http://schemas.android.com/tools"
  5. android:layout_width="match_parent"
  6. android:layout_height="match_parent"
  7. android:orientation="vertical"
  8. android:gravity="center">
  9. <LinearLayout
  10. android:layout_width="match_parent"
  11. android:layout_height="match_parent"
  12. android:layout_weight="1"
  13. android:gravity="center"
  14. android:orientation="vertical">
  15. <TextView
  16. android:layout_width="wrap_content"
  17. android:layout_height="wrap_content"
  18. android:layout_marginBottom="50dp"
  19. android:text="第二个应用"
  20. android:textSize="30dp" />
  21. <TextView
  22. android:id="@+id/id_tv"
  23. android:layout_width="wrap_content"
  24. android:layout_height="wrap_content"
  25. android:layout_marginBottom="250dp"
  26. android:text="" />
  27. </LinearLayout>
  28. <LinearLayout
  29. android:layout_width="match_parent"
  30. android:layout_height="match_parent"
  31. android:layout_weight="2"
  32. android:gravity="center"
  33. android:orientation="vertical">
  34. <EditText
  35. android:id="@+id/xuhao2"
  36. android:layout_width="wrap_content"
  37. android:layout_height="wrap_content"
  38. android:ems="10"
  39. android:hint="请输入序号"
  40. android:inputType="number" />
  41. <EditText
  42. android:id="@+id/xingming2"
  43. android:layout_width="wrap_content"
  44. android:layout_height="wrap_content"
  45. android:ems="10"
  46. android:hint="请输入姓名"
  47. android:inputType="textPersonName" />
  48. <EditText
  49. android:id="@+id/zhiye2"
  50. android:layout_width="wrap_content"
  51. android:layout_height="wrap_content"
  52. android:ems="10"
  53. android:hint="请输入职业"
  54. android:inputType="textPersonName" />
  55. </LinearLayout>
  56. <LinearLayout
  57. android:layout_width="match_parent"
  58. android:layout_height="match_parent"
  59. android:layout_weight="2"
  60. android:orientation="vertical">
  61. <LinearLayout
  62. android:layout_width="match_parent"
  63. android:layout_height="match_parent"
  64. android:layout_weight="1"
  65. android:gravity="center"
  66. android:orientation="horizontal">
  67. <Button
  68. android:id="@+id/btn_query2"
  69. android:layout_width="wrap_content"
  70. android:layout_height="wrap_content"
  71. android:layout_marginTop="20dp"
  72. android:text="查询数据" />
  73. <Button
  74. android:id="@+id/btn_insert2"
  75. android:layout_width="wrap_content"
  76. android:layout_height="wrap_content"
  77. android:layout_marginLeft="20dp"
  78. android:layout_marginTop="20dp"
  79. android:text="插入数据" />
  80. </LinearLayout>
  81. <LinearLayout
  82. android:layout_width="match_parent"
  83. android:layout_height="match_parent"
  84. android:layout_weight="1"
  85. android:gravity="center_horizontal"
  86. android:orientation="horizontal">
  87. <Button
  88. android:id="@+id/btn_delete2"
  89. android:layout_width="wrap_content"
  90. android:layout_height="wrap_content"
  91. android:text="删除数据" />
  92. <Button
  93. android:id="@+id/btn_update2"
  94. android:layout_width="wrap_content"
  95. android:layout_height="wrap_content"
  96. android:layout_marginLeft="20dp"
  97. android:text="更新数据" />
  98. </LinearLayout>
  99. </LinearLayout>
  100. </LinearLayout>

第二个应用的AndroidManifest.xml

  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"
  3. xmlns:tools="http://schemas.android.com/tools"
  4. package="com.example.contentprovidertest">
  5. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
  6. <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
  7. tools:ignore="ProtectedPermissions" />
  8. <uses-permission android:name="android.permissions.READ_DATABASE"/>
  9. <uses-permission android:name="android.permissioms.WRITE_DATABASE"/>
  10. <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
  11. <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
  12. <uses-permission android:name="cn.sch.myprovider.Read"/>
  13. <uses-permission android:name="cn.sch.myprovider.Write"/>
  14. <application
  15. android:allowBackup="true"
  16. android:icon="@mipmap/ic_launcher"
  17. android:label="@string/app_name"
  18. android:roundIcon="@mipmap/ic_launcher_round"
  19. android:supportsRtl="true"
  20. android:theme="@style/Theme.MyApplication1">
  21. <activity
  22. android:name=".MainActivity"
  23. android:exported="true">
  24. <intent-filter>
  25. <action android:name="android.intent.action.MAIN" />
  26. <category android:name="android.intent.category.LAUNCHER" />
  27. </intent-filter>
  28. </activity>
  29. </application>
  30. </manifest>

第二个应用的build.gradle

  1. plugins {
  2. id 'com.android.application'
  3. }
  4. android {
  5. compileSdk 29
  6. defaultConfig {
  7. applicationId "com.example.contentprovidertest"
  8. minSdk 21
  9. targetSdk 29
  10. versionCode 1
  11. versionName "1.0"
  12. testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  13. }
  14. buildTypes {
  15. release {
  16. minifyEnabled false
  17. proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
  18. }
  19. }
  20. compileOptions {
  21. sourceCompatibility JavaVersion.VERSION_1_8
  22. targetCompatibility JavaVersion.VERSION_1_8
  23. }
  24. }
  25. dependencies {
  26. implementation 'androidx.appcompat:appcompat:1.2.0'
  27. implementation 'com.google.android.material:material:1.3.0'
  28. implementation 'androidx.constraintlayout:constraintlayout:2.0.4'
  29. testImplementation 'junit:junit:4.+'
  30. androidTestImplementation 'androidx.test.ext:junit:1.1.2'
  31. androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
  32. }

如果又遇到啥问题,可以留言,一起来解决。

到此所有代码展示完毕,希望你们喜欢,觉得不错的可以给我个赞哈,嘿嘿。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/寸_铁/article/detail/941067
推荐阅读
相关标签
  

闽ICP备14008679号