小作坊的安全管家之软件管理
2015-11-04 00:06
344 查看
软件管理
作为安全管家里最为基本的功能之一,软件管家的工作大致包括读取内部存储容量剩余,内存卡容量剩余,系统应用列表,用户应用列表,先来看看我low了一脸的界面:首先把我们的布局搭起来,整体的布局文件:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" > <TextView style="@style/TitleStyle" android:text="软件管理" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:id="@+id/tv_romfree" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="内存可用XXX" /> <TextView android:id="@+id/tv_sdfree" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="SD卡可用XXX" /> </LinearLayout> <FrameLayout android:layout_width="match_parent" android:layout_height="match_parent" > <ListView android:id="@+id/lv_app" android:layout_width="match_parent" android:layout_height="wrap_content" > </ListView> <TextView android:id="@+id/tv_app" android:layout_width="match_parent" android:layout_height="wrap_content" android:background="#ff888888" android:textColor="#fff" /> </FrameLayout> </LinearLayout>
整个布局使用了垂直方向的线性布局,在软件管理这一标题栏中设置了style,因为每个功能的Activity中都会用到这种Style,所以设置通用的Style可以增加工作效率,TitleStyle内容设置在style.xml文件中
<style name="TitleStyle"> <item name="android:layout_width">match_parent</item> <item name="android:layout_height">50dp</item> <item name="android:background">#8866ff00</item> <item name="android:gravity">center</item> <item name="android:textColor">@android:color/black</item> <item name="android:textSize">22sp</item> </style>
下面的大部分显示空间使用了帧布局,主要是为了实现用户应用顶栏,系统应用顶栏的顶部停留,喜闻乐见的ListView就不用详细介绍了,下面上ListView的item布局
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" > <ImageView android:paddingTop="5dip" android:paddingBottom="5dip" android:id="@+id/iv_icon" android:layout_width="45dip" android:layout_height="45dip" android:src="@drawable/ic_launcher" /> <LinearLayout android:paddingTop="5dip" android:paddingBottom="5dip" android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="vertical" > <LinearLayout android:layout_width="fill_parent" android:layout_height="wrap_content" android:orientation="horizontal" > <TextView android:singleLine="true" android:id="@+id/tv_name" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:layout_weight="1.0" android:ellipsize="end" android:textSize="20sp" android:textColor="#000000" android:gravity="center_vertical" android:paddingLeft="5.0dip" android:text="标题" /> <TextView android:textSize="14sp" android:textColor="#99000000" android:id="@+id/tv_apk_size" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:gravity="center_vertical" android:paddingRight="5.0dip" android:text="应用程序大小" /> </LinearLayout> <TextView android:textSize="14sp" android:textColor="#99000000" android:id="@+id/tv_location" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="center_vertical" android:gravity="center_vertical" android:paddingLeft="5.0dip" /> </LinearLayout> </LinearLayout>大家对照图上的显示就能清楚理解item布局。
说完布局就说一下软件管理的业务逻辑:
看图片我们需要拿到手机的内部存储剩余,外部存储剩余,每个应用的详细信息,我们先写一个类,用来存取传递应用的详细信息
import android.graphics.drawable.Drawable; public class AppInfo { /** * 软件图标 */ private Drawable icon; /** * 软件名称 */ private String apkName; /** * 软件名字 */ private long apkSize; /** * 是否用户软件 * 是则为true * 否则为false */ private boolean userApp; /** * 软件的包名 */ private String apkPackageName; /** * 放置的位置 */ private boolean isRom; public Drawable getIcon() { return icon; } public void setIcon(Drawable icon) { this.icon = icon; } public String getApkName() { return apkName; } public void setApkName(String apkName) { this.apkName = apkName; } public long getApkSize() { return apkSize; } public void setApkSize(long apkSize) { this.apkSize = apkSize; } public boolean isUserApp() { return userApp; } public void setUserApp(boolean userApp) { this.userApp = userApp; } public String getApkPackageName() { return apkPackageName; } public void setApkPackageName(String apkPackageName) { this.apkPackageName = apkPackageName; } public boolean isRom() { return isRom; } public void setRom(boolean isRom) { this.isRom = isRom; } @Override public String toString() { return "AppInfo [icon=" + icon + ", apkName=" + apkName + ", apkSize=" + apkSize + ", userApp=" + userApp + ", apkPackageName=" + apkPackageName + ", isRom=" + isRom + "]"; } }
有了应用信息存储传递的地方,我们就要想办法把手机里的所有应用详细信息给获取出来,下面再创建一个类:
import java.io.File; import java.util.ArrayList; import java.util.List; import com.mobileSafe.bean.AppInfo; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; import android.graphics.drawable.Drawable; public class AppInfos { public static List<AppInfo> getAppInfos(Context context) { /** * 新建一个list用来存放应用信息 */ ArrayList<AppInfo> list = new ArrayList<AppInfo>(); /** * 获取包管理器 * 利用包管理器获取所有安装过应用的包信息并存放在list中 */ PackageManager pm = context.getPackageManager(); List<PackageInfo> installPackages = pm.getInstalledPackages(0); /** * 获取每个PackageInfo中我们需要的信息 */ for (PackageInfo installPackage : installPackages) { AppInfo appInfo = new AppInfo(); /** * 获取app的图标并设置 */ Drawable loadIcon = installPackage.applicationInfo.loadIcon(pm); appInfo.setIcon(loadIcon); /** * 获取app的名字并设置 */ String loadLabel = installPackage.applicationInfo.loadLabel(pm).toString(); appInfo.setApkName(loadLabel); /** * 获取app的包名并设置 */ String packageName = installPackage.packageName.toString(); appInfo.setApkPackageName(packageName); /** * 获取apk的资源路径 */ String apkDir = installPackage.applicationInfo.sourceDir.toString(); File file = new File(apkDir); /** * 获取app的大小并设置 */ long length = file.length(); appInfo.setApkSize(length); // 获取应用标记,标记中存储了大量信息 int flags = installPackage.applicationInfo.flags; /** * 利用标记判断应用存放位置 */ if ((flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) { appInfo.setRom(false); } else { appInfo.setRom(true); } /** * 利用标记判断用户应用还是系统应用 */ if ((flags & ApplicationInfo.FLAG_SYSTEM) != 0) { appInfo.setUserApp(false); } else { appInfo.setUserApp(true); } list.add(appInfo); } return list; } }
利用这个类获取应用信息并返回给Activity。
package com.lyang.mobileSafe.Activity; import java.util.ArrayList; import java.util.Formatter; import java.util.List; import com.example.mobileSafe.R; import com.lyang.mobileSafe.bean.AppInfo; import com.lyang.mobileSafe.engine.AppInfos; import android.app.Activity; import android.content.res.ColorStateList; import android.graphics.Color; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Environment; import android.os.Handler; import android.os.Message; import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AbsListView.OnScrollListener; import android.widget.BaseAdapter; import android.widget.ImageView; import android.widget.LinearLayout; import android.widget.ListView; import android.widget.TextView; public class AppManagerActivity extends Activity { private TextView romFree; private TextView sdFree; private ListView lv; private TextView tv_app; private List<AppInfo> appInfos; private List<AppInfo> userAppInfos; private List<AppInfo> systemAppInfos; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); /** * 初始化UI */ initUI(); initData(); } /** * 接受子线程消息 */ private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { super.handleMessage(msg); AppManagerAdapter adapter = new AppManagerAdapter(); lv.setAdapter(adapter); } }; /** * 获取应用信息为耗时操作,所以要在子线程执行 */ private void initData() { new Thread() { @Override public void run() { super.run(); /** * 获取应用信息 */ appInfos = AppInfos.getAppInfos(AppManagerActivity.this); /** * 新建两个分别存储用户应用信息,系统应用信息 */ userAppInfos = new ArrayList<AppInfo>(); systemAppInfos = new ArrayList<AppInfo>(); for (AppInfo appInfo : appInfos) { if (appInfo.isUserApp()) { userAppInfos.add(appInfo); } else { systemAppInfos.add(appInfo); } } /** * 向主线程发送空消息 */ handler.sendEmptyMessage(0); } }.start(); } /** * * @author *listview需要用到的adapter,继承自BaseAdapter,更加灵活 * */ private class AppManagerAdapter extends BaseAdapter { /** * 返回item数量 */ @Override public int getCount() { return appInfos.size() + 2; } @Override public Object getItem(int position) { if (position == 0) { return null; } else if (position == userAppInfos.size() + 1) { return null; } else if (position < userAppInfos.size() + 1) { return userAppInfos.get(position - 1); } else if (position > userAppInfos.size() + 1) { return systemAppInfos.get(position - userAppInfos.size() - 2); } return null; } @Override public long getItemId(int position) { // TODO Auto-generated method stub return position; } @Override public View getView(int position, View convertView, ViewGroup parent) { /** * 这两种情况是显示用户应用,系统应用及其个数的TextView */ if (position == 0) { TextView textView = new TextView(AppManagerActivity.this); textView.setText("用户应用:" + userAppInfos.size()); textView.setTextColor(Color.WHITE); textView.setBackgroundColor(Color.GRAY); return textView; } else if (position == userAppInfos.size() + 1) { TextView textView = new TextView(AppManagerActivity.this); textView.setText("系统应用:" + systemAppInfos.size()); textView.setTextColor(Color.WHITE); textView.setBackgroundColor(Color.GRAY); return textView; } /** * 在任一position时要取的appInfo的对应位置 */ AppInfo appInfo = null; if (position < userAppInfos.size() + 1) { appInfo = userAppInfos.get(position - 1); } else if (position > userAppInfos.size() + 1) { appInfo = systemAppInfos .get(position - userAppInfos.size() - 2); } View view = null; ViewHolder holder; /** * 优化item的显示,减少findViewById的次数 */ if (convertView != null && convertView instanceof LinearLayout) { view = convertView; holder = (ViewHolder) view.getTag(); } else { view = View.inflate(AppManagerActivity.this, R.layout.app_manager_item, null); holder = new ViewHolder(); holder.icon = (ImageView) view.findViewById(R.id.iv_icon); holder.apkName = (TextView) view.findViewById(R.id.tv_name); holder.apkSize = (TextView) view.findViewById(R.id.tv_apk_size); holder.userApp = (TextView) view.findViewById(R.id.tv_location); view.setTag(holder); } holder.icon.setImageDrawable(appInfo.getIcon()); holder.apkName.setText(appInfo.getApkName()); holder.apkSize.setText(android.text.format.Formatter .formatFileSize(AppManagerActivity.this, appInfo.getApkSize())); if (!appInfo.isRom()) { holder.userApp.setText("外部存储"); } else { holder.userApp.setText("手机内存"); } return view; } } /** * * @author * 设置内部类用于数据的存取 * */ static class ViewHolder { ImageView icon; TextView apkName; TextView apkSize; TextView userApp; } private void initUI() { setContentView(R.layout.activity_app_manager); lv = (ListView) findViewById(R.id.lv_app); romFree = (TextView) findViewById(R.id.tv_romfree); sdFree = (TextView) findViewById(R.id.tv_sdfree); tv_app = (TextView) findViewById(R.id.tv_app); /** * 获取运行内存的剩余空间ROM */ long romFreeSpace = Environment.getDataDirectory().getFreeSpace(); romFree.setText("内存可用:" + android.text.format.Formatter.formatFileSize( AppManagerActivity.this, romFreeSpace)); /** * 获取内存卡剩余空间 */ long sdcardFreeSpace = Environment.getExternalStorageDirectory() .getFreeSpace(); sdFree.setText("sd卡可用:" + android.text.format.Formatter.formatFileSize( AppManagerActivity.this, sdcardFreeSpace)); lv.setOnScrollListener(new OnScrollListener() { @Override public void onScrollStateChanged(AbsListView view, int scrollState) { } /** * 设置滚动时顶部TextView */ @Override public void onScroll(AbsListView view, int firstVisibleItem, int visibleItemCount, int totalItemCount) { if (userAppInfos != null && systemAppInfos != null) { if (firstVisibleItem > (userAppInfos.size())) { tv_app.setText("系统进程:" + systemAppInfos.size()); } else { tv_app.setText("用户进程:" + userAppInfos.size()); } } } }); } }
相关文章推荐
- 图像滤镜艺术---ZPhotoEngine超级算法库
- iOS学习之iOS沙盒(sandbox)机制和文件操作(一)
- varnish学习笔记
- 《30天自制操作系统》学习笔记
- linux 下MySQL主从复制
- 为什么费尽心思讲产品卖点,用户仍然不相信你?
- 轻松掌握Linux关机重启命令
- JSP中内建exception对象时出现500错误的解决方法
- jsp编程中session的用法实例分析
- 浅析.NET逻辑分层架构
- 总结十条.NET异常处理建议
- PHP实现GIF图片验证码
- PHP扩展开发教程(总结)
- 两种php去除二维数组的重复项方法
- php实现分页功能的3种方法第1/3页
- php对二维数组进行相关操作(排序、转换、去空白等)
- php实现网站留言板功能
- PHP实现HTML页面静态化的方法
- php对文件夹进行相关操作(遍历、计算大小)
- 非常全面的php日期时间运算汇总