i am developing a program which uses the android camera to take pictures. but when i capture the pic i will have 2 result pics both in /sdcard/dcim and in my output dir. this situation happens in my htc desire and sumsung p1000, but in my huwei device the pic would be saved only in my output dir, there is not a copy in /sdcard/dcim. why and how to fix it?
and this is my code to call the camera
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(new File(strFilePath)));
startActivityForResult(intent, CAMERA_RESULT_CODE_PIC_TAKEN);
I had have the same problem and could not solve it. The behaviour did not occur on all devices and/or all Android Versions, but i tryed to find out if a second copy exists and delete the copy. I used the following code to find the last taken picture.
String[] projection = new String[]{MediaStore.Images.ImageColumns._ID,MediaStore.Images.ImageColumns.DATA,MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME,MediaStore.Images.ImageColumns.DATE_TAKEN,MediaStore.Images.ImageColumns.MIME_TYPE};
final Cursor cursor = managedQuery(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,projection, null, null, MediaStore.Images.ImageColumns.DATE_TAKEN + " DESC");
if(cursor != null){
cursor.moveToFirst();
// you will find the last taken picture here
cursor.close();
}
But because of beeing unsatisfied by this solution,finally i decided to write a custom camera app to avoid the strange behaviour.
Related
I made an app. It has 2 options for uploading photo:
1) by taking a photo using camera
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, 1);
2) by picking from gallery
Intent intent = new Intent(Intent.ACTION_PICK,android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, 2);
My problem is getting file path after these intents in onActivityResult.
Is there any methods to get those paths for new File(path) , that also takes care of sdk level changes? For example till KitKat is 1 type of file system , after KitKat is other type.
My problem is getting file path after these intents in onActivityResult.
There will be no file path for the ACTION_IMAGE_CAPTURE approach, because you did not provide EXTRA_OUTPUT. If you do provide EXTRA_OUTPUT, then you already know what the file path is.
There is no file path for ACTION_PICK, insofar as there is no requirement that what the user picks be in a file that you have access to. For example, it could be an image on removable storage. Use a ContentResolver and methods like openInputStream() to get the content represented by the Uri that you are given.
If you can able to get path from camera then for Intent.ACTION_PICK you can directly get uri of image using data.getData() and then you can get file path using this method(as suggested in the link provided by Gennadii Saprykin
public String getRealPathFromURI(Uri uri) {
Cursor cursor = getContentResolver().query(uri, null, null, null, null);
cursor.moveToFirst();
int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA);
return cursor.getString(idx); }
I have an app that lets user choose music file from sdcard. To launch chooser intent I am using
Intent intent = new Intent();
intent.setType("audio/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(
Intent.createChooser(intent, "Complete action using"), 0);
But I am getting different absolute paths depending on what method user choose. If user uses ES File Explorer then I get /sdcard/Music/song.mp3 but if user uses some music app then I am getting /storage/sdcard0/Music/song.mp3. Its very confusing and my app requires me to know one final base path.
Environment.getExternalStorageDirectory() returns /storage/sdcard0/. Any help would be appreciated.
Note: in both cases
Uri uri = Uri.parse(new File(soundPath).getAbsolutePath());
mPlayer = MediaPlayer.create(this, uri);
works fine.
/sdcard is usually symlinked to the real(*) path in the filesystem (the /storage one) to stay compatible with early Android devices where /sdcard was the default.
Using Environment.getExternalStorageDirectory() is the method you should use. There is no guarantee that /sdcard or /storage/sdcard0 will work if you hardcode that path. Device manufacturers can use pretty much any filesystem layout they want but they will make sure that Environment knows the correct path.
(*) Starting Honeycomb & the "unified storage model" the real path is actually something like /data/media which is loop-mounted via fuse to /storage/sdcard0 (or whatever Environment tells you) to enforce the correct permission required for the WRITE_EXTERNAL_STORAGE permission.
Impromptu Q&A Session With Android Engineer Dan Morrill Brings To Light Reasons Behind Galaxy Nexus' Lack Of USB Mass Storage - second question has some details.
getAbsolutePath() is by the way not working in the same way as it does for desktop Java apps. On Android, the current working directory / root is always /. So getAbsolutePath() would always return the same as getPath() does and will at most prefix the path with a /.
Uris from File can be easily constructed via
Uri uri = Uri.fromFile(new File(soundPath));
that way you get a correct Uri using the file:// scheme which is not the case (and could lead to errors) if you use Uri.parse("/some/path")
Getting full path and file name:
Private String getPath(Uri u) {
String[] projection = { MediaStore.Audio.Media.DATA };
Cursor cursor = managedQuery(u, projection, null, null, null);
int column_index = cursor
.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
cursor.moveToFirst();
return cursor.getString(column_index);
}
use this on onActivityResult
String mpath = getPath(data.getData());
Note- even though im using phonegap, the question is not about some issue in that.
Hi, im developing a android app. my app is using phonegap 1.3.
mi problem...
Im using phonegap apis to take a picture and display it in my app. But whats happening is due to some reason the os kills my app after the camera is launched, so that after the photo is clicked, my app is relaunched and it doesnt get the info abt the taken picture.
As a workaround to this problem (the problem), i designed a phonegap plugin which on app start checks if the app had crashed while taking a picture (some flags in code), and if it is restarting after crash, it retrieves the Pic.jpg taken by the camera and tries to displays it. The problem is that its not able to get the right image, or even a proper .jpg file for that matter.
mi code...
Phonegap makes an intent to start the camera and passes the uri for the Pic.jpg that it creates into that intent which it passes to startActivityForResult.
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
File photo = new File(DirectoryManager.getTempDirectoryPath(ctx), "Pic.jpg");
intent.putExtra(android.provider.MediaStore.EXTRA_OUTPUT, Uri.fromFile(photo));
this.imageUri = Uri.fromFile(photo);
this.ctx.startActivityForResult((Plugin) this, intent, 0);
Note- The above code is from the file CameraLauncher.java of Phonegap.
Now, im assuming that the startActivityForResult stores the picture the user captures at the file which was created by 'photo' in the above code. So even if after the os closes the app while the camera is open (refer - the problem) the photo will be stored there. PLEASE correct me if this assumption is wrong, or if the photo might be being saved somewhere else.
So taking into account this assumption i wrote a plugin which retrieves this image using the same logic which Phonegap uses in CameraLauncher.java
Uri imageUri;
ExifHelper exif = new ExifHelper();
exif.createInFile(getTempDirectoryPath(ctx) + "/Pic.jpg");
exif.readExifData();
File photo = new File(getTempDirectoryPath(ctx), "Pic.jpg");
imageUri = Uri.fromFile(photo);
Bitmap bitmap = null;
bitmap = android.provider.MediaStore.Images.Media.getBitmap(this.ctx.getContentResolver(), imageUri);
ContentValues values = new ContentValues();
values.put(android.provider.MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
Uri uri = null;
try {
uri = this.ctx.getContentResolver().insert(android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
} catch (UnsupportedOperationException e) {
uri = this.ctx.getContentResolver().insert(android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI, values);
}
// Add compressed version of captured image to returned media store Uri
OutputStream os = this.ctx.getContentResolver().openOutputStream(uri);
bitmap.compress(Bitmap.CompressFormat.JPEG, 20, os);
os.close();
exif.createOutFile(getRealPathFromURI(uri, this.ctx));
exif.writeExifData();
bitmap.recycle();
bitmap = null;
System.gc();
result = new PluginResult(Status.OK, uri.toString());
This is roughly the same logic as Phonegap uses. (I've removed all exception handling n all for posting. So assume there are no compile errors n all.) So, im basically trying to retrieve the Pic.jpg and return it to my phonegap app. BUT whats happening is that im getting a corrupted file of abt 150kb that isn't even a jpg (doesnt open).
Please tell me if its even possible to retrieve images in this manner after the activity that started the camera as died. And if its possible then, what am i doing wrong. Please help!
As I mentioned over in your other SO question,
phonegap android app crashing due to low memory on opening camera
the problem is most probably the Sony implementation of the camera intent. You should try testing by adding a third party camera app and when you take a picture select that app and see if it still crashes. It probably won't.
The issue here was because of some changed code in the FileTransfer plugin of Phonegap.
I was able to retrieve an image taken by the camera, after my app restarted after the crash using the above code only. :)
I am simply trying to get the path of an image that the user selects and then convert it into a bitmap. The problem is, only some of the images in the gallery work when selected (by "work" I mean they are found to be a file that exists), while the others claim the file does not exist (even though the image is showing up in the gallery?). Even more strange is that this doesn't seem to be consistent, an image that was at one point considered to "exist" now claims to be nonexistent. My code is below:
-----The Intent-----
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, GALLERY_ACTIVITY);
-----onActivityForResult-----
Uri uri = intent.getData();
String [] proj={MediaStore.Images.Media.DATA};
Cursor cursor = managedQuery(uri,proj,null,null,null);
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
cursor.moveToFirst();
BitmapFactory.Options opts = new BitmapFactory.Options();<br/>
opts.inSampleSize = 2;<br/>
Bitmap b = BitmapFactory.decodeFile(cursor.getString(column_index),opts);
Any ideas on this will be greatly appreciated, thank you!
Matt.
Some images in gallery were loaded from external sources (such as Picasa), thus were not stored locally, causing local filepath reading failure. You can distinguish them by reading your uri value. I could not find a fix for this, perhaps this bug http://code.google.com/p/android/issues/detail?id=21234 can lure out a solution soon.
I am making an application which requires me to list all the images available on the SD-Card of the phone.
I tried querying the ContentResolver way i.e.
Cursor image = getContentResolver().query(Images.Media.EXTERNAL_CONTENT_URI, new String[]{Images.Media._ID,Images.Media.DATA,Images.Media.DISPLAY_NAME}, null, null, null);
but without any result.
Is there any way i can get the list or if that's not possible then is there any possible intent (e.g. PICK) by which I can allow the user to select a file and then access the path of the file the user selected??
//where contextObject is your activity
ContentResolver cr = contextObject.getContentResolver();
String[] columns = new String[] {
ImageColumns._ID,
ImageColumns.TITLE,
ImageColumns.DATA,
ImageColumns.MIME_TYPE,
ImageColumns.SIZE };
cur = cr.query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
columns, null, null, null);
My code is pretty much like yours (except broken down) and it works. You don't need to go about asking the Gallery Intent for stuff, it should work. My two guesses are:
1) Make sure your USB storage is not mounted, if it is you'll see no external images.
2) Maybe a permissions issue? Try adding GLOBAL_SEARCH permission to see if that helps at all.
You could use the gallery activity to select images, something like this:
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"),SELECT_IMAGE);
in the callback for the activity the file uri will be in the intent parameter