Reputation: 1207
I want to pick image from gallery and copy it in to other folder in SDCard.
Code to Pick Image from Gallery
Intent photoPickerIntent = new Intent(Intent.ACTION_PICK);
photoPickerIntent.setType("image/*");
startActivityForResult(photoPickerIntent, REQUEST_CODE_CHOOSE_PICTURE_FROM_GALLARY);
I get content://media/external/images/media/681
this URI onActivityResult.
I want to copy the image,
Form path ="content://media/external/images/media/681
To path = "file:///mnt/sdcard/sharedresources/
this path of sdcard in Android.
How to do this?
Upvotes: 22
Views: 51851
Reputation: 67
You can copy image files to any other folder directory using Content Resolver from this function
fun copyImageFileToMediaStore(
context: Context,
sourceFilePath: String,
destinationFolder: File
) {
val sourceFile = File(sourceFilePath)
val extension = MimeTypeMap.getFileExtensionFromUrl(sourceFilePath)
val mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension)
val fileName = sourceFile.name
val inputStream = FileInputStream(sourceFile)
val resolver: ContentResolver = context.contentResolver
// Check if a file with the same name already exists in the destination folder
val projection = arrayOf(MediaStore.MediaColumns._ID)
val selection =
"${MediaStore.MediaColumns.DISPLAY_NAME} = ? AND ${MediaStore.MediaColumns.RELATIVE_PATH} = ? AND ${MediaStore.MediaColumns.DATA} = ?"
val selectionArgs = arrayOf(
fileName,
"${destinationFolder.path}/",
destinationFolder.absolutePath + File.separator + fileName
)
val cursor = resolver.query(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
projection,
selection,
selectionArgs,
null
)
if (cursor != null && cursor.count > 0) {
// File already exists in the MediaStore, do not insert it again
cursor.close()
return
}
// File does not exist in the MediaStore, insert it
val values = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, fileName)
put(MediaStore.MediaColumns.MIME_TYPE, mimeType)
put(MediaStore.MediaColumns.RELATIVE_PATH, destinationFolder.parent)
put(
MediaStore.MediaColumns.DATA,
destinationFolder.absolutePath + File.separator + fileName
)
}
var outputStream: FileOutputStream? = null
var uri: Uri? = null
try {
val contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI
uri = resolver.insert(contentUri, values)
if (uri == null) {
throw IOException("Failed to create new MediaStore record.")
}
outputStream = resolver.openOutputStream(uri) as FileOutputStream?
if (outputStream == null) {
throw IOException("Failed to get output stream.")
}
val buffer = ByteArray(4 * 1024)
var read: Int
while (inputStream.read(buffer).also { read = it } != -1) {
outputStream.write(buffer, 0, read)
}
outputStream.flush()
} catch (e: IOException) {
uri?.let { resolver.delete(it, null, null) }
uri = null
} finally {
inputStream.close()
outputStream?.close()
}
}
Call this function like this
val destinationFolder = File("/storage/emulted/0/DCIM/foldername")
val sourceFilePath = "/storage/emulted/0/DCIM/anyOtherFolder/abcd.jpeg"
copyImageFileToMediaStore(requireContext(), sourceFilePath, destinationFolder)
Upvotes: 0
Reputation: 1207
Thanks to all ... Working Code is Here..
private OnClickListener photoAlbumListener = new OnClickListener(){
@Override
public void onClick(View arg0) {
Intent photoPickerIntent = new Intent(Intent.ACTION_GET_CONTENT);
imagepath = Environment.getExternalStorageDirectory()+"/sharedresources/"+HelperFunctions.getDateTimeForFileName()+".png";
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);
}
};
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
switch(requestCode){
case 22:
Log.d("onActivityResult","uriImagePath Gallary :"+data.getData().toString());
Intent intentGallary = new Intent(mContext, ShareInfoActivity.class);
intentGallary.putExtra(IMAGE_DATA, uriImagePath);
intentGallary.putExtra(TYPE, "photo");
File f = new File(imagepath);
if (!f.exists())
{
try {
f.createNewFile();
copyFile(new File(getRealPathFromURI(data.getData())), f);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
startActivity(intentGallary);
finish();
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);
}
Upvotes: 36
Reputation: 3645
Even though I have upvoted the answer by @AAnkit, I borrowed and went ahead to modify some items. He mentions to use Cursor
but without proper illustration it can be confusing to newbies.
I think this is simpler than the most voted answer.
String mCurrentPhotoPath = "";
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(
imageFileName, /* prefix */
".jpg", /* suffix */
storageDir /* directory */
);
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
/*Then I proceed to select from gallery and when its done selecting it calls back the onActivityResult where I do some magic*/
private void snapOrSelectPicture() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
File photoFile = null;
try {
photoFile = createImageFile();
} catch (IOException ex) {
ex.printStackTrace();
}
if (photoFile != null) {
Uri photoURI = FileProvider.getUriForFile(this,
"com.example.android.fileprovider",
photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
startActivityForResult(Intent.createChooser(takePictureIntent, "SELECT FILE"), 1001);
}
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (resultCode == RESULT_OK) {
try {
/*data.getDataString() contains your path="content://media/external/images/media/681 */
Uri u = Uri.parse(data.getDataString());
Cursor cursor = getContentResolver().query(u, null, null, null, null);
cursor.moveToFirst();
File doc = new File(cursor.getString(cursor.getColumnIndex("_data")));
File dnote = new File(mCurrentPhotoPath);
FileOutputStream fout = new FileOutputStream(dnote, false);
fout.write(Files.toByteArray(doc));
} catch (Exception e) {
e.printStackTrace();
}
}
}
Upvotes: 0
Reputation: 5795
Was reading this link, here they are talking about four ways to copy files in Java,
so relevant for android as well.
Though author concludes that using 'channel' as used in @Prashant's answer are the best way, you may even explore other ways.
(I have tried first two, and both of them work find)
Upvotes: 0
Reputation: 3193
OutputStream out;
String root = Environment.getExternalStorageDirectory().getAbsolutePath()+"/";
File createDir = new File(root+"Folder Name"+File.separator);
if(!createDir.exists()) {
createDir.mkdir();
}
File file = new File(root + "Folder Name" + File.separator +"Name of File");
file.createNewFile();
out = new FileOutputStream(file);
out.write(data);
out.close();
Hope it will help u
Upvotes: 13
Reputation: 27549
one solution can be,
1) read bytes from inputStream of the picked file.
i get "content://media/external/images/media/681" this URI onActivityResult. You can get the file name by querying this Uri u got. get inputStream of it. read it into byte[].
here you go/
Uri u = Uri.Parse("content://media/external/images/media/681");
Cursor cursor = contentResolver.query(u, null, null, null, null); there is a column name "_data" which will return you the filename, from filename you can create inputstream,
you can now read this input stream
byte data=new byte[fis.available()];
fis.read(data);
So you have data(byte array) with images byte
2) create a file on to sdcard, and write with byte[] taken in step one.
File file=new File(fileOnSD.getAbsolutePath() +"your foldername", fileName);
FileOutputStream fout=new FileOutputStream(file, false);
fout.write(data);
as fileName you already have from the query method, use same here.
Upvotes: 5