Copy image from internal storage to destination folder. (If destination not exist create one)
from the CommonsWare Community archivesAt 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.