Reputation: 39
I'm new to Content Provider. As i'm trying to fetch info from an app to another one but Im getting a permission denial:opening provider error. I tried to do so by creating a Content provider in one of my apps(App1) :
public class DroneProvider extends ContentProvider {
private static final String AUTHORITY = "com.x.x.adminapp";
private static final String BASE_PATH = "Drone";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH );
private static final int DRONE = 1;
private static final int DRONE_NAME = 2;
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(AUTHORITY,BASE_PATH, DRONE);
uriMatcher.addURI(AUTHORITY,BASE_PATH + "/#",DRONE_NAME);
}
and my query function in my Provider class is :
@Nullable
@Override
public Cursor query(Uri uri, String[] strings, String s, String[] strings1, String s1) {
Cursor cursor;
switch (uriMatcher.match(uri)) {
case DRONE:
cursor = database.query(MyDBHandler.TABLED_NAME,MyDBHandler.ALL_DRONE_COLUMNS,
s,null,null,null,MyDBHandler.COLUMN_DNAME +" ASC");
break;
default:
throw new IllegalArgumentException("This is an Unknown URI " + uri);
}
cursor.setNotificationUri(getContext().getContentResolver(),uri);
return cursor;
}
I added the permissions in the Manifest :
<provider
android:name=".DroneProvider"
android:authorities="com.x.x.adminapp"
android:readPermission="com.x.x.adminapp.READ_DATABASE"
android:writePermission="com.x.x.adminapp.WRITE_DATABASE"
android:enabled="true"
android:exported="true"></provider>
In my other app(App2), im using a resolver in my activity to grab data from (App1) as follows :
private static final String AUTHORITY = "com.x.x.adminapp";
private static final String BASE_PATH = "Drone";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/" + BASE_PATH );
private static final int DRONE = 1;
private static final int DRONE_NAME = 2;
private static final UriMatcher uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
static {
uriMatcher.addURI(AUTHORITY,BASE_PATH, DRONE);
uriMatcher.addURI(AUTHORITY,BASE_PATH + "/#",DRONE_NAME);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,Bundle savedInstanceState) {
ContentResolver contentResolver = getContext().getContentResolver();
String sortOrder = "name ASC";
Cursor cursor = contentResolver.query(CONTENT_URI,null,null,null,sortOrder);
if (cursor!= null && cursor.getCount()>0){
cursor.moveToFirst();
Drone drone ;
Marker m;
LatLng latLng;
do {
drone = new Drone();
drone.setName(cursor.getString(0));
latLng = new LatLng(0.0,0.0);
m = googleMap.addMarker(new MarkerOptions().position(latLng).title(drone.getName()));
Drones.add(m);
}
while (cursor.moveToNext());
}
And i added the permissions in the App2 Manifest:
<uses-permission android:name="com.x.x.adminapp.READ_DATABASE" />
<uses-permission android:name="com.x.x.adminapp.WRITE_DATABASE" />
But im getting this error :
java.lang.SecurityException: Permission Denial: opening provider com.x.x.adminapp.DroneProvider from ProcessRecord{46a1928 24678:com.x.x.myapplication11/u0a165} (pid=24678, uid=10165) requires com.x.x.adminapp.READ_DATABASE or com.x.x.adminapp.WRITE_DATABASE
Thank you in advance for your help :)
Upvotes: 1
Views: 5998
Reputation: 1537
You need to define any custom permission:
https://developer.android.com/guide/topics/permissions/defining.html
<permission
android:name="com.x.x.adminapp.WRITE_DATABASE"
android:label="Write Database"
android:description="Write to my database."
android:protectionLevel="normal" />
<permission
android:name="com.x.x.adminapp.READ_DATABASE"
android:label="Read Database"
android:description="Read from my database."
android:protectionLevel="normal" />
Note the protection level "normal" that means ANY app can request and be granted that permission. I'd suggest you change it to "signature" so only your apps can be granted the permission. It goes with out saying that both apps need to be signed with the same key. :)
Upvotes: 4