Android:获取应用信息,打开、卸载应用

来源:互联网 发布:黑帽seo好学吗 编辑:程序博客网 时间:2024/06/05 10:20

在项目里有一个需求,点击App介绍里面的官方微信公众号,就可以直接打开微信搜索、关注。这个功能实现起来并不复杂,获取包名,用intent跳转即可。那么如何获取某一个应用的包名呢?可以反编译apk,在文件里查看,这个方法比较麻烦。我们也可以直接通过Android系统为我们提供的类PackageManager来获得PackageInfo,这个类里面包含相关应用程序的很多信息。示例用到了SwipeMenuListView,菜单里提供打开App与卸载App两个功能。主要示例代码如下:

package com.li.applistdemo;import android.content.ComponentName;import android.content.Intent;import android.content.pm.ApplicationInfo;import android.content.pm.PackageInfo;import android.content.pm.ResolveInfo;import android.graphics.Color;import android.graphics.drawable.ColorDrawable;import android.net.Uri;import android.support.v7.app.AppCompatActivity;import android.os.Bundle;import android.util.TypedValue;import android.view.View;import android.view.ViewGroup;import android.widget.ImageView;import android.widget.TextView;import com.baoyz.swipemenulistview.BaseSwipListAdapter;import com.baoyz.swipemenulistview.SwipeMenu;import com.baoyz.swipemenulistview.SwipeMenuCreator;import com.baoyz.swipemenulistview.SwipeMenuItem;import com.baoyz.swipemenulistview.SwipeMenuListView;import java.util.ArrayList;import java.util.List;public class MainActivity extends AppCompatActivity {    public final int GET_ALL_APP = 0; // 所有应用程序    public final int GET_SYSTEM_APP = 1; // 系统程序    public final int GET_THIRD_APP = 2; // 第三方应用程序    public final int GET_SDCARD_APP = 3; // 安装在SDCard的应用程序    private List<PackageInfo> mAppList;    private AppListAdapter mAdapter;    private SwipeMenuListView mListView;    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        setContentView(R.layout.activity_main);        mAppList = getPackageInfos(GET_THIRD_APP);        mListView = (SwipeMenuListView) findViewById(R.id.swipeListView);        mAdapter = new AppListAdapter();        mListView.setAdapter(mAdapter);        SwipeMenuCreator creator = new SwipeMenuCreator() {            @Override            public void create(SwipeMenu menu) {                SwipeMenuItem openItem = new SwipeMenuItem(                        getApplicationContext());                openItem.setBackground(new ColorDrawable(Color.rgb(0xC9, 0xC9,0xCE)));                openItem.setWidth(dp2px(100));                openItem.setTitle("Open");                openItem.setTitleSize(18);                openItem.setTitleColor(Color.WHITE);                menu.addMenuItem(openItem);                SwipeMenuItem deleteItem = new SwipeMenuItem(                        getApplicationContext());                deleteItem.setBackground(new ColorDrawable(Color.rgb(0xF9, 0x3F, 0x25)));                deleteItem.setWidth(dp2px(100));                deleteItem.setIcon(R.mipmap.ic_delete);                menu.addMenuItem(deleteItem);            }        };        mListView.setMenuCreator(creator);        mListView.setOnMenuItemClickListener(new SwipeMenuListView.OnMenuItemClickListener() {            @Override            public boolean onMenuItemClick(int position, SwipeMenu menu, int index) {                PackageInfo item = mAppList.get(position);                switch (index) {                    case 0:                        open(item);                        break;                    case 1:                        uninstall(item);                        mAppList.remove(position);                        mAdapter.notifyDataSetChanged();                        break;                }                return false;            }        });    }    private List<PackageInfo> getPackageInfos(int type){        // 0 表示不接受任何参数。其他参数都带有限制        // 版本号、APP权限只能通过PackageInfo获取,所以这里不使用getInstalledApplications()方法        List<PackageInfo> packageInfos = getPackageManager().getInstalledPackages(0);        if (packageInfos == null){            return null;        }        List<PackageInfo> result = new ArrayList<>();        switch (type) {            case GET_ALL_APP:                result = packageInfos;                break;            case GET_SYSTEM_APP: // 系统自带APP                for (PackageInfo info : packageInfos) {                    // FLAG_SYSTEM = 1<<0,if set, this application is installed in                    // the device's system image.                    // 下面&运算有两种结果:                    // 1,则flags的末位为1,即系统APP                    // 0,则flags的末位为0,即非系统APP                    if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 1) {                        result.add(info);                    }                }                break;            case GET_THIRD_APP: // 第三方APP                for (PackageInfo info : packageInfos) {                    // FLAG_SYSTEM = 1<<0,同上                    if ((info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {                        result.add(info);                    }                    // 本来是系统程序,被用户手动更新后,该系统程序也成为第三方应用程序了                    // FLAG_UPDATED_SYSTEM_APP = 1<<7, this is set if this                    // application has been                    // install as an update to a built-in system application.                    else if ((info.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) == 1) {                        result.add(info);                    }                }                break;            case GET_SDCARD_APP: // 安装在SDCard的应用程序                for (PackageInfo info : packageInfos) {                    // FLAG_EXTERNAL_STORAGE = 1<<18,Set to true if the application                    // is                    // currently installed on external/removable/unprotected storage                    if ((info.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 1) {                        result.add(info);                    }                }                break;        }        return result;    }    private void uninstall(PackageInfo item) {        try {            Intent intent = new Intent(Intent.ACTION_DELETE);            intent.setData(Uri.fromParts("package", item.packageName, null));            startActivity(intent);        } catch (Exception e) {            e.printStackTrace();        }    }    private void open(PackageInfo item) {        Intent resolveIntent = new Intent(Intent.ACTION_MAIN, null);        resolveIntent.addCategory(Intent.CATEGORY_LAUNCHER);        resolveIntent.setPackage(item.packageName);        List<ResolveInfo> resolveInfoList = getPackageManager()                .queryIntentActivities(resolveIntent, 0);        if (resolveInfoList != null && resolveInfoList.size() > 0) {            ResolveInfo resolveInfo = resolveInfoList.get(0);            String activityPackageName = resolveInfo.activityInfo.packageName;            String className = resolveInfo.activityInfo.name;            Intent intent = new Intent(Intent.ACTION_MAIN);            intent.addCategory(Intent.CATEGORY_LAUNCHER);            ComponentName componentName = new ComponentName(                    activityPackageName, className);            intent.setComponent(componentName);            startActivity(intent);        }    }    class AppListAdapter extends BaseSwipListAdapter {        @Override        public int getCount() {            return mAppList.size();        }        @Override        public PackageInfo getItem(int position) {            return mAppList.get(position);        }        @Override        public long getItemId(int position) {            return position;        }        @Override        public View getView(int position, View convertView, ViewGroup parent) {            if (convertView == null) {                convertView = View.inflate(getApplicationContext(),                        R.layout.item_list_app, null);                new ViewHolder(convertView);            }            ViewHolder holder = (ViewHolder) convertView.getTag();            PackageInfo item = getItem(position);            holder.iv_icon.setImageDrawable(item.applicationInfo.loadIcon(getPackageManager()));            holder.tv_name.setText(item.applicationInfo.loadLabel(getPackageManager()) + "\n" + item.packageName);            return convertView;        }        class ViewHolder {            ImageView iv_icon;            TextView tv_name;            public ViewHolder(View view) {                iv_icon = (ImageView) view.findViewById(R.id.iv_icon);                tv_name = (TextView) view.findViewById(R.id.tv_name);                view.setTag(this);            }        }        @Override        public boolean getSwipEnableByPosition(int position) {            return true;        }    }    private int dp2px(int dp) {        return (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp,                getResources().getDisplayMetrics());    }}

获取App列表信息比较耗时,可能会引起ANR,所以这些操作应该放在子线程里面。

获取到结果以后,我们要通过Adapter来更新UI,但是Android不允许在非UI线程里面更新UI,可以用Handler去post一个Runnable对象来解决这个问题。为什么Handler可以呢?感兴趣的可以看看 http://blog.csdn.net/ly502541243/article/details/52062179/ ,里面分析得很详细。
简单来说,通过Handler.post(Runnable r)传入的Runnable,在回调的时候会调用run方法,而直接调用线程的run方法相当于是在一个普通的类调用方法,还是在当前线程执行,并不会开启新的线程。在post中传了个Runnable,还是在主线程中,因此可以更新UI。

原创粉丝点击