Android之——清理手机SD卡缓存

转载请注明出处:http://blog.csdn.net/l1028386804/article/details/47375595

目前,市场上很多Android手机软件都具有清理SD卡缓存的功能,比如360,金山等等。那么这些软件是如何实现清理sd卡缓存数据功能的呢?下面,我就给大家演示下,这些功能是如何实现的吧。

一、原理

首先我们还是讲一下这个功能实现的原理吧。

将Android手机中常用的一些应用缓存目录,全部放在一个数据库表中,将这个表中的目录查询出来放在一个List集合中,我们暂且将这个list集合定义为paths,之后我们去换获取到sd卡中所有的文件目录,遍历sdk下所有的文件目录,如果paths中包含某一个目录,则递归删除这个目录文件。

原理又啰嗦完了,很简单吧,那就让我们一起来实现这些功能吧。

二、实现

实现分为两个步骤,数据库的准备和代码实现

1、数据库准备

这个示例中用到了一个存放应用缓存目录的数据库clearpath.db,首先将这个数据库放置在应用程序项目的assets目录下

如图:

2、代码实现

在这个示例中,我将这个功能代码都分成一个个方法写在了MainActivity中,我们主要分析一下这个类中的每个方法就可以了。

1)拷贝数据库的方法copyDb

这个方法实现的功能是将assets目录下的数据库拷贝到/data/data/应用程序包名/files目录下,同时返回数据库文件对象。

具体实现代码如下:

/**
 * 拷贝数据库,并返回数据库文件对象
 * @return
 */
private File copyDb(){
	//将数据库拷贝到files目录
	File file = new File(getFilesDir(), "clearpath.db");
	if(!file.exists()){
		try {
			InputStream in = getAssets().open("clearpath.db");
			OutputStream out = new FileOutputStream(file);
			byte[] buffer = new byte[1024];
			int len = 0;
			while((len = in.read(buffer)) != -1){
				out.write(buffer, 0, len);
			}
			out.close();
			in.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	return file;
}
2)获取数据库中要清理的文件目录集合的方法getPaths

这个方法实现的功能是调用copyDb方法拷贝数据库,并获取数据库文件对象,查询数据库中存放的所有的文件目录,并将这些目录封装到一个list集合中返回。

具体代码实现如下:

/**
 * 获取数据库中要清理的文件目录集合
 * @return
 */
private List<String> getPaths(){
	//复制数据库
	List<String >list = new ArrayList<String>();
	File file = copyDb();
	if(file != null){
		SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY);
		if(db.isOpen()){
			Cursor c = db.query("softdetail", new String[]{"filepath"}, null, null, null, null, null);
			while(c.moveToNext()){
				String path = c.getString(c.getColumnIndex("filepath"));
				list.add(path);
			}
			c.close();
			db.close();
		}
	}
	return list;
}
3)递归删除文件delete

这个方法主要实现了递归删除文件的操作,首先遍历文件目录,如果当前文件是目录,则遍历子目录,继续调用自身delete方法,如果是文件,则调用File的delete方法。

具体实现代码如下:

/**
 * 递归删除文件
 * @param file
 */
private void delete(File file){
	if(file.isDirectory()){
		File[] files = file.listFiles();
		for(File f : files){
			delete(f);
		}
	}else{
		file.delete();
	}
}
4)获取文件集合paths

我们定义一个全局list集合paths,并在oncreate方法中调用getPaths方法,给这个集合赋值。这样这个集合中封装了数据库中所有的文件路径。之所以我们将paths定义为全局变量,并在oncreate方法中调用getPaths方法为其赋值,是为了提高性能。因为从数据库中读取数据是一个耗费性能的操作,这个方法只在onCreate中执行一次,避免了在点击事件中每点击按钮一次,就执行一次。这样明显提高了应用程序的性能。

具体实现代码如下:

private List<String> paths;
@Override
protected void onCreate(Bundle savedInstanceState) {
	super.onCreate(savedInstanceState);
	setContentView(R.layout.activity_main);
	paths = this.getPaths();
}
5)按钮点击事件clearData

这个方法主要是响应了按钮的点击事件,实现清理缓存的功能,在这里我们将清理功能放到一个子线程中执行,通过Looper机制来提醒用户清理完成。

具体代码实现如下:

//按钮点击事件
public void clearData(View v){
	new Thread(new Runnable() {
		@Override
		public void run() {
			// TODO Auto-generated method stub
			File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
			File[] files = file.listFiles();
			if(files != null && files.length > 0){
				for(File f : files){
					String name = "/" + f.getName();
					//paths集合中包含name
					if(paths.contains(name)){
						delete(f);
					}
				}
			}
			Looper.prepare();
			Toast.makeText(MainActivity.this, "SD卡缓存清理完成", Toast.LENGTH_SHORT).show();
			Looper.loop();
		}
	}).start();
}
6)MainActivity整体实现代码
package com.lyz.test.cache;

import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.os.Bundle;
import android.os.Environment;
import android.os.Looper;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;

/**
 * 主程序入口
 * @author liuyazhuang
 *
 */
public class MainActivity extends Activity {

	private List<String> paths;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		paths = this.getPaths();
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		// Inflate the menu; this adds items to the action bar if it is present.
		getMenuInflater().inflate(R.menu.main, menu);
		return true;
	}

	//按钮点击事件
	public void clearData(View v){
		new Thread(new Runnable() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath());
				File[] files = file.listFiles();
				if(files != null && files.length > 0){
					for(File f : files){
						String name = "/" + f.getName();
						//paths集合中包含name
						if(paths.contains(name)){
							delete(f);
						}
					}
				}
				Looper.prepare();
				Toast.makeText(MainActivity.this, "SD卡缓存清理完成", Toast.LENGTH_SHORT).show();
				Looper.loop();
			}
		}).start();
	}

	/**
	 * 递归删除文件
	 * @param file
	 */
	private void delete(File file){
		if(file.isDirectory()){
			File[] files = file.listFiles();
			for(File f : files){
				delete(f);
			}
		}else{
			file.delete();
		}
	}

	/**
	 * 拷贝数据库,并返回数据库文件对象
	 * @return
	 */
	private File copyDb(){
		//将数据库拷贝到files目录
		File file = new File(getFilesDir(), "clearpath.db");
		if(!file.exists()){
			try {
				InputStream in = getAssets().open("clearpath.db");
				OutputStream out = new FileOutputStream(file);
				byte[] buffer = new byte[1024];
				int len = 0;
				while((len = in.read(buffer)) != -1){
					out.write(buffer, 0, len);
				}
				out.close();
				in.close();
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return file;
	}

	/**
	 * 获取数据库中要清理的文件目录集合
	 * @return
	 */
	private List<String> getPaths(){
		//复制数据库
		List<String >list = new ArrayList<String>();
		File file = copyDb();
		if(file != null){
			SQLiteDatabase db = SQLiteDatabase.openDatabase(file.getAbsolutePath(), null, SQLiteDatabase.OPEN_READONLY);
			if(db.isOpen()){
				Cursor c = db.query("softdetail", new String[]{"filepath"}, null, null, null, null, null);
				while(c.moveToNext()){
					String path = c.getString(c.getColumnIndex("filepath"));
					list.add(path);
				}
				c.close();
				db.close();
			}
		}
		return list;
	}
}
7)布局文件activity_main

这个布局很简单,我们就是放置了一个按钮。

具体实现代码如下:

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context=".MainActivity" >

    <Button
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:onClick="clearData"
        android:text="清理SD卡数据" />

</RelativeLayout>

3、应用授权

这里,我们要清除sd卡中的数据,所有要对写sd卡进行授权,我们在AndroidManifest.xml文件中添加如下授权信息

<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

三、运行效果

四、温馨提示

大家可以到链接http://download.csdn.net/detail/l1028386804/8980767下载Android清理SD卡缓存数据库文件,可以到链接http://download.csdn.net/detail/l1028386804/8980789下载Android清理SD卡缓存完整示例源代码

本实例中,为了方面,我把一些文字直接写在了布局文件中和相关的类中,大家在真实的项目中要把这些文字写在string.xml文件中,在外部引用这些资源,切记,这是作为一个Android程序员最基本的开发常识和规范,我在这里只是为了方便直接写在了类和布局文件中。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-18 03:21:36

Android之——清理手机SD卡缓存的相关文章

【Java/Android性能优 6】Android 图片SD卡缓存 使用简单 支持预取 支持多种缓存算法 支持不同网络类型 支持序列化

本文转自:http://www.trinea.cn/android/android-imagesdcardcache/ 本文主要介绍一个支持图片自动预取.支持多种缓存算法.支持数据保存和恢复的图片Sd卡缓存的使用.功能及网友反馈的常见问题解答. 需要二级缓存或ListView和GridView图片加载请优先使用ImageCache. 与Android LruCache相比主要特性:(1). 使用简单  (2). 轻松获取及预取新图片  (3). 可选择多种缓存算法(FIFO.LIFO.LRU.M

[android] 保存文件到SD卡

手机里面有两块空间,手机内部空间(/data/data/)和外部存储空间(/mnt/sdcard/ 或者直接/sdcard/) 与上面的代码基本一样,只是在new File(“/sdcard/文件名”),此时会报错,primission denied Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied) 在清单文件中添加权限 android.primission.WRITE_EXTERNAL_S

获取手机SD卡路径(国产神机多个SD卡)

通过系统的 Environment.getExternalStorageDirectory().getAbsoluteFile(); 只能得到系统的SD卡路径,对于对个SD卡的国产神机,想得到外部SD卡就无能为力了.   下面介绍一个编写的工具类,通过反射得到系统隐藏的得到所有挂载路径方法获取所有SD卡路径: package com.itheima.mobilesafe.utils; import java.lang.reflect.InvocationTargetException; impo

Android设备内存和SD卡操作工具类

package cc.c; import java.io.File; import java.util.List; import android.os.StatFs; import java.io.FileReader; import java.io.IOException; import java.io.BufferedReader; import android.os.Environment; import android.content.Context; import android.ap

Android数据存储之SD卡

为了更好的存取应用程序的大文件数据,应用程序需要读. 写SD卡上的文件.SD卡大大扩充手机的存储能力. 操作SD首先要加权限: <!--在SDCard中创建与删除文件权限 --> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> <!-- 往SDCard写入数据权限 --> <uses-permission android:name=&q

Android中播放本地SD卡中歌曲需要的添加的权限

使用MediaPlayer播放本地Mp3文件时,需要注意的访问路径的问题以及访问权限的问题. 1.访问路径:/storage/emulated/0 此路径即为手机的根路径,可以通过下载ES文件浏览器软件查看当前播放的Mp3具体的路径,通过Environment.getExternalStorageDirectory().getPath()获取/storage/emulated/0这个SdCard路径这在组织 void android.media.MediaPlayer.setDataSource

Android USB大容量存储时SD卡状态监听(转)

对SD卡状态监听,到现在为止我知道的有两种方式: 1.注册StorageEventListener来监听sd卡状态 StorageEventListener中有onStorageStateChanged()方法,当sd卡状态改变时,此方法会调用,对各状态的判断一般会用到Environment类,此类中包含的有关sd卡状态的常量有: MEDIA_BAD_REMOVAL:表明SDCard 被卸载前己被移除 MEDIA_CHECKING:表明对象正在磁盘检查 MEDIA_MOUNTED:表明sd对象是

数据恢复软件使用经验-支持U盘,手机SD卡,硬盘数据,解决图片恢复后打不开的问题

数据恢复软件使用经验-支持U盘,手机SD卡,硬盘数据,解决图片恢复后打不开的问题. 用过很多数据恢复软件,最早EasyRecovery pro,恢复过U盘,手机SD卡,硬盘数据.但现在下载不了最新版,而且BAIDU出来的都是国产收费软件假冒的,因为国产恢复软件都太差劲了,所以想偷梁换柱,不仅要收费,而且网上评论恢复效果也很差. 后来用过两款国外crack版的recuva和FinalData,效果也不错,但是有几次帮朋友恢复手机sd卡的时候,照片图片恢复后很多,打不开也不能预览.研究了很长时间,和

手机SD卡损坏补救措施

现在的应用程序越来越重,比如微信.来往之类的,稍微用一段时间,就会占用几十MB甚至上百MB的空间.而有时候甚至手机会出现"无响应"的现象,需要你选择"继续等待"还是"强行关闭":前阵子有几次,无响应之后我直接给强制重启了,结果发现重启完成之后,出现"SD卡已损坏,您可能必须将其重新格式化"的问题. 可是,我的SD卡里面还有一些之前的文件和资料等,需要拷贝出来,不能格式化,使用豌豆荚链接,不认识SD卡,于是寻找解决办法. 我找了