小白马卫士项目总结之程序管理

程序管理模块


程序管理这个模块的话说起来也挺简单的,其实就是通过PackageManager这个类获取包的管理者对象然后再得到手机上所有程序的有关信息,包括程序的包名,名字,版本,图标等等!然后把它放在list集合中,然后通过适配器把它放在listView里面就可以了!

恩~~ 首先就是写一个程序信息的提供类,在这个类里面有得到应有程序的方法,还有判断出那个是用户程序,那个是系统程序的方法:

package cn.cbd.mobilesafe.activity.engine;

import java.util.ArrayList;
import java.util.List;

import cn.cbd.mobilesafe.activity.bean.AppInfo;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;

public class AppInfoProvider {
	
	public static List<AppInfo> getAppInfos(Context context)
	{
		//获取包管理者对象
		PackageManager pm=context.getPackageManager();
		//获取所有安装的程序的包信息对象
		List<PackageInfo> packInfos=pm.getInstalledPackages(0);
		List<AppInfo> appInfos=new ArrayList<AppInfo>();
		AppInfo app=null;
		for(PackageInfo packInfo : packInfos)
		{
		
			app=new AppInfo();
			app.setPackagename(packInfo.packageName);
			app.setVersion(packInfo.versionName);
			ApplicationInfo applicationInfo=packInfo.applicationInfo;
			app.setIcon(applicationInfo.loadIcon(pm));
			app.setName(applicationInfo.loadLabel(pm).toString());
			if(isUserApp(applicationInfo))
			{
				app.setUserapp(true);
			}else{
				app.setUserapp(false);
			}
			appInfos.add(app);
			
		}
		
		
		return appInfos;
	}
	
	/**
	 * 判断该应用程序是否为用户自定义安装程序
	 * @param applicationInfo 当前应用的包信息对象
	 * @return true表示用户程序,false表示系统程序
	 */
	public static boolean isUserApp(ApplicationInfo applicationInfo)
	{
		if((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM)==1)
		{
			return false;
		}else{
			return true;
		}
	}

}

然后就是主程序的操作了,里面有我的详细的注释:

package cn.cbd.mobilesafe.activity;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.support.v4.view.ViewPager.LayoutParams;
import android.text.format.Formatter;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.view.animation.ScaleAnimation;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import cn.cbd.mobilesafe.activity.bean.AppInfo;
import cn.cbd.mobilesafe.activity.engine.AppInfoProvider;

public class AppManagerActivity extends Activity implements OnClickListener {
	
	private TextView tv_mobile_space;   //手机的可用空间
	private TextView tv_sdcard_space;  //sdcard的可用空间
	
	private ListView lv_app_manager;    //显示手机程序的listView
	private List<AppInfo> appInfos;   //存放手机程序的集合
	private List<AppInfo> userAppInfos;   //存放用户程序的集合
	private List<AppInfo> systemAppInfos;  //存放系统程序的集合
	private AppInfo selectItem;  //javaBean的声明
	private PopupWindow popupWindow;  //弹出窗口的类的声明
	private MyAppManagerAdapter adapter;   //给listView加的适配器
	
	protected void onCreate(Bundle savedInstanceState) 
	{
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_app_manager);
		//实例化: 手机可用空间  sdcard的可用空间  显示手机程序的listView 
		tv_mobile_space=(TextView) findViewById(R.id.tv_mobile_space);
		tv_sdcard_space=(TextView) findViewById(R.id.tv_sdcard_space);
		lv_app_manager=(ListView) findViewById(R.id.lv_app_manager);
		
		fillDate();
		//给listView上面设置监听
		lv_app_manager.setOnItemClickListener(new OnItemClickListener(){ 

			@Override
			public void onItemClick(AdapterView<?> parent, View view,int position, long id) {
				
				/**
				 * getItemAtPosition
				 * 此方法是当点击一个条目的时候他会返回这个条目的对象而这个对象就是我们调用的
				 * AppInfoProvider.getAppInfos(this)的这个方法返回来的集合里面的对象
				 * 这个对象里面有:
				 * 	private String name;
					private String packagename;
					private boolean userapp;
					
					private String version;
					private Drawable icon;
				 */
				selectItem=(AppInfo) lv_app_manager.getItemAtPosition(position);
				
				/**
				 * contentView
				 * 获得一个视图这个视图就是点击一下那个条目的时候弹出来的那个窗口
				 */
				View contentView=View.inflate(getApplicationContext(), R.layout.layout_popupwindow,null);
				//ll_popup_uninstall  卸载的选项
				LinearLayout ll_popup_uninstall=(LinearLayout)contentView.findViewById(R.id.ll_popup_uninstall);
				//ll_popup_start   启动的选项
				LinearLayout ll_popup_start=(LinearLayout) contentView.findViewById(R.id.ll_popup_start);
				//ll_popup_share  分享的选项
				LinearLayout ll_popup_share=(LinearLayout) contentView.findViewById(R.id.ll_popup_share);
				
				ll_popup_uninstall.setOnClickListener(AppManagerActivity.this); //给卸载加监听
				ll_popup_start.setOnClickListener(AppManagerActivity.this);   //给启动加监听
				ll_popup_share.setOnClickListener(AppManagerActivity.this);  //给分享加监听
				
				
				/**
				 * 得到一个弹出窗口的实例
				 * 参数:
				 * contentView:弹出窗口的视图上面已经获得与设置
				 * LayoutParams.WRAP_CONTENT: 宽度是包裹内容
				 * LayoutParams.WRAP_CONTENT: 高度也是包裹内容
				 * true:   是否具有焦点
				 */
				popupWindow=new PopupWindow(contentView, LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT,true);
				popupWindow.setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));  //给弹窗设置背景
				int[] loaction=new int[2];   //位置
				view.getLocationInWindow(loaction);  //获得窗口的位置
				ScaleAnimation animation=new ScaleAnimation(0.2f,1.0f, 0.2f,1.0f);  //设置弹出的动作
				animation.setDuration(200);  //设置弹出的时间
				/**
				 * 设置弹窗的显示位置
				 * 参数:
				 * view: 弹窗的视图
				 * Gravity.LEFT|Gravity.TOP: 弹出的方向是左上角的方向
				 * loaction[0]+30: X轴的变化
				 * loaction[1]:  Y轴的变化
				 */
				popupWindow.showAtLocation(view, Gravity.LEFT|Gravity.TOP, loaction[0]+30, loaction[1]);
				contentView.setAnimation(animation);  //将动画添加到这个视图中
				
				
			}
			
		});
	}


	private void fillDate() {
		
	
		tv_mobile_space.setText("手机可用空间:"+getAvailableRomSize());  //设置手机的可用空间
		tv_sdcard_space.setText("SDcard可用空间"+getAvailableSdcardSize());  //设置sdcard的可用空间
		//用户级别的程序对象集合
		userAppInfos=new ArrayList<AppInfo>();
		//系统级别的程序对象集合
		systemAppInfos=new ArrayList<AppInfo>();
		appInfos=AppInfoProvider.getAppInfos(this);
		
        for(AppInfo appInfo : appInfos)
        {
        	/**
        	 * 通过isUserapp()判断一下获得的程序是否是用户程序
        	 * 如果是用户程序的话那就把它放在用户程序的集合里面
        	 * 如果是系统程序的话,那就把它放在系统程序的集合里面
        	 */
        	if(appInfo.isUserapp())   
        	{
        		userAppInfos.add(appInfo);
        	}
        	else
        	{
        		systemAppInfos.add(appInfo);
        	}
        }
		
		if(adapter==null)
		{
			adapter=new MyAppManagerAdapter();  //实例化适配器
			lv_app_manager.setAdapter(adapter);  //给程序列表添加适配器
		}else{ 
			adapter.notifyDataSetChanged();  //如果不为空的话就对列表进行刷新  
		}
	}
	
	/**
	 * onClick(View v)
	 * 此方法执行的是对弹出里的卸载,启动,分享选项进行
	 * 监听的操作
	 */
	public void onClick(View v) {
		
		popupWindow.dismiss();
		switch(v.getId())
		{
		    case R.id.ll_popup_uninstall :
		    	
		    	uninstall();  //卸载方法
		    	break;
		    case R.id.ll_popup_start :
		    	start();  //启动方法
		    	
		    	break;
		    case R.id.ll_popup_share :
		    	  share();  //分享方法
		    	  
		    	break;
		}
	}
	
	private void uninstall() {  //卸载方法
		
		/**
		 * 判断如果是应用程序的话那就进行卸载
		 * 否则的话就提示说是要获取root权限
		 */
		if(selectItem.isUserapp())  
		{
			Intent intent=new Intent();
			intent.setAction("android.intent.action.DELETE");  //设置意图的动作为删除
			intent.addCategory("android.intent.category.DEFAULT");  //设置类别为默认
			intent.setData(Uri.parse("package:"+selectItem.getPackagename())); //获取程序的包名进行删除操作
			//startActivity(intent);
			startActivityForResult(intent, 0);
		}else{
			Toast.makeText(this, "系统应用不能被卸载,只有获得root权限后能才卸载!", Toast.LENGTH_SHORT).show();
		}
	}

    
	/**
	 * 举例说我想要做的一个事情是,在一个主界面(主Activity)上能连接往许
	 * 多不同子功能模块(子Activity上去),当子模块的事情做完之后就回到主界面,
	 * 或许还同时返回一些子模块完成的数据交给主Activity处理。这个时候就要用到
	 * 回调函数onActivityResult()。 
	 */
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		
		fillDate();
		super.onActivityResult(requestCode, resultCode, data);
	}


	private void start() {  //启动方法
		
		try 
		{
			String packageName=selectItem.getPackagename();  //获得包名
			//得到程序包信息的类
			PackageInfo packageInfo=getPackageManager().getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
			ActivityInfo[] Infos=packageInfo.activities;
			if(Infos!=null && Infos.length>0)
			{
				ActivityInfo activityInfo= Infos[0];
				String className=activityInfo.name;  //获取程序的名字
				
				Intent intent=new Intent();
				intent.setClassName(packageName, className);  //设置包名与类名
				startActivity(intent);   //跳转到这个应用
				
			}
			else
			{
				Toast.makeText(this, "无法启动该应用", Toast.LENGTH_SHORT).show();
			}
			
		} catch (NameNotFoundException e) {
			Toast.makeText(this, "无法启动该应用", Toast.LENGTH_SHORT).show();
			e.printStackTrace();
		}

		
		
	}


	private void share() {  //分享方法
		Intent intent=new Intent();
		intent.setAction(Intent.ACTION_SEND);
		intent.setType("text/plain");
		intent.putExtra(Intent.EXTRA_TEXT, 
				"向你推荐一个好用的软件:"+selectItem.getName()+"版本:"+selectItem.getVersion());
		startActivity(intent);
		
	}

	/**
	 * 程序列表的适配器
	 * @author Administrator
	 *
	 */
	private class MyAppManagerAdapter extends BaseAdapter
	{

		
		public int getCount() {
			
			return userAppInfos.size()+1+systemAppInfos.size()+1;
		}

		
		public Object getItem(int position) {
			
			/**
			 * 这里需要说明一下
			 * 此方法是获得一个条目的对象,需要说明的是:
			 * position是这个条目的位置,判断如果位置比用户程序
			 * 的list集合的大小还小的话,那就返回用户集合里的对象
			 * 如果位置等于用户程序的集合里的大小加1的话那就返回null因为这里要设置textView的
			 * 也就是显示那个“系统程序”这个条目的;否则的话就是当前的位置减去用户集合的大小再减去
			 * 那连个textView所占用的位置!剩下的就是系统列表的位置了
			 */
			if(position==0)
			{
				return null;  //这个条目显示“用户程序”这几个字的
			}else if(position<=userAppInfos.size()){
				
				int newPosition=position-1;
				return userAppInfos.get(newPosition);
			}else if(position==(userAppInfos.size()+1)){
				return null;
			}else{
				int newPosition=position-userAppInfos.size()-1-1;
				return systemAppInfos.get(newPosition);
				
			}
			
			
		}

		
		public long getItemId(int position) {
			
			return position;
		}
				
		public View getView(int position, View convertView, ViewGroup parent) {
			
			
			if(position==0) //判断如果是第一个位置的话那就设置textView
			{
				TextView tv=new TextView(getApplicationContext());
				tv.setBackgroundColor(Color.GRAY);
				tv.setTextColor(Color.BLACK);
				tv.setText("用户程序("+userAppInfos.size()+")");
				return tv;
			}else if(position<=userAppInfos.size()){
				
				int newPosition=position-1;
				View view;
				ViewHolder holder;  //这个类里面有程序的图标,名字,版本
				if(convertView!=null && convertView instanceof RelativeLayout)  //如果不为空的话而且这个视图是相对布局的话
				{
				    view=convertView;  //将这个方法里的视图参数赋给这个视图对象
				    holder=(ViewHolder) view.getTag();  //通过这个视图获得程序的标签
				    
				}else{
					holder=new ViewHolder();  //否则的话就实例化这个类
					//获得一个条目视图对象
					view=View.inflate(getApplicationContext(), R.layout.layout_appmanager_item, null);
					//实例化获得图标
					holder.iv_icon=(ImageView) view.findViewById(R.id.iv_app_icon);
					//实例化程序的名字的对象
					holder.tv_name=(TextView) view.findViewById(R.id.tv_app_name);
					//实例化版本的对象
					holder.tv_version=(TextView) view.findViewById(R.id.tv_app_version);
				    view.setTag(holder);  //将这个对象设置到这个条目中去
				    
				}
				AppInfo appInfo=userAppInfos.get(newPosition);  //获取程序的信息
				holder.iv_icon.setImageDrawable(appInfo.getIcon());  //设置图标
				holder.tv_name.setText(appInfo.getName());  //设置名字
				holder.tv_version.setText("版本:"+appInfo.getVersion());  //设置版本信息
				return view;
			}else if(position==(userAppInfos.size()+1)){   //如果是系统应用的话就设置它的textView
				TextView tv=new TextView(getApplicationContext());
				tv.setBackgroundColor(Color.GRAY);
				tv.setTextColor(Color.BLACK);
				tv.setText("系统程序("+systemAppInfos.size()+")");
				return tv;
			}else{
				int newPosition=position-userAppInfos.size()-1-1;  //位置
				//Log.i("newPosition", newPosition+"");
				AppInfo appInfo=systemAppInfos.get(newPosition);
				//Log.i("newPosition", appInfo.getName()+"");
				View view;
				ViewHolder holder;
				if(convertView!=null && convertView instanceof RelativeLayout)
				{
				    view=convertView;
				    holder=(ViewHolder) view.getTag();
				    
				    
				}else{
					holder=new ViewHolder();
					view=View.inflate(getApplicationContext(), R.layout.layout_appmanager_item, null);
				    holder.iv_icon=(ImageView) view.findViewById(R.id.iv_app_icon);
				    holder.tv_name=(TextView) view.findViewById(R.id.tv_app_name);
				    holder.tv_version=(TextView) view.findViewById(R.id.tv_app_version);
				    view.setTag(holder);
				    Log.i("newPosition",holder.tv_name.toString()+"aaa");
				    
				}
				Log.i("newPosition", newPosition+appInfo.getName());
				Log.i("newPosition", newPosition+appInfo.getVersion());
				holder.iv_icon.setImageDrawable(appInfo.getIcon());
				holder.tv_name.setText(appInfo.getName());
				holder.tv_version.setText("版本:"+appInfo.getVersion());
				return view;
			}
			
		}


		/**
		 * public boolean isEnabled (int position):
		 * 如果列表的一项item是separator(充当分隔项目,跟其他item项一样,也可以不一样,但是无法进行点击),
		 * 返回true,也就是可以点击,并接收响应事件。如果此时position处的item是separator的话,返回false,
		 * 也就无法响应点击或触摸事件,此项目是不可以点击的,表现形式为点了没任何反应,可以充当一个列表中的分隔,
		 * 当然可以自定义这个分隔项的布局。
		 */
		@Override
		public boolean isEnabled(int position) {
			if(position==0 || position==(userAppInfos.size()+1))
			{
				return false;
			}else{
				return true;
			}
		}
	}
	
	static class ViewHolder  //此类用来存放程序的图标,名字,版本
	{
		ImageView iv_icon;
		TextView  tv_name;
		TextView  tv_version;
		
	}
	
	/**
	 * 
	 * @return  手机的可用空间
	 */
	private  String getAvailableRomSize()
	{
		File file=Environment.getDataDirectory(); 
		StatFs stat=new StatFs(file.getPath());
		long blockSize=stat.getBlockSize();
		long availableBlock=stat.getAvailableBlocks();
		long availableSize=availableBlock*blockSize;
		return Formatter.formatFileSize(this, availableSize);
		
	}
	/**
	 * 
	 * @return  sdcard的可用空间
	 */
	private  String getAvailableSdcardSize()
	{
		File file=Environment.getExternalStorageDirectory();
		StatFs stat=new StatFs(file.getPath());
		long blockSize=stat.getBlockSize();
		long availableBlock=stat.getAvailableBlocks();
		long availableSize=availableBlock*blockSize;
		return Formatter.formatFileSize(this, availableSize);
		
	}

	

}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值