Pictures wont save on Samsung Nexus - android

I have a Problem. I start from my own Application the Build-In Photoapplication with a Photo-Intent.
String photoName = System.currentTimeMillis() + ".jpg";
File file = new File(getFilesDir(),//Environment.getExternalStoragePublicDirectory(
//Environment.DIRECTORY_DCIM),
photoName); // Anlegen der Datei im entsprechenden
// Verzeichnis
FileOutputStream fos = null;
try {
fos = openFileOutput(photoName, Context.MODE_WORLD_WRITEABLE);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
fos.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
outputFileUri = Uri.fromFile(file);
intentPhoto.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
//startActivity(intentPhoto);
startActivityForResult(intentPhoto, TAKE_PICTURE);
This is my Code to start the Activity. As you can see, the first thing i do is to set up the file in the directory and then give the intent the location of the file to store it.
But everytime i take a picture it is not saved to the Pictures Directory. The only way to save the picture is to turn off the phone and restart it. Then every picture I have taken befor is there. This happens since the last updated to 4.1.1. Befor i updated the phone, everything worked fine, but since the update I have this problem.
Can somebody help me? Does anyone have the same Issue?

Make sure you offer the new file to be scanned:
MediaScannerConnection.scanFile(this,
new String[] { file.toString() }, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
// code to execute when scanning is complete
}
});
You can pass in a null argument for the OnScanCompletedListener if you don't need to be notified when the scanner has picked it up, but you might want to at least put a logging statement there.

It works fine now, the problem was that I create the File by my self, with:
File file = new File(..);
But you have to use:
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.TITLE, "IMG_"+ timeStamp+.jpg");
And put it into the intent to save the file at once without restarting the phone.

Related

Save to Gallery - Android

I've a strange (and oddly specific) issue with saving to the gallery on Android.
A bit of background: The app I'm developing needs to be able to save images to the gallery, which has been well discussed on here before. However, there's a specific requirement for this project which is I need to be able to tag it with a specific date/time.
I've tried several methods to get this to work correctly and so far the best I have is a workaround.
What I'm doing at the moment is generating the image, saving it to a file and setting the created date in the EXIF data. I then open the Google Photos app and it shows up in the gallery, showing the correct date and time and is in the correct place within the gallery.
The issue with this however, is that it doesn't automatically show in any other gallery software (for example, the OEM gallery apps that may be shipped with a given device), nor does it show if the Google Photos app is open at the time of saving; It must be closed and relaunched in order for it to show.
Now, if I run a media scan it ignores the EXIF data and the image shows up as the last image created.
Here's the code I'm currently using:
static class InsertImageObj{
public String url;
public long id;
}
public static InsertImageObj insertImage(Bitmap source,
String title, long time) {
String path = createDirectoryAndSaveFile(source, title, time);
String stringUrl = path;
InsertImageObj retVal = new InsertImageObj();
retVal.url = stringUrl;
return retVal;
}
private static String createDirectoryAndSaveFile(Bitmap imageToSave, String fileName, long dateTime) {
File directory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM); //DCIM = Digital Camera Image. This is where camera photos go!
if (!directory.exists()) {
directory.mkdirs();
}
File file = new File(directory, fileName);
if (file.exists()) {
file.delete();
}
try {
FileOutputStream out = new FileOutputStream(file);
imageToSave.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
ExifInterface ei = new ExifInterface(file.getAbsolutePath());
ei.setAttribute(ExifInterface.TAG_DATETIME, convertToExifDateTime(dateTime));
ei.setAttribute(ExifInterface.TAG_DATETIME_ORIGINAL, convertToExifDateTime(dateTime));
ei.setAttribute(ExifInterface.TAG_DATETIME_DIGITIZED, convertToExifDateTime(dateTime));
ei.saveAttributes();
} catch (Exception e) {
e.printStackTrace();
}
return file.getAbsolutePath();
}
private static String convertToExifDateTime(long timestamp) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss", Locale.getDefault());
return sdf.format(new Date(timestamp));
}
I've also tried running setLastModified on the file (which doesn't work, OS permissions or something or other) and using a MediaScannerConnection instance to scan the individual file once it has been saved. The latter, however causes the system to ignore the date/time tags in the Exif data.
I also tried inserting the image into the gallery via a ContentResolver instance and setting the DATE_ADDED and DATE_TAKEN fields, again to no avail.
Is there something really, really obvious I've missed here?
You need to save your image in the media store provider
Use this function
public static void imageToGallery(Context context, String fileName) {
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DATE_TAKEN, System.currentTimeMillis());
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.MediaColumns.DATA, fileName);
context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
}
So, after saving your image, call imageToGallery.
Images are only visible in gallery apps if they are added to the android-media-db.
You can ask MediaScannerConnection.scanFile(...) to add the new photo-file to the android-media-db.
On some androiddevices (but not on all) the mediascanner starts automatically.
Also note: you should save the new photo as ".../DCIM/myApp/myPhotoName.jpg" instead of ".../DCIM/myPhotoName.jpg"
Use this function. Its working for me!
private void galleryAddPic() {
File f = new File(imageFilePath);
try {
MediaStore.Images.Media.insertImage(getActivity().getContentResolver(),
f.getAbsolutePath(), f.getName(), null);
getActivity().sendBroadcast(new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(f)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}

[Android ]Intent.ACTION_VIEW - Not found

I am having an issue, I have never had problem opening files via ACTION_VIEW the next way:
File file = new File(getActivity().getFilesDir(), TEMP_FILE_NAME);
String dataType = "image/*";
if (file.exists()) {
Intent fileIntent = new Intent(Intent.ACTION_VIEW);
fileIntent.setDataAndType(Uri.fromFile(file), dataType);
fileIntent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
Intent intent = Intent.createChooser(fileIntent, "Open file");
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
Log.e(TAG, "There is a problem when opening the file");
}
} else {
Toast.makeText(getContext(), "Invalido", Toast.LENGTH_LONG).show();
}
The problem I am having right now is that even though the file exists when I choose the app to open the file it immediately closes and tells me Not found. I have put the image I am loading in an image view and there is no problem, so the file is valid but for some reason it has conflicts when I am opening it via intent.
I am aware that it may have something to do with the way I am creating the file, I am retrieving it from Google drive so I am writing the file using the Apache Commons library the next way:
DriveContents contents = result.getDriveContents();
InputStream inputStream = contents.getInputStream();
File file = new File(getActivity().getFilesDir(), TEMP_FILE_NAME);
try {
OutputStream outputStream = new FileOutputStream(file);
IOUtils.copy(inputStream, outputStream);
IOUtils.closeQuietly(inputStream);
IOUtils.closeQuietly(outputStream);
} catch (IOException e) {
e.printStackTrace();
}
What is it I am doing wrong? I am not totally sure if the problem has to do with the copy method executing asynchronously or something like that.
Thanks in advance.
I have never had problem opening files via ACTION_VIEW the next way
That code will never work, as third-party apps have no rights to work with files on getFilesDir() of your app.
What is it I am doing wrong?
You are attempting to serve an inaccessible file to third-party programs. Use FileProvider to serve the file, using FileProvider.getUriForFile() to get the Uri to use in your ACTION_VIEW Intent.

Saving a bitmap to disk/gallery in Android 4.3

I've been using the way the system saves screenshots to save my bitmaps to the disk and gallery. This works in Android 4.2 and before but not in Android 4.3.
Relevant code :
Uri imageUri = resolver.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
OutputStream out = resolver.openOutputStream(uri);
Full code here.
In 4.3 (new Nexus 7) however, I get a FileNotFoundException on the second line. I couldn't see any changes in 4.3 relevant to this on the website.
So what is the right way to save an image to the disk and gallery?
Verified :
storage is mounted with this method
imageUri is not null (usually something like "content://media/external/images/media/2034")
manifest has permission android.permission.WRITE_EXTERNAL_STORAGE
This is the way I save bitmaps to the Gallery:
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
Uri contentUri; //instantiate Uri with location of image
mediaScanIntent.setData(contentUri);
context.sendBroadcast(mediaScanIntent);
In your manifest file try with change target sdk to 18.-
<uses-sdk android:minSdkVersion="7"
android:targetSdkVersion="18"/>
It might solve your prob(May not). In 4.3 JELLY_BEAN_MR2, android did couple of changes and android clearly written that Your app might misbehave in a restricted profile environment. so please look at http://developer.android.com/about/versions/android-4.3.html
I have these permission in my Manifest.
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
But I am using a Target SDK version 15. Is there a requirement that you have to use a target SDK 18?
BTW:
Here is a sample code for downloading profile pictures from Facebook:
private class DownloadProfilePicTask extends AsyncTask<Void,String,String> {
Bitmap profilePic;
String fileName;
String id;
String type;
URL img_value;
public DownloadProfilePicTask(String i,String ty)
{
id = i;
if(id==null)
{
//Log.v("Id is null", "Error");
}
//Log.v("Download Profile Pic Task initialized for id:",id);
type = ty;
}
#Override
protected String doInBackground(Void...param) {
String root = Environment.getExternalStorageDirectory().toString();
if(root==null)
{
return null;
}
try{
profilePic = BitmapFactory.decodeStream(img_value.openConnection().getInputStream());
}
catch (IOException e) {
e.printStackTrace();
}
if(profilePic == null)
{
//Log.v("profilePic is null", "Error");
}
//Log.v("Root for saving images",root );
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
fileName = root + "/saved_images/" + id + ".png";
//Log.v("filename is ",fileName);
File file = new File (fileName);
fileName = file.getPath();
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
profilePic.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
return id;
}
#Override
protected void onPreExecute()
{
try
{
img_value = new URL("http://graph.facebook.com/"+id+"/picture?type=" + type);
}
catch (MalformedURLException e) {
e.printStackTrace();
}
}
#Override
protected void onPostExecute(String result) {
}
}
and then I just call:
new DownloadProfilePicTask(id,type).execute();
to download and automatically save images.
Note: You will have to play with filePath a bit for exact location.
There some changes in the fileSystem on Android 4.3 to start to avoid dev. to directly write in "/sdcard" or "/mnt/sdcard" but use the android ExternalStorage system. (http://source.android.com/devices/tech/storage/index.html)
N.B. : ExternalStorage can be an internal memory :p
For your case, have you tryed to use a method based on getExternalStorage ?
(like this : Find an external SD card location)

How to SetModifiedDate() Drive SDK

i'm developing an app using google drive SDK currently on Android using eclipse, i encounter an error which happen everytime i try to update modified date from file that i upload. this my code.
com.google.api.services.drive.model.File f=null;
File a=new File(file[1]);
com.google.api.services.drive.model.File body = new com.google.api.services.drive.model.File();
body.setTitle(file[1].substring(file[1].lastIndexOf("/")+1, file[1].length()));
Uri selectedUri = Uri.fromFile(a);
String fileExtension
= MimeTypeMap.getFileExtensionFromUrl(selectedUri.toString());
String mimeType
= MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileExtension);
body.setMimeType(mimeType);
System.out.println(DateTime.parseRfc3339(file[2]));
body.setModifiedDate(DateTime.parseRfc3339(file[2]));
//this modified date code causing error
FileContent mediaContent = new FileContent(mimeType, a);
try {
f = service.files().insert(body, mediaContent).setConvert(true).execute();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
handleException(e);
}
can someone tell me how to setModifiedDate in correct way, i'm totally stuck here..
thanks in advance
You can only set the date on a files().update not on files().insert. Also make sure you set the parameter setModifiedDate to true if you use update.
service.files().update(body,mediacontent).setSetModifiedDate(true).execute();

Android Display Camera Image In New Activity

So far I have my app taking a picture creating a new folder on the SD Card and saving the pictuers into the new folder.
I'm trying to get it so once the picture has been took it will display in a new Activity with two buttons that say "Use" or "Retake". So far the image saving is working perfectly fine but once the image has been took and it tries to open the new Activity it just stays on the camera Activity and shows the image which I cant use as it has a surfaceView onit.
In my LogCat I get the error "Oh, no reference" which is set to show if it can't find the picture, which is why im thinking it may be because I am not calling the picture from the correct place in my Punch.java.
So basiclly I am trying to once an image has been took the app to open a New Activity "Punch.java" and display the image that has just been took.
UPDATE Thanks to Lumis (code below has been updated)
Changed
intent.putExtra("filepath",uriSavedImage);
to
intent.putExtra("filepath",uriSavedImage.toString());
Which now opens the new Activity but still cannot see the image.
UPDATE 2 Punch.java
I have updated my Punch.java as with the new code if i change (myRef) to "/sdcard/Punch/image_0.jpg" I can see that image but I need it to referance to the image that was just taken with the camera which is something to do with this line I think intent.putExtra("filepath",uriSavedImage.toString());
Update 3
Nearly working perfectly now using intent.putExtra("filepath",Uri.parse(output.getAbsolutePath()).toString()); but for some reason it is still putting mnt/sdcard at the start it just needs to be sdcard/
Ok now working fine /mnt/sdcard is when the sdcard was mounted to the computer while i took the picture.
In my Camera Activity I have
PictureCallback myPictureCallback_JPG = new PictureCallback(){
public void onPictureTaken(byte[] arg0, Camera arg1) {
// TODO Auto-generated method stub
/*Bitmap bitmapPicture
= BitmapFactory.decodeByteArray(arg0, 0, arg0.length); */
int imageNum = 0;
Intent imageIntent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
File imagesFolder = new File(Environment.getExternalStorageDirectory(), "Punch");
imagesFolder.mkdirs(); // <----
String fileName = "image_" + String.valueOf(imageNum) + ".jpg";
File output = new File(imagesFolder, fileName);
while (output.exists()){
imageNum++;
fileName = "image_" + String.valueOf(imageNum) + ".jpg";
output = new File(imagesFolder, fileName);
}
Uri uriSavedImage = Uri.fromFile(output);
imageIntent.putExtra(MediaStore.EXTRA_OUTPUT, uriSavedImage);
OutputStream imageFileOS;
try {
imageFileOS = getContentResolver().openOutputStream(uriSavedImage);
imageFileOS.write(arg0);
imageFileOS.flush();
imageFileOS.close();
Toast.makeText(AndroidCamera.this,
"Image saved",
Toast.LENGTH_LONG).show();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
Intent intent = new Intent(getBaseContext(), Punch.class);
intent.putExtra("filepath",uriSavedImage.toString());
//just using a request code of zero
int request=0;
startActivityForResult(intent,request);
}};
And my Punch.java which is the next Activity is:
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.punch);
String myRef = this.getIntent().getStringExtra("filepath");
File imgFile = new File(myRef);
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
ImageView myImage = (ImageView) findViewById(R.id.imagepunch);
myImage.setImageBitmap(myBitmap);
}
}
}
I think it is the file path issue. You submitted your file path as URI but you are reading it in the viewer activity as a string.
Perhaps you neet to change this line into:
intent.putExtra("filepath",uriSavedImage.toString());
Or
intent.putExtra("filepath",Uri.parse(output.getAbsolutePath()).toString());
Different version of android may not work the same when it comes to file path, so you need to experiment using Uri.parse(fileStr) or String...
Just looking at your code and your approach, I think what you would typically see in this scenario is a new content handler registered so that it appears under the "Share" option of the camera / image library. This way, you are not getting involved in the use/retake logic which is essentially redundant for built-in Android functionality. Think of an app like Evernote or Picasa. You take a picture (or look one up that you took previously) and select "Share". One of the Share options, along with Picasa, Email, etc would be your app. That is how I would do it.

Categories

Resources