Code shortening with while, for,,,etc? - android

This code is messy and long, that's why I can't modify easly. I try to use while, for loop, et cetera, but I couldn't. Could you plese help me for shorten it. Thank you so much.
String path1 = "/storage/Folder/" + file_name;
String path2 = Environment.getExternalStorageDirectory().getPath() + "/Folder/" + file_name;
String path3 = Environment.getExternalStorageDirectory().getPath() + "/Folder2/" + file_name;
File file1 = new File(path1);
File file2 = new File(path2);
File file3 = new File(path3);
if (file1.exists()) {
// do something 1
} else if (file2.exists()) {
// do something 2
} else if (file3.exists()) {
// do something 3
} else {
// do something 4
}
I'm trying like this;
String[] path_array = {path1, path2, path3};
for (String current_str : path_array) {
File fi = new File(current_str);
if (fi.exists()) {
// do something
}
}

If you have stream api, you could use it like this:
List<File> files = new ArrayList<>();
files.add(new File("/"));
files.add(new File("/"));
files.add(new File("/"));
files.stream().filter(File::exists).forEach(f -> { /* do something */ });
else you could do :
List<File> files = new ArrayList<>();
files.add(new File("/"));
files.add(new File("/"));
files.add(new File("/"));
for (File file: files) {
if(file.exists()) {
//do something
}
}

Loops are used for repetitive tasks. Since you "do something" different for every single file, you don't need to loop. You can use loop for File construction, but then you have to make array of File objects for later access. If you want easily understandable code (not shorter), you can try something like this, but again, your code is fine.
public void yourCallingMethod() {
if(!file1Exists && !file2Exists && !file3Exists) {
// do something 4
}
}
public boolean file1Exists(String file_name) {
File file = new File("/storage/Folder/" + file_name);
if (file.exists()) {
// do something 1
return true;
}
return false;
}
public boolean file2Exists(String file_name) {
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/Folder/" + file_name);
if (file.exists()) {
// do something 2
return true;
}
return false;
}
public boolean file3Exists(String file_name) {
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/Folder2/" + file_name);
if (file.exists()) {
// do something 3
return true;
}
return false;
}

Related

Speeding up the doinbackground() process

I'm splitting an encrypted video into 4 parts using this code
public class SplitVideoFile {
private static String result;
static ArrayList<String>update=new ArrayList<>();
public static String main(File file) {
try {
// File file = new File("C:/Documents/Despicable Me 2 - Trailer (HD) - YouTube.mp4");//File read from Source folder to Split.
if (file.exists()) {
String videoFileName = file.getName().substring(0, file.getName().lastIndexOf(".")); // Name of the videoFile without extension
// String path = Environment.getDataDirectory().getAbsolutePath().toString() + "/storage/emulated/0/Videointegrity";
String path = "/storage/emulated/0/Videointegrity";
// File myDir = new File(getFile, "folder");
//myDir.mkdir();
File splitFile = new File(path.concat("/").concat(videoFileName));//Destination folder to save.
if (!splitFile.exists()) {
splitFile.mkdirs();
Log.d("Directory Created -> ", splitFile.getAbsolutePath());
}
int i = 01;// Files count starts from 1
InputStream inputStream = new FileInputStream(file);
String videoFile = splitFile.getAbsolutePath() +"/"+ String.format("%02d", i) +"_"+ file.getName();// Location to save the files which are Split from the original file.
OutputStream outputStream = new FileOutputStream(videoFile);
Log.d("File Created Location: ", videoFile);
update.add("File Created Location: ".concat(videoFile));
int totalPartsToSplit =4 ;// Total files to split.
int splitSize = inputStream.available() / totalPartsToSplit;
int streamSize = 0;
int read = 0;
while ((read = inputStream.read()) != -1) {
if (splitSize == streamSize) {
if (i != totalPartsToSplit) {
i++;
String fileCount = String.format("%02d", i); // output will be 1 is 01, 2 is 02
videoFile = splitFile.getAbsolutePath() +"/"+ fileCount +"_"+ file.getName();
outputStream = new FileOutputStream(videoFile);
Log.d("File Created Location: ", videoFile);
streamSize = 0;
}
}
outputStream.write(read);
streamSize++;
}
inputStream.close();
outputStream.close();
Log.d("Total files Split ->", String.valueOf(totalPartsToSplit));
result="success";
} else {
System.err.println(file.getAbsolutePath() +" File Not Found.");
result="failed";
}
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public ArrayList<String> getUpdate()
{
return update;
}
And in my activity file i call this using async task's doinbackground method like below
protected String doInBackground(Void...arg0) {
Log.d(TAG + " DoINBackGround", "On doInBackground...");
File encvideo=new File(epath.getText().toString());
SplitVideoFile split=new SplitVideoFile();
String result=split.main(encvideo);
publishProgress(1);
return result;
}
Even though it splits the video, it takes too much of time to do the process.
How can I speed them up. As I'm showing a progress bar in preexecute method it looks like the user sees the progress bar for a long time, which I don't want.

OSMdroid : How to render offline map from a local sqlite archive

Programming with Android Studio and the osmdroid library.
I downloaded a portion of a map using the cacheManager.downloadAreaAsync() method. This method stores the map piece in a sqlite file in the data/data/<package>/osmdroid/tiles directory, chosen by me.
Now I want to use this map to load it offline in a mobile application.
I've tried to do it through all kinds of classes (MapTileSqlCacheProvider, XYTileSource, OfflineTileProvider, ...) but I can't get the map to appear.
How should I do it?
To download a portion of the map I do this:
map.setTileSource(TileSourceFactory.OpenTopo);
outputPath = "/data/data/<package>/files" + File.separator + "osmdroid" + File.separator + "tiles" + File.separator;
outputName = outputPath + boxE6.name + ".db";
try {
writer=new SqliteArchiveTileWriter(outputName);
} catch (Exception ex) {
ex.printStackTrace();
}
CacheManager cacheManager = new CacheManager(map,writer);
cacheManager.downloadAreaAsync(this, boxE6, 7, 13, new CacheManager.CacheManagerCallback() {
#Override
public void onTaskComplete() {
Toast.makeText(ctx, "Download complete!", Toast.LENGTH_LONG).show();
if (writer!=null)
writer.onDetach();
} ...
To retrieve the stored map (in this case it is in the usa.db file) I try to do this:
map.setUseDataConnection(false);
map.setTileSource(TileSourceFactory.OpenTopo);
File cache = new File(outputName);
Configuration.getInstance().setOsmdroidTileCache(cache);
mapController.setCenter(new GeoPoint((n+s)/2,(e+w)/2));
I will show how I store and load multiple sqlite Tiles, not just one.
The above answer from José Espejo Roig worked only partly for me. It worked almost fine for caching the tiles, but not for reading them. Writing down cache files though is also not complete. I have created my own code using as example: Make a tile archive from OSMDroid Github.
So to store potentially more than 1 tiles in a specific directory I use a code like below. It creates sequentially my_mapX.sqlite, where X are just stepped consecutive integers. So I get my_map1.sqlite, my_map2.sqlite and so on.
private final String MAP_FILE_NAME = "my_map";
private final String MAP_FILE_EXTENSION = ".sqlite";
// ...
Context ctx = getActivity();
mMapView = new MapView(ctx);
((ConstraintLayout) view.findViewById(R.id.osm_fragment)).addView(mMapView);
mMapView.setTileSource(TileSourceFactory.OpenTopo);
ContextWrapper contextWrapper = new ContextWrapper(ctx);
File root_directory = contextWrapper.getDir(ctx.getFilesDir().getName(), Context.MODE_PRIVATE);
File directory_osm = new File(root_directory, "osmdroid");
directory_osm.mkdir();
File directory = new File(directory_osm, "tiles");
directory.mkdir();
File[] nrFiles = directory.listFiles(new FilenameFilter() {
#Override
public boolean accept(File dir, String name) {
if (name.endsWith(MAP_FILE_EXTENSION))
return true;
return false;
}
});
String osmdroidTile = directory.getAbsolutePath() + File.separator + MAP_FILE_NAME + (nrFiles.length + 1) + MAP_FILE_EXTENSION;
BoundingBox boxE6 = mMapView.getBoundingBox();
SqliteArchiveTileWriter writer = null;
try {
writer = new SqliteArchiveTileWriter(osmdroidTile);
} catch (Exception ex) {
ex.printStackTrace();
}
CacheManager cacheManager = new CacheManager(mMapView, writer);
SqliteArchiveTileWriter finalWriter = writer;
int currZoom = (int)mMapView.getZoomLevelDouble();
cacheManager.downloadAreaAsync(ctx, boxE6, currZoom, currZoom + 1, new CacheManager.CacheManagerCallback() {
#Override
public void onTaskComplete() {
Toast.makeText(ctx, "Download complete!", Toast.LENGTH_LONG).show();
if (finalWriter != null)
finalWriter.onDetach();
}
#Override
public void updateProgress(int progress, int currentZoomLevel, int zoomMin, int zoomMax) {
}
#Override
public void downloadStarted() {
}
#Override
public void setPossibleTilesInArea(int total) {
}
#Override
public void onTaskFailed(int errors) {
Toast.makeText(getActivity(), "Download complete with " + errors + " errors", Toast.LENGTH_LONG).show();
if (finalWriter != null)
finalWriter.onDetach();
}
});
}
});
This way I can create as many tile files as I want. Important is that they have ".sqlite" extension. ".db" extension didn't work for me.
Now to read these tiles I used again example from OSMDroid Github: Sample SQLITE example. In OSMDroid Github example TileSource is being determined with IArchiveFile. I skipped that, as I assume I know what TileSource I used (in my case it is OpenTopo, as you can see). Then to read multiple offline tiles from the same TileSource (basing on example from OSMDroid) my code looks like this:
//first we'll look at the default location for tiles that we support
Context ctx = getActivity();
mMapView = new MapView(ctx);
((ConstraintLayout) view.findViewById(R.id.osm_fragment)).addView(mMapView);
mMapView.setUseDataConnection(false);
ContextWrapper contextWrapper = new ContextWrapper(ctx);
File root_directory = contextWrapper.getDir(ctx.getFilesDir().getName(), Context.MODE_PRIVATE);
String osmDir = root_directory.getAbsolutePath() + File.separator + "osmdroid" + File.separator + "tiles";
File f = new File(osmDir);
if (f.exists()) {
File[] list = f.listFiles();
ArrayList<File> sqliteArray = new ArrayList<>();
if (list != null) {
for (int i = 0; i < list.length; i++) {
if (list[i].isDirectory()) {
continue;
}
String name = list[i].getName().toLowerCase();
if (!name.contains(".")) {
continue; //skip files without an extension
}
name = name.substring(name.lastIndexOf(".") + 1);
if (name.length() == 0) {
continue;
}
//narrow it down to only sqlite tiles
if (ArchiveFileFactory.isFileExtensionRegistered(name) && name.equals("sqlite")) {
sqliteArray.add(list[i]);
}
}
}
OfflineTileProvider tileProvider;
if (sqliteArray.size() > 0) {
try {
tileProvider = new OfflineTileProvider(new SimpleRegisterReceiver(getActivity()), sqliteArray.toArray(new File[0]));
mMapView.setTileProvider(tileProvider);
mMapView.setTileSource(TileSourceFactory.OpenTopo);
mMapView.invalidate();
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
Toast.makeText(getActivity(), f.getAbsolutePath() + " dir not found!", Toast.LENGTH_SHORT).show();
}

List of files in assets folder and its subfolders

I have some folders with HTML files in the "assets" folder in my Android project. I need to show these HTML files from assets' sub-folders in a list. I already wrote some code about making this list.
lv1 = (ListView) findViewById(R.id.listView);
// Insert array in ListView
// In the next row I need to insert an array of strings of file names
// so please, tell me, how to get this array
lv1.setAdapter(new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, filel));
lv1.setTextFilterEnabled(true);
// onclick items in ListView:
lv1.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
//Clicked item position
String itemname = new Integer(position).toString();
Intent intent = new Intent();
intent.setClass(DrugList.this, Web.class);
Bundle b = new Bundle();
//I don't know what it's doing here
b.putString("defStrID", itemname);
intent.putExtras(b);
//start Intent
startActivity(intent);
}
});
private boolean listAssetFiles(String path) {
String [] list;
try {
list = getAssets().list(path);
if (list.length > 0) {
// This is a folder
for (String file : list) {
if (!listAssetFiles(path + "/" + file))
return false;
else {
// This is a file
// TODO: add file name to an array list
}
}
}
} catch (IOException e) {
return false;
}
return true;
}
Call the listAssetFiles with the root folder name of your asset folder.
listAssetFiles("root_folder_name_in_assets");
If the root folder is the asset folder then call it with
listAssetFiles("");
try this it will work in your case
f = getAssets().list("");
for(String f1 : f){
Log.v("names",f1);
}
The above snippet will show the contents of the asset root.
For example... if below is the asset structure..
assets
|__Dir1
|__Dir2
|__File1
Snippet's output will be ....
Dir1 Dir2 File1
If you need the contents of the Directory Dir1
Pass the name of Directory in the list function.
f = getAssets().list("Dir1");
Hope This Help:
following code will copy all the folder and it's content and content of sub folder to sdcard location:
private void getAssetAppFolder(String dir) throws Exception{
{
File f = new File(sdcardLocation + "/" + dir);
if (!f.exists() || !f.isDirectory())
f.mkdirs();
}
AssetManager am=getAssets();
String [] aplist=am.list(dir);
for(String strf:aplist){
try{
InputStream is=am.open(dir+"/"+strf);
copyToDisk(dir,strf,is);
}catch(Exception ex){
getAssetAppFolder(dir+"/"+strf);
}
}
}
public void copyToDisk(String dir,String name,InputStream is) throws IOException{
int size;
byte[] buffer = new byte[2048];
FileOutputStream fout = new FileOutputStream(sdcardLocation +"/"+dir+"/" +name);
BufferedOutputStream bufferOut = new BufferedOutputStream(fout, buffer.length);
while ((size = is.read(buffer, 0, buffer.length)) != -1) {
bufferOut.write(buffer, 0, size);
}
bufferOut.flush();
bufferOut.close();
is.close();
fout.close();
}
Here is a solution to my problem that I found out working 100% listing all directories and files even sub-directories and files in subdirectories.
Note: In my case
Filenames had a . in them. i.e. .htm .txt etc
Directorynames did not have any . in them.
listAssetFiles2(path); // <<-- Call function where required
//function to list files and directories
public void listAssetFiles2 (String path){
String [] list;
try {
list = getAssets().list(path);
if(list.length > 0){
for(String file : list){
System.out.println("File path = "+file);
if(file.indexOf(".") < 0) { // <<-- check if filename has a . then it is a file - hopefully directory names dont have .
System.out.println("This is a folder = "+path+"/"+file);
listAssetFiles2(file); // <<-- To get subdirectory files and directories list and check
}else{
System.out.println("This is a file = "+path+"/"+file);
}
}
}else{
System.out.println("Failed Path = "+path);
System.out.println("Check path again.");
}
}catch(IOException e){
e.printStackTrace();
}
}//now completed
Thanks
i think that this is best that check file is dir or not, altarnative try,catch!
public static List<String> listAssetFiles(Context c,String rootPath) {
List<String> files =new ArrayList<>();
try {
String [] Paths = c.getAssets().list(rootPath);
if (Paths.length > 0) {
// This is a folder
for (String file : Paths) {
String path = rootPath + "/" + file;
if (new File(path).isDirectory())
files.addAll(listAssetFiles(c,path));
else files.add(path);
}
}
} catch (IOException e) {
e.printStackTrace();
}
return files;
}
Based on the #Kammaar answer. This kotlin code scans the file tree for the leafs:
private fun listAssetFiles(path: String, context: Context): List<String> {
val result = ArrayList<String>()
context.assets.list(path).forEach { file ->
val innerFiles = listAssetFiles("$path/$file", context)
if (!innerFiles.isEmpty()) {
result.addAll(innerFiles)
} else {
// it can be an empty folder or file you don't like, you can check it here
result.add("$path/$file")
}
}
return result
}
This method return file names in a directory in Assets folder
private fun getListOfFilesFromAsset(path: String, context: Context): ArrayList<String> {
val listOfAudioFiles = ArrayList<String>()
context.assets.list(path)?.forEach { file ->
val innerFiles = getListOfFilesFromAsset("$path/$file", context)
if (innerFiles.isNotEmpty()) {
listOfAudioFiles.addAll(innerFiles)
} else {
// it can be an empty folder or file you don't like, you can check it here
listOfAudioFiles.add("$path/$file")
}
}
return listOfAudioFiles
}
For example you want to load music file path from sound folder
You can fetch all sound like this:
private const val SOUND_DIRECTORY = "sound"
fun fetchSongsFromAssets(context: Context): ArrayList<String> {
return getListOfFilesFromAsset(SOUND_DIRECTORY, context)
}
public static String[] getDirectoryFilesRecursive(String path)
{
ArrayList<String> result = new ArrayList<String>();
try
{
String[] files = Storage.AssetMgr.list(path);
for(String file : files)
{
String filename = path + (path.isEmpty() ? "" : "/") + file;
String[] tmp = Storage.AssetMgr.list(filename);
if(tmp.length!=0) {
result.addAll(Arrays.asList(getDirectoryFilesRecursive(filename)));
}
else {
result.add(filename);
}
}
}
catch (IOException e)
{
Native.err("Failed to get asset file list: " + e);
}
Object[] objectList = result.toArray();
return Arrays.copyOf(objectList,objectList.length,String[].class);
}

How to list all the files in a custom Directory

I'm trying to list all the files in a directory I have made, when I create the directory I warp a file for each contact into the dir. I then want to be able to list all those files inside/within the directory. I have tried everything including
String a = listFiles().tostring();
Yet, nothing happens. To sum it up, I want to list all the files within a custom dir in the SD card.
Here's my updated code
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
FileInputStream iStream = new FileInputStream(path);
String read = path.getbytes().tostring();
You have to see this tutorial how to build an android file browser it will help you a lot!!
This one list all folder and files in sdcard you can adapt it to what you need by changing the value of currentDir in the code
This code is travel entire sdcard and list files. that's may be helpful to you ..!
import java.io.*;
import java.util.*;
public class DirUtils {
public static List recurseDir(String dir) {
String result, _result[];
result = recurseInDirFrom(dir);
_result = result.split("\\|");
return Arrays.asList(_result);
}
private static String recurseInDirFrom(String dirItem) {
File file;
String result,list[];
result = dirItem;
file = new File(dirItem);
if (file.isDirectory()) {
list = file.list();
File[] fileslist = file.listFiles(new MyDocFileFilter());
if (fileslist != null) {
for (File file1: fileslist) {
System.out.println(file1.getAbsolutePath());
}
}
else {
System.out.println("No Subdirectory Found.");
}
for (int i = 0; i < list.length; i++)
result = result + "\n" + recurseInDirFrom(dirItem + File.separatorChar + list[i]);
}
return result;
}
static class MyDocFileFilter implements FileFilter
{
private final String[] myDocumentExtensions
= new String[] {".java", ".png", ".html", "class"};
public boolean accept(File file) {
if (!file.isFile())
return false;
for (String extension : myDocumentExtensions) {
if (file.getName().toLowerCase().endsWith(extension))
return true;
}
return false;
}
}
public static void main(String arg[]) {
DirUtils.recurseDir("your path ");
}
}

List all the files from all the folders in a single list

I am looking for the solution to list all the files from root/Android device.
Suppose there are three folders inside the root directory, but I want to display all the files in all of these folders in a single list...
Now if am using
File f = new File("/sdcard");
Then it will list all the files from the sdcard folder only... And if I will use
File f = new File("/download");
Then it will list all the files from download folder only ..and if I will use
File f = new File("/");
Then it will list only the root directory files...not the files inside /sdcard or /download.
So what steps shall I follow to list all the files with a filter to list only .csv files from all the folder inside root?
Try this:
.....
List<File> files = getListFiles(new File("YOUR ROOT"));
....
private List<File> getListFiles(File parentDir) {
ArrayList<File> inFiles = new ArrayList<File>();
File[] files = parentDir.listFiles();
for (File file : files) {
if (file.isDirectory()) {
inFiles.addAll(getListFiles(file));
} else {
if(file.getName().endsWith(".csv")) {
inFiles.add(file);
}
}
}
return inFiles;
}
Or a variant without recursion:
private List<File> getListFiles2(File parentDir) {
List<File> inFiles = new ArrayList<>();
Queue<File> files = new LinkedList<>();
files.addAll(Arrays.asList(parentDir.listFiles()));
while (!files.isEmpty()) {
File file = files.remove();
if (file.isDirectory()) {
files.addAll(Arrays.asList(file.listFiles()));
} else if (file.getName().endsWith(".csv")) {
inFiles.add(file);
}
}
return inFiles;
}
I've modified Vyacheslav's solution because I needed only file names inside the directory.
...
List<String> files = getList(new File("YOUR ROOT"));
...
private List<String> getList(File parentDir, String pathToParentDir) {
ArrayList<String> inFiles = new ArrayList<String>();
String[] fileNames = parentDir.list();
for (String fileName : fileNames) {
if (fileName.toLowerCase().endsWith(".txt") || fileName.toLowerCase().endsWith(".rtf") || fileName.toLowerCase().endsWith(".txd")) {
inFiles.add(pathToParentDir + fileName);
} else {
File file = new File(parentDir.getPath() + "/" + fileName);
if (file.isDirectory()) {
inFiles.addAll(getList(file, pathToParentDir + fileName + "/"));
}
}
}
return inFiles;
}
You can use the following method,
private int readLogList(String filePath)
{
File directory = Environment.getExternalStorageDirectory();
File folder = new File(directory + ConstantCodes.FILE_SEPARATOR + filePath);
if (!folder.exists())
{
return 0;
}
return folder.list().length;
}

Categories

Resources