I want to let the user safely remove the SD card in my program, but it seems the Android 2.2 public API does not provide a way to do this. Does anyone know what's a proper way to do it?
You need to take the user to the device's built-in Settings. I think this will work.
Intent i = new Intent(android.provider.Settings.ACTION_MEMORY_CARD_SETTINGS);
startActivity(i);
Unmounting the SD card is one of those actions which could be used maliciously if it wasn't under full user control. If it could be done purely in software (without user intervention) then code could disrupt other apps running on the device.
Indeed on the Logitech Revue (the Google TV companion box) that Intent call launches the Storage control panel which gives user access to the Unmount command for safe removal. If you just pull the USB device out on that unit it is experienced as an Unsafe/unexpected removal and your card could be left in proverbial disarray if treated that way. Thanks for the hint, very useful.
The Revue by the way have an unusual arrangement with the /sdcard unit built in,
so if you plug in an external SD card via USB adapter or use some USB stick it will show up under /mnt/ as a name beginning with "usb" and some number. So you have three storage areas on that unit, internal, the built in "sdcard" and USB ports where drives will mount when inserted.
I haven't earned enough points yet to be allowed to include a snapshot of how the panel looks.
Related
This emerged out of an earlier question Android app on Chromebook to access USB devices?
It seems that ARC does not yet provide any way to access external storage except using { "enableExternalDirectory": true }. This has some significant limitations for my use case.
The intent is that a user can insert a USB Flash Drive into the device, and for my app to read and write files on it.
Unfortunately, with the enableExternalDirectory option enabled, the user is forced to select a directory, even if they are not using any of the features for which my app requires such access. The simplest approach is for the user to select the Downloads folder instead of the USB device.
Later, if the user wishes to write data to the Flash Drive, he must use the Directory icon in the top left corner of the ARC App window, and then restart.
I plan to include the required instructions in-app, but for better experience, I'd like to be able to track whether they have done this.
How can I
Pop open the prompt for the user to choose a directory
Detect which directory was selected. (external or internal)
Restart my app so the new mounted directory will take effect?
Are any of these possible in an ARC app?
My goal is to save data from app in a text file for further analysis. I used the exact code as given here for saving data:
The data is stored and retrieved according to the app, but I am not able to find MySampleFile.txt (even using the search functionality) on the phone.
I can't find it in Android -> data -> com.*.*. I have a Samsung Galaxy S3. Is anything different in this phone?
Should I make any modifications in the phone?
Do the following to be able to see your data stored in the phone's internal memory.
Turn on USB Debugging on your phone.
Connect your phone to the system.
Open DDMS perspective in your Eclipse.
Select your device from the devices tab on the left.
On the right, the last tab will be File Explorer. Open that.
Traverse to data/data/your.app.package to find the data you want to see.
P.S:- NEVER root your phone, unless you're a developer who loves to mess around with the System apps.
To see data, you phone must be root. Samsung Galaxy S3 is not a root from vendor, you need to root your phone to access internal memory/storage, you can only access external memory/storage in your phone i.e. sdcard
But, i would suggest you to use Emulator rather root your phone.
Here, are some links about what is rooting, you can go through these:
http://gizmodo.com/5982287/reasons-to-root-your-android-device
http://lifehacker.com/5789397/the-always-up+to+date-guide-to-rooting-any-android-phone
http://en.wikipedia.org/wiki/Android_rooting
But again I would suggest to use Emulator unless you are not expert enough to root and Install firmwares again when you don't want your phone root.
Please use Emulator to see data->com.package
From Windows Menu->ShowView->Others->android->fileExplorer you can see the file in your device
Specify permission in AndroidManifest.xml:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
I've got a DSLR camera and Samsung Galaxy Tab running Android Honeycomb. DSLR connected to a tablet using USB-cable (via USB kit enabling host functionality on a tablet). I'd like to being notified when user takes a photo using this external camera, in order to download this image to the tablet or do something else with it like showing Toast notification containing meta-information taken from the image.
As far as I get all of the existing tools (like FileObserver using underlying inotify mechanism, MediaContentProvider etc) allowing to watch for changes, demand a specific file or a filesystem path to be watched. This was good enough till we had a block layer protocol support in 2.x and earlier Android versions - when you connected device it'd been mounted somewhere on the device's filesystem and you was able to use this mountpoint as a watch point for those tools.
Since Honeycomb Google has changed the way of accessing external USB devices to Media Transfer Protocol with PTP as a subset of this. Now when I connect external USB device to an Android device I won't see any mountpoints for it (I'm using adb shell and subsequent mount command for getting them). Moreover, MTP implementation uses storage ids which apparently act as a higher level of abstraction and are just plain integer values. I was hoping there is a way to somehow translate these storage ids to the real paths/mountpoint/whatever but apparently there does not appear to be.
Thinking about Android MediaScanner which is already running on my device I guessed it could manage this issue with a special Intent broadcasted when there're changes in media files accessible from the device, so I started looking for already existing and suitable Intents for being notified, but no luck - I found only ACTION_MEDIA_MOUNTED and ACTION_MEDIA_REMOVED which are broadcasted only when device is connected and disconnected respectively. That means MediaScanner can't notice any changes on the device until you remount it (I've double checked it using stock Gallery app - it doesn't see any newly created images on the camera until you unplug and then plug it into the Android device again).
Trying to get this mount path for external sdcard, I used Environment.getExternalStorageDirectory() API call but it yields emulated Galaxy's sdcard path
which is /mnt/sdcard, not the camera's one. So it doesn't work for me either.
I managed to work out this issue only having launched periodic Timer event with AsyncTask acting as a TimerTask. This task does initialize usb connection, open device,
scan the whole device memory, getting only the last taken photo and then close device descriptor and usb connection.
It doesn't look like the best and efficient way of doing that taking into account it has to do all of these actions every time which could be pretty often, say each 5 or 10 seconds. It definitely quickly drains battery out and produces unnecessary system I/O for only taking last taken photo and comparing it with the previous last taken photo (in 99% it'd the same image), but I haven't found any better working solution for doing this. It'd much better off to have an observer mechanism with event-based notifications.
So my question is there more efficient way of being notified about changes in external USB storage for Honeycomb or later Android versions rather than one described above?
If you would like a more efficient way the camera would have to send out some sort of signal over usb that it has taken a photo. I guess it is not doing that.
Therefore you will have to check manually by doing the way your are discribing:
mount storage --> check for changes --> do your thing with your detected changes.
I dont know what you used to read "the MTP way" but here an example application:
https://github.com/ynakanishi/Honeycomb-MTP-sample
To not scan the entire storage every time you could save the result of read out file names for example every time you check and compare it to find the new ones. Usually the naming of the file also starts with the same number on a camera. So if you start a session with an empty sd card you know already the file name the photo will have. lets say img0001.jpg. So you just need to write a function to grab that file until it succeeds. if you want the next one img0002.jpg you can write a task/service/function to grab that file until successful, and so on.
If you want to save on battery you could implement an additional battery/power source inbetween for powering the usb port.
Instead of an Async task or timerTask you could try a ScheduledExecutorService and see if it uses less power.
Hope that gave you some new thoughts
I'm developing an app that makes file downloads, handles lists, contains a map, and so on.
My problem appears when I use a device that has the automount mass storage option activated.
If, at some moment, while running my app, I plug in the USB cable for some reason (charge, copy pics while app is in background, see app logs etc), the mass storage is mounted automatically and all my activities are recreated and my app status is lost.
OK, I could keep some data in DB/preferences in order to be able to restore it, but it's not ok to keep each variable in DB or preferences.
I know that there is an option is settings where I can uncheck this option, but I cannot ask this to every user that will use my app.
I also tried to find a solution to programatically uncheck the automount setting, but I couldn't find one.
I ran out of solutions. Any idea is more than welcome.
Thanks.
Checks the apps you have installed.
Some apps automount your USB storage (AFAIK, doubleTwist and Winamp do this)
We've developed an Android program that relies on access to a particular directory on the SD card. Our program detects whether the SD card is available to the phone, and displays an error message to the user if it's not. The most common use case that will trigger this error is having the device plugged into a computer and having the SD card mounted to the computer.
We're working on the error message, which will instruct the user to make sure the SD card is available to the phone.
Unfortunately, it appears that each phone manufacturer has their own terminology for whether the SD card is available to the phone and how to mount/unmount it. For example, (some?) Samsung devices display a screen with a Mount/Unmount button. The HTC Thunderbolt has a menu one of whose options is "Charge Only". Motorola devices seem split between the Samsung-like behavior and the HTC Thunderbolt-like behavior. The XOOM is it's whole own contraption.
So, two questions:
Is there a common correct terminology that will communicate to the user that they should make the SD card available to the device instead of available to the computer?
If there's not a good common terminology, is there a way to determine what sort of device we're running on and tailor our error message to the particular device's terminology?
"Please remove all usb peripherals (exc chargers) for this app to work"?
NB. (when its mounted but they think its just a charger they will eventually remove it to see if it works anyway!)
Otherwise:
http://developer.android.com/reference/android/os/Build.html
Check out BRAND or MANUFACTURER or a combination of them plus others (MODEL == 'XOOM' maybe?)
if("Motorola".equals(android.os.Build.MANUFACTURER)){ // or .contains or .starts with etc
// Do stuff
}
You may want to do some testing as it may return "Mtrla" or "MotorolaChina" etc..