练手小项目(5)安全卫士_软件管理器

来源:互联网 发布:美工工作流程 编辑:程序博客网 时间:2024/05/25 23:24

还是继续复习我的安卓基础吧,毕竟基础才是最重要的

这一篇文章将会用到复杂的listview,和获取系统软件信息,还有给Listview加动画效果. 

先看看布局吧,源码在后面提供下载,只是一个包,因为我是拿测试项目在演示。

① 布局的建立


布局很简单 我直接贴源码吧 因为怕有些手机装的APP过多,所以加入了一个progressbar

<?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" >    <RelativeLayout        android:layout_width="fill_parent"        android:layout_height="wrap_content" >        <TextView            android:id="@+id/tv_avail_rom"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:text="内存可用:"            android:textColor="#000000" />        <TextView            android:id="@+id/tv_avail_sd"            android:layout_width="wrap_content"            android:layout_height="wrap_content"            android:layout_alignParentRight="true"            android:text="SD卡可用:"            android:textColor="#000000" />    </RelativeLayout>    <FrameLayout        android:layout_width="fill_parent"        android:layout_height="fill_parent" >        <LinearLayout            android:id="@+id/ll_loading"            android:layout_width="fill_parent"            android:layout_height="fill_parent"            android:gravity="center"            android:orientation="vertical"            android:visibility="invisible" >            <ProgressBar                android:layout_width="wrap_content"                android:layout_height="wrap_content" />            <TextView                android:layout_width="wrap_content"                android:layout_height="wrap_content"                android:text="正在加载程序信息..." />        </LinearLayout>        <ListView            android:overScrollMode="never"            android:fastScrollEnabled="true"            android:id="@+id/lv_app_manager"            android:layout_width="fill_parent"            android:layout_height="fill_parent" >        </ListView>                <TextView             android:id="@+id/tv_status"             android:layout_width="fill_parent"                android:layout_height="wrap_content"            android:text="用户程序:6个"            android:textColor="#ffffff"            android:background="#ff888888"            />    </FrameLayout></LinearLayout>



②建立获取系统软件信息类

要得到系统软件信息,首先要通过一个类,PackageManager,里面可以获得很多东西 

一 、PackageManager的介绍

主要是管理应用程序包,通过它就可以获取应用程序信息。

二、利用PackageManager得到我们需要的软件信息

package com.example.Darkbutton.Appmanager;import java.util.ArrayList;import java.util.List;import android.content.Context;import android.content.pm.ApplicationInfo;import android.content.pm.PackageInfo;import android.content.pm.PackageManager;import android.graphics.drawable.Drawable;/** * @author xiaoxin007 * 2014-12-6下午8:18:58 * TODO 业务方法,提供手机里面安装的所有的应用程序信息 */public class AppInfoProvider {/** * 获取所有的安装的应用程序信息。 * @param context 上下文 * @return */public static List<AppInfo> getAppInfos(Context context){//1.获得一个包管理器PackageManager pm = context.getPackageManager();//2.所有的安装在系统上的应用程序包信息。List<PackageInfo> packInfos = pm.getInstalledPackages(0);//3.建立一个实体类 存储东西List<AppInfo> appInfos = new ArrayList<AppInfo>();//4.遍历for(PackageInfo packInfo : packInfos){AppInfo appInfo = new AppInfo();//packInfo  相当于一个应用程序apk包的清单文件String packname = packInfo.packageName;Drawable icon = packInfo.applicationInfo.loadIcon(pm);String name = packInfo.applicationInfo.loadLabel(pm).toString();int flags = packInfo.applicationInfo.flags;//应用程序信息的标记 相当于用户提交的答卷if((flags&ApplicationInfo.FLAG_SYSTEM)==0){//用户程序appInfo.setUserApp(true);}else{//系统程序appInfo.setUserApp(false);}if((flags&ApplicationInfo.FLAG_EXTERNAL_STORAGE)==0){//手机的内存appInfo.setInRom(true);}else{//手机外存储设备appInfo.setInRom(false);}appInfo.setPackname(packname);appInfo.setIcon(icon);appInfo.setName(name);appInfos.add(appInfo);}return appInfos;}}

三、建立一个实体类

package com.example.Darkbutton.Appmanager;import android.graphics.drawable.Drawable;/** * @author xiaoxin007 * 2014-12-6下午5:37:47 * TODO 应用程序信息的业务bean */public class AppInfo {private Drawable icon;private String name;private String packname;private boolean inRom;private boolean userApp;public Drawable getIcon() {return icon;}public void setIcon(Drawable icon) {this.icon = icon;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getPackname() {return packname;}public void setPackname(String packname) {this.packname = packname;}public boolean isInRom() {return inRom;}public void setInRom(boolean inRom) {this.inRom = inRom;}public boolean isUserApp() {return userApp;}public void setUserApp(boolean userApp) {this.userApp = userApp;}@Overridepublic String toString() {return "AppInfo [name=" + name + ", packname=" + packname + ", inRom="+ inRom + ", userApp=" + userApp + "]";}}

③ 主界面的业务逻辑

其实主要逻辑也无非是初始化组件,初始化数据,然后给listview 填充数据,最难的也就是adapter里面的逻辑

0.获取某个目录的空间大小

/** * 获取某个目录的可用空间 *  * @param path * @return */private long getAvailSpace(String path) {StatFs statf = new StatFs(path);statf.getBlockCount();// 获取分区的个数long size = statf.getBlockSize();// 获取分区的大小long count = statf.getAvailableBlocks();// 获取可用的区块的个数return size * count;}


一,初始化组件

/** * 初始化组件 */private void initView() {tv_status = (TextView) findViewById(R.id.tv_status);tv_avail_rom = (TextView) findViewById(R.id.tv_avail_rom);tv_avail_sd = (TextView) findViewById(R.id.tv_avail_sd);lv_app_manager = (ListView) findViewById(R.id.lv_app_manager);ll_loading = (LinearLayout) findViewById(R.id.ll_loading);}

二,初始化数据

/** * 初始化数据 */private void initData() {sdsize = getAvailSpace(Environment.getExternalStorageDirectory().getAbsolutePath());romsize = getAvailSpace(Environment.getDataDirectory().getAbsolutePath());tv_avail_sd.setText("SD卡可用空间:" + Formatter.formatFileSize(this, sdsize));tv_avail_rom.setText("内存可用空间:"+ Formatter.formatFileSize(this, romsize));}

三,给listview加入动画

/** * listview动画 */private void initAnim() {AnimationSet set = new AnimationSet(false); Animation animation =  new TranslateAnimation(1, 13, 10, 50);  //ScaleAnimation 控制尺寸伸缩的动画效果  animation.setDuration(300);  set.addAnimation(animation); LayoutAnimationController controller = new LayoutAnimationController(set, 1);lv_app_manager.setLayoutAnimation(controller);   //ListView 设置动画效果  }

四,给Listview填充数据

/** * 给Listview填充数据 */private void fillDataToListView() {//1.用户体验,加入progressbarll_loading.setVisibility(View.VISIBLE);//2.耗时操作加入线程以免GGnew Thread() {public void run() {//3.调用 类,获取到软件信息appInfos = AppInfoProvider.getAppInfos(AppManagerActivity.this);//4.因为要把系统,用户软件分开,所以单独建立两个数据存储userAppInfos = new ArrayList<AppInfo>();systemAppInfos = new ArrayList<AppInfo>();//5.遍历 填充进数组for (AppInfo info : appInfos) {if (info.isUserApp()) {userAppInfos.add(info);} else {systemAppInfos.add(info);}}// 加载listview的数据适配器 因为在线程之中,所以使用runOnUiThread 可以在ui更新runOnUiThread(new Runnable() {@Overridepublic void run() {if (adapter == null) {adapter = new AppManagerAdapter();lv_app_manager.setAdapter(adapter);} else {adapter.notifyDataSetChanged();}ll_loading.setVisibility(View.INVISIBLE);}});};}.start();}

5.复杂的listview布局是怎么来的

private class AppManagerAdapter extends BaseAdapter {// 控制listview有多少个条目 第一个1 代表是显示 用户应用 第二个1代表系统应用@Overridepublic int getCount() {return userAppInfos.size() + 1 + systemAppInfos.size() + 1;}@Overridepublic View getView(int position, View convertView, ViewGroup parent) {AppInfo appInfo;if (position == 0) {// 显示的是用程序有多少个的小标签TextView tv = new TextView(getApplicationContext());tv.setTextColor(Color.WHITE);tv.setBackgroundColor(Color.GRAY);tv.setText("用户程序:" + userAppInfos.size() + "个");return tv;} else if (position == (userAppInfos.size() + 1)) {TextView tv = new TextView(getApplicationContext());tv.setTextColor(Color.WHITE);tv.setBackgroundColor(Color.GRAY);tv.setText("系统程序:" + systemAppInfos.size() + "个");return tv;} else if (position <= userAppInfos.size()) {// 用户程序int newposition = position - 1;// 因为多了一个textview的文本占用了位置appInfo = userAppInfos.get(newposition);} else {// 系统程序int newposition = position - 1 - userAppInfos.size() - 1;appInfo = systemAppInfos.get(newposition);}View view;ViewHolder holder;// if(position<userAppInfos.size()){//这些位置是留个用户程序显示的。// appInfo = userAppInfos.get(position);// }else{//这些位置是留个系统程序的。// int newposition = position - userAppInfos.size();// appInfo = systemAppInfos.get(newposition);// }if (convertView != null && convertView instanceof RelativeLayout) {// 不仅需要检查是否为空,还要判断是否是合适的类型去复用view = convertView;holder = (ViewHolder) view.getTag();} else {view = View.inflate(getApplicationContext(),R.layout.list_item_appinfo, null);holder = new ViewHolder();holder.iv_icon = (ImageView) view.findViewById(R.id.iv_app_icon);holder.tv_location = (TextView) view.findViewById(R.id.tv_app_location);holder.tv_name = (TextView) view.findViewById(R.id.tv_app_name);view.setTag(holder);}holder.iv_icon.setImageDrawable(appInfo.getIcon());holder.tv_name.setText(appInfo.getName());if (appInfo.isInRom()) {holder.tv_location.setText("手机内存");} else {holder.tv_location.setText("外部存储");}return view;}@Overridepublic Object getItem(int position) {return null;}@Overridepublic long getItemId(int position) {return 0;}}

④ 软件管理的功能实现




当点击 listview条目的时候,会出现一个popwindow 有卸载 有分享,有启动 
/** * 设置listview的点击事件 */lv_app_manager.setOnItemClickListener(new OnItemClickListener() {@Overridepublic void onItemClick(AdapterView<?> parent, View view,int position, long id) {//设置点击第一个条目的时候不显示,因为不是软件if (position == 0) {return;//以此类推} else if (position == (userAppInfos.size() + 1)) {return;} else if (position <= userAppInfos.size()) {// 用户程序int newposition = position - 1;appInfo = userAppInfos.get(newposition);} else {// 系统程序int newposition = position - 1 - userAppInfos.size() - 1;appInfo = systemAppInfos.get(newposition);}// System.out.println(appInfo.getPackname());dismissPopupWindow();//填充一个popwindowView contentView = View.inflate(getApplicationContext(),R.layout.popup_app_item, null);ll_start = (LinearLayout) contentView.findViewById(R.id.ll_start);ll_share = (LinearLayout) contentView.findViewById(R.id.ll_share);ll_uninstall = (LinearLayout) contentView.findViewById(R.id.ll_uninstall);//启动的监听ll_start.setOnClickListener(AppManagerActivity.this);//分享的监听ll_share.setOnClickListener(AppManagerActivity.this);//卸载的监听ll_uninstall.setOnClickListener(AppManagerActivity.this);popupWindow = new PopupWindow(contentView, -2, -2);// 动画效果的播放必须要求窗体有背景颜色。// 透明颜色也是颜色popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));int[] location = new int[2];view.getLocationInWindow(location);// 在代码里面设置的宽高值 都是像素。---》dipint dip = 60;int px = DensityUtil.dip2px(getApplicationContext(), dip);System.out.println("px=" + px);popupWindow.showAtLocation(parent, Gravity.LEFT | Gravity.TOP,px, location[1]);ScaleAnimation sa = new ScaleAnimation(0.3f, 1.0f, 0.3f, 1.0f,Animation.RELATIVE_TO_SELF, 0,Animation.RELATIVE_TO_SELF, 0.5f);sa.setDuration(300);AlphaAnimation aa = new AlphaAnimation(0.5f, 1.0f);aa.setDuration(300);AnimationSet set = new AnimationSet(false);set.addAnimation(aa);set.addAnimation(sa);contentView.startAnimation(set);}});}

 具体功能的实现 

一,点击事件的处理

/** * 布局对应的点击事件 */@Overridepublic void onClick(View v) {dismissPopupWindow();switch (v.getId()) {case R.id.ll_share:shareApplication();break;case R.id.ll_start:startApplication();break;case R.id.ll_uninstall:if (appInfo.isUserApp()) {uninstallAppliation();}else{Toast.makeText(this, "系统应用只有获取root权限才可以卸载", 0).show();//Runtime.getRuntime().exec("");}break;}}

二,用短信实现分享功能

/** * 分享一个应用程序 */private void shareApplication() {// Intent { act=android.intent.action.SEND typ=text/plain flg=0x3000000 cmp=com.android.mms/.ui.ComposeMessageActivity (has extras) } from pid 256Intent intent = new Intent();intent.setAction("android.intent.action.SEND");intent.addCategory(Intent.CATEGORY_DEFAULT);intent.setType("text/plain");intent.putExtra(Intent.EXTRA_TEXT, "推荐您使用一款软件,名称叫:"+appInfo.getName());startActivity(intent);}

三 ,卸载应用

/** * 卸载应用 */private void uninstallAppliation() {// <action android:name="android.intent.action.VIEW" />// <action android:name="android.intent.action.DELETE" />// <category android:name="android.intent.category.DEFAULT" />// <data android:scheme="package" />Intent intent = new Intent();intent.setAction("android.intent.action.VIEW");intent.setAction("android.intent.action.DELETE");intent.addCategory("android.intent.category.DEFAULT");intent.setData(Uri.parse("package:" + appInfo.getPackname()));startActivityForResult(intent, 0);}

四 ,开启一个应用程序

/** * 开启一个应用程序 */private void startApplication() {// 查询这个应用程序的入口activity。 把他开启起来。PackageManager pm = getPackageManager();// Intent intent = new Intent();// intent.setAction("android.intent.action.MAIN");// intent.addCategory("android.intent.category.LAUNCHER");// //查询出来了所有的手机上具有启动能力的activity。// List<ResolveInfo> infos = pm.queryIntentActivities(intent,// PackageManager.GET_INTENT_FILTERS);Intent intent = pm.getLaunchIntentForPackage(appInfo.getPackname());if (intent != null) {startActivity(intent);} else {Toast.makeText(this, "不能启动当前应用", 0).show();}}

点击下载源码

0 0
原创粉丝点击