Android ExifInterface not saving attribute - android

Below is my code-
try {
InputStream inputStream = getAssets().open("thumbnail.jpg");
exifInterface = new ExifInterface(inputStream);
exifInterface.setAttribute(ExifInterface.TAG_ARTIST,"TEST INPUT");
exifInterface.saveAttributes();
} catch (IOException e) {
e.printStackTrace();
}
On the exifInterface.saveAttributes() line I get the following error -
java.io.IOException: ExifInterface does not support saving attributes
for the current input.
I am not sure if the error is due to the image file or due to the attribute. I'm trying to save. Also I looked online for possible solutions (eg. Sanselan) but not sure if it will solve this.
Can somebody explain how to fix this?
Thanks!

You can't do attribute mutation using Input Stream.
You can check the code of ExifInterface, it says that:
/**
* Reads Exif tags from the specified image input stream. Attribute mutation is not supported
* for input streams. The given input stream will proceed its current position. Developers
* should close the input stream after use. This constructor is not intended to be used with
* an input stream that performs any networking operations.
*/
public ExifInterface(InputStream inputStream) throws IOException {
/* Irrelevant code here */
So, if you would like to write in the meta data of your file, you need to pass the file in the constructor. Otherwise it is going to fail. You can also see the code that will always fail (with InputStream) in the class:
public void saveAttributes() throws IOException {
if (!mIsSupportedFile || mMimeType != IMAGE_TYPE_JPEG) {
throw new IOException("ExifInterface only supports saving attributes on JPEG formats.");
}
if (mFilename == null) {
throw new IOException(
"ExifInterface does not support saving attributes for the current input.");
}
//Irrelevant code
So use ExifInterface(file) and you'll be able to make your code work.
Happy coding!

ExifInterface does not support saving attributes for the current input.
The current input is an InputStream. One cannot save data to an InputStream. Only to an OutputStream.
A second problem is that the file in assets is read only. Hence you could not even open an OutputStream if you had tried that. So impossible.

What I think might be the issue is : you are trying to add attribute to read only assets placed inside app during the zip of app is created.
And adding attribute to files inside zip is still not supported by exifInterface. Howsoever you can easily add attributes to other files that exist outside say in SDCard.

Related

Allocate a HTML file inside a section using Kotlin

I made a HTML file and I located into /app/src/main/assets
and I'm trying to get the entire text but I got null from my app:
try {
val fileContent = this.javaClass.getResource("file:///android_asset/index.html")!!.readText()
lblSection.text = HtmlCompat.fromHtml(fileContent, HtmlCompat.FROM_HTML_MODE_LEGACY)
}catch (exception: Exception){
Log.d("error loading HTML", exception.message!!)
}
I don't know where do I need to allocate my file to get read from my app.
Thank you so much
file:///android_asset/index.html is a URL that you could use with WebView, but little else. It definitely will not work with Java's getResource().
To read in an asset, retrieve an AssetManager from your Activity or other Context via getAssets(). Then, call open() on the AssetManager, with a relative path within assets/ to your desired content (in your case, getAssets().open("index.html")). That will give you an InputStream from which you can read in the content.

Android, FileNotFound Exception, but found by Glide without problems. What is the problem?

Using Glide, the following uri path to a png file is loaded without problems. In Android, the following code results in "file not found exception". Why? What do I need to do with the uri to make it work "everywhere" in Android?
uri = content://com.android.providers.media.documents/document/image%3A11322, as given by the default file chooser, used programmatically.
FileInputStream in = null;
try {
in = new FileInputStream(new File(uri));
} catch (FileNotFoundException e) {
Using BitMapFactory.decodeFile(uri) is even worse, since it also gives the same exception because it cannot find the file on the path = content:/com.android…. Important: Note that BitmapFactory removed one of the two slashes, for whatever reason. A bug?
Thanks for any help that can convert this work down from a two day "seek and find" the solution, down to the expected two minute job. Android contains an amazing number of built-in traps, I must say.
You cannot open a FileInputStream on a content scheme uri.
Open an InputStream on the uri instead.
InputStream is = getContentResolver().openInputStream(uri);
You can use the stream as before.
BitmapFactory.decodeStream(is);

Buffered file reading in Flutter

I have following Dart code and I am trying to make reading the file buffered. Just like Java's BufferedReader or C++ ifstream. Is there such functionality? I cannot even find buffer mentioned in file.dart nor file_impl.dart. If I understood my debugging correctly, it seems that Dart is reading the whole file at once.
So could anybody help me make it buffered or point me in right direction where the buffer is?
final file = File(join(documentsDirectory, "xxx.txt"));
final List<String> lines = await file.readAsLines(); //file.readAsLinesSync()
lines.forEach((line) {
....
});
Use file.openRead(). This will return a Stream of bytes. If you want to read as characters, transform the stream using the appropriate decoder (probably utf8).
As it says, you must read the stream to the end, or cancel it.

How can i get the uri of non media type and its id in android?

I'm having a big problem with this. Getting the image, video and audio is not so hard but what if I like to get the non media type i want to display every non media type in a grid view or list view but can I do it? Anyone have idea in getting the uri and id of the non media files?
I'm sure you are going to find that you are looking for in the answer to this question: MediaStore - Uri to query all types of files (media and non-media)
To get the information of any file in Android, we can use the File class.
The File class has a number of methods to get the information from some file. To use any of these, you must create a File object containing the name of the file (path) in which to work.
Should be noted that the creation of an object of type File has no permanent effect on the file system but it is only one object in the memory of Java.
To change the file system of the File object, there are numerous methods of "change", such as one for creating a new file (empty), another to change the file name, others giving information about the file, etc. .
For example you can read some file:
try {
File fileSD = Environment.getExternalStorageDirectory();
File file = new File(fileSD.getAbsolutePath(), "file.txt");
BufferedReader buffered =
new BufferedReader(
new InputStreamReader(
new FileInputStream(file)));
String texto = buffered.readLine();
buffered.close();
}
catch (Exception ex) {
Log.e(TAG, "Cannot read the file");
}
If you want to know the absolute path you can use:
fileSD.getAbsolutePath()
I hope this help you.

Write to txt file, but not overwrite

I got a little problem, it seems simple (personally I think it is), but I couldn't find a answer. But atleast I don't know how to fix it.
I write some lines to a .txt file when I hit the button Save.
Then after that, when I type something else, and hit Save again, it overwrites my first lines.
But I want that it writes at a new line. Also when I close and restart the app again, and hit save again, it must save the text on a new line again.
So basically: How can I write text to a .txt file, without overwriting previous lines.
I can write to a file, so that is not the problem, but only how to NOT overwrite.
This is the "little" part of my code:
public void Data_save_contacts(View v) {
Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
try {
writer_contact = new BufferedWriter(new FileWriter(root + "/Save/Contacten.txt"));
writer_contact.write("Perceel "+str_boer_teler_nummer+" = "+str_boer_teler);
writer_contact.newLine();
} catch (IOException e) {
System.err.println(e);
}
}
Please put me in the good directions.
Thanks already, Bigflow
You have to do
writer_contact = new BufferedWriter(new FileWriter(root + "/Save/Contacten.txt",true));
Just as said in java documentation:
FileWriter
public FileWriter(File file,
boolean append)
throws IOException
Constructs a FileWriter object given a File object. If the second argument is true, then bytes will be written to the end of the file rather than the beginning.
Parameters:
file - a File object to write to
append - if true, then bytes will be written to the end of the file rather than the beginning
try:
public FileWriter (File file, boolean append)
set the append to true
Well given this is just a little of your code (and I'm assuming you chunked it out so as to not reveal other parts) what I suspect is going on is that you're opening the file root + "/Save/Contacten.txt" in a non-append mode. The first time you call it the file is created and written to. Subsequent times you call it, it finds the file, and recreates (or deletes content) and then writes to it.
Try using:
writer_contact = new BufferedWriter(new FileWriter(root + "/Save/Contacten.txt", true));
Of course the first time you open/create the file you'll want it to be false (unless you ALWAYS want to append if the file already exists).
Give that a spin.
you can check for if file exits or not ?
or you can also append old file.
If not exits then and then only create new one.

Categories

Resources