Storing .txt files on Android - android

So I made the grave error of storing a bunch of .txt files in the Assets folder on Android only to discover that it is read-only and I need to be able to write to some of them, delete others and add new ones when needed.
I know I can store it internally or externally on the SD card.
If I store it internally, where do I place all of my files?
Is externally a better idea here?
Thanks
EDIT
It isnt a major problem if they are visible to the user

Here is a sample code i use for getting the storage directory:
/**
* Check if external storage is built-in or removable.
*
* #return True if external storage is removable (like an SD card), false
* otherwise.
*/
#TargetApi(9)
public static boolean isExternalStorageRemovable() {
if (hasGingerbread()) {
return Environment.isExternalStorageRemovable();
}
return true;
}
/**
* Get the external app cache directory.
*
* #param context The context to use
* #return The external cache dir
*/
#TargetApi(8)
public static File getExternalCacheDir(Context context) {
if (hasFroyo()) {
return context.getExternalCacheDir();
}
// Before Froyo we need to construct the external cache dir ourselves
final String cacheDir = "/Android/data/" + context.getPackageName() + "/cache/";
return new File(Environment.getExternalStorageDirectory().getPath() + cacheDir);
}
/**
* Get a usable cache directory (external if available, internal otherwise).
*
* #param context The context to use
* #param uniqueName A unique directory name to append to the cache dir
* #return The cache dir
*/
public static File getDiskCacheDir(Context context, String uniqueName) {
// Check if media is mounted or storage is built-in, if so, try and use external cache dir
// otherwise use internal cache dir
final String cachePath =
Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()) ||
!isExternalStorageRemovable() ? getExternalCacheDir(context).getPath() :
context.getCacheDir().getPath();
return new File(cachePath + File.separator + uniqueName);
}
And you got yourself a path to place your files....
And now to place them upon install, you should copy them on first run from your assets to that folder, or create them and populate them depending on your needs....and no there is no other way to have files shipped with your app, they can come in assets, you can create them from your app, or download them from some server.
Edit1: the folder will be in Android/data/your_package_name/cache+anything you want...
and the two functions used for gingerbread and froyo:
public static boolean hasFroyo() {
// Can use static final constants like FROYO, declared in later versions
// of the OS since they are inlined at compile time. This is guaranteed behavior.
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.FROYO;
}
public static boolean hasGingerbread() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD;
}

Related

After clear cache on Android File.mkdirs() return false and I Can't create directory

This code works perfectly until you clear cache from Device's Settings/App/your app menu.
/**
* #param context te get packageName & {#code cacheDir} from internal storage
* #return file for {#code cacheDir} either SD card or internal storage. Or {#code null} if cacheDir doesn't exist
*/
public static File getCacheDir(Context context) throws IOException {
File cacheDir;
if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
String cacheDirPath = getApplicationCacheDirPath(context.getPackageName());
cacheDir = new File(Environment.getExternalStorageDirectory() + File.separator + cacheDirPath);
} else {
cacheDir = context.getCacheDir();
}
if (cacheDir != null && !cacheDir.exists()) {
if (!cacheDir.mkdirs()) {
throw new IOException("Can't use cacheDir");
}
}
return cacheDir;
}
I've tried to delete this file and create it again, as a workaround, to release lock by some other(system) app, and that failed also. Only device's reboot do solve that problem. Any help would be appreciated. Thank you!

how to create directory path which contains space

Every time when my app tries to create a directory on SD card, it throws runtime exception.
The error is
java.lang.RuntimeException: Could not create library directory /storage/sdcard0/Seafile/logan676#163.com (cloud.seafile.com)/personal folder
So my question is if it is allowed to create directories which contains space.
And I implemented the code like below.
if (path != null) {
// Has record in database
repoDir = new File(path);
if (!repoDir.exists()) {
if (!repoDir.mkdirs()) {
throw new RuntimeException("Could not create library directory " + path);
}
}
return path;
}
I have to create such kind of directories because I deleted them when user clear caches.
/**
* Deletes cache directory under a specific account<br>
* remember to clear cache from database after called this method
*
* #param dirPath
* #throws IOException
*/
public static void clearCache(String dirPath) throws IOException {
// clear all cached files inside of the directory, the directory itself included
File cacheDir = new File(dirPath);
FileUtils.deleteDirectory(cacheDir);
}
This clearCache method will delete the root directory and its sub-directories.
So does it have anything to do with the runtime exceptions above.

Find SD card path for android

My phone has its SD card path named as "/storage/external_SD"
But I hear different phone manufacturers name their paths differently. Like SD_card , externalMemory etc..
I am developing an app that opens the SD card contents when a filechooser is opened.
How can I set a path to open when different brands name their sd card paths differently ?
Yes. Different manufacturer use different SDcard name like in Samsung Tab 3 its extsd, and other samsung devices use sdcard like this different manufacturer use different names.
I had the same requirement as you. so i have created a sample example for you from my project goto this link Android Directory chooser example which uses the androi-dirchooser library.
This example detect the SDcard and list all the subfolders and it also detects if the device has morethan one SDcard.
Part of the code looks like this For full example goto the link
Android Directory Chooser
Helper Methods
/**
* Returns the path to internal storage ex:- /storage/emulated/0
*
* #return
*/
private String getInternalDirectoryPath() {
return Environment.getExternalStorageDirectory().getAbsolutePath();
}
/**
* Returns the SDcard storage path for samsung ex:- /storage/extSdCard
*
* #return
*/
private String getSDcardDirectoryPath() {
return System.getenv("SECONDARY_STORAGE");
}
mSdcardLayout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
String sdCardPath;
/***
* Null check because user may click on already selected buton before selecting the folder
* And mSelectedDir may contain some wrong path like when user confirm dialog and swith back again
*/
if (mSelectedDir != null && !mSelectedDir.getAbsolutePath().contains(System.getenv("SECONDARY_STORAGE"))) {
mCurrentInternalPath = mSelectedDir.getAbsolutePath();
} else {
mCurrentInternalPath = getInternalDirectoryPath();
}
if (mCurrentSDcardPath != null) {
sdCardPath = mCurrentSDcardPath;
} else {
sdCardPath = getSDcardDirectoryPath();
}
//When there is only one SDcard
if (sdCardPath != null) {
if (!sdCardPath.contains(":")) {
updateButtonColor(STORAGE_EXTERNAL);
File dir = new File(sdCardPath);
changeDirectory(dir);
} else if (sdCardPath.contains(":")) {
//Multiple Sdcards show root folder and remove the Internal storage from that.
updateButtonColor(STORAGE_EXTERNAL);
File dir = new File("/storage");
changeDirectory(dir);
}
} else {
//In some unknown scenario at least we can list the root folder
updateButtonColor(STORAGE_EXTERNAL);
File dir = new File("/storage");
changeDirectory(dir);
}
}
});
getExternalStorageDirectory () will give you the path to (usually) an SD card, so you can you this in your code.
You are looking for the Environment class and its static method getExternalStorageDirectory.
Return the primary external storage directory.
...
In devices with multiple "external" storage directories, this directory represents the
"primary" external storage that the user will interact with. Access to
secondary storage is available through

Android 4.4+ : check if path is on secondary storage

My app has to check if a certain folder is on the secondary storage when the Android version is 4.4+.
I am using this:
private boolean isPathOnSecondaryStorage(String path) {
boolean res=false;
String secondaryStorage=System.getenv("SECONDARY_STORAGE");
String[] secondaryPaths=secondaryStorage.split(":");
for (int i=0;i<secondaryPaths.length;i++) {
String secondaryPath=secondaryPaths[i].trim();
if (path.contains(secondaryPath)) {
res=true;
}
}
return res;
}
Note that:
path is chosen by the user by means of a file chooser activity, starting from /mnt
the app wants to check what is mounted as usual, like when an external SD-card is inserted in its slot
So I ask whether the above mentioned code will be always able to detect when the path is on a secondary storage, or instead on some devices it could find strange mounting points different from /mnt (Android 4.4+).
Here is my current solution. Not ideal, but it should work.
/**
* Uses the Environmental variable "SECONDARY_STORAGE" to locate a removable micro sdcard
*
* #return the primary secondary storage directory or
* {#code null} if there is no removable storage
*/
public static File getRemovableStorage() {
final String value = System.getenv("SECONDARY_STORAGE");
if (!TextUtils.isEmpty(value)) {
final String[] paths = value.split(":");
for (String path : paths) {
File file = new File(path);
if (file.isDirectory()) {
return file;
}
}
}
return null;
}
/**
* Checks if a file is on the removable SD card.
*
* #see {#link Environment#isExternalStorageRemovable()}
* #param file a {#link File}
* #return {#code true} if file is on a removable micro SD card, {#code false} otherwise
*/
public static boolean isFileOnRemovableStorage(File file) {
final File microSD = getRemovableStorage();
if (microSD != null) {
String canonicalPath;
try {
canonicalPath = file.getCanonicalPath();
if (canonicalPath.startsWith(microSD.getAbsolutePath())) {
return true;
}
} catch (IOException e) {
}
}
return false;
}

ImageLoader.getInstance().getDiscCache().get(imageUrl) returns different paths

Call to cache
ImageLoader.getInstance().loadImage(cnt, imageUrl, new ImageLoadingListener()
/mnt/sdcard/Android/data/[package]/cache/40d1dxbmdamufgcs742bjraew is created
ImageLoader.getInstance().getDiscCache().get(imageUrl) - returns /mnt/sdcard/Android/data/[package]/cache/40d1dxbmdamufgcs742bjraew -> OK
reboot device
ImageLoader.getInstance().getDiscCache().get(imageUrl) - returns /data/data/[package]/cache/40d1dxbmdamufgcs742bjraew -> KO (THIS FOLDER IS CREATED BUT ITS" EMPTY)
Thanks to Doctoror Drive
https://github.com/nostra13/Android-Universal-Image-Loader/tree/master/library/src/com/nostra13/universalimageloader/core
/**
* Returns application cache directory. Cache directory will be created on SD card
* ("/Android/data/[app_package_name]/cache") if card is mounted. Else - Android defines cache directory on
* device's file system.
*
* #param context Application context
* #return Cache {#link File directory}
*/
public static File getCacheDirectory(Context context) {
File appCacheDir = null;
if (Environment.getExternalStorageState().equals(android.os.Environment.MEDIA_MOUNTED)) {
appCacheDir = getExternalCacheDir(context);
}
if (appCacheDir == null) {
appCacheDir = context.getCacheDir();
}
return appCacheDir;
}

Categories

Resources