Как удалить кеш других приложений из нашего приложения для Android?
Я пытаюсь разработать приложение для Android, которое могло бы стереть данные кэша других приложений, я пытался просмотреть все блоги, но ни один из них не помог мне, я могу очистить кэш своего приложения с помощью следующего кода
File cache = getCacheDir();
File appDir = new File(cache.getParent());
if (appDir.exists())
{
String[] children = appDir.list();
for (String s : children)
{
if (!s.equals("lib"))
{
deleteDir(new File(appDir, s));
Toast.makeText(DroidCleaner.this, "Cache Cleaned", Toast.LENGTH_LONG).show();
Log.i("TAG", "**************** File /data/data/APP_PACKAGE/" + s + " DELETED *******************");
}
}
}
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();
}
Мой манифест код
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>
Я тестировал код на 2.2, 2.3 и 4.0
а после просмотра поста по следующей ссылке Android: очистить кеш всех приложений?
Я изменил свой код на
PackageManager pm = getPackageManager();
// Get all methods on the PackageManager
Method[] methods = pm.getClass().getDeclaredMethods();
for (Method m : methods) {
if (m.getName().equals("freeStorage")) {
// Found the method I want to use
try {
long desiredFreeStorage = 8 * 1024 * 1024 * 1024; // Request for 8GB of free space
m.invoke(pm, desiredFreeStorage , null);
} catch (Exception e) {
// Method invocation failed. Could be a permission problem
}
break;
}
}
Я хочу очистить кэш другого приложения, может ли любое тело, пожалуйста, помогите мне, пожалуйста, исправьте меня, если я ошибаюсь, Заранее спасибо.
3 ответа
Этот API больше не поддерживается в API 23, то есть Marshmallow. Разрешение не рекомендуется в Зефир.
Но есть и другой способ, спрашивая разрешение времени выполнения для аксессуаров. Попробуйте приложение All-in-one Toolbox из игрового магазина. Это приложение может очистить кэш других приложений, даже в Зефир. Тогда мы сможем это сделать.
Я исследую это. Как только я найду решение, я обновлю ответ. Благодарю.
СТАРЫЙ ОТВЕТ КАК СЛЕДУЕТ
Я использовал следующий код, и теперь я могу очистить кэш всего приложения без рута, он отлично работает для меня,
private static final long CACHE_APP = Long.MAX_VALUE;
private CachePackageDataObserver mClearCacheObserver;
btnCache.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
clearCache();
}
});//End of btnCache Anonymous class
void clearCache()
{
if (mClearCacheObserver == null)
{
mClearCacheObserver=new CachePackageDataObserver();
}
PackageManager mPM=getPackageManager();
@SuppressWarnings("rawtypes")
final Class[] classes= { Long.TYPE, IPackageDataObserver.class };
Long localLong=Long.valueOf(CACHE_APP);
try
{
Method localMethod=
mPM.getClass().getMethod("freeStorageAndNotify", classes);
/*
* Start of inner try-catch block
*/
try
{
localMethod.invoke(mPM, localLong, mClearCacheObserver);
}
catch (IllegalArgumentException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (IllegalAccessException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
catch (InvocationTargetException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
/*
* End of inner try-catch block
*/
}
catch (NoSuchMethodException e1)
{
// TODO Auto-generated catch block
e1.printStackTrace();
}
}//End of clearCache() method
private class CachePackageDataObserver extends IPackageDataObserver.Stub
{
public void onRemoveCompleted(String packageName, boolean succeeded)
{
}//End of onRemoveCompleted() method
}//End of CachePackageDataObserver instance inner class
А также создайте pacakge в вашем src
папка с именем android.content.pm
внутри этого пакета создайте файл на имя IPackageDataObserver.aidl
и вставьте в него следующий код
package android.content.pm;
/**
* API for package data change related callbacks from the Package Manager.
* Some usage scenarios include deletion of cache directory, generate
* statistics related to code, data, cache usage(TODO)
* {@hide}
*/
oneway interface IPackageDataObserver {
void onRemoveCompleted(in String packageName, boolean succeeded);
}
и в своем манифесте убедитесь, что вы использовали следующий код
<uses-permission android:name="android.permission.CLEAR_APP_CACHE"/>
Если вы, ребята, найдете какие-либо проблемы, не стесняйтесь связаться со мной, спасибо.
Кеш это не просто одно. Для каждого приложения есть папка кеша в системных папках данных и одна папка кеша для каждого доступного раздела хранилища (по одной на внутренней SD-карте устройства, и если есть внешняя SD-карта, то и там есть).
Таким образом, чтобы очистить кеш в системных папках данных, вы делаете это
Method method = pmClass.getDeclaredMethod("freeStorageAndNotify", new Class[] { Long.TYPE, Class.forName("android.content.pm.IPackageDataObserver") });
method.setAccessible(true);
method.invoke(con.getPackageManager(), Long.MAX_MALUE, null);
//null is for the IPackageDataObserver object that let's you know when the process is done and it is not necessary to provide.
Поскольку у вас нет доступа к системным папкам, чтобы самостоятельно удалить их на нерутированном устройстве, поэтому вы вежливо просите Android сделать это за вас.
Чтобы очистить кэш в несистемных папках данных, вы делаете это
for(String storageVolumePath:storageVolumePaths) {
File androidDataFolder = new File((String) storageVolumePath + "/Android/data/");
if (androidDataFolder.exists()) {
File[] filesList = androidDataFolder.listFiles();
if (filesList != null) {
for (File file : filesList) {
if (file.isDirectory()) {
file = new File(file.getAbsolutePath() + "/cache/");
if(file.exists()) {
try {
deleteFile(file);
}catch (Exception e ){}
}
}
}
}
}
}
Все в одном наборе инструментов НЕ очищает кеш из системных папок данных в marshmellow, потому что без корневого доступа это невозможно. Он использует только второй метод и очищает часть общего кэша. Для достижения этого в API 23 и выше без корневого доступа вам нужно быть системным приложением, поскольку нет способа запросить разрешение android.permission.CLEAR_APP_CACHE с помощью Permission API
Другой вариант - добавить файл layoutlib.jar, расположенный в каталоге \sdk\platform \android-19\data, в библиотеку вашего проекта. Вы сможете разрешить этот и другие классы, не добавляя их вручную в исходный код.
Я должен добавить, что эти классы не будут добавлены в ваш бинарный файл. Это только позволит вам решить пункты.