I'm working on cache cleaner app, after doing research on google I found that Android system has moved "CLEAR_APP_CACHE" permission to "signature, privileged" state. So I'm unable clear cache with freeStorageAndNotify method.
Apps on google playstore like CCleaner, Power Clean etc.. are using Accessibility Service To Delete Cache.
I have also created basic accessibility service for my app, but don't know how to delete cache of apps
You can get a list of installed apps and delete cache like:
public static void clearALLCache()
{
List<PackageInfo> packList = getPackageManager().getInstalledPackages(0);
for (int i=0; i < packList.size(); i++)
{
PackageInfo packInfo = packList.get(i);
if ( (packInfo.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0)
{
String appName = packInfo.applicationInfo.loadLabel(getPackageManager()).toString();
try {
// clearing app data
// Runtime runtime = Runtime.getRuntime();
// runtime.exec("pm clear "+packInfo.packageName);
Context context = getApplicationContext().createPackageContext(packInfo.packageName,Context.CONTEXT_IGNORE_SECURITY);
deleteCache(context);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public static void deleteCache(Context context) {
try {
File dir = context.getCacheDir();
deleteDir(dir);
} catch (Exception e) {}
}
public static boolean deleteDir(File dir) {
if (dir != null && dir.isDirectory()) {
String[] children = dir.list();
for (int i = 0; i < children.length; i++) {
boolean success = deleteDir(new File(dir, children[i]));
if (!success) {
return false;
}
}
return dir.delete();
} else if(dir!= null && dir.isFile()) {
return dir.delete();
} else {
return false;
}
}
It is equivalent to clear data option under Settings --> Application Manager --> Your App --> Clear data. (In comment)
For making your application support this you should also follow Privileged Permission Whitelisting from google
I am new to android and am writing an app to copy all document files into my PC programmatically. I have the list of files in folders with me (Currently in a listview). All I need to know is how to copy each file into my PC. Once copied, how to retrieve them back? I am sure that I need to code a server side program in my PC as well, But a little concerned on where to start and how. Below is the android code snippet.
public class DocsList extends Activity implements OnClickListener {
CheckBox ChkSelectAll;
ListView DocsList;
Button Backup, Reset, GoBack;
TextView textview;
String[] FileNames;
int k = 0;
public List<String> myList;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
myList = new ArrayList<String>();
setContentView(R.layout.docslist);
ChkSelectAll = (CheckBox)findViewById(R.id.SelectAllDocscheckBox);
DocsList = (ListView)findViewById(R.id.DocsList);
Backup = (Button)findViewById(R.id.BackupDocs);
Reset = (Button)findViewById(R.id.ResetDocs);
GoBack = (Button)findViewById(R.id.GoBackDocs);
String dir = Environment.getExternalStorageDirectory().toString();
File f = new File(dir);
ArrayList<String> files = getListofDocs(f);
ArrayAdapter<String> PhoneAdptr = new ArrayAdapter<String>(this, android.R.layout.simple_selectable_list_item,files);
DocsList.setAdapter(PhoneAdptr);
boolean NetState = isNetworkConnected(this);
if (NetState == true) {
// Code yet to be written
}
else {
// Code yet to be written
}
}
private boolean isNetworkConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
// There are no active networks.
return false;
} else
return true;
}
public ArrayList<String> getListofDocs(File parentdir) {
ArrayList<String> infiles = new ArrayList<String>();
File[] files = parentdir.listFiles();
if (files != null) {
for(File file : files)
if (file.isDirectory()) {
infiles.addAll(getListofDocs(file));
}
else {
if (file.getName().endsWith("doc") || file.getName().endsWith("DOC") ||
file.getName().endsWith("docx") || file.getName().endsWith("DOCX") ||
file.getName().endsWith("htm") || file.getName().endsWith("HTM") ||
file.getName().endsWith("html") || file.getName().endsWith("HTML") ||
file.getName().endsWith("txt") || file.getName().endsWith("TXT") ||
file.getName().endsWith("pdf") || file.getName().endsWith("PDF")) {
infiles.add(file.toString());
}
}
}
return infiles;
}
#Override
public void onClick(View v) {
if (v == GoBack) {
Intent Back = new Intent(DocsList.this, CloudStorage.class);
startActivity(Back);
finish();
}
}
}
I have made use of Dropbox to store my files. Thanks all for your help. I am still working on the retrieval though.
I am developing an application in which i have to get all available storage directories on device, like file directory, on Board storage, external sdCard storage (Removable)
but the storage path varies device to device such as
i have Samsung Galaxy tab 7 with Froyo2.2 that has these three storage
1: Files Directory
/mnt/.lfs,
2: OnBoard Storage Directory
/mnt/sdcard,
3: External sdCard Removeable Storage Directory
/mnt/sdcard/external_sd
i am getting these using this code
public static String[] getDirectories()
{
Log.d(TAG, "getStorageDirectories");
File tempFile;
String[] directories = null;
String[] splits;
ArrayList<String> arrayList = new ArrayList<String>();
BufferedReader bufferedReader = null;
String lineRead;
try
{
arrayList.clear(); // redundant, but what the hey
bufferedReader = new BufferedReader(new FileReader("/proc/mounts"));
while ((lineRead = bufferedReader.readLine()) != null)
{
Log.d(TAG, "lineRead: " + lineRead);
splits = lineRead.split(" ");
// System external storage
if (splits[1].equals(Environment.getExternalStorageDirectory().getPath()))
{
arrayList.add(splits[1]);
Log.d(TAG, "gesd split 1: " + splits[1]);
continue;
}
// skip if not external storage device
if (!splits[0].contains("/dev/block/"))
{
continue;
}
// skip if mtdblock device
if (splits[0].contains("/dev/block/mtdblock"))
{
continue;
}
// skip if not in /mnt node
if (!splits[1].contains("/mnt"))
{
continue;
}
// skip these names
if (splits[1].contains("/secure"))
{
continue;
}
if (splits[1].contains("/mnt/asec"))
{
continue;
}
// Eliminate if not a directory or fully accessible
tempFile = new File(splits[1]);
if (!tempFile.exists())
{
continue;
}
if (!tempFile.isDirectory())
{
continue;
}
if (!tempFile.canRead())
{
continue;
}
if (!tempFile.canWrite())
{
continue;
}
// Met all the criteria, assume sdcard
arrayList.add(splits[1]);
}
}
catch (FileNotFoundException e)
{
}
catch (IOException e)
{
}
finally
{
if (bufferedReader != null)
{
try
{
bufferedReader.close();
}
catch (IOException e)
{
}
}
}
// Send list back to caller
if (arrayList.size() == 0)
{
arrayList.add("sdcard not found");
}
directories = new String[arrayList.size()];
for (int i = 0; i < arrayList.size(); i++)
{
directories[i] = arrayList.get(i);
}
return directories;
}
but when i run this code on Nexus7 4.2.2 Jelly Beans it returns only one path at runtime how may i know what path is this
and this storage paths varies among different devices
i have to identify onBoard storage if available user can select device storage
if external sdcard available then user can select onBoard or external storage
I am trying to create a mp3 player as an android app and I want to have it that it will automatically find any .mp3 file in my My Files folder. I don't want to have a direct path to a Music folder as I will include a link to Dropbox, where I can download a .mp3 file that is already on it. This will go to a Download folder and I want my MP3 player to pick it up for me.
How could I do this? Any help would be much appreciated.
This method should work
private void searchMusic() {
int count = 0;
ArrayList<String> musicFiles;
LinkedList<File> stack = new LinkedList<File>();
File directory = new File(Environment.getExternalStorageDirectory()
.getAbsolutePath());
stack.add(directory);
while (!stack.isEmpty()) {
File fmusic = stack.removeLast();
File[] files = null;
try {
files = fmusic.listFiles();
} catch (Exception e) {
}
musicFiles = new ArrayList<String>();
if (files != null) {
for (File folder : files) {
if (folder.getName().endsWith(".mp3")
|| folder.getName().endsWith(".ogg")
|| folder.getName().endsWith(".wav")
&& folder.isFile() && folder.canRead()
&& !folder.getName().startsWith("._")) {
count++;
musicFiles.add(folder.getPath());
}
try {
if (folder.isDirectory()
&& !FileUtils.isSymlink(folder)) {
stack.addFirst(folder);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return;
}
I am looking for a way to detect and access removable sd cards on a variety of Android devices (Samsung, Motorola, LG, Sony, HTC).
I also need to be compatible with 2.2 so Environment.isExternalStorageRemovable() is unavailable for me.
Motorola has its own library, and for Samsung I can detect the existence of /external_sd/
I have no clue for the rest of them. For example, I have seen a /_ExternalSD/ on some LG's but it the directory remains even when the SD is removed.
A bonus question: will the ACTION_MEDIA_MOUNTED intent be broadcast for any of them
Any hint on this would be very helpful.
Here's a class I use to find all sdcards on a device; built in and removable. I've been using it on Ice Cream Sandwich, but it should work at 2x levels.
public class GetRemovableDevice {
private final static String TAG = "GetRemoveableDevice";
public GetRemovableDevice() {
}
public static String[] getDirectories() {
MyLog.d(TAG, "getStorageDirectories");
File tempFile;
String[] directories = null;
String[] splits;
ArrayList<String> arrayList = new ArrayList<String>();
BufferedReader bufferedReader = null;
String lineRead;
try {
arrayList.clear(); // redundant, but what the hey
bufferedReader = new BufferedReader(new FileReader("/proc/mounts"));
while ((lineRead = bufferedReader.readLine()) != null) {
MyLog.d(TAG, "lineRead: " + lineRead);
splits = lineRead.split(" ");
// System external storage
if (splits[1].equals(Environment.getExternalStorageDirectory()
.getPath())) {
arrayList.add(splits[1]);
MyLog.d(TAG, "gesd split 1: " + splits[1]);
continue;
}
// skip if not external storage device
if (!splits[0].contains("/dev/block/")) {
continue;
}
// skip if mtdblock device
if (splits[0].contains("/dev/block/mtdblock")) {
continue;
}
// skip if not in /mnt node
if (!splits[1].contains("/mnt")) {
continue;
}
// skip these names
if (splits[1].contains("/secure")) {
continue;
}
if (splits[1].contains("/mnt/asec")) {
continue;
}
// Eliminate if not a directory or fully accessible
tempFile = new File(splits[1]);
if (!tempFile.exists()) {
continue;
}
if (!tempFile.isDirectory()) {
continue;
}
if (!tempFile.canRead()) {
continue;
}
if (!tempFile.canWrite()) {
continue;
}
// Met all the criteria, assume sdcard
arrayList.add(splits[1]);
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
}
}
}
// Send list back to caller
if (arrayList.size() == 0) {
arrayList.add("sdcard not found");
}
directories = new String[arrayList.size()];
for (int i = 0; i < arrayList.size(); i++) {
directories[i] = arrayList.get(i);
}
return directories;
}
}
The MyLog.d is a trace class that expands Log.d - it can be dropped.
The class reads /proc/mounts/ and:
checks to see if the path name is the internal sdcard directory
checks to see if its a block device
skips mtdblock devices
skips anything that is not mounted
skips secure and asec directories
makes sure it exists, is a directory, and read/write accessible
If all this is matched, it assumes that you have an sdcard and adds the path to the array list. It returns a string array of path names.
To call the getDirectories function, code something similar to:
String[] sdcardDirectories = GetRemoveableDevice.getDirectories();
The paths returned can be used to create a user selection list, scan for a file, or whatever.
Finally, here's two lines of MyLog.d from an emulator test (second line is the emulator sdcard):
09-19 15:57:12.511: D/GetRemoveableDevice(651): lineRead: /dev/block/mtdblock2 /cache yaffs2 rw,nosuid,nodev 0 0
09-19 15:57:12.511: D/GetRemoveableDevice(651): lineRead: /dev/block/vold/179:0 /mnt/sdcard vfat rw,dirsync,nosuid,nodev,noexec,uid=1000,gid=1015,fmask=0702,dmask=0702,allow_utime=0020,codepage=cp437,iocharset=iso8859-1,shortname=mixed,utf8,errors=remount-ro 0 0
Based on Howards class I made some modifications to make it work on the Galaxy S3.
Environment.getExternalStorageDirectory() returns internal storage on the S3.
Removable storage is not necessarily mounted under /mnt
Removable media must have vfat filesystem
_
public static String getDirectory() {
Log.d(TAG, "getStorageDirectories");
File tempFile;
String[] splits;
ArrayList<String> arrayList = new ArrayList<String>();
BufferedReader bufferedReader = null;
String lineRead;
try {
arrayList.clear(); // redundant, but what the hey
bufferedReader = new BufferedReader(new FileReader("/proc/mounts"));
while ((lineRead = bufferedReader.readLine()) != null) {
Log.d(TAG, "lineRead: " + lineRead);
splits = lineRead.split(" ");
// skip if not external storage device
if (!splits[0].contains("/dev/block/")) {
continue;
}
// skip if mtdblock device
if (splits[0].contains("/dev/block/mtdblock")) {
continue;
}
// skip if not in vfat node
if (!splits[2].contains("vfat")) {
continue;
}
// skip these names
if (splits[1].contains("/secure")) {
continue;
}
if (splits[1].contains("/mnt/asec")) {
continue;
}
// Eliminate if not a directory or fully accessible
tempFile = new File(splits[1]);
if (!tempFile.exists()) {
continue;
}
if (!tempFile.isDirectory()) {
continue;
}
if (!tempFile.canRead()) {
continue;
}
if (!tempFile.canWrite()) {
continue;
}
// Met all the criteria, assume sdcard
return splits[1];
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
}
}
}
return null;
}
Based on Howards class I modified the class further on noticing that all of the external removable storage on several phones and tablets that I could find were mounted using vold, the volume mounting daemon.
// skip if not external storage device
if (!splits[0].contains("vold")) {
continue;
}
if (splits[1].contains("/mnt/asec")) {
continue;
}
// Eliminate if not a directory or fully accessible
tempFile = new File(splits[1]);
if (!tempFile.exists()) {
continue;
}
if (!tempFile.isDirectory()) {
continue;
}
if (!tempFile.canRead()) {
continue;
}
if (!tempFile.canWrite()) {
continue;
}
// Met all the criteria, assume sdcard
arrayList.add(splits[1]);
These capabilities are available in all Android versions:
To obtain the application's folder on the external storage, call Context.getExternalFilesDir.
Keep in mind that your app needs explicit permission to access external storage, and that you should check if it is available via Environment.getExternalStorageState
And yes, ACTION_MEDIA_MOUNTED will be broadcast whenever removable media becomes accessible (You should also listen for ACTION_MEDIA_EJECT and ACTION_MEDIA_REMOVED)
This is the method I created and am using. This has worked on Samsung Galaxy S4, Samsung Galaxy Note 3 and Sony Xperia Z2.
private static String[] getRemovableStoragePaths() {
String[] directories;
String[] splits;
ArrayList<String> pathList = new ArrayList<String>();
BufferedReader bufferedReader = null;
String lineRead;
try {
bufferedReader = new BufferedReader(new FileReader("/proc/mounts"));
while ((lineRead = bufferedReader.readLine()) != null) {
Log.d(TAG, "lineRead: " + lineRead);
splits = lineRead.split(" ");
Log.d(TAG, "Testing path: " + splits[1]);
if (!splits[1].contains("/storage")) {
continue;
}
if (splits[1].contains("/emulated")) {
// emulated indicates an internal storage location, so skip it.
continue;
}
// Eliminate if not a directory or fully accessible
Log.d(TAG, "Path found: " + splits[1]);
// Met all the criteria, assume sdcard
pathList.add(splits[1]);
}
} catch (FileNotFoundException e) {
} catch (IOException e) {
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
}
}
}
// Send list back to caller
if (pathList.size() == 0) {
pathList.add("sdcard not found");
} else {
Log.d(TAG, "Found potential removable storage locations: " + pathList);
}
directories = new String[pathList.size()];
for (int i = 0; i < pathList.size(); i++) {
directories[i] = pathList.get(i);
}
return directories;
}