a应用中存了数据在a应用sqlite数据库中 ,b应用想访问a应用的数据出现了错误:
Failed to find provider info for com.example.mycontentprovder.personprovider
a应用的代码:
MainActivity 文件代码:
package com.example.mycontentprovder; import androidx.appcompat.app.AppCompatActivity; import android.database.sqlite.SQLiteDatabase; import android.os.Bundle; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } }
DBhelper 类代码
package com.example.mycontentprovder;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
public class DBhelper extends SQLiteOpenHelper {
public DBhelper(Context context){
super(context, "data.db", null, 1);
Log.d("ssssssssss","DBhelper");
}
@Override
public void onCreate(SQLiteDatabase db) {
Log.e("hfq","onCreate");
db.execSQL("create table person(_id integer primary key autoincrement ,name varchar)");
db.execSQL("insert into person (name) values ('Tome')");
}
@Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
}
}
自定义的ContentProvider PersonProvider
package com.example.mycontentprovder; import android.content.ContentProvider; import android.content.ContentUris; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; import android.database.sqlite.SQLiteDatabase; import android.net.Uri; import android.util.Log; import androidx.annotation.IdRes; import androidx.annotation.NonNull; import androidx.annotation.Nullable; public class PersonProvider extends ContentProvider { private static UriMatcher matcher=new UriMatcher(UriMatcher.NO_MATCH); private DBhelper mDBhelper; static { matcher.addURI("com.example.mycontentprovder.personprovider","/person",1); matcher.addURI("com.example.mycontentprovder.personprovider","/person/#",2); } public PersonProvider() { Log.d("ssssssssss","PersonProvider"); } @Override public boolean onCreate() { Log.d("ssssssssss","PersonProvider:onCreate"); mDBhelper=new DBhelper(getContext()); return false; } @Nullable @Override public Cursor query(@NonNull Uri uri, @Nullable String[] projection, @Nullable String selection, @Nullable String[] selectionArgs, @Nullable String sortOrder) { Log.d("ssssssssss","query"); SQLiteDatabase database=mDBhelper.getReadableDatabase(); int code=matcher.match(uri); if(code==1){ Cursor cursor=database.query("person",projection,selection,selectionArgs,null,null,null); return cursor; }else if(code==2){ long id= ContentUris.parseId(uri); Cursor cursor=database.query("person",projection,"_id=?",new String[]{id+""},null,null,null); return cursor; }else { throw new RuntimeException("查询的ui不合法"); } } @Nullable @Override public String getType(@NonNull Uri uri) { return null; } @Nullable @Override public Uri insert(@NonNull Uri uri, @Nullable ContentValues values) { return null; } @Override public int delete(@NonNull Uri uri, @Nullable String selection, @Nullable String[] selectionArgs) { return 0; } @Override public int update(@NonNull Uri uri, @Nullable ContentValues values, @Nullable String selection, @Nullable String[] selectionArgs) { return 0; } }
<provider android:authorities="com.example.mycontentprovder.personprovider" android:name=".PersonProvider" android:exported="true" />
加上了 android:exported="true"属性显示其他应用允许通过content://com.example.mycontentprovder.personprovidera访问a应用的数据
b应用的代码:
package com.example.mycontentresolver; import androidx.appcompat.app.AppCompatActivity; import android.content.ContentResolver; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.view.View; import android.widget.Toast; public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); } public void query(View view) { ContentResolver resolver=getContentResolver(); Uri uri=Uri.parse("content://com.example.mycontentprovder.personprovider/person/1"); Cursor cursor=resolver.query(uri,null,null,null,null); if(cursor!=null){ if(cursor.moveToNext()){ int id=cursor.getInt(0); String name=cursor.getString(1); Toast.makeText(this,id+":"+name,0).show(); } }else { Toast.makeText(this,"数据为空",0).show(); } } public void insert(View view) { } public void delete(View view) { } public void update(View view) { } }
当两个应用都运行时,b应用点击查询数据按钮时报以下错误:
Failed to find provider info for com.example.mycontentprovder.personprovider
解决办法:在b应用的AndroidManifest.xml中加上
<queries> <package android:name="com.example.mycontentprovder" /> </queries>
这是在 Android 11 下才会出现的问题,简单来说,就是出于安全考虑,Android 11 要求应用事先说明需要访问的其他软件包
name 的value为你要访问的那个应用的包名