SANDBOX is application's private space, this is where you can save all your application specific data safely. (Unless device is ROOTED)
Yes, before we see how to use it, why actually we need a content provider and how can it help us ?
What if you had to download files from an FTP server and save in your private space and open them at later point, for files like Images, music and text you could easily create your own custom in-app viewers.
Problem if you need to open a .pdf, a word document or an .xls ect. you will depend on external apps, but since the files are saved in your application memory you can't see them in your sdcard or can't browse them in the external viewer apps.
Solution to this problem is CONTENT PROVIDER, yes!! This allows you to share your private files with external apps so that you can preview / edit based on the permission you define.
Below is a quick code snippet of how it can be implemented :
Create a java class : MyContentProvider.java
public class MyContentProvider extends ContentProvider {
private static final String CLASS_NAME = your defined name;
// The authority is the symbolic name for the provider class
public static final String AUTHORITY = your defined name;
// UriMatcher used to match against incoming requests
private UriMatcher uriMatcher;
@Override
public boolean onCreate() {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// Add a URI to the matcher which will match against the form
// 'content://com.ashray.example.activity.contentprovider.provider/*'
// and return 1 in the case that the incoming Uri matches this pattern
uriMatcher.addURI(AUTHORITY, "*", 1);
return true;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
String LOG_TAG = CLASS_NAME + " - openFile";
Log.v(LOG_TAG, "Called with uri: '" + uri + "'." + uri.getLastPathSegment());
// Check incoming Uri against the matcher
switch (uriMatcher.match(uri)) {
// If it returns 1 - then it matches the Uri defined in onCreate
case 1:
String fileLocation = "";
// The desired file name is specified by the last segment of the path
// E.g. 'content://com.ashray.example.activity.contentprovider/Abc.txt'
// Take this and build the path to the file
Preference preferences = Preferences.getInstance(YourActivity.getBaseContext());
fileLocation = directorypath +''/"+ uri.getLastPathSegment();
}
// Create & return a ParcelFileDescriptor pointing to the file
// Note: Here we use Read-Write but we can restrict it to Read-Only
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(
fileLocation), ParcelFileDescriptor.MODE_READ_WRITE);
return pfd;
// Otherwise unrecognized Uri
default:
Log.v(LOG_TAG, "Unsupported uri: '" + uri + "'.");
throw new FileNotFoundException("Unsupported uri: "
+ uri.toString());
}
}
// //////////////////////////////////////////////////////////////
// Below methods are not used.
// //////////////////////////////////////////////////////////////
@Override
public int update(Uri uri, ContentValues contentvalues, String s,
String[] as) {
return 0;
}
@Override
public int delete(Uri uri, String s, String[] as) {
return 0;
}
@Override
public Uri insert(Uri uri, ContentValues contentvalues) {
return null;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String s, String[] as1,
String s1) {
return null;
}
}
In Activity call the Intent to open the file in external app : The content provider will handle creating a ParcelFileDescriptor pointing to the file, creating a bridge for external app to access the file.
// Eg : To open a Powerpoint file
The below code will either open the file directly in a app which can handle powerpoint files - If only one app is installed in device which can read ppt files.
OR
Show user a list of apps t choose from if multiple apps capable of handling power-point are installed
in the app
String localFile = path of file to open.
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(localFile), "application/vnd.ms-powerpoint");
startActivity(intent);
Finally in Manifest file declare the provider, inside the application tag
<provider
android:name="com.ashray.example.contentprovider.MyContentProvider"
android:authorities="com.ashray.example.contentprovider.provider"
android:grantUriPermissions="true"
android:exported="true" />
Permissions :
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_INTERNAL_STORAGE" />