Recently there is a need, assistant's Google satellite map and opencyclemap downloaded offline map data, to be able to switch between the built-in storage and external storage space, because the offline tile data is very large, many outdoor users want to store these files on the external TF card, do not occupy the internal storage space, So the recent study of the collation of the next, to share to everyone.
Issues to consider and encounter (mainly for different phones, different system compatibility):
1. How do I get all of the memory attached to my phone?
Android is not providing explicit interface, first of all must be to read the system settings App "Storage" section of the source code, see how the storage there is obtained by what way. Finally, we find the 2 important classes of StorageManager and Storagevolume, and then get the storagevolume[] list by reflection.
2. What is the uniqueness of a memory?
Storage path? No (some phones do not plug the TF card, the built-in storage path is/storage/sdcard0, plug in the TF card, the built-in storage path into the/STORAGE/SDCARD1,TF card into/storage/sdcard0).
Memory card name? No (the system language may be switched, causing the name match to fail, and the resid of the name, the lower system version Storagevolume does not have the Mdescriptionid attribute).
After testing, it is found that using Mstorageid can indicate the uniqueness of the memory, the number of memory changes, and the ID of each memory will not change.
3. How do I get the name of the memory?
After testing, there are 3 main ways to get memory name for different mobile phones: getdescription (), getdescription (context context), first get Getdescriptionid () and then get the name by Resid.
4. When the task file is downloaded in half, switch the file to save the memory, how to deal with it?
There are 2 types of options:
4.1 When switching, if the new storage space enough for all file transfer, stop all download tasks, copy all downloaded and downloaded files to the new storage space, and then update the download database download task storage path, and then resume the download task;
4.2 When switching, copy all downloaded files to the new storage space, download the task to continue to download, download and then move to the new storage space.
5. On 4.4 Systems, third-party applications cannot read external memory card issues. (Refer to "External Storage")
In order to uninstall the program, Google can completely completely clean up the program all the data, the application will not be able to write to the Level 2 storage area file.
"The WRITE_EXTERNAL_STORAGE permission must only grant write access to the primary external storage on a device. Apps must not being allowed to write to secondary external storage devices, except in their package-specific directories as a llowed by synthesized permissions. Restricting writes in this ensures, the system can clean up files when applications is uninstalled. "
To be able to write files to a TF card on a 4.4 system, you must first root, and you can do so by Google.
So on the 4.4 system, the switchover will cause file transfer and download failure, if users want to switch to TF card, at least need to remind the user, and it is best to give 4.4 root solution.
Here is some of the code to get the memory:
public static class mystoragevolume{public int mstorageid; Public String MPath; Public String mdescription; public Boolean mprimary; public Boolean mremovable; public Boolean memulated; public int mmtpreservespace; public Boolean mallowmassstorage; public long mmaxfilesize; The maximum file size. (0 means no limit) public String mstate; Returns null public Mystoragevolume (context context, Object Reflectitem) {try {Method Fmstor Ageid = Reflectitem.getclass (). Getdeclaredmethod ("Getstorageid"); Fmstorageid.setaccessible (TRUE); Mstorageid = (Integer) fmstorageid.invoke (Reflectitem); } catch (Exception e) {} try {Method Fmpath = Reflectitem.getclass (). Getdeclaredmet Hod ("GetPath"); Fmpath.setaccessible (TRUE); MPath = (String) fmpath.invoke (Reflectitem); } catch (Exception e) {} try {Method Fmdescriptionid = Reflectitem.getclass (). Getdeclaredmethod ("GetDescription"); Fmdescriptionid.setaccessible (TRUE); Mdescription = (String) fmdescriptionid.invoke (Reflectitem); } catch (Exception e) {} if (mdescription = = NULL | | Textutils.isempty (mdescription)) {try {Method Fmdescriptionid = Reflectitem.getclass (). Getdeclaredmethod ("GetDescription"); Fmdescriptionid.setaccessible (TRUE); Mdescription = (String) fmdescriptionid.invoke (Reflectitem, context); } catch (Exception e) {}} if (mdescription = = NULL | | Textutils.isempty (mdescription)) {try {Method Fmdescriptionid = Reflectitem.getclass (). Getdeclaredmethod ("Getdescriptionid"); Fmdescriptionid.setaccessible (TRUE); int Mdescriptionid = (INteger) Fmdescriptionid.invoke (Reflectitem); if (Mdescriptionid! = 0) {mdescription = Context.getresources (). getString (Mdescriptionid); }} catch (Exception e) {}} try {Method F Mprimary = Reflectitem.getclass (). Getdeclaredmethod ("Isprimary"); Fmprimary.setaccessible (TRUE); Mprimary = (Boolean) fmprimary.invoke (Reflectitem); } catch (Exception e) {} try {Method fisremovable = Reflectitem.getclass (). Getdecla Redmethod ("isremovable"); Fisremovable.setaccessible (TRUE); Mremovable = (Boolean) fisremovable.invoke (Reflectitem); } catch (Exception e) {} try {Method fisemulated = Reflectitem.getclass (). getdeclar Edmethod ("isemulated"); Fisemulated.setaccessible (TRUE); memulated = (BOolean) Fisemulated.invoke (Reflectitem); } catch (Exception e) {} try {Method fmmtpreservespace = Reflectitem.getclass (). Get Declaredmethod ("Getmtpreservespace"); Fmmtpreservespace.setaccessible (TRUE); Mmtpreservespace = (Integer) fmmtpreservespace.invoke (Reflectitem); } catch (Exception e) {} try {Method fallowmassstorage = Reflectitem.getclass (). Get Declaredmethod ("Allowmassstorage"); Fallowmassstorage.setaccessible (TRUE); Mallowmassstorage = (Boolean) fallowmassstorage.invoke (Reflectitem); } catch (Exception e) {} try {Method fmaxfilesize = Reflectitem.getclass (). Getdecla Redmethod ("Getmaxfilesize"); Fmaxfilesize.setaccessible (TRUE); Mmaxfilesize = (Long) fmaxfilesize.invoke (Reflectitem); } catch (Exception e) {} try {Method fstate = Reflectitem.getclass (). Getdeclaredmethod ("GetState"); Fstate.setaccessible (TRUE); Mstate = (String) fstate.invoke (Reflectitem); } catch (Exception e) {}}/** * Get volume mount status, for example environment.media_mounted */ Public String getvolumestate (context context) {return storagevolumeutil.getvolumestate (context, MPath); The public boolean ismounted (context context) {return getvolumestate (context). Equals (environment.med ia_mounted); } public String GetDescription () {return mdescription; }/** * Gets the unique identity of the storage device */public String Getuniqueflag () {return "" + Mstorageid; }/*public Boolean isusbstorage () {return Mdescriptionid = = Android. R.STRING.STORAGE_USB; }*//** * Get directory free space Size */public long getavailablesize () { Return Storagevolumeutil.getavailablesize (MPath); }/** * Get directory Total storage space */public long gettotalsize () {return Storagevolumeutil.gettota Lsize (MPath); } @Override Public String toString () {return ' mystoragevolume{' + ' \nmstorage Id= "+ Mstorageid +" \ n, mpath= ' + mPath + ' \ ' + "\ n, mdescription=" + mdescriptio n + "\ n, mprimary=" + mprimary + "\ n, mremovable=" + mremovable + "\ n, memulated=" + memulated + "\ n, mmtpreservespace=" + mmtpreservespace + "\ n, MA Llowmassstorage= "+ mallowmassstorage +" \ n, mmaxfilesize= "+ mmaxfilesize +" \ n, MS Tate= ' + mstate + ' \ ' + '} ' + ' \ n '; }} Store Information Mystoragevolume
public static list<mystoragevolume> Getvolumelist (context context) { list<mystoragevolume> svlist = New Arraylist<mystoragevolume> (3); StorageManager Mstoragemanager = (storagemanager) context . Getsystemservice (activity.storage_service); try { Method mmethodgetpaths = Mstoragemanager.getclass (). GetMethod ("Getvolumelist"); object[] List = (object[]) Mmethodgetpaths.invoke (Mstoragemanager); for (Object item:list) { svlist.add (new Mystoragevolume (context, item)), } } catch (Exception e) { E.printstacktrace (); } return svlist; } Get all Storage
Examples of tests on GitHub:
Https://github.com/John-Chen/BlogSamples/tree/master/StorageTest
If there is any other place that is not considered, welcome to the discussion.
Other great article articles
Android Learning Notes ($) Android Options Menu and submenu (submenu) Android Learning note (notification) features and usage of Android Learning notes ($) Android using listeners to listen to menu events Android Learning notes (+) Android Create a single-selection menu and a check menu for jquery tutorials ( -ajax operations based on request load Data jquery tutorial (-ajax) append HTML for operationmore about Android Development articles
Android File storage location switch