Using ACTION_VIEW
with a FileProvider
uri for a html file lets browsers like Chrome and Edge display the html page.
Also HTML-viewer app displays. And editor apps can handle the file.
If using a ContentProvider
extended uri the browsers only offer to download the file.
HTML-viewer shows an indefinite progressbar.
My apps and external editor apps will still read and edit the file. So providing works.
I see that Chrome, Edge and HTML-viewer only call openFile() and getType().
content://com.jmg.expas.fileprovider/external_files/Documents/index.html
content://com.jmg.expas.simpleprovider/storage/emulated/0/Documents/index.html
I have no idea why both content scheme uries are treated differently.
This is the simple content provider code:
public class SimpleContentProvider extends ContentProvider
{
static String TAG = "simplecontentprovider";
public static Uri getUriForFile ( Context context, File file)
{
return Uri.parse("content://" + context.getPackageName() + ".simpleprovider" + file.getAbsolutePath());
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
{
Log.d(TAG, "open-File() mode: " + mode ); // "w"
Log.d(TAG, "uri.getEncodedPath(): " + uri.getEncodedPath() );
String path = uri.getEncodedPath();
File f = new File(path);
if ( ! f.exists() )
{
Log.d(TAG, "path does not exist" );
throw new FileNotFoundException(
"in SimpleContentProvider\n"
+
uri.getPath() );
}
if ( mode.equals("r") )
return (ParcelFileDescriptor.open(f,ParcelFileDescriptor.MODE_READ_ONLY));
return (ParcelFileDescriptor.open(f,ParcelFileDescriptor.MODE_READ_WRITE));
}
private String getExtension ( String fileName )
{
int index = fileName.lastIndexOf(".");
if ( index < 0 )
return "";
return fileName.substring(index+1);
}
@Override
public String getType(Uri uri)
{
Log.d(TAG, "get-Type() getPath(): " + uri.getPath() );
String path = uri.getPath();
String extension = getExtension(path);
MimeTypeMap mimeTypeMap = MimeTypeMap.getSingleton();
String mimeType = mimeTypeMap.getMimeTypeFromExtension(extension);
Log.d(TAG, "mimetype: " + mimeType + " for extension " + extension );
// O Oh Oh ..
//return extension;
return mimeType; // and problem solved ;-)
}
// Other member functions not used. They will be added by Android Studio
}
In manifest:
<provider
android:name=".SimpleContentProvider"
android:authorities="${applicationId}.simpleprovider"
android:enabled="true"
android:exported="true" />
Use:
String mimetype = "text/html";
String filePath = .... any filepath to a html file the app can read itself...
Uri uri = SimpleContentProvider.getUriForFile(context, new File(filePath));
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(uri, mimetype);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION
);
context.startActivity(intent);
The question is: What do i have to do to let browsers display the source like when FileProvider used? Or what makes them to offer a download instead?