1

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?

blackapps
  • 8,011
  • 2
  • 11
  • 25
  • Try overriding `query()` and offering support for the `OpenableColumns`. – CommonsWare Nov 07 '21 at 15:11
  • @CommonsWare, Cursor query() is not called. So would that make sense then? For OpenableColums i have to get some needed knowledge first. – blackapps Nov 07 '21 at 15:14
  • "Cursor query() is not called" -- if you are not overriding it, how do you know whether or not it is being called? – CommonsWare Nov 07 '21 at 15:16
  • 1
    @CommonsWare, I override it and it is not called. So i left it out for this post as only openFile() and getType() are called. And it has to be overriden and Android Studio adds them then. – blackapps Nov 07 '21 at 15:19
  • @CommonsWare, I only had overriden one query() member function (the one AS adds) . Now all three. Not one is called. – blackapps Nov 07 '21 at 15:33
  • Problem solved. O shame i was returning `extension` in `getTyoe()` instead of `mimeType`. Looks like a typo... – blackapps Dec 20 '21 at 12:06

0 Answers0