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.
Related
I have a list of arrays of data in my app that I would now like to write to a file (csv) and use a 3rd party app (such as email) to share this csv file. I have had no luck finding any helpful resources for creating, finding the file path for, and appending to a file in Kotlin. Does anyone have experience with this or have examples to point to? Just to get started I'm trying to write the header and close the file so I can see that it is correctly writing.
This is what I have for now:
val HEADER = "ID, time, PSI1, PSI2, PSI3, speed1, speed2, temp1, temp2"
val filename = "export.csv"
var fileOutStream : FileOutputStream = openFileOutput(filename,Context.MODE_PRIVATE)
try {
fileOutStream.write(HEADER.toByteArray())
fileOutStream.close()
}catch(e: Exception){
Log.i("TAG", e.toString())
}
It doesn't throw the exception, but I cannot find the file in the file system. I'm using a physical tablet for testing/debug. I've checked the com.... folder for my app.
I cannot find the file in the file system
Use Android Studio's Device File Explorer and look in /data/data/.../files/, where ... is your application ID.
Also, you can write your code a bit more concisely as:
try {
PrintWriter(openFileOutput(filename,Context.MODE_PRIVATE)).use {
it.println(HEADER)
}
} catch(e: Exception) {
Log.e("TAG", e.toString())
}
use() will automatically close the PrintWriter, and PrintWriter gives you a more natural API for writing out text.
It appears there are many ways to create a file and append to it, depending on the minimum API version you are developing for. I am using minimum Android API 22. The code to create/append a file is below:
val HEADER = "DATE,NAME,AMOUNT_DUE,AMOUNT_PAID"
var filename = "export.csv"
var path = getExternalFilesDir(null) //get file directory for this package
//(Android/data/.../files | ... is your app package)
//create fileOut object
var fileOut = File(path, filename)
//delete any file object with path and filename that already exists
fileOut.delete()
//create a new file
fileOut.createNewFile()
//append the header and a newline
fileOut.appendText(HEADER)
fileOut.appendText("\n")
/*
write other data to file
*/
openFileOutput() creates a private file, likely inside of app storage. These files are not browsable by default. If you want to create a file that can be browsed to, you'll need the WRITE_EXTERNAL_STORAGE permission, and will want to create files into a directory such as is provided by getExternalFilesDir()
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.
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.
In Android webview, you could pass something like this file:///android_asset/myfile.txt or this http://www.mysite.com/t.html and it will get it without a problem. Now if I tried the first url with the file prefix in a reader "FileReader" it will throw an exception that File not found although in WebView it work with no problem (why?)
What I want is to create a function that could take a file or http url and get the content html using the full path "file:/// ..." how could I do this without facing the file not found exception ?
Now if i tried the first url with the file prefix in a reader "FileReader" it will throw an exception that file not found although in WebView it work with no problem (why?)
Because "File Reader" does not have an asset named /myfile.txt, presumably. "File Reader" is somebody else's program, not yours, so file:///android_asset/myfile.txt refers to an asset in that other program, not yours.
What i want is to create a function that could take a file or http url and get the content html using the full path "file:/// ..." how could i do this without facing the file not found exception ?
Have an asset named /myfile.txt in your app.
I have not tried using standard Java I/O (e.g., File objects) to read file:///android_asset paths. That might work. If not, use startsWith() to determine if the string begins with file:///android_asset -- if it does, trim that off and use the rest with AssetManager to read the asset.
I am newbie to android don't know much about it. I have imported a image to my project and when i tried it check it using File that the file exists or not.
This is the code i have used..
existingFileName="res/drawable-ldpi/login.png";
File f= new File(existingFileName);
// Log.d("Image path",);
if(f.exists())
{
Log.d("EXISTS", "====File Exists===");
}
Still it is showing me no image exist.
thanks for help in advance,
aby
If you are putting your images in drawable folder, I don't think you can access them like this. Try this
Drawable image= getResources().getDrawable(R.drawable.<id>);
id will be your file name.
If you store the image in the "res/drawable" folder you can do:
Drawable drawable = getResources().getDrawable(R.drawable.name)
See http://developer.android.com/reference/android/content/res/Resources.html#getDrawable
For the case you store your image in the assets folder, you need to use getAssets() ( http://developer.android.com/reference/android/content/Context.html#getAssets() )
You can do something like this:
InputStream is = getAssets().open(imageName);
BufferedInputStream buf = new BufferedInputStream(is);
Bitmap bitmap = BitmapFactory.decodeStream(buf);
Remember that for both case you need to have a Context (ie an Activity)
There is no need to check the existence of an asset file before you read it. AssetManager takes care of it. If file is missing, it throws an exception. Your coding practice should be to always enclose that part of code in try catch and split the logic. Extra code is not needed. If you try an open a file that doesn't exist you will get an exception.
Though, if you still want to do that manual job, try below code.
AssetManager mg = getResources().getAssets();
try {
//do all considering file exists
mg.open(pathInAssets);
} catch (IOException ex) {
//do all in case file is missing
}
If your file is located in assets/folder/file.ext, then pathInAssets would be "folder/file.ext"
Check for file existence in androids assets folder?
How to check Android Asset resource?
Usually if you use res/drawable, your ressource identifier is compiled into the R.java file. So if you use an identifier from there, you can be sure the file IS there, otherwise you cannot compile your project.
If however you like to exchange R.java later and really need to list the ressources in res/drawable, you can do it with java Reflection, examining the R class like this:
Class<?> c=R.drawable.class;
Field[] fs=c.getFields();
for(Field f: fs)
Log.v("test", f.getName());
You will then get a list of the ressources, without the file extension. The Ressource Identifier (an integer) for every ressource is then read with int id=f.getInt(null);.
Use the DDMS perspective in eclipse to browse for the image on an emulator running your app.
If you get this error.. "Cannot make a static reference to the non-static method getResources() from the type ContextWrapper"
Try Drawable image=Classname.this.getResources().getDrawable(R.drawable.<id>);
here Classname.this means the ClassContext/Application Context.