Copy image from internal storage to destination folder. (If destination not exist create one)

from the CommonsWare Community archives

At July 3, 2020, 1:08am, arpit999 asked:

Hi, I would like to copy the image from the internal storage and it should copy in Image directory in internal storage.

I was getting the toast message but the image couldn’t find in folder. Right now I giving permission manually so don’t worry about that.

I also added permission in the manifest file.

Here is my code. Any help much appreciated.

    public class MainActivity extends AppCompatActivity {
    
        private static final int REQUEST_CODE_CHOOSE_PICTURE_FROM_GALLARY = 22;
        private static final String TAG = MainActivity.class.getSimpleName();
        Button btn_copy;
        private String imagepath;
        private Uri uriImagePath;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            btn_copy = findViewById(R.id.btn_copy);
    
    
        }
    
        public void CopyImage(View view) {
    
            Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
            imagepath = Environment.getExternalStorageDirectory() + "/Images";
            uriImagePath = Uri.fromFile(new File(imagepath));
            photoPickerIntent.setType("image/*");
            photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriImagePath);
            photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.name());
            photoPickerIntent.putExtra("return-data", true);
            startActivityForResult(photoPickerIntent, REQUEST_CODE_CHOOSE_PICTURE_FROM_GALLARY);
    
            Toast.makeText(this, "Hi hello", Toast.LENGTH_SHORT).show();
    
        }
    
    
        protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
            super.onActivityResult(requestCode, resultCode, data);
            if (resultCode == RESULT_OK) {
                switch (requestCode) {
    
                    case 22:
                        Log.d("onActivityResult", "uriImagePath Gallary :" + data.getData().toString());
                        Log.d("onActivityResult", "imagePath Gallary :" + imagepath);
    //                    Intent intentGallary = new Intent(this, ShareInfoActivity.class);
    //                    intentGallary.putExtra(IMAGE_DATA, uriImagePath);
    //                    intentGallary.putExtra(TYPE, "photo");
                        File f = new File(imagepath);
                        if (!f.exists()) {
                            try {
                                f.createNewFile();
                                Log.d(TAG, "onActivityResult: "+getRealPathFromURI(data.getData()));
                                copyFile(new File(getRealPathFromURI(data.getData())), f);
                            } catch (IOException e) {
                                // TODO Auto-generated catch block
                                e.printStackTrace();
                            }
                        }
    
    //                    startActivity(intentGallary);
    //                    finish();
                        Toast.makeText(this, "Copy Complete", Toast.LENGTH_SHORT).show();
                        break;
    
    
                }
            }
    
        }
    
        private void copyFile(File sourceFile, File destFile) throws IOException {
            if (!sourceFile.exists()) {
                return;
            }
    
            FileChannel source = null;
            FileChannel destination = null;
            source = new FileInputStream(sourceFile).getChannel();
            destination = new FileOutputStream(destFile).getChannel();
            if (destination != null && source != null) {
                destination.transferFrom(source, 0, source.size());
            }
            if (source != null) {
                source.close();
            }
            if (destination != null) {
                destination.close();
            }
    
    
        }
    
    
        private String getRealPathFromURI(Uri contentUri) {
    
            String[] proj = {MediaStore.Video.Media.DATA};
            Cursor cursor = managedQuery(contentUri, proj, null, null, null);
            int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
            cursor.moveToFirst();
            return cursor.getString(column_index);
        }
    }

At July 3, 2020, 1:31pm, mmurphy replied:

Step #1: Get an InputStream on the original content
Step #2: Get an OutputStream on your destination location
Step #3: Copy the bytes from the InputStream to the OutputStream

For files that you create, in places like getFilesDir(), feel free to use FileInputStream or FileOutputStream. If you get a Uri for something, and the scheme is file or content (or the obscure android.resource), always use openInputStream() or openOutputStream() on ContentResolver`.

I review this in https://wares.commonsware.com/app/internal/book/Jetpack/page/chap-content-001.html, though I use ACTION_OPEN_DOCUMENT rather than ACTION_GET_CONTENT.

uriImagePath = Uri.fromFile(new File(imagepath));

Uri.fromFile() has been banned (effectively) since Android 7.0. Please do not use it. Use FileProvider. Though, as we will see next, you do not need this Uri.

photoPickerIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriImagePath);

EXTRA_OUTPUT is not used for ACTION_GET_CONTENT, so you can remove this.

photoPickerIntent.putExtra("outputFormat", Bitmap.CompressFormat.PNG.name());
photoPickerIntent.putExtra("return-data", true);

These are undocumented Intent extras, may not have any effect, and probably should be removed.

File f = new File(imagepath);

imagepath may be null, as your app’s process may have been terminated while the content-selection UI is in the foreground. Consider holding onto this in the saved instance state Bundle (or using SavedStateHandle if you are using ViewModel).

private String getRealPathFromURI(Uri contentUri)

Please delete this method. ACTION_GET_CONTENT has nothing to do with MediaStore. You are assuming that every Uri that you might get from ACTION_GET_CONTENT somehow magically has a DATA column that represents a filesystem path. This is far from the case.