This is the code i used to get the uri of my image
Uri imageUri = data.getData();
How do I get the actual path of an image selected?
the Uri value/path that i am currently getting is
content://com.miui.gallery.open/raw/%2Fstorage%2Femulated%2F0%2FLightStick%2F144pixels.bmp
the correct filepath of the image that i need is for my other function is
/storage/emulated/0/LightStick/144pixels.bmp
The image selection function:
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(resultCode == RESULT_OK){//everything processed successfully
if(requestCode == IMAGE_GALLERY_REQUEST){ //hearing back from image gallery
//the address of the image on the SD card
Uri imageUri = data.getData();
BMPfilepath =imageUri.getPath();
//stream to read image data from SD card
InputStream inputStream;
try {
inputStream = getContentResolver().openInputStream(imageUri);//getting an input stream, based no the URI of image
Bitmap image = BitmapFactory.decodeStream(inputStream);//get bitmap from stream
imgPicture.setImageBitmap(image);//show image to user in imageview
} catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(this, "Unable to open image", Toast.LENGTH_LONG).show(); //let user know image unavail
}//catch
} //requestCode == IMAGE_GALLERY_REQUEST
}
The upload function which uses the imageUri from the previous function.
String path = imageUri.getPath().toString(); the app crashes and goes to a looper file when in debug
public void onUploadToArduino(){
String path = imageUri.getPath().toString();//<- app crashes and goes to a looper file when in debug
String sdpath = System.getenv("EXTERNAL_STORAGE");
String extStore = Environment.getExternalStorageDirectory().getPath();
String FILENAME = extStore + "/LightStick/144pixels.bmp";
String collected = null;
FileInputStream fis = null;
FileInputStream fileInputStream = null;
byte[] bytesArray = null;
try {
File file = new File(FILENAME);//<- this works
//File file = new File(path);//<- this doesnt
bytesArray = new byte[(int) file.length()];
//read file into bytes[]
fileInputStream = new FileInputStream(file);
fileInputStream.read(bytesArray);
How do I get the actual path of an image selected?
You don't. A Uri is not a file and may not point to a file, let alone one that you can access.
Use a ContentResolver and openInputStream() to get an InputStream on the content identified by the Uri. Ideally, just use the stream. If you need a File for some other API that is poorly written and does not support streams:
Create a FileOutputStream on some File that you control (e.g., in getCacheDir())
Use the InputStream and the FileOutputStream to copy the bytes to your file
Use your file
Related
I have not found the answer to this question anywhere.
The Bitmap Image is processed in The application, meaning there is no File path to get the Image.
Below is how to convert a Uri to Bitmap
if (requestCode == RC_PHOTO_PICKER && resultCode == RESULT_OK) {
Uri selectedImageUri = data.getData();
imageview.setImageURI(selectedImageUri);
try {
bitmap1 = MediaStore.Images.Media.getBitmap(this.getContentResolver(), selectedImageUri);
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(this, "" + e, Toast.LENGTH_SHORT).show();
}
bitmap1.compress(Bitmap.CompressFormat.JPEG, 7, bytearrayoutputstream);
BYTE = bytearrayoutputstream.toByteArray();
bitmap2 = BitmapFactory.decodeByteArray(BYTE, 0, BYTE.length);
imagetoo.setImageBitmap(bitmap2);
}
How do I now reconvert to a Uri
URI is super set of URL that means its a path to file . whereas Bitmap is a digital image composed of a matrix of dots.Bitmap represents a data and uri represents that location where data is saved .SO if you need to get a URI for a bitmap You just need to save it on a storage . In android you can do it by Java IO like below:First Create a file where you want to save it :
public File createImageFile() {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.US).format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File mFileTemp = null;
String root=activity.getDir("my_sub_dir",Context.MODE_PRIVATE).getAbsolutePath();
File myDir = new File(root + "/Img");
if(!myDir.exists()){
myDir.mkdirs();
}
try {
mFileTemp=File.createTempFile(imageFileName,".jpg",myDir.getAbsoluteFile());
} catch (IOException e1) {
e1.printStackTrace();
}
return mFileTemp;
}
Then flush it and you will get the URi
File file = createImageFile(context);
if (file != null) {
FileOutputStream fout;
try {
fout = new FileOutputStream(file);
currentImage.compress(Bitmap.CompressFormat.PNG, 70, fout);
fout.flush();
} catch (Exception e) {
e.printStackTrace();
}
Uri uri=Uri.fromFile(file);
}
This is just an example not idle code for all android version. To use Uri above and on android N you should use FileProvider to serve the file . Follow the Commonsware's answer.
Use compress() on Bitmap to write the bitmap to a file. Then, most likely, use FileProvider to serve that file, where getUriForFile() gives you the Uri corresponding to the file.
IOW, you do not "convert" a bitmap to a Uri. You save the bitmap somewhere that gives you a Uri.
I am developing an Android app. In my app, I am uploading multiple images to server using Retrofit network library. Before I uploading file I create a temporary file from bitmaps. Then delete them after uploaded.
photoFiles = new ArrayList<File>();
MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
int index = 0;
for(Bitmap bitmap: previewBitmaps)
{
File file = null;
try{
String fileName = String.valueOf(System.currentTimeMillis())+".jpeg";
file = new File(Environment.getExternalStorageDirectory(), fileName); // create temporary file start from here
if(file.exists())
{
file.delete();
}
OutputStream os = new BufferedOutputStream(new FileOutputStream(file));
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, os);
os.close();
photoFiles.add(file);
requestBodyBuilder.addFormDataPart("files",file.getName(), RequestBody.create(MediaType.parse("image/png"),file));
}
catch (Exception e)
{
Toast.makeText(getBaseContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
index++;
}
//Upload process goes here and delete files back after upload
Using above code, all working fine. But the problem is I have to create temporary files. I do not want to create temporary files. What I want to do is I create array list of Uri string when I pick up the file. Then on file upload, I will convert them to file back and do the upload process.
photoFiles = new ArrayList<File>();
MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
int index = 0;
for(Bitmap bitmap: previewBitmaps)
{
File file = null;
try{
Uri uri = Uri.parse(photosUriStrings.get(index));
file = new File(getPathFromUri(uri));
Toast.makeText(getBaseContext(),getPathFromUri(uri),Toast.LENGTH_SHORT).show();
photoFiles.add(file);
requestBodyBuilder.addFormDataPart("files",file.getName(), RequestBody.create(MediaType.parse("image/png"),file));
}
catch (Exception e)
{
Toast.makeText(getBaseContext(),e.getMessage(),Toast.LENGTH_SHORT).show();
}
index++;
}
As you can see in the above, I am converting the URI string back to file and then upload it. But this time retrofit unable to upload the file. File is not null as well. So I am pretty sure the error is with converting uri string back to image file back because my old code above working fine. Why can I not do that? How can I successfully convert from URI to image file back please?
I found this
Convert file: Uri to File in Android
and
Create File from Uri type android
both not working.
I am not clear about your question but I think this may help you. This single line code will help you to convert URI to file and show in your view.
Picasso.with(getContext()).load("URI path").into(holder.imgID);
I am trying to create an app that will store some PDf files as base64 encoded Strings in a database and then later decode them and dispay them (with an Intent to open other PDF reader).
But something doesn't work properly. I know that the byte array is the same before and after storage as encoded String, so that isn't the problem.
I think the problem is somewhere in the process of creating a File to open with the intent, but I'm not sure.
Creating the String:
byte[] b = Files.toByteArray(pdf);
String encodedFile = Base64.encodeToString(b, Base64.DEFAULT);
pdf is the File I get from this:
else if (requestCode == PICK_PDF_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null)
{
Uri uri = data.getData();
try {
String fileName = uri.toString();
fileName = fileName.substring(fileName.length()-10);
service.addPDF(order, fileName, new File(uri.getPath()));
} catch (IOException e) {
e.printStackTrace();
}
updateFileList();
}
Getting File from String:
case PDF:
try {
byte[] pdfAsBytes = Base64.decode(file.getContent(), Base64.DEFAULT);
File dir = getStorageDir();
File pdffile = new File(dir, file.getName());
if(!pdffile.exists())
{
pdffile.getParentFile().mkdirs();
pdffile.createNewFile();
}
Files.write(pdfAsBytes, pdffile);
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(Uri.fromFile(pdffile), "application/pdf");
pdfIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(pdfIntent);
} catch (IOException e) {
e.printStackTrace();
}
break;
This code runs with no errors, but the PDF viewer cannot display the file. I have tried with several viewers. I suspect the resulting file
Turns out I needed to save to external storage instead of the dir.
File dir = getStorageDir();
Should be
File dir = Environment.getExternalStorageDirectory();
Then it works.
I've got an Image Uri, retrieved using the following:
public Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
This works just amazing for Intents that require an Image URI, etc (so I know for sure the URI is valid).
But now I want to save this Image URI to a file on the SDCARD. This is more difficult because the URI does not really point at a file on the SDCARD or the app.
Will I have to create a bitmap from the URI first, and then save the Bitmap on the SDCARD or is there a quicker way (preferable one that does not require the conversion to a bitmap first).
(I've had a look at this answer, but it returns file not found - https://stackoverflow.com/a/13133974/1683141)
The problem is that the Uri you've been given by Images.Media.insertImage() isn't to an image file, per se. It is to a database entry in the Gallery. So what you need to do is read the data from that Uri and write it out to a new file in the external storage using this answer https://stackoverflow.com/a/8664605/772095
This doesn't require creating a Bitmap, just duplicating the data linked to the Uri into a new file.
You can get the data using an InputStream using code like:
InputStream in = getContentResolver().openInputStream(imgUri);
Update
This is completely untested code, but you should be able to do something like this:
Uri imgUri = getImageUri(this, bitmap); // I'll assume this is a Context and bitmap is a Bitmap
final int chunkSize = 1024; // We'll read in one kB at a time
byte[] imageData = new byte[chunkSize];
try {
InputStream in = getContentResolver().openInputStream(imgUri);
OutputStream out = new FileOutputStream(file); // I'm assuming you already have the File object for where you're writing to
int bytesRead;
while ((bytesRead = in.read(imageData)) > 0) {
out.write(Arrays.copyOfRange(imageData, 0, Math.max(0, bytesRead)));
}
} catch (Exception ex) {
Log.e("Something went wrong.", ex);
} finally {
in.close();
out.close();
}
Official facebook App has a bug, when you try to share an image with share intent, the image gets deleted from the sdcard. This is the way you have to pass the image to facebook app using the uri of the image:
File myFile= new File(Environment.getExternalStorageDirectory(), "car.jpg");
Uri uri = Uri.fromFile(myFile);
i.putExtra(Intent.EXTRA_STREAM, uri);
Then, suppose that if i create a copy from the original myFile object, and i pass the uri of the copy to facebook app, then, my original image will not be deleted.
I tried with this code, but it doesn't work, the original image file is still getting deleted:
File myFile= new File(Environment.getExternalStorageDirectory(), "car.jpg");
File auxFile=myFile.getAbsoluteFile();
Uri uri = Uri.fromFile(auxFile);
Can someone tell me how to do a exact copy of a file that doesn't redirect to the original File?
Please check: Android file copy
The file is copied byte by byte so no reference to the old file is maintained.
Here, this should be able to create a copy of your file:
private void CopyFile() {
InputStream in = null;
OutputStream out = null;
try {
in = new FileInputStream(<file path>);
out = new FileOutputStream(<output path>);
copyFile(in, out);
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch(Exception e) {
Log.e("tag", e.getMessage());
}
}
private void copyFile(InputStream in, OutputStream out) throws IOException {
byte[] buffer = new byte[1024];
int read;
while((read = in.read(buffer)) != -1){
out.write(buffer, 0, read);
}
}