1

My Android app needs to store 15 GB of data, so it needs to use removable storage. So I need to check if fsck is running while my app is loading (to quit if that is the case). Of course I can do a

Runtime.getRuntime().exec("ps");

but I have read that this solution is not reliable... So I tried with

ActivityManager manager = (ActivityManager) getSystemService(ACTIVITY_SERVICE);
for (RunningAppProcessInfo tasks : manager.getRunningAppProcesses()) {
     System.out.println(" ########## " + tasks.processName + " #######");
}

but I don't see any fsck. Actually, using ps I see it as being executed as

/system/bin/fsck.exfat -R -f /dev/...

Is the only way using Runtime.getRuntime().exec("ps")?

Thanks!

L.

EDIT

The command Environment.getExternalStorageState() does not work for me. After unmounting/mounting the SD card, with the code below, I get AT THE SAME TIME, MOUNTED and /system/bin/fsck.exfat -R -f /dev/...

String line;
BufferedReader br;
try {
    br = new BufferedReader(new InputStreamReader( Runtime.getRuntime().exec("ps").getInputStream()));
    while ((line = br.readLine()) != null) {
    if (line.contains("/fsck")) 
        System.out.println("### PS:" + Environment.getExternalStorageState() + " ### " +line);
} catch (IOException e1) {
     e1.printStackTrace();
}

This is the output I get:

PS:mounted ### root  [...] D /system/bin/fsck.exfat /dev/...
Luis A. Florit
  • 2,169
  • 1
  • 33
  • 58
  • 1
    Why on earth do you need to know this? If you're worried about the external storage being in a bad state, you can check `Environment.getExternalStorageState()`. – Kevin Coppock Sep 15 '13 at 21:11
  • @kcoppock: Simply because you're wrong. `Environment.getExternalStorageState()` does *NOT* return the external storage in many devices, but the internal memory (Samsung Galaxys always returm `MOUNTED` even without any SD card in the slot). The docs explicitly warn about this. It's amazing how many times this is referred as a solution... – Luis A. Florit Sep 15 '13 at 21:19
  • 1
    "Simply because you're wrong" -- no, he is not. Please read [the documentation](http://developer.android.com/guide/topics/data/data-storage.html#filesExternal). If you are concerned about something other than `Environment.getExternalStorageState()`, then you are concerned about something other than external storage. All bets are off as to the behavior of other data stores, and if you are down to the level of worrying about `fsck`, that would be a big neon sign indicating that you are working at a level far beyond what an Android SDK developer should be doing. – CommonsWare Sep 15 '13 at 21:31
  • @Luis Why does this matter? You shouldn't be hardcoding a reference to the SD card, but acquiring it through the APIs for external storage. Many devices do not *have* SD cards (such as the Nexus 4). Why is it important that it be an actual physical SD card? If you're worried about whether or not it's removable storage, there's also the `isExternalStorageRemovable()` method. – Kevin Coppock Sep 15 '13 at 21:32
  • @CommonsWare, @kcoppock: Please, read the `EDIT` to my original post. There I implemented the `Environment.getExternalStorageState()`, and I get, *at the same time*, `MOUNTED` and `/system/bin/fsck.exfat...` Therefore, `Environment.getExternalStorageState()` is not referring to the SD card slot. I always get `MOUNTED` from `Environment.getExternalStorageState()` because it refers to the internal device memory (in my devices), and I don't care about this memory. So: how can I force `ExternalStorageState()` to look for the SD card (or whatever I want) state? – Luis A. Florit Sep 15 '13 at 21:57
  • If for your device `getExternalStorageState()` refers to the internal storage, then `getExternalStorageDirectory()` will also return the internal storage. If the external storage state is MOUNTED, then you're safe to read/write to the external storage directory. If you're hardcoding `/sdcard/` you're going to run into a host of other issues anyway. – Kevin Coppock Sep 15 '13 at 21:59
  • 1
    "So: how can I force ExternalStorageState() to look for the SD card (or whatever I want) state?" -- you can't. There is the official external storage, and that's it. Anything beyond that, if it exists, is unsupported. Quoting the docs: "It's possible that a device using a partition of the internal storage for the external storage may also offer an SD card slot. In this case, the SD card is not part of the external storage and your app cannot access it (the extra storage is intended only for user-provided media that the system scans)." – CommonsWare Sep 15 '13 at 22:00
  • @CommonsWare: Ok, so we agree: `ExternalStorageState()` is useless for me. Therefore, if I understand you correctly, I should use something like the `Runtime.getRuntime().exec("ps")` solution, right? – Luis A. Florit Sep 15 '13 at 22:04
  • @LuisA.Florit Can you describe your use case for this? – Kevin Coppock Sep 15 '13 at 22:05
  • @kcoppock: I don't know why you think I hardcoded '/sdcard'. My app uses 15GB of storage, so the user in general has to use a SD card (at least in 2013), and he enters the path. Hence, I don't want him to open the app right after rebooting the phone, while `fsck` is checking for the SD card (/NOT/ the ExternalStorage!). – Luis A. Florit Sep 15 '13 at 22:07
  • @LuisA.Florit If you're not hardcoding `/sdcard/` then to what directory are you writing this 15 GB of data? – Kevin Coppock Sep 15 '13 at 22:09
  • Ideally, you don't do any of it (reference an unsupported data store, assume particular `fsck` behaviors, assume that the only possible interference with whatever you are doing is `fsck`, etc.). I have no particular advice on how to make doing this particular bit of unsupported stuff any more reliable, other than to note that `getRunningAppProcesses()` is for *app* processes (forks of the zygote), not arbitrary system processes. – CommonsWare Sep 15 '13 at 22:09
  • @CommonsWare: Yes, that's why I didn't want to use `Runtime + ps`. But I don't know what else to do besides blocking my app from opening if `fsck` is running. About the last part you wrote, exactly, I tried with `PM.getRunningAppProcesses()` but got no `fsck`: no system process appear. Maybe there's some tool to get the system processes...? – Luis A. Florit Sep 15 '13 at 22:15
  • @kcoppock: user defined. – Luis A. Florit Sep 15 '13 at 22:18
  • 1
    What happens if the app opens while the SD card is not ready? If there's an exception thrown, why not just catch the exception during launch and make that your determination of whether or not to continue? – Kevin Coppock Sep 15 '13 at 22:21
  • @kcoppock: The user puts databases and files in a `mainfolder`, wherever he wants, and then he tells the app where this `mainfolder` is. In general, because of size, `mainfolder` sits in the SD card. The app stores the location of this `mainfolder` in preferences, so next time the app knows where it is. If the folder does not exist, a preference window opens asking for the user to fix the path. But it may not exist only because the SD card is not prepared: this always happens after a reboot... because `fsck`. Makes more sense now? – Luis A. Florit Sep 15 '13 at 22:25
  • @CommonsWare: Actually, when an app is installed on the SD card, the icon is greyed out... Is there any way to tell Android that I want my app to be available only after all the devices are ready? – Luis A. Florit Sep 15 '13 at 23:12
  • "Is there any way to tell Android that I want my app to be available only after all the devices are ready?" -- nothing in the Android SDK. If you are making your own ROM mod, though, you could probably hack something in there. – CommonsWare Sep 15 '13 at 23:23
  • @CommonsWare: No, no ROMs here. It would be nice if I could tell Android that my app is also installed in the SD card.... Anyway, thanks a lot for your patience! – Luis A. Florit Sep 15 '13 at 23:41

1 Answers1

0

Jeff Sharkey writes:

Good news! In KitKat there's now a public API for interacting with these secondary shared storage devices.

The new Context.getExternalFilesDirs() and Context.getExternalCacheDirs() methods can return multiple paths, including both primary and secondary devices. You can then iterate over them and check Environment.getStorageState() and File.getFreeSpace() to determine the best place to store your files. These methods are also available on ContextCompat in the support-v4 library.

Also note that if you're only interested in using the directories returned by Context, you no longer need the READ_ or WRITE_EXTERNAL_STORAGE permissions. Going forward, you'll always have read/write access to these directories with no additional permissions required.

Apps can also continue working on older devices by end-of-lifing their permission request like this:

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18" />
Community
  • 1
  • 1