0

My Problem: When openFile() intent attempts StartActivityForResult, the application hangs with a blank screen and circular cursor. The file(s) are stored to app.

What I have done: Before and after this issue I researched how to open files by use of Intents. I found a number of similar but different approaches and either used the literal example or a combination of various examples to see if I could find and resolve the issue (see some below). I'm not receiving any type of error message that I have found, and I had the FileUriExposedException previously but resolved it. These files are stored to the app and it may be a permissions issue and have tried what I know, including updating the manifest with for External Read and Write and added a flag setting on the intent for access.

What I'm trying to do: I'm trying to learn how to open files through intents with simple JPG images, then eventually expand to opening various file types after I understand how to do so.

Below is the current code I'm using and it included a MimeTypeMap that I tried in place of "image/jpeg" in case my syntax was not correct on the MIME Type, which did not seem to have an impact.

private void openFile(Uri uri, String fName) {

        MimeTypeMap myMime = MimeTypeMap.getSingleton();
        String mimeType = myMime.getMimeTypeFromExtension(getUpperBound(fName));

        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse("content://" + uri), "image/jpeg");
        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
        startActivityForResult(intent, 2);
    }

An image of the resulting issue hanging and never opening below:

Hanging Image

Some of the referenced links I tried:

https://developer.android.com/guide/components/intents-common

ACTION_VIEW intent for a file with unknown MimeType

Open File With Intent (Android)

http://www.androidsnippets.com/open-any-type-of-file-with-default-intent.html

svstackoverflow
  • 665
  • 6
  • 19

2 Answers2

1

I was able to resolve my issue combined with S-Sh's second suggestion of considering the use of FileProvider. I had to perform some refinements and ended up with the following to work. I also provided links to the sources in which I used.

Context of the solution:

As a note to future readers as to the context of this solution within my Android app, the code below is launched by clicking a "clickable" TableRow in a TableLayout. The TableLayout lists each filename and file ID as a TableRow. Once a row is clicked, the onClick method of the selected TableRow the filename is acquired and the File class and FileProvider are used and filename passed to create an Uri. This Uri is then passed to an openFile(Uri uri) method I created encapsulating (so-to-speak) the Intent used to open the file.

Code

Adding of the FileProvider to the AndroidManifest.xml' within the` tag:

<provider
        android:name="androidx.core.content.FileProvider"
        android:authorities="com.mistywillow.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
    <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths" />
</provider>

Creating within res directory the file_paths.xml and xml directory (res/xml/):

<?xml version="1.0" encoding="utf-8"?>
   <paths xmlns:android="http://schemas.android.com/apk/res/android">
      <files-path name="myFiles" path="." />
   </paths>

The onClick capturing the filename and preparing the Uri to be passed to the openFile():

    row.setOnClickListener(v -> {

        TableRow tablerow = (TableRow) v;
        TextView sample = (TextView) tablerow.getChildAt(1);
        String result = sample.getText().toString();

        File filePaths = new File(getFilesDir().toString());
        File newFile = new File(filePaths, result);
        Uri contentUri = getUriForFile(getApplicationContext(), "com.mydomain.fileprovider", newFile);
        openFile(contentUri);

    });

The openFile(Uri uri) method containing the Intent to open a file:

private void openFile(Uri uri){
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.setData(uri);
    intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivityForResult(intent, 2);
}

Links referenced:

https://developer.android.com/reference/androidx/core/content/FileProvider

FileProvider - IllegalArgumentException: Failed to find configured root

svstackoverflow
  • 665
  • 6
  • 19
0

Try use origin Uri itself:

 intent.setDataAndType(uri, "image/jpeg");
S-Sh
  • 3,564
  • 3
  • 15
  • 19
  • I had started with this but due to the version and that this defaults to the use of "file://...", it is not recommended to be used because it will fail and cause the `FileUriExposedException`. It is suggested to use the parse method to replace the "file://" to "content://". See: [FileUriExposedException suggested resolution](https://developer.android.com/reference/android/os/FileUriExposedException) – svstackoverflow Mar 17 '20 at 16:04
  • I'm also wondering if there may be a permissions issue that I may not be familiar with. These files are stored in a "file" folder created by the OS and accessible by 'getFileDir().getPath() + /fileName.jpg`. – svstackoverflow Mar 17 '20 at 16:38
  • 1
    You can use a `FileProvider` to share the file. For examle, see this reference: https://infinum.com/the-capsized-eight/share-files-using-fileprovider – S-Sh Mar 18 '20 at 06:05