android_content_provider 0.4.2 android_content_provider: ^0.4.2 copied to clipboard
Flutter plugin to use ContentProvider/ContentResolver APIs on Android
android_content_provider #
This plugin exposes ContentProvider and related ContentResolver APIs on Android.
Android 11 package visibility #
Android 11 introduced a security mechanism that is called a package visibility.
If you are using AndroidContentResolver
and trying to access some content provider within a package that is not
visible by default,
your app will fail to connect to it.
To fix this, add to your AndroidManifest.xml
a new <queries>
element:
<manifest>
...
<queries>
<package android:name="com.example.app" />
</queries>
...
</manifest>
Configuring AndroidContentProvider
#
You may ignore these steps if you only want to use AndroidContentResolver
.
-
Use the
FlutterEngineGroup
, provided by the plugin, in yourMainActivity
to improve performance and reduce memory footprint from engine creation.This step is optional, but is strongly recommended.
- Kotlin
import android.content.Context
import com.nt4f04und.android_content_provider.AndroidContentProvider
import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine
class MainActivity : FlutterActivity() {
override fun provideFlutterEngine(context: Context): FlutterEngine? {
return AndroidContentProvider.getFlutterEngineGroup(this)
.createAndRunDefaultEngine(this)
}
}
- Java
import android.content.Context;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.nt4f04und.android_content_provider.AndroidContentProvider;
import io.flutter.embedding.android.FlutterActivity;
import io.flutter.embedding.engine.FlutterEngine;
public class MainActivity extends FlutterActivity {
@Nullable
@Override
public FlutterEngine provideFlutterEngine(@NonNull Context context) {
return AndroidContentProvider.Companion.getFlutterEngineGroup(this)
.createAndRunDefaultEngine(this);
}
}
- Subclass
AndroidContentProvider
in native code, setting the authority and Dart entrypoint name you want to use
- Kotlin
package com.example.myapp // <-- replace this with your package
import com.nt4f04und.android_content_provider.AndroidContentProvider
class MyAndroidContentProvider : AndroidContentProvider() {
override val authority: String = "com.example.myapp.MyAndroidContentProvider"
override val entrypointName = "exampleContentProviderEntrypoint"
}
- Java
package com.example.myapp; // <-- replace this with your package
import com.nt4f04und.android_content_provider.AndroidContentProvider;
import org.jetbrains.annotations.NotNull;
public class MyAndroidContentProvider extends AndroidContentProvider {
@NotNull
@Override
public String getAuthority() {
return "com.example.myapp.MyAndroidContentProvider";
}
@NotNull
@Override
public String getEntrypointName() {
return "exampleContentProviderEntrypoint";
}
}
- Declare your ContentProvider in the
AndroidManifest.xml
.
- If you want to allow other apps to access the provider unconditionally
<provider
android:name=".MyAndroidContentProvider"
android:authorities="com.example.myapp.MyAndroidContentProvider"
android:exported="true" />
- If you want to make other apps declare
<uses-permission>
<provider
android:name=".MyAndroidContentProvider"
android:authorities="com.example.myapp.MyAndroidContentProvider"
android:exported="false"
android:readPermission="com.example.myapp.permission.READ"
android:writePermission="com.example.myapp.permission.WRITE" />
- Subclass
AndroidContentProvider
in Dart code and override needed methods
import 'package:android_content_provider/android_content_provider.dart';
class MyAndroidContentProvider extends AndroidContentProvider {
MyAndroidContentProvider(String authority) : super(authority);
@override
Future<int> delete(
String uri,
String? selection,
List<String>? selectionArgs,
) async {
return 0;
}
@override
Future<String?> getType(String uri) async {
return null;
}
@override
Future<String?> insert(String uri, ContentValues? values) async {
return null;
}
@override
Future<CursorData?> query(
String uri,
List<String>? projection,
String? selection,
List<String>? selectionArgs,
String? sortOrder,
) async {
return null;
}
@override
Future<int> update(
String uri,
ContentValues? values,
String? selection,
List<String>? selectionArgs,
) async {
return 0;
}
}
- Create the Dart entrypoint
@pragma('vm:entry-point')
void exampleContentProviderEntrypoint() {
MyAndroidContentProvider('com.example.myapp.MyAndroidContentProvider');
}