【android开发】手机应用管理器的实现之实现对应用程序的运行、分享、卸载功能(三)

上一篇我们利用popupwindow类实现对话框,对话框主要功能包括运行、分享、加锁、卸载。今天我们就对其中的运行、分享、卸载功能进行实现,由于软件锁实现起来相对复杂一些,这个功能我们会放在下一次博客中单独讲解。今天的任务还是比较轻松的,让我们先看看效果图吧:

                             主界面                                         点击分享界面                                                          点击卸载界面

    

一、实现原理:

对于我们通过第三方apk调用其他apk,来实现对其的运行、分享、卸载,是比较简单的,总的思想就是通过android封装好的类,根据自己的需求来调用想用的方法,不会像图软件锁那样复杂。

启动一个apk我们首相是要获取这个apk包名,

AppInfo item = (AppInfo) v.getTag();
	PackageInfo packageInfo = getPackageManager().getPackageInfo(item.getPackageName(), PackageManager.GET_UNINSTALLED_PACKAGES);
	//扫描出来的所以activity节点的信息
	ActivityInfo[] activityInfos = packageInfo.activities;
	//有些应用是无法启动的,所以我们就要判断一下
	if(activityInfos != null && activityInfos.length > 0 ){
		//在扫描出来的应用里面,第一个是具有启动意义的
		ActivityInfo startActivity = activityInfos[0];
		//设置Intent,启动activity,这里我们使用异常处理,对启动结果进行处理
		try{
			Intent intent = new Intent();
			intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
			intent.setClassName(item.getPackageName(), startActivity.name);
			startActivity(intent);
		}catch(Exception e){
			Toast.makeText(MainActivity.this, "很抱歉,启动失败!", Toast.LENGTH_SHORT).show();
		}
	}else{
		Toast.makeText(MainActivity.this, "这个应用程序无法启动", Toast.LENGTH_SHORT).show(); 
	}


我是用了一个异常,对启动失败来进行处理,在实现过程中,我们一些系统的程序不能启动,这些程序按照道理说是可以启动的,具体启动报错,原因还在琢磨中。

实现分享功能和卸载功能都很简单,主要代码:

Intent shareintent = new Intent();
//设置Intent的action
shareintent.setAction(Intent.ACTION_SEND);
//设定分享的类型是纯文本的
			shareintent.setType("text/plain");
//设置分享主题
shareintent.putExtra(Intent.EXTRA_SUBJECT, "分享");
//设置分享的文本
shareintent.putExtra(Intent.EXTRA_TEXT, "有一个很好的应用程序哦!给你推荐一下:" +item.getAppName()+"/n本消息来自系统测试");
startActivity(shareintent);
下面是卸载:

if(item.isSystemApp()){
	Toast.makeText(MainActivity.this, "不能卸载系统的应用程序", Toast.LENGTH_SHORT).show();  
}else{
	String strUri = "package:"+item.getPackageName();
	Uri uri = Uri.parse(strUri);//通过uri去访问你要卸载的包名
	Intent delectIntent = new Intent();
	delectIntent.setAction(Intent.ACTION_DELETE);
	delectIntent.setData(uri);
	startActivityForResult(delectIntent, 0);
}
通过上面的代码,打击可以发现,无论是运行还是分享、卸载,主要都是用到了Intent,所以这个类是非常重要的,未来我们也会针对这个intent进行系统的讲一下。

二、实现完整代码:

今天的工作主要是是对MainActivity类进行了代码添加,代码如下:

package com.xh.ui;


import java.util.ArrayList;
import java.util.List;
import com.example.appmanager.R;

import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnLongClickListener;
import android.view.animation.ScaleAnimation;
import android.view.ViewGroup;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AbsListView;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.TextView;
import android.widget.Toast;
import android.annotation.SuppressLint;
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;
/**
 * 类名称:MainActivity 
 * 类描述:系统主页面
 * 创建人:LXH 
 * 创建时间:2013-11-5 下午3:31:00 
 */
public class MainActivity extends Activity implements OnClickListener,OnLongClickListener{

	private static final int GET_ALL_APP_FINISH = 1;
	private static final int GET_USER_APP_FINISH = 2;
    private ListView lv_app_manager;//应用信息列表  
    private LinearLayout ll_app_manager_progress; //进度条 
    private AppInfoProvider provider;  
    private AppManagerAdapter adapter;  
    private List<AppInfo> list;  
    private PopupWindow popupWindow;
    private ImageView iv_app_lock;
    private TextView tv_app_lock;
    private LinearLayout ll_app_logo;
    private TextView tv_app_title;
    //判断是不是还在加载中,如果还在加载中的话,就不能进行应用的切换  
    private boolean flag = false; 
    @SuppressLint("HandlerLeak")  
    private Handler handler = new Handler()  
    {  
        public void handleMessage(Message msg)   
        {  
            switch(msg.what)  
            {  
            case GET_ALL_APP_FINISH :   
                //进度条设置为不可见  
                ll_app_manager_progress.setVisibility(View.GONE);  
                adapter = new AppManagerAdapter(list);  
                lv_app_manager.setAdapter(adapter);
                flag = true;
                break;  
            case GET_USER_APP_FINISH:
            	//进度条设置为不可见
            	ll_app_manager_progress.setVisibility(View.GONE);
                adapter = new AppManagerAdapter(getUserApp());  
                lv_app_manager.setAdapter(adapter);  
                flag = true;  
                break;   
            default :   
                break;   
            }  
        };  
    };  
      
    @Override  
    protected void onCreate(Bundle savedInstanceState)  
    {  
        super.onCreate(savedInstanceState);  
        setContentView(R.layout.main_layout);  
          
        initView();
        initUI(false);
        
        
        //实现点击listview触发事件
        lv_app_manager.setOnItemClickListener(new OnItemClickListener() {

			@Override
			public void onItemClick(AdapterView<?> parent, View view, int position,
					long id) {
				// TODO Auto-generated method stub
				dismissPopupWindow();
				//用来存放当前的item的坐标值,第一个是x的坐标,第二个是y的坐标 
				int[] location = new int[2];
				//把当前的item的坐标值放到int数组里面
				view.getLocationInWindow(location);
				View popupView = View.inflate(MainActivity.this, R.layout.popup_item, null);
				LinearLayout ll_app_run = (LinearLayout) popupView.findViewById(R.id.ll_app_start);  
	            LinearLayout ll_app_share = (LinearLayout) popupView.findViewById(R.id.ll_app_share);  
	            LinearLayout ll_app_lock = (LinearLayout) popupView.findViewById(R.id.ll_app_lock);
	            LinearLayout ll_app_uninstall = (LinearLayout) popupView.findViewById(R.id.ll_app_uninstall);
	            iv_app_lock = (ImageView) popupView.findViewById(R.id.iv_app_lock);
	            tv_app_lock = (TextView) popupView.findViewById(R.id.tv_app_lock);
	            ll_app_run.setOnClickListener(MainActivity.this);  
	            ll_app_share.setOnClickListener(MainActivity.this);
	            ll_app_lock.setOnClickListener(MainActivity.this);
	            ll_app_lock.setOnLongClickListener(MainActivity.this);
	            ll_app_uninstall.setOnClickListener(MainActivity.this);
				//new 一个PopupWindow出来
				popupWindow = new PopupWindow(popupView, 615, 150);
				//一定要给PopupWindow设置一个背景图片,不然的话,会有很多未知的问题的  
				//如没办法给它加上动画,还有显示会有问题等,  
				//如果我们没有要设置的图片,那么我们就给它加上了一个透明的背景图片
				Drawable drawable = new ColorDrawable(Color.TRANSPARENT);
				popupWindow.setBackgroundDrawable(drawable);
				
				int x = location[0]+60;
				int y = location[1];
				//把PopupWindow显示出来 
				popupWindow.showAtLocation(view, Gravity.LEFT | Gravity.TOP, x, y);
				
				//拿到当时点击的条目,并设置到view里面  
	            AppInfo info = (AppInfo) lv_app_manager.getItemAtPosition(position);
	            String packageName = info.getPackageName();
	            ll_app_run.setTag(info);
	            ll_app_share.setTag(info);
	            ll_app_lock.setTag(info);
	            ll_app_uninstall.setTag(info);
				//增加一个动画效果
				LinearLayout ll_app_popup = (LinearLayout) popupView.findViewById(R.id.ll_app_popup);
				ScaleAnimation scaleAnimation = new ScaleAnimation(0.0f, 1.0f, 0.0f, 1.0f);
	            scaleAnimation.setDuration(300);
	            ll_app_popup.startAnimation(scaleAnimation);
			}
		});
        //listview滚动时判断一下对话框,防止对话框一直存在
        lv_app_manager.setOnScrollListener(new OnScrollListener() {
			
			@Override
			public void onScrollStateChanged(AbsListView arg0, int arg1) {
				// TODO Auto-generated method stub
				dismissPopupWindow();
			}
			
			@Override
			public void onScroll(AbsListView arg0, int arg1, int arg2, int arg3) {
				// TODO Auto-generated method stub
				dismissPopupWindow();
			}
		});
    }
    @Override
	public void onClick(View v) {
		// TODO Auto-generated method stub
    	AppInfo item = (AppInfo) v.getTag();
		switch (v.getId()) {
		case  R.id.tv_app_title:
    	case R.id.ll_app_logo:
    		if(flag){
    			if("所有应用程序".equals(tv_app_title.getText().toString().trim())){
    				tv_app_title.setText("用户应用程序");
    				adapter.setAppInfos(getUserApp());
    				//通知ListView数据发生了变化  
    				adapter.notifyDataSetChanged(); 
    			}else{
    				tv_app_title.setText("所有应用程序");  
    				adapter.setAppInfos(list);  
    				adapter.notifyDataSetChanged();  
    			}
    		}else{
    			Toast.makeText(MainActivity.this, "正在加载请稍后……", Toast.LENGTH_SHORT).show();
    		}
    		break;
		case R.id.ll_app_start://启动应用程序
			try {
					/**
					 * 拿到这个包对应的PackageInfo对象,这里我们指定了两个flag,  
					 * 一个就是之前讲过的,所有的安装过的应用程序都找出来,包括卸载了但没清除数据的  
					 * 一个就是指定它去扫描这个应用的AndroidMainfest文件时候的activity节点,  
					 * 这样我们才能拿到具有启动意义的ActivityInfo,如果不指定,是无法扫描出来的 
					 * 
					 * */
					PackageInfo packageInfo = getPackageManager().getPackageInfo(item.getPackageName(), PackageManager.GET_UNINSTALLED_PACKAGES | PackageManager.GET_ACTIVITIES);
					//扫描出来的所以activity节点的信息
					ActivityInfo[] activityInfos = packageInfo.activities;
					//有些应用是无法启动的,所以我们就要判断一下 
					if(activityInfos != null && activityInfos.length > 0){
						//在扫描出来的应用里面,第一个是具有启动意义的 
						ActivityInfo startActivity = activityInfos[0];
						//设置Intent,启动activity
						try{
							Intent intent = new Intent();
							intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
							intent.setClassName(item.getPackageName(), startActivity.name);
							startActivity(intent);
						}catch(Exception e){
							Toast.makeText(MainActivity.this, "很抱歉,启动失败!", Toast.LENGTH_SHORT).show();
						}
					}else{
						Toast.makeText(MainActivity.this, "这个应用程序无法启动", Toast.LENGTH_SHORT).show(); 
					}
				} catch (NameNotFoundException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			break;
		case R.id.ll_app_share://分享应用程序
			Intent shareintent = new Intent();
			//设置Intent的action
			shareintent.setAction(Intent.ACTION_SEND);
			//设定分享的类型是纯文本的
			shareintent.setType("text/plain");
			//设置分享主题
			shareintent.putExtra(Intent.EXTRA_SUBJECT, "分享");
			//设置分享的文本
			shareintent.putExtra(Intent.EXTRA_TEXT, "有一个很好的应用程序哦!给你推荐一下:" +item.getAppName()+"/n本消息来自系统测试");
			startActivity(shareintent);
			break;
		case R.id.ll_app_lock://软件锁
			
			break;
		case R.id.ll_app_uninstall://卸载
			if(item.isSystemApp()){
				 Toast.makeText(MainActivity.this, "不能卸载系统的应用程序", Toast.LENGTH_SHORT).show();  
			}else{
				String strUri = "package:"+item.getPackageName();
				Uri uri = Uri.parse(strUri);//通过uri去访问你要卸载的包名
				Intent delectIntent = new Intent();
				delectIntent.setAction(Intent.ACTION_DELETE);
				delectIntent.setData(uri);
				startActivityForResult(delectIntent, 0);
			}
			break;
		default:
			break;
		}
		dismissPopupWindow();
	}
	@Override
	public boolean onLongClick(View arg0) {
		// TODO Auto-generated method stub
		return false;
	}  
  //判断PopupWindow是不是存在,存在就把它dismiss掉  
    private void dismissPopupWindow()  
    {  
        if(popupWindow != null)  
        {  
            popupWindow.dismiss();  
            popupWindow = null;  
        }  
    }
    private void initView(){
    	lv_app_manager = (ListView) findViewById(R.id.lv_app_manager);  
        ll_app_manager_progress = (LinearLayout) findViewById(R.id.ll_app_manager_progress);  
        ll_app_logo = (LinearLayout) findViewById(R.id.ll_app_logo);
        tv_app_title = (TextView) findViewById(R.id.tv_app_title);
        ll_app_logo.setOnClickListener(MainActivity.this);
		tv_app_title.setOnClickListener(this);
    }
    private void initUI(final boolean isUserApp)  
    {  
        flag = false;  
        ll_app_manager_progress.setVisibility(View.VISIBLE);  
          
        /**
         * 开一个线程用于完成对所有应用程序信息的搜索  
         * 当搜索完成之后,就把一个成功的消息发送给Handler,
         * 然后handler把搜索到的数据设置进入listview里面  .
         * */ 
        new Thread()  
        {  
            public void run()   
            {  
                provider = new AppInfoProvider(MainActivity.this);  
                list = provider.getAllApps();  
                Log.i("info", "-->list"+"="+list.size());
                Message msg = new Message();  
                if(isUserApp)  
                {  
                    msg.what = GET_USER_APP_FINISH;  
                }  
                else  
                {  
                    msg.what = GET_ALL_APP_FINISH;  
                }  
                handler.sendMessage(msg);  
            };  
        }.start();  
    }  
    /**
     * 筛选出用户程序
     * */
    private List<AppInfo> getUserApp()  
    {  
        List<AppInfo> userApps = new ArrayList<AppInfo>();  
        for(AppInfo info : list)  
        {  
            if(!info.isSystemApp())  
            {  
                userApps.add(info);  
            }  
        } 
        Log.i("info", "-->userApps"+"="+userApps.size());
        return userApps;  
    }  
    //定义一个内部适配器类,一般建议把适配器单独封装在一个文件中 
    private class AppManagerAdapter extends BaseAdapter  
    {  
    	private List<AppInfo> appInfos;
		public AppManagerAdapter(List<AppInfo> appInfos) {
			// TODO Auto-generated constructor stub
			this.appInfos = appInfos; 
		}
		//设置adapter的数据
		public void setAppInfos(List<AppInfo> appInfos) {
			// TODO Auto-generated method stub
			 this.appInfos = appInfos;
		}

		@Override
		public int getCount() {
			// TODO Auto-generated method stub
			return appInfos.size();
		}

		@Override
		public Object getItem(int position) {
			// TODO Auto-generated method stub
			return appInfos.get(position);
		}

		@Override
		public long getItemId(int position) {
			// TODO Auto-generated method stub
			return position;
		}
        @Override  
        public View getView(int position, View convertView, ViewGroup parent)  
        {  
        	// TODO Auto-generated method stub
			AppInfo info = appInfos.get(position);
			if(convertView == null){
				View view = View.inflate(MainActivity.this, R.layout.app_manager_item, null);
				AppManagerViews views = new AppManagerViews();  
                views.iv_app_icon = (ImageView) view.findViewById(R.id.iv_app_manager_icon);  
                views.tv_app_name = (TextView) view.findViewById(R.id.tv_app_manager_name);
                views.iv_appisLock = (ImageView) view.findViewById(R.id.iv_app_lock);
                views.iv_app_icon.setImageDrawable(info.getIcon());  
                views.tv_app_name.setText(info.getAppName());
                view.setTag(views);  
                return view;  
			
			}else{  
                AppManagerViews views = (AppManagerViews) convertView.getTag();  
                views.iv_app_icon.setImageDrawable(info.getIcon());  
                views.tv_app_name.setText(info.getAppName());
                return convertView;  
            }  
		}
          
    }  
    /**
     * 用来优化listview的类  
     * */
    private class AppManagerViews  
    {  
        ImageView iv_app_icon;  
        TextView tv_app_name;
        ImageView iv_appisLock;
    }
	
}
需要提出的是,在点击列表时,我们需要先把当前的点击条目拿到,病=并放到view里面,这点需要大家注意,代码如下:

 AppInfo info = (AppInfo) lv_app_manager.getItemAtPosition(position);
String packageName = info.getPackageName();
ll_app_run.setTag(info);
ll_app_share.setTag(info);
ll_app_lock.setTag(info);
ll_app_uninstall.setTag(info);
另外我们这次还加入对于应用程序的刷选,加入了用户程序,点击logo的button可切换所有应用和用户应用。到此,我们四个模块中的三个功能已经完成了,下一次我们将继续讲解如何对一个应用程序进行加锁,也就是我们说的软件加锁功能,这个功能对于很多安全软件来说都有。这个功能实现起来相对复杂一些,下一次我们将慢慢来分享给大家。欢迎大家继续关注下一篇博客,对于每一次发布的资源都是本人测试,是完全可以正常运行的,如果出现不能运行问题,多数是配置问题,大家可以在博客下面留言,一起交流,如果您在资源下面留言,我们是无法交流的。所有跟随的资源,都不需要积分,如果无法下载可以留下自己的邮箱,将会把资源发送给你。欢迎大家继续关注…


所有资源下载列表






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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值