Reputation: 4993
Man, I am still not able to save a picture when I send an intent asking for a photo to be taken. Here's what I am doing:
Make a URI representing the pathname
android.content.Context c = getApplicationContext();
String fname = c.getFilesDir().getAbsolutePath()+"/parked.jpg";
java.io.File file = new java.io.File( fname );
Uri fileUri = Uri.fromFile(file);
Create the Intent (don't forget the pkg name!) and start the activity
private static int TAKE_PICTURE = 22;
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE );
intent.putExtra("com.droidstogo.boom1." + MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult( intent, TAKE_PICTURE );
The camera activity starts, and I can take a picture, and approve it. My onActivityResult()
then gets called. But my file doesn't get written.
The URI is: file:///data/data/com.droidstogo.boom1/files/parked.jpg
I can create thumbnail OK (by not putting the extra into the Intent), and can write that file OK, and later read it back).
Can anyone see what simple mistake I am making? Nothing obvious shows up in the logcat - the camera is clearly taking the picture. Thanks,
Peter
I should mention that I have the appropriate permissions set in the AndroidManifest.xml file:
<uses-permission android:name="android.permission.READ_OWNER_DATA" />
<uses-permission android:name="android.permission.WRITE_OWNER_DATA" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-library android:name="com.google.android.maps" />
</application>
Any ideas? Any ideas on things to try, to get more info about the problem?
Upvotes: 8
Views: 16106
Reputation: 136
As Steve said, you should save your picture in your SD card. The directory where you are trying to save is private and unless you have your device rooted you will can't write there. Try replace this line:
String fname = c.getFilesDir().getAbsolutePath()+"/parked.jpg";
with this line
String fname = Environment.getExternalStorageDirectory().getAbsolutePath() + "somePathYouKnownExists" + +"/parked.jpg";
This should be enough.
Upvotes: 0
Reputation: 43412
As Steve H said you can't just use file:///data/data/com.droidstogo.boom1/files/parked.jpg for that. It's your application private directory and camera can't write there. You can use some SD card file for example - it's available for all.
As stealthcopter said, intent extra is just MediaStore.EXTRA_OUTPUT without your package name.
Not an issue just FYI. I guess none of the permissions you specified are actually required for this operation.
Here's my code sample:
final int REQUEST_FROM_CAMERA=1;
private File getTempFile()
{
//it will return /sdcard/image.tmp
return new File(Environment.getExternalStorageDirectory(), "image.tmp");
}
private void getPhotoClick()
{
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT,Uri.fromFile(getTempFile()));
startActivityForResult(intent, REQUEST_FROM_CAMERA);
}
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_FROM_CAMERA && resultCode == RESULT_OK) {
InputStream is=null;
File file=getTempFile();
try {
is=new FileInputStream(file);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
//On HTC Hero the requested file will not be created. Because HTC Hero has custom camera
//app implementation and it works another way. It doesn't write to a file but instead
//it writes to media gallery and returns uri in intent. More info can be found here:
//http://stackoverflow.com/questions/1910608/android-actionimagecapture-intent
//http://code.google.com/p/android/issues/detail?id=1480
//So here's the workaround:
if(is==null){
try {
Uri u = data.getData();
is=getContentResolver().openInputStream(u);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
//Now "is" stream contains the required photo, you can process it
DoSomeProcessing(is);
//don't forget to remove the temp file when it's not required.
}
}
Upvotes: 7
Reputation: 55714
Your problem might be with the directory you're trying to store the file in. To save files to the SD card you don't need any special permissions, but the way you get the folder reference is different to how you've done it. It also depends on whether you want to save the image in a way that can be retrieved by the MediaStore (i.e. things like the gallery or albums application, or any other app that relies on those to find images) or not. Assuming you want it to be listed in the MediaStore, here's the code to do that:
ContentValues newImage = new ContentValues(2);
newImage.put(Media.DISPLAY_NAME, "whatever name you want shown");
newImage.put(Media.MIME_TYPE, "image/png");
Uri uri = contentResolver.insert(Media.EXTERNAL_CONTENT_URI, newImage);
try {
Bitmap bitmap = //get your bitmap from the Camera, however that's done
OutputStream out = contentResolver.openOutputStream(uri);
boolean success = bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.close();
if (success){
Log.d("Image Writer", "Image written successfully.");
} else {
Log.d("Image Writer", "Image write failed, but without an explanation.");
}
} catch (Exception e){
Log.d("Image Writer", "Problem with the image. Stacktrace: ", e);
}
On my emulator running v1.5, that's successfully saves a bitmap onto the SD card in the DCIM/Camera folder with its file name being current time. (The time is saved in milliseconds since 1st Jan 1970, also known as the "Epoch" for some reason.)
Upvotes: 1
Reputation: 14176
Is it because you've added an extra dot:
intent.putExtra("com.droidstogo.boom1."
Instead of:
intent.putExtra("com.droidstogo.boom1"
Upvotes: 1