I guess I'm a little confused as to how files are stored on an actual machine (or emulator even).
While programming, I can save my xml file in the assets folder manually, but how to write an app that will have to connect to the network and download the file,save it somewhere and then manipulate it ? where will it store said file ?
I want to create a new file, but I read on another post that the assets folder as such is not available once packaged; So where are they created and stored ? How can they be transferred. Its just, I'm new to this platform and the file system is a little confusing.
If you want to use XML that is updated, you should think of copying the file(s) from assets to device storage. You can take a look at How to copy files from 'assets' folder to sdcard? to know how this can be done.
Another alternative is to use the database where you can store the parsed data from the XML. So that you need not parse the file whenever you need to access the contents.
You have two options: call getFilesDir() from your activity to obtain a path to the internal data folder that can only be read/write from your app.
Or, you can write/read your xml file to external storage (SD Card). Use the method Environment.getExternalStorageDirectory() to get the root path of the external storage, then create your own folder as you see fit.
Note that if you write to external storage, every app in the phone will have access to it.
Even I faced this issue. Now I have a xml file which is has application properties.This is packaged in the assets folder.Once packaged we cannot edit a file in assets folder.
Now on app load I just copy this file to path returned by
context.getFilesDir().getAbsolutePath();
And the application edit it from the same place. You can see if the file is modified in the FileExplorer panel of DDMS view. The file is stored in the folder named same as your application package name for eg: com.abhi.maps
Alternatively you can also copy it to SD card.However it is risky because, sd card may bot be available all the time.
You can use the following code to copy file from assets folder:
private static void copyFile(String filename, Context context) {
AssetManager assetManager = context.getAssets();
InputStream in = null;
OutputStream out = null;
try {
in = assetManager.open(filename);
String newFileName = context.getFilesDir() + "/" + filename;
out = new FileOutputStream(newFileName);
byte[] buffer = new byte[1024];
int read;
while ((read = in.read(buffer)) != -1) {
out.write(buffer, 0, read);
}
in.close();
in = null;
out.flush();
out.close();
out = null;
} catch (Exception e) {
Log.e("tag", e.getMessage());
}
}
Hope it helps! :)
Related
Currently, we have an app that we are targeting Android 10 and right now are using the legacy storage API. Our app communicates via Bluetooth sensors and reads and writes raw data in CSV files in a subfolder in the main directory, with that subfolder having subfolders for each user.
I know Android 11 will enforce Scoped Storage. I would like to know, is our use case outside of the Scoped Storage requirement? It appears our use case isn't supported by MediaStore. If not, how would we go about this?
MediaStore APIs are just for media files - images, videos, and audio.
You can store all files in the app's private folder and add an export option to your app (maybe compress the whole structure to an archive). So a user will be able to store or send it wherever they want.
In this case, you need to use FileProvider to expose the file from the private directory.
reads and writes raw data in CSV files in a subfolder in the main directory,
For an Android 11 device you can create your own folders an subfolders in the Documents directory of what you call the 'main folder'.
And for using the MediaStore: you can also write any file to that Documents directory. Well in a subfolder if not directly.
I'm in a similar boat. This may help you get started.
public class FirstFragment extends Fragment {
...
public void fauxMakeCsvSurveyFile() {
File appDir = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS), "Field_data");
appDir.mkdirs();
try {
String storageState = Environment.getExternalStorageState();
if (storageState.equals(Environment.MEDIA_MOUNTED)) {
File file = new File(getContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + "/Field_data/" + "OutputFile.csv");
FileOutputStream fos = new FileOutputStream(file);
String text = "Hello, world!";
fos.write(text.getBytes());
fos.close();
}
} catch (IOException e) {
Log.e("IOException", "exception in createNewFile() method");
}
}
...
}
I have a number of pdf files (but I might extend the functionality to other document types as well) that I want to show in my app. Static images go in drawable folder, static text goes in the strings file. But where do I put pdf files?
I know I can host it on a server and have a one-time-download kind of thing, but for my app's use case that's impossible. The app is being designed for a very specific use case in mind and I absolutely need to bundle the pdf files along with the app.
Create directory named assets in your app and put your pdf files in that directory. use this to read and display pdf files.
I think you can keep your PDF file (or any other file type) inside assets folder. So while downloading the APK form store, it will download those files too. Only problem is it will increase the APP size.
Check the below answer how you can access the PDF file from the Assets using assetManager
https://stackoverflow.com/a/17085759/7023751
I'm answering my own question because other answers didn't fully work for me.
Like the other answers, I read the file from assets folder and created a file in internal storage. I used muPDF which works perfectly with file URI.
items is an ArrayList of file names.
try
{
AssetManager assetManager = getAssets();
InputStream in = assetManager.open(items.get(position));
byte[] buffer = new byte[in.available()];
in.read(buffer);
File targetFile = new File(getFilesDir(), items.get(position));
OutputStream outStream = new FileOutputStream(targetFile);
outStream.write(buffer);
in.close();
outStream.flush();
outStream.close();
//Change below intent statements as per your code
Intent intent = new Intent(this, DocumentActivity.class);
intent.setAction(Intent.ACTION_VIEW);
intent.setData(Uri.fromFile(targetFile));
startActivity(intent);
}
catch (Exception e)
{
e.printStackTrace();
}
I am working on an application where I have created some directory which I am accessing through my application I want to make that directory hidden for security purpose .Such that the user can access them only within the application does not access them outside the application as like through file manager.
Any help is appreciated.
Don't make it duplicate because I search out all the answer, but no one has worked for me.
Just appending a dot before the folder name will not protect it. It is only invisible to the user. It can still be accessed from apps, including file managers and therefore the user. It's just hidden by most file managers by default.
As you want to hide the files for security purposes, you should use Android's internal storage.
From the official Android developer guide:
You can save files directly on the device's internal storage. By default, files saved to the internal storage are private to your application and other applications cannot access them (nor can the user). When the user uninstalls your application, these files are removed.
Example:
String FILENAME = "hello_file";
String string = "hello world!";
FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
Android developer guide
You could also encrypt your files and store the encryption key in the android Keystore.
Here is a good answer regarding encryption of files in android.
Official guide regarding the Android Keystore.
Be clear "You want to create directory or folder which is not accessible for other application"(Which is your application folder) Or Create Folder any location but it is hide from your
For First Solution is -
public static File saveFileInAppDirectory(Context context,byte[] inpute, String directoryName,String fileName){
File mypath;
File directory = new File(context.getExternalFilesDir(
Environment.DIRECTORY_PICTURES), directoryName);
if (!directory.mkdirs()) {
directory.mkdir();
}
mypath = new File(directory, fileName);
try {
InputStream is = new ByteArrayInputStream(inpute);
FileOutputStream f = new FileOutputStream(mypath);
byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) > 0) {
f.write(buffer, 0, len1);
}
f.close();
} catch (Exception e) {
Log.e("SAVE_IMAGE", e.getMessage(), e);
e.printStackTrace();
}
return mypath;
}
It will create Directory of your app folder Path - Android/Data/Data/Your.Package.Name/FolderName/FileName
For second Solution - just change file name
File mypath = new File(directory, "."+fileName);
If you want to achive both than just replace
new File(directory, fileName); with new File(directory, "."+fileName);
just write the directory name followed by a dot(.)
example:
.myDir or .myDir1
so these directories will not be visible through file manager. And while accessing these directories call them using dot(.) only
example:
"/path/to/folder/.myDir/"
same can be done for filename
For Hiding Folder in Android
Name of your folder is MyApplicationFolder then u need to add (.)Dot in front of the folder name like .MyApplicationFolder.
So When the Folder is created then the folder is hidden mode for images,video,etc inside but it will be visible in FileManager.
I need to download some pdf files into data/data/com.**.* folder.
Those files are application specific and only application should read and display it that's the reason storing on data/data/com.**.* folder.
Please let me know how to download into that folder and open/read it in the application.
I know how to download it into SD card, but I do not have idea to downloading to application specific folder.
Please let me know some code examples to do this and also I need to know the capacity/size of the data/data/com.**.* folder.
As long as you want write your own applications Data folder, you can create a FileOutputStream like this FileOutputStream out = new FileOutputStream("/data/data/com.**.*/somefile"); than use that output stream to save file. Using the same way you can create a FileInputStream and read the file after.
You will get Permission Denied if you try to access another application's data folder.
I am not sure for capacity but you can calculate the size of the data folder using this
File dataFolder = new File("/data/data/com.**.*/");
long size = folderSize(dataFolder);
...
public static long folderSize(File directory) {
long length = 0;
for (File file : directory.listFiles()) {
if (file.isFile())
length += file.length();
else
lengthlong += folderSize(file);
}
return length;
}
Hi here i am attaching the link of a tutorial explained.
http://www.mysamplecode.com/2012/06/android-internal-external-storage.html
and there are many discussions going on internet that you should root your phone in order to access the data from data/data folder and I am also attaching some links about the discussion, I hope these are also some of the links that are related to your question
where do i find app data in android
How to access data/data folder in Android device?
and as well as some links that makes out the things without rooting your phone i mean
You can get access to /data/data/com*.* without rooting the device
http://denniskubes.com/2012/09/25/read-android-data-folder-without-rooting/
To Write file
FileOutputStream out = new FileOutputStream("/data/data/your_package_name/file_name.xyz");
To Read file
FileInputStream fIn = new FileInputStream(new File("/data/data/your_package_name/file_name.xyz"));
Now you have your input stream , you can convert it in your file according to the file type .
I am giving you example if your file is contain String data the we can do something like below ,
BufferedReader myReader = new BufferedReader(
new InputStreamReader(fIn));
String mDataRow = "";
String mBuffer = "";
while ((mDataRow = myReader.readLine()) != null) {
mBuffer += mDataRow + "\n";
}
Remember to add write file permission to AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I am using gridview example with image adapter to render images with difference that these images are retrieved from a particular folder in sdcard for e.g. /sdcard/images.
I am testing this application on emulator.For this i have firstly configured sdcard on emulator and then pushed the images on this particular folder through DDMS under eclipse.
What i want to know is that is it possible to create images folder containing images in sdcard when a user installs the application on the real device and if possible what is the way to do it?
I'm not aware of a way to do it (which is not to say that it cant be done).
One thing that you definitely can do is create the folder when the user first runs the application, and fill it with the images.
You should read the Android Documentation covering the External Storage section.
I think it is possible . you can put all images in a asset folder and when you application will start you can copy it to a particular folder in SD Card. Here is the link for copy the database form asset folder to application . You can try it for copy the images form asset folder to SDCard.
http://www.reigndesign.com/blog/using-your-own-sqlite-database-in-android-applications/
You can copy images from assets to SDcard
This method copies images from assets folder to your Sdcard .here Jaydeep's Folder is the name of my folder on sdcard.You can use your folder name in that place.
public void copyImagesInSdcard()
{
assetManager = mycontext.getAssets();
assetManager1 = mycontext.getAssets();
System.out.println("In copyImagesInSdcard");
try
{
str1=assetManager.list("");
ss=assetManager1.list(str1[1]);
InputStream is;
//System.out.println(ss[0]);
File file=new File(Environment.getExternalStorageDirectory().getPath() + "/Jaydeep's Folder");
if(file.exists()!=true)
{
file.mkdir();
}
else
{
if(file.length()==0)
{
file.mkdir();
}
System.out.println("Length:"+file.length());
}
for(int i=0;i<ss.length;i++)
{
is=assetManager1.open(str1[1] + "/" + ss[i]);
file=new File(Environment.getExternalStorageDirectory().getPath() + "/Jaydeep's Folder/" + ss[i] );
FileOutputStream out=new FileOutputStream(file);
//Bitmap bi = BitmapDrawable.createFromStream(is,ss[0]);
byte b[] =new byte[4096];
while (is.read(b) != -1) {
out.write(b);
}
out.close();
}
}
catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
This can be done by creating zip of all resources and put them in assets folder and then unzip these folder into sdcard using following reference: http://www.jondev.net/articles/Unzipping_Files_with_Android_%28Programmatically%29