5

I want to open an image from internal folder with the android default image viewer, on the Nexus 7 tablet. I use the following code,but for some reason the image is not displayed. What I'm doing wrong? The path to the file is :

file:///data/data/com.example.denandroidapp/files/Attachments/photoTemp/photo.jpg

(this is what Uri.parse("file://" + file) returns).

ArticlePhoto photo =  new ArticlePhoto(soapObject);
File f = new File(context.getFilesDir() + "/Attachments/photoTemp");

if(!f.exists())
    f.mkdirs();

if (photo.ArtPhoto != null) {
    Bitmap articlePhoto = BitmapFactory.decodeByteArray(photo.ArtPhoto, 0, photo.ArtPhoto.length);                      
    ByteArrayOutputStream  bytesFile  =  new ByteArrayOutputStream();
    articlePhoto.compress(Bitmap.CompressFormat.JPEG, 100, bytesFile);

    File file = new File(f + "/photo.jpeg");

    try {
        if(!file.exists())
            file.createNewFile();

        FileOutputStream outStream =  new FileOutputStream(file);

        outStream.write(bytesFile.toByteArray());                  
        outStream.close();

        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_VIEW);
        intent.setDataAndType(Uri.parse("file://" + file),"image/jpeg"); 
        startActivity(intent);

    } catch(Exception ex) {
        AlertDialog alert =  new  AlertDialog.Builder(context).create();
        alert.setTitle("Warning!");
        alert.setMessage(ex.getMessage());
        alert.show();
    }
}
Mattia Maestrini
  • 32,270
  • 15
  • 87
  • 94
Roman Marius
  • 456
  • 3
  • 9
  • 21

8 Answers8

6

Try with this :

    Intent intent = new Intent();  
    intent.setAction(android.content.Intent.ACTION_VIEW);
    Uri uri = Uri.parse("file://" + file.getAbsolutePath());                 
    intent.setDataAndType(uri,"image/*");
    startActivity(intent);

Thanks.

Pratik Sharma
  • 13,307
  • 5
  • 27
  • 37
  • 2
    still nothing.only a black screen. – Roman Marius Jan 24 '13 at 07:48
  • i think the problem is the part that writes the photo on tablet internal storage,because if a browse the tablet folder i cannot see the Attachments/photoTemp folders. – Roman Marius Jan 24 '13 at 10:59
  • its weird.if i run the app in debug mode,it says that the file exist,but if i browse the tablet folders form windows i cannot see the folders or the photo. – Roman Marius Jan 24 '13 at 11:03
  • This method not work.I used Uri.fromFile(file) instead of Uri.parse("file://" + file.getAbsolutePath()) and it worked. – Saeid Z Jul 28 '19 at 19:44
3

The problem is that the image is internal to your application! So an external application (Image Viewer) has no access to the data that is internal to your application.

What you might have to do is create a Content Provider . http://web.archive.org/web/20111020204554/http://www.marcofaion.it/?p=7

Android Manifest.xml

<provider android:authorities="com.example.denandroidapp" android:enabled="true" android:exported="true" android:name=<fully classified name of provider class>>
</provider>

Creating Intent

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);

Uri uri = Uri.parse("content://com.example.denandroidapp/" + filename);
intent.setDataAndType(uri, "image/jpeg");
3tz
  • 31
  • 1
  • This helped me get my code working. See also http://stackoverflow.com/questions/21304489/how-to-open-private-files-saved-to-the-internal-storage-using-intent-action-view http://stackoverflow.com/questions/12170386/create-and-share-a-file-from-internal-storage – mc9 Nov 10 '15 at 00:13
3

If a file is associated with your app (stored on the internal storage of your app space ), other apps can not access your file directly provided a valid file path. Instead, you have to create a file provider and generate a content uri.

First, add the file provider in your AndroidManifest.xml

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

Then you need to create an a file named file_paths in xml/file_paths.xml (the directory xml is not created by default, so create it).

file_paths.xml looks like

<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <files-path name="myFiles" path="./"/>
</paths>

add as much as paths you want your provider to access in .

atlast you need to create your intent

Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
File imagePath = new File(context.getFilesDir(), "fileName");
Uri contentUri = FileProvider.getUriForFile(context, "com.mydomain.fileprovider", imagePath);
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(contentUri,"image/*");
context.startActivity(intent);

Note: make sure the file path sepecefied in file_paths.xml and new File(context.getFilesDir(),"fileName"), matches. getFilesDir() will give you the root directory of your app.

Nathaniel
  • 71
  • 1
  • 6
1
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
 intent.setDataAndType(Uri.fromFile(new File(outputFileName)),"image/jpeg");
 startActivity(intent);
kamal
  • 290
  • 3
  • 20
1

You can use FileProvider which extends ContentProvider

Check the link -

https://developer.android.com/reference/android/support/v4/content/FileProvider

To specify the FileProvider component itself, add a "provider" element to your app manifest.

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

You must specify a child element of "paths" for each directory that contains files for which you want content URIs. For example, these XML elements specify two directories

<paths xmlns:android="http://schemas.android.com/apk/res/android">
  <files-path name="my_images" path="images/"/>
  <files-path name="my_docs" path="docs/"/>
</paths>

After this you need to generate content URI for the file and then call the intent, refer the below link

https://developer.android.com/reference/android/support/v4/content/FileProvider#GetUri

Shainu Thomas
  • 360
  • 3
  • 12
0

Check this: https://stackoverflow.com/a/11088980/1038442;

File file = new File(filePath);
MimeTypeMap map = MimeTypeMap.getSingleton();
String ext = MimeTypeMap.getFileExtensionFromUrl(file.getName());
String type = map.getMimeTypeFromExtension(ext);
if (type == null)
    type = "*/*";

Intent intent = new Intent(Intent.ACTION_VIEW);
Uri data = Uri.fromFile(file);
intent.setDataAndType(data, type);
startActivity(intent);

PS: if your are trying to open .jpg files, try to Replace String ext = MimeTypeMap.getFileExtensionFromUrl(file.getName()); With String ext = MimeTypeMap.getFileExtensionFromUrl(".jpg");

Good luck.

Community
  • 1
  • 1
Sam003
  • 331
  • 3
  • 3
0

In my case, The gallery launched but did not show any images and went straight to the home page. My situation is quite different from what OP faced but I think it's worth mentioning here since the question is about images not being shown through implicit intent.

My problem came from the code below.

val intent = context.packageManager.getLaunchIntentForPackage(packageName ?: "")

The code above tells PackageManager to launch the entry point of the application, instead of the activity that shows the images.

enter image description here

If you look at the Logcat above, you can find that the intent launched with cat=[android.intent.category.Launcher] will go to SplashActivity. This happened because I created the intent with getLaunchIntentForPackage()

Alternative is to use Intent with setPackage() like the code in below

val intent = Intent()
val uri = Uri.fromFile(file) // You should probably replace with ContentProvider's uri
intent.apply {
    flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
    action = Intent.ACTION_VIEW
    setPackage(packageName)
    setDataAndType(uri, "image/*")
}
context.startActivity(intent)
flamyoad
  • 519
  • 7
  • 15
0

Little change in lines of code worked for me.

val intent = Intent(Intent.ACTION_VIEW)
val contentUri = FileProvider.getUriForFile(mContext, mContext.packageName + ".provider", mediaFile)
intent.setDataAndType(contentUri, mimeType)
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK // <-- should be before 'addFlags'
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)  // <--- this line
mContext.startActivity(intent)

Below code did not work.

 val intent = Intent(Intent.ACTION_VIEW)
 val contentUri = FileProvider.getUriForFile(mContext, mContext.packageName + ".provider", mediaFile)
 intent.setDataAndType(contentUri, mimeType) 
 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) 
 intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK 
             
 mContext.startActivity(intent)
erkuy
  • 76
  • 1
  • 7