简体   繁体   中英

How to programatically store image in Gallery on Android 4.4

My code worked well on older Androids but gives and error on Android 4.4. I've tried to copy the file to external storage but that doesn't help. You can see in the log that the file is copied OK, but the Bitmap is likely not created properly because the code chokes on Media.insertImage .

Just note that this exact code works well if I use Intent to open the file in an application (thus the external storage must work well).

Also note, that I have these permissions:

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

My code

public static void storeImageToSystemGalery (String image_fullPathFileName) {
    try {
        Log.e(TAG, "Pp: CALLED: storeImageToSystemGalery (image_fullPathFileName=" + image_fullPathFileName +")");

        java.io.File internal_f = new java.io.File(image_fullPathFileName);
        Log.e(TAG, "Pp: internal_f: exists test=" + internal_f.exists());
        Log.e(TAG, "Pp: internal_f: canRead test=" + internal_f.canRead());


        File external_f = new File(parentActivity.getExternalFilesDir(null), "galery_shared.jpg");
        Log.e(TAG, "Pp: external_f.AbsolutePath=" + external_f.getAbsolutePath());
        _f_copy(internal_f, external_f);
        Log.e(TAG, "Pp: external_f: exists test=" + external_f.exists());
        Log.e(TAG, "Pp: external_f: canRead test=" + external_f.canRead());

        Uri imageURI = Uri.fromFile(external_f);

        android.graphics.Bitmap bmp = android.provider.MediaStore.Images.Media.getBitmap(parentActivity.getContentResolver(), imageURI);
        android.provider.MediaStore.Images.Media.insertImage(parentActivity.getContentResolver(), bmp, "Prstynek", "Muj prstynek");

    } catch (Exception ex) {
        Log.w(TAG, "FAILED to storeImageToSystemGalery: " + ex);
        ex.printStackTrace();
    }
}


static private void _f_copy(File fin, File dst) throws IOException {
    FileInputStream in=new FileInputStream(fin);
    FileOutputStream out=new FileOutputStream(dst);
    byte[] buf=new byte[1024];
    int len;

    while ((len=in.read(buf)) > 0) {
        out.write(buf, 0, len);
    }

    in.close();
    out.close();
}

Log dump:

E/cocos2d.sharkintelligence.Helper__sharkCore( 5824): Pp: CALLED: storeImageToSystemGalery (image_fullPathFileName=/data/data/com.sharkintelligence.test.trivialdrive2/files/product_preview_shared.jpg)
E/cocos2d.sharkintelligence.Helper__sharkCore( 5824): Pp: internal_f: exists test=true
E/cocos2d.sharkintelligence.Helper__sharkCore( 5824): Pp: internal_f: canRead test=true
E/cutils  (  166): Failed to mkdirat(/Removable/MicroSD): Read-only file system
W/ContextImpl( 5824): Failed to ensure directory: /Removable/MicroSD/Android/data/com.sharkintelligence.test.trivialdrive2/files
E/cocos2d.sharkintelligence.Helper__sharkCore( 5824): Pp: external_f.AbsolutePath=/storage/emulated/0/Android/data/com.sharkintelligence.test.trivialdrive2/files/galery_shared.jpg
W/Vold    (  166): Returning OperationFailed - no handler for errno 30
E/cocos2d.sharkintelligence.Helper__sharkCore( 5824): Pp: external_f: exists test=true
E/cocos2d.sharkintelligence.Helper__sharkCore( 5824): Pp: external_f: canRead test=true
D/dalvikvm( 5824): GC_CONCURRENT freed 2216K, 24% free 7501K/9764K, paused 3ms+4ms, total 15ms
D/dalvikvm( 5824): WAIT_FOR_CONCURRENT_GC blocked 15ms
I/dalvikvm-heap( 5824): Grow heap (frag case) to 11.358MB for 4187152-byte allocation
D/dalvikvm( 5824): GC_CONCURRENT freed 138K, 18% free 11452K/13856K, paused 1ms+3ms, total 7ms
E/MediaStore( 5824): Failed to insert image
E/MediaStore( 5824): java.io.FileNotFoundException: No such file or directory
E/MediaStore( 5824):    at android.database.DatabaseUtils.readExceptionWithFileNotFoundExceptionFromParcel(DatabaseUtils.java:146)
E/MediaStore( 5824):    at android.content.ContentProviderProxy.openAssetFile(ContentProviderNative.java:611)
E/MediaStore( 5824):    at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:922)
E/MediaStore( 5824):    at android.content.ContentResolver.openOutputStream(ContentResolver.java:669)
E/MediaStore( 5824):    at android.content.ContentResolver.openOutputStream(ContentResolver.java:645)
E/MediaStore( 5824):    at android.provider.MediaStore$Images$Media.insertImage(MediaStore.java:912)
E/MediaStore( 5824):    at com.sharkintelligence.android.app.Helper__sharkCore.storeImageToSystemGalery(Helper__sharkCore.java:295)
E/MediaStore( 5824):    at org.cocos2dx.lib.Cocos2dxRenderer.nativeRender(Native Method)
E/MediaStore( 5824):    at org.cocos2dx.lib.Cocos2dxRenderer.onDrawFrame(Cocos2dxRenderer.java:91)
E/MediaStore( 5824):    at android.opengl.GLSurfaceView$GLThread.guardedRun(GLSurfaceView.java:1531)
E/MediaStore( 5824):    at android.opengl.GLSurfaceView$GLThread.run(GLSurfaceView.java:1248)
D/MediaProvider(  787): object removed 188

Finaly got it working. Used this function: createExternalStoragePublicPicture() from this link: http://developer.android.com/reference/android/os/Environment.html#getExternalStoragePublicDirectory(java.lang.String)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM