1

i'm writing an app that needs to "scan" phone memory for files with specific extension (now using txt for testing purposes). I have a problem understanding how Android filesystem actually works - I found how to access both internal and external sdcard, i can open it with file explorer from root folder. I cannot access these folders from app though.

Here is my code:

private void findTXT(File directory) {
    directory.setReadable(true); //found this advice - doesnt help

    if(directory.listFiles() != null) { //if not empty
        for (File i : directory.listFiles()) { //iterate trough all files
            try {
                if (i.isDirectory()) //if it is directory
                    findTXT(i); //recurse
                else if (MimeTypeMap.getFileExtensionFromUrl(i.toURI().toURL().toString()) == "txt") //check ending of regular file
                    files.add(i); //store it
            }
            catch(IOException e) {}
        }
    }
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_menu);

    TextView text = (TextView) findViewById(R.id.textView);

    findTXT(new File("/sdcard/")); //this should be phones built-in memory
    findTXT(new File("/mnt/sdcard")); //this is the same folder as above
    findTXT(Environment.getExternalStorageDirectory()); //this one too
    findTXT(new File("/mnt/ext_sdcard")); //this should be removable sdcard

    for (File i : getExternalFilesDirs(null) ) //this should be universal?
        findTXT(i);

    //list file names on screen
    if(files != null) {
        for (File i : files)
            text.setText(text.getText() + i.getName() + "\n");
    }
}

Here are my permissions in manifest

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

The problem is, that the app doesnt list files in the /sdcard or other folders - it seems to be able to list only

/storage/emulated/0/Android/data/*com.mycompany.appname*/files

Am I having some problem with permisions that I dont understand? Because even after few hours of research, I am no closer to understand how storage on Android works...

Thanks for all answers :)

  • Lederer you can't application level files without root permisiion – Jagjit Singh Sep 02 '16 at 09:43
  • 1
    Oh, OK... I dont need aplication level files, i need user files (files on external/internal sd like multimedia, documents etc.). Am I looking in the wrong place then? – Tomáš Lederer Sep 02 '16 at 09:48
  • Lederer Refer here http://stackoverflow.com/questions/5858107/how-to-get-file-path-from-sd-card-in-android – Jagjit Singh Sep 02 '16 at 09:50
  • Thanks for answer, I already tried all the options listed there... (hardcored path, getexternalstoragedirectory() and newer getExternalFilesDirs()...) – Tomáš Lederer Sep 02 '16 at 09:55
  • First, **never hardcode paths**. Android is a multi-user OS, and paths will vary by account. *Always* use a method to derive a base path, such as `Environment.getExternalStorageDirectory()` and `getExternalFilesDirs(null)` in your code. Second, you do not have direct filesystem access to arbitrary locations on [removable storage](https://commonsware.com/blog/2014/04/09/storage-situation-removable-storage.html) on Android 4.4+. Third, querying the `MediaStore` would be much faster than doing your own filesystem scan. – CommonsWare Sep 02 '16 at 10:59

2 Answers2

0

Try this

File directory = Environment.getExternalStorageDirectory();
List<File> files = getListFiles(directory); 
 ....
 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;
}

Hope it helps. If you are on API level 23. Then you need to ask runtime permisiion

Jagjit Singh
  • 1,909
  • 1
  • 14
  • 19
  • Still the same problem... getExternalStorageDirectory() returns "/storage/emulated/0", which seems to be an empty folder. Both for emulator and my phone – Tomáš Lederer Sep 02 '16 at 10:11
  • @Tomas Lederer Its the path to your Sd card and then enter name of the folder you will get there – Jagjit Singh Sep 02 '16 at 10:16
0

give run time permission for read and write as below

  if (Build.VERSION.SDK_INT >= 23 &&
                ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED &&
                ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {

            ActivityCompat.requestPermissions((BaseActivity) context,
                    new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE},
                    MY_PERMISSIONS_REQUEST_READ_AND_WRITE_SDK);
        } else {
            callYourMethod();


        }

and

  @Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    switch (requestCode) {
        case MY_PERMISSIONS_REQUEST_READ_AND_WRITE_SDK:

            if (grantResults.length > 0
                    && grantResults[0] == PackageManager.PERMISSION_GRANTED) {

                callYourMethod();
            }
            break;


    }
}
Rahul Chaudhary
  • 1,059
  • 1
  • 6
  • 15
  • This helped, thanks! I didnt know that runtime permissions are now requirement... – Tomáš Lederer Sep 02 '16 at 10:26
  • Should also check for the second permission to be granted by user. `if (grantResults.length == 2 && grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {...}` – Roman Samoilenko Sep 02 '16 at 10:45