The exif interface is used in my application to write new data to a stored image,captured using the camera intent in Android.
The problem is when the image file is output to storage, my code for updating the attributes of the image doesn't actually update the stored image when I view details of the image in the gallery.
For example I use the UserComment tag to add some generic text as a test input but this is not displayed in the image's details on the device.
My question is, how can I check if the data is actually being written to the file?
If I know that the attributes are being appended to the image then I can debug the storage of the file as the problem.
This is the getOutputPhotoFile() method which retrieves the last captured image in the directory of the project:
private File getOutputPhotoFile() throws IOException {
File directory = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), getPackageName());
if (!directory.exists()) {
if (!directory.mkdirs()) {
Log.e(TAG, "Failed to create storage directory.");
return null;
}
}
String timeStamp = new SimpleDateFormat("yyyMMdd_HHmmss", Locale.ENGLISH).format(new Date());
File[] files = directory.listFiles();
File origFile = new File(directory.getPath(), "IMG_" + timeStamp + ".jpg");
if(files.length!=0) {
File newestFile = files[files.length-1];
origFile = new File(directory.getPath() + File.separator + newestFile.getName());
}
String mString = "Generic Text..";
ExifInterface exifFile = new ExifInterface(origFile.getAbsolutePath());
exifFile.setAttribute("UserComment", mString);
exifFile.setAttribute(ExifInterface.TAG_GPS_LATITUDE,
String.valueOf(latituteField.toString()));
exifFile.setAttribute(ExifInterface.TAG_GPS_LONGITUDE,
String.valueOf(longitudeField.toString()));
exifFile.saveAttributes();
return origFile;
}
Upon looking into ExifInterface API, it seems that there is no Exif TAG with the name "UserComment".
It seems that it only supports TAGs mentioned in the given API.
After setting the location values, you can use same ExifInterface API getAttribute(ExifInterface.TAG_GPS_LATITUDE,) and getAttribute(ExifInterface.TAG_GPS_LONGITUDE) to check whether the file has the values set.
Related
Here is My Code the way I'm creating my folder in app Specific directory.
private File createDirectory(String dirName) {
File file = new File(getApplicationContext().getExternalFilesDir(dirName) + "/" + dirName);
if (!file.exists()) {
file.mkdir();
}
return file;
}
your method returns File, which is a directory. now you have to create new image file object
File dir = createDirectory("imagesDirectory");
File file = new File(dir.getAbsolutePath(), "imageName.jpg");
FileOutputStream outStream = new FileOutputStream(file);
now you have to compress your Bitmap as JPG (as name set above) and feed this stream
Bitmap pictureBitmap = ...; // your image
pictureBitmap.compress(Bitmap.CompressFormat.JPEG, 90, outStream);
and don't foregt to close stream
outStream.flush();
outStream.close();
if you want lossless format you can use PNG (Bitmap.CompressFormat.PNG), don't forget to name your file extension accordingly
you can only write in your app-specific files
File dir_ = new File(context.getFilesDir(), "YOUR_DIR");
dir_.mkdirs();
you can use the function "getExternalFilesDir" and you change the value between in parenthesis. Here I put "Environment.DIRECTORY8DCIM" but there are others (you can check in the android developer web site).
I show you an exemple:
private fun getOutputMediaFile(): File? {
val mediaStorageDir = getExternalFilesDir(Environment.DIRECTORY_DCIM).let {
File(it, "[name_folder]").apply { mkdirs() } }
Log.v(TAG, "storage: $mediaStorageDir") ///storage/emulated/0/Android/data/[name_of_your_program]/files/DCIM/[name_folder]
if (!mediaStorageDir?.exists()!!){
if (!mediaStorageDir.mkdirs()) {
Log.v(TAG, "Failed to create directory")
return null
}
}
}
Hope that work for you :)
I want to upload simple image file to google cloud storage
when the upload is to root bucket upload happens smoothly but when i try to upload image to folder within a bucket it fails
following is my code to do so
static Storage sStorage;
public static void uploadFileToServer(Context context, String filePath) {
Storage storage = getStorage(context);
StorageObject object = new StorageObject();
object.setBucket(BUCKET_NAME);
File sdCard = Environment.getExternalStorageDirectory();
File file = new File(sdCard + filePath);
try {
InputStream stream = new FileInputStream(file);
String contentType = URLConnection.guessContentTypeFromStream(stream);
InputStreamContent content = new InputStreamContent(contentType, stream);
Storage.Objects.Insert insert = storage.objects().insert(BUCKET_NAME, null, content);
insert.setName(file.getName());
insert.execute();
} catch (Exception e) {
e.printStackTrace();
}
}
i tried putting bucket name like [PARENT_BUCKET]/[CHILD_FOLDER]
but it doesn't work
GCS has a flat namespace, with "folders" being just a client-supported abstraction (basically, treating "/" characters in object names as the folder delimiter).
So, to upload to a folder you should put just the bucket name in the bucket field of the request, and put the folder at the beginning of of the object field. For example, to upload to bucket 'my-bucket', folder 'my-folder' and file-within-folder 'file', you'd set bucket name to 'my-bucket' and object name to 'my-folder/file'.
If I save a Bitmap called "picture.jpg" in internal storage and some steps later I save another Bitmap called "picture.jpg" too, what happens then?
Does the second Bitmap overwrite the first or are there two Bitmaps with the same name then?
It will show you an error, I suggest you could use a dynamic file name or delete it before saving, in the case of dynamic, you could use something like this:
static int fCount = 0;
File file = new File(Environment.getExternalStorageDirectory()
+ File.separator + "/test" + String.valueOf(fCount++) +".jpg" );
Or
File file = new File(getExternalCacheDir(), "test.jpg" ); if (file.exists()) { boolean deleted = file.delete(); }
This is my function for converting blob to mp3:
private void convertByyeToMP3(byte[] bytearray,String trackName) {
try {
ContextWrapper c = new ContextWrapper(getApplicationContext());
File directory = new File(c.getFilesDir().getAbsolutePath()
+ "/Music");
if (!directory.exists()){
directory.mkdir();
}
File tempMp3 = File.createTempFile(trackName, ".mp3",
directory);
FileOutputStream fos = new FileOutputStream(tempMp3);
fos.write(bytearray);
fos.close();
Log.d("Byte array to mp3 conversion: ", "successfull");
} catch (Exception ex) {
Log.d("In convertToByteToMp3 Function:", ex.toString());
}
}
When I execute this function ,I can see the created mp3 files in my app folder but when I try to play them Using my own code or using ES File Explorer, they both can't play it.
This is the function I use play my music:
private MediaPlayer mp = new MediaPlayer();
private void playSong(String songPath) {
try {
mp.reset();
mp.setDataSource(songPath);
mp.prepare();
mp.start();
} catch (IOException e) {
Log.v(getString(R.string.app_name), e.getMessage());
}
}
And I use this sample code to play the track:
ContextWrapper c = new ContextWrapper(getApplicationContext());
File directory = new File(c.getFilesDir().getAbsolutePath() + "/Music");
playSong(directory.getPath() + File.separator + "kurchina");
This is where I read database and send the blob:
cursor = mDbHelper.GetTables();
byte[] blob = null;
DATAS data = new DATAS();
while (cursor.moveToNext()) {
blob = cursor.getBlob(cursor.getColumnIndex("data"));
if (blob != null) {convertByyeToMP3(blob,data_MusicName);}
db.addDATAS(data);
}
FYIs:
-Read and Write permissions added to manifest.
-Path and filename are check and they exist
-blob byte is not corrupted
There are all sorts of things that might have gone wrong, either in the code that you have shown us or elsewhere. So you need to do your own troubleshooting. Methodically.
Figure out if the problem is with the song file you have extracted or the way you are playing it. For example, try to play the extracted file using a free-standing mp3 player utility.
Assuming that the problem is the extracted file, the next thing is to figure out if the file is the same as the one that you originally inserted into the database. Compare the file sizes and the checksums using the relevant external applications.
and so on.
Found the problem.
It didn't play because the music files were stored in my app folder which is only accessible using a rooted device.
When I copied the music to my sdcard they played well, but in my app folder using rooted nexus 7 I couldn't play it even with an mp3-player app.
I'm sure this is a trivial question, but I failed to find an answer.
I'm making an Android app from which I want to open the image viewer
showing several images. I know how to do this with only one image:
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
File file1 = new File("/mnt/sdcard/photos/20397a.jpg");
intent.setDataAndType(Uri.fromFile(file1), "image/jpg");
startActivity(intent);
This works perfectly. But how do I pass several images to the viewer?
Thanks!!
L.
I want to open the image viewer
There is no "the image viewer" in Android. Devices and users may have many, many different apps that are capable of viewing image/jpeg files loaded from a local file.
But how do I pass several images to the viewer?
Sorry, but there is no standard Intent to open multiple files of any sort.
Also, please do not hardcode /mnt/sdcard/ in your app. Please use the proper methods on the Environment class to determine directories on external storage.
You need to list all files you want to view in a array. Then you display one of the array and when you drag, you show the next image.
ArrayList list;
private DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // Ansi date format
list = new ArrayList();
String path = "c:/temp/";
File dir = new File(path);
for (String dirListing : dir.list()) {
if ((dirListing.endsWith(".jpg")) ||
(dirListing.endsWith(".png")) ||
(dirListing.endsWith(".gif"))) {
try { // write all file-info to a arraylist
File f = new File(path+dirListing);
list.add(f.getCanonicalPath());
list.add(f.getName());
list.add(String.valueOf(f.length()));
String lastModified = dateFormat.format(new Date(f.lastModified()));
list.add(lastModified);
}
catch (IOException e) {
e.printStackTrace();
}
catch (IndexOutOfBoundsException e) {
e.printStackTrace();
}
}
}
Now you can read the array and display then one by one.
Do not use Hard Coded Paths.
Change this line :
File file1 = new File("/mnt/sdcard/photos/20397a.jpg");
to
File sdDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
It will locate to
/storage/emulated/0/Picture
You can remove Environment.DIRECTORY_PICTURES If you want the parent directory of your sdcard.
Since you are specifying a single file 20397a.jpg that's why you are unable to see other images.
And if you want to see other contents other than images then change 'image/jpg' to 'image/*'