android 输入法sd卡,如何android扫描SD卡列出大文件
闲来无事,正好以前老碰到这个磁盘空间满的问题
背景
安卓手机用了一段时间之后经常就报磁盘空间不够了,当然可以用手机管家,或者缓存/应用清理工具释放空间,但是还是会有莫名其妙的空间不够;这是由安卓的属性导致的,即使把APP卸载,他占用的空间SD卡空间也不会被释放。
image.png
导致的结果是SD空间会越来越紧张,最后只能恢复出厂设置解决问题。
谁用了我的空间
我们自然会想到底是谁用了我的SD卡空间呢;现在各个厂家安卓系统都会提供一定功能,检测大文件,检测应用占用大空间;但是到目前我还没有发现有基于目录罗列的,列出每一个目录,每一个文件占用多大的空间,因为有了这个,我们就比较清楚,到底是谁在占用我们的空间。
然后我们可以自己判断,是否可以删除这个文件或者目录。手动把文件删除,以释放空间。
我的SD卡扫描程序
基于上述目标,反正闲着也是闲着,写了一个很简单的SD卡扫描程序,列出所有的大文件。
程序主题页面如下:
image.png
第一个输入框指示扫描多大的文件(M),点击"Scan"按钮,在下面的列表框中,显示出SD卡所有的大于指定大小的文件,在这个例子中一共22个大于5M的大文件。
这里我们可以看到Baidu_music和baiduTTS下面有很多大文件,这些文件是可以放心的删除的,而用手机管家(华为家的)就扫不出这个问题,他会认为这些是真实的APP文件,不能删除。
贴代码,供参考
在Android 6.0上测试通过。
AndroidManifest.xml
package="com.example.mydiskscan">
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
这个地方,注意一点,因为其他都是缺省生成的:
我们需要SD卡的读取权限,因为要扫描SD卡啊。
两个layout文件
activity_main.xml
这是主activity,也就是APP的主界面。
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:focusable="true"
android:focusableInTouchMode="true"
tools:context="com.example.mydiskscan.MainActivity">
android:layout_width="match_parent"
android:layout_height="76dip"
android:orientation="horizontal" >
android:layout_width="80dip"
android:layout_height="40dip"
android:inputType="numberDecimal"
android:text="5"
android:id="@+id/edit_size"
android:contentDescription="Scan file greater than" />
android:layout_width="40dip"
android:layout_height="40dip"
android:text="M"
android:id="@+id/textView" />
android:text="Scan"
android:layout_width="120dip"
android:layout_height="40dip"
android:id="@+id/button_scan" />
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/list_file" />
注意在头上的这两行:
android:focusable="true"
android:focusableInTouchMode="true"
这两行是用来使得APP刚打开的时候焦点不在EditText框里面,否则每回一打开,焦点定位输入框,输入法窗口就显示出来,极不美观大方。
filelistitem.xml
这是文件的列表项的view,每一个大于指定大小的大文件,包含一项;内容包含序号,大小,和文件路径。
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal" >
android:id="@+id/filelistitem_id"
android:layout_width="20dp"
android:layout_height="20dp" />
android:id="@+id/filelistitem_size"
android:layout_width="40dp"
android:layout_height="20dp" />
android:id="@+id/filelistitem_path"
android:layout_width="wrap_content"
android:layout_height="20dp" />
activity源代码文件
作为简易程序,我把所有的代码都放在了一个源文件里面;当然这不是规范的做法,不符合软件工程的追求啊。
package com.example.mydiskscan;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends Activity {
private static final String tag = MainActivity.class.getSimpleName();
private List fileList = new ArrayList();
private FileListAdapter fileListAdapter = new FileListAdapter();
private ScanListener scanListener = new ScanListener();
private EditText edtThreshold;
private ListView listFileView;
private Button btnScan;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
requestStoragePermission();
edtThreshold = (EditText)findViewById(R.id.edit_size);
listFileView = (ListView)findViewById(R.id.list_file);
btnScan = (Button) findViewById(R.id.button_scan);
btnScan.setOnClickListener(scanListener);
listFileView.setAdapter(fileListAdapter );
}
private void requestStoragePermission() {
String[] permissions = {"android.permission.READ_EXTERNAL_STORAGE"};
int requestCode = 200;
int permission = checkSelfPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
requestPermissions(permissions, requestCode);
}
}
private long getFileSize(String prefix, File file, int threshold) {
long size = file.length();
if (file.isDirectory()) {
File[] subs = file.listFiles();
if (subs != null) {
for (File sub : subs) {
size += getFileSize(prefix, sub, threshold);
}
}
}
float sizem = (float) (size * 1.0 / 1024 / 1024);
if (sizem > threshold && !file.isDirectory()) {
String path = file.getPath();
if (path.startsWith(prefix)) {
path = path.substring(prefix.length());
}
Log.i(tag, "File: path=" + path + ", size= " + sizem);
fileList.add(new ViewFile(path, sizem));
}
return size;
}
class ViewFile {
ViewFile(String p, float s) {
path = p;
size = s;
}
private String path;
private float size;
}
class ScanListener implements View.OnClickListener {
@Override
public void onClick(View v) {
StatFs sf = null;
long blockSize = 0, total = 0, free = 0, available = 0;
/*
File root = Environment.getRootDirectory();
sf = new StatFs(root.getPath());
blockSize = sf.getBlockSize();
total = sf.getBlockCount() * blockSize/1024/1024;
free = sf.getFreeBlocks() * blockSize/1024/1024;
available = sf.getAvailableBlocks() * blockSize/1024/1024;
Log.i(tag, "Root Storage: path = " + root.getAbsolutePath() + ", total=" + total + ", free=" + free + ", available=" + available);
*/
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)) {
File sdcardDir = Environment.getExternalStorageDirectory();
//sf = new StatFs(sdcardDir.getPath());
//blockSize = sf.getBlockSize();
//total = sf.getBlockCount() * blockSize/1024/1024;
//free = sf.getFreeBlocks() * blockSize/1024/1024;
//available = sf.getAvailableBlocks() * blockSize/1024/1024;
//Log.i(tag, "External Storage: path=" + sdcardDir.getAbsolutePath() + ", total=" + total + ", free=" + free + ", available=" + available);
if (sdcardDir.isDirectory()) {
File[] subs = sdcardDir.listFiles();
if (subs != null) {
fileList.clear();
int threshold = 5;
try {
threshold = Integer.parseInt(edtThreshold.getText().toString());
} catch (NumberFormatException e) {
edtThreshold.setText("5");
}
for (int i = 0; i < subs.length; i++) {
getFileSize(sdcardDir.getPath(), subs[i], threshold);
}
fileListAdapter.notifyDataSetChanged();
}
}
}
}
}
class FileListAdapter extends BaseAdapter {
@Override
public int getCount() {
return fileList.size();
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = null;
if(convertView == null){
LayoutInflater inflater = MainActivity.this.getLayoutInflater();
view = inflater.inflate(R.layout.filelistitem, null);
}else{
view = convertView;
}
ViewFile m = fileList.get(position);
TextView v = (TextView)view.findViewById(R.id.filelistitem_id);
v.setText( String.valueOf(position + 1) );
v = (TextView)view.findViewById(R.id.filelistitem_size);
v.setText( String.valueOf(m.size) );
v = (TextView)view.findViewById(R.id.filelistitem_path);
v.setText( m.path );
return view;
}
@Override
public Object getItem(int position) {
// TODO Auto-generated method stub
return null;
}
@Override
public long getItemId(int position) {
// TODO Auto-generated method stub
return 0;
}
}
}
几个注意的地方:
requestStoragePermission();
虽然在manifest文件里面指定了需要SD卡的读权限,但是后来的版本都需要APP显式的请求用户确认,以获取相应的权限,否则即使在manifest指定了权限,APP还是无法访问SD卡。
image.png
后续还可以增强一下
增加等待提示符,也就是在扫描的同时,提示用户我正在扫描,请稍后。
界面和代码可以继续美化改进
谢谢。
android 输入法sd卡,如何android扫描SD卡列出大文件相关推荐
- 开发android 输入法,Android输入法开发实例解析 Android开发技术
Android输入法开发实例解析 Android开发技术 2013 年 4 月 13 日 这里我们建立表1为BiHua,同时构建两个字段,字段1为"input"来存放输入的,字段2 ...
- android pda界面美化,安卓设备扫描cpu卡和rfid超频卡插件cordova-plugin-pda
1.该插件只支持安卓设备,可以扫描上海复旦fm1216卡(CPU卡),s50卡,rfid超频卡等:这是我写的一个cordova插件,下面是安装步骤 2.安装方法: cordova plugin add ...
- android 输入法 候选,写一个Android输入法02——候选窗、转换
上一篇介绍了完成Android输入法的最小化步骤,它只能将按键对应的字符上屏.一般的东亚语言都有一个转换的过程,比如汉语输入拼音,需要由拼音转成汉字再上屏.本文将在前文基础上加入完成转换过程所必需的候 ...
- 哪些公司开发android输入法软件,六款Android平台第三方输入法软件横评
虽然现在非智能手机在第三方应用上已经有了相当大的进步,不少已经支持软件后台运行,与智能手机一样可以同时挂QQ.听音乐.看网页等等.不过安装第三方输入法仍然还只是智能手机的专利.记得第一次在诺基亚668 ...
- 2022-09-06 Android输入法顶起输入框,遮挡RecyclerView
背景 IM项目中的会话界面,一般就是顶部一个标题,底部是输入区域,中间显示消息列表. 微信的会话界面中,进入会话界面,有以下几点: 隐藏输入法 当消息数量能占满屏幕时,底部显示最后一条,依次往上排列 ...
- Android基础—基于Socket实现上传大文件
上节中我们给大家接触了Socket的一些基本概念以及使用方法,然后写了一个小猪简易聊天室的 Demo,相信大家对Socket有了初步的掌握,本节我们来学习下使用Socket来实现大文件的断点续传! 这 ...
- android 扫描手机内存和SD卡,获取手机的视频、音频文件。把获取不到的文件扫描出来
网上查了下android手机扫描内存或者SD卡里面的音频或者视频文件,进行显示.但是有些视频或者音频扫描不出来.有其中一个原因是当你添加了一个视频或者音频文件后,手机自身没有重新进行扫描.只有手机重启 ...
- android 无法显示SD卡目录,Android studio无法在SD卡上创建新目录?
我使用名为scanlibrary的库来扫描照片,然后将它传递给tess-two来执行OCR过程.问题是,在目录"ScanDemoExample"不被创建因此tessdata文件不会 ...
- android ProgressBar实现扫描SD卡文件 + SimpleAdapter绑定ListView
代码 activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/andro ...
最新文章
- ubuntu 查看内存和cpu使用情况
- 腾讯GaiaStack容器平台负责人罗韩梅:All on GaiaStack
- CAN总线抗干扰的六种解决方案
- leetcode——面试题 17.10. 主要元素
- CompletableFuture 异步编程
- 罗马音平假名片假名转换器_记不住五十音的你,你肯定需要这套日语五十音谐音巧记法...
- C语言基础教程读书笔记2(第二章常量、变量、类型转换)
- 华为与奔驰展开合作 HMS for Car登陆S级轿车
- put与putIfAbsent区别
- FPGA厂家谁家强?
- 开始学习鸟哥的Linux私房菜-基础篇(第五章)
- 如何将pdf分割成一页一页的
- c语言学习——设圆半径r = 1.5,圆柱高h = 3,求圆周长,圆面积,圆球表面积,圆球体积,圆柱体积
- LeedCode 376. 摆动序列
- 如何用echarts组件制作图表
- 史玉柱: 我的成功不是偶然
- Java 本地接口(JNI)编程指南和规范学习笔记2
- vue+echarts+3D地图 制作大屏
- 虎父的素数年之黄帝内经谭
- linux下ant编译android,linux(以ubuntu為例)下Android利用ant自動編譯、修改配置文件、批量多渠道,打包生成apk文件...
热门文章
- 大一matlab知识整理,MATLAB基础课程 第二章 MATLAB绘图知识(5)
- java 指针 引用_java中的引用与c中的指针
- python随机生成奇数_python实现按照给定范围随机生成小数,偶数,奇数,整数,正态分布,均匀分布数据以及图片...
- devops 解决方案_DevOps是值得投资的职业倦怠解决方案
- angular 创建服务器_使用D3和Angular创建通用的可视化
- VSCode自定义代码片段9——JS中的面向对象编程
- 组件化开发_思维导图
- 面试 | #面试面试面试 做#Java 就是要这种不要脸的…
- Bootstrap3 模态对话框的事件
- Integer 数据类型