如何做一个应用程序的快捷方式入口
来源:互联网 发布:短作业优先算法例题 编辑:程序博客网 时间:2024/04/20 16:54
最近在做一个桌面的快捷方式展示的功能。将其中的一些技术点做一个分享。
一、筛选应用程序
要完成桌面快捷方式展示,首先要能够拿到当前系统中安装的应用程序,且这些应用程序是用户可见的(不包含系统的app)
网上有人用如下的方法:
List<PackageInfo> list = getPackageManager().getInstalledPackages(0);
但是从源码中可以得知,这样会得到所有系统的package:
packageManager的getInstalledPackages()方法实际上是一个抽象方法,具体实现在ApplicationPackageManager中
@SuppressWarnings("unchecked")@Overridepublic List<PackageInfo> getInstalledPackages(int flags) { return getInstalledPackages(flags, mContext.getUserId());}/** @hide */@Overridepublic List<PackageInfo> getInstalledPackages(int flags, int userId) { try { ParceledListSlice<PackageInfo> slice = mPM.getInstalledPackages(flags, userId); return slice.getList(); } catch (RemoteException e) { throw new RuntimeException("Package manager has died", e); }}
所以最终还是到packageManagerService中去:
@Overridepublic ParceledListSlice<PackageInfo> getInstalledPackages(int flags, int userId) { final boolean listUninstalled = (flags & PackageManager.GET_UNINSTALLED_PACKAGES) != 0; enforceCrossUserPermission(Binder.getCallingUid(), userId, true, "get installed packages"); // writer synchronized (mPackages) { ArrayList<PackageInfo> list; if (listUninstalled) { list = new ArrayList<PackageInfo>(mSettings.mPackages.size()); for (PackageSetting ps : mSettings.mPackages.values()) { PackageInfo pi; if (ps.pkg != null) { pi = generatePackageInfo(ps.pkg, flags, userId); } else { pi = generatePackageInfoFromSettingsLPw(ps.name, flags, userId); } if (pi != null) { list.add(pi); } } } else { list = new ArrayList<PackageInfo>(mPackages.size()); for (PackageParser.Package p : mPackages.values()) { PackageInfo pi = generatePackageInfo(p, flags, userId); if (pi != null) { list.add(pi); } } } return new ParceledListSlice<PackageInfo>(list); }}
mSettings.mPackages.values()中存储的即为当前系统的所有package,包括系统app。因此这条路不行。
其实有非常方便的方法,实例代码如下:
Intent baseIntent = new Intent();baseIntent .setAction(Intent.ACTION_MAIN);baseIntent .addCategory(Intent.CATEGORY_LAUNCHER);PackageManager packageManager = getPackageManager(); List<ResolveInfo> list = packageManager.queryIntentActivities( baseIntent, 0 /* no flags */); Collections.sort(list, new ResolveInfo.DisplayNameComparator( packageManager));
Intent.CATEGORY_LAUNCHER帮助我们很好的过滤的系统app,good!
二、利用Gridview做内容展示
因为已安装的应用程序是动态的,所以这里选择使用gridview来做展示
ArrayList<HashMap<String, Object>> items = new ArrayList<HashMap<String, Object>>();final int listSize = list.size();for (int i = 0; i < listSize; i++) { ResolveInfo resolveInfo = list.get(i); HashMap<String, Object> map = new HashMap<String, Object>(); map.put("ItemImage",resolveInfo.loadIcon(packageManager)); map.put("ItemText", resolveInfo.loadLabel(packageManager)); items.add(map); SimpleAdapter adapter = new SimpleAdapter(this, items, R.layout.shortcut_item, new String[] { "ItemImage", "ItemText" }, new int[] { R.id.shortcut_image, R.id.shortcut_title });gridview.setAdapter(adapter);这里的list即为第一步中得到的package列表,我们将icon信息,和application的名字保存到items这个列表中,用来作为adapter的数据来源。
这里有一点需要特别注意的,gridview或者listview这些对象在显示图片的时候只能使用本地drawable中的资源,但是这些app的图标却在另外app当中,这时候就需要用到viewBinder的绑定机制,如此一来不仅能够显示外部app中的资源,也可以从网络获取资源图片。代码也很简单:
adapter.setViewBinder(new ViewBinder() { @Override public boolean setViewValue(View view, Object data, String textRepresentation) { if (view instanceof ImageView && data instanceof Drawable) { ImageView iv = (ImageView) view; iv.setImageDrawable((Drawable) data); return true; } else return false; } });
三、实现快捷方式的选取
通过上面的步骤,我们已经实现了app的选取和展示,那么我们最后要实现的就是在上面的界面中选择一个应用,并添加到桌面。
那么这里在处理点击事件的时候要怎么处理呢?
其实Android源码已经提供了一个非常方便的Action:ACTION_PICK_ACTIVITY
Android SDK API对其的描述是:
ACTION_PICK_ACTIVITY
Input: get*Extra field EXTRA_INTENT is an Intent used with PackageManager.queryIntentActivities to determine the set of activities from which to pick.
Output: Class name of the activity that was selected.
要实现点击应用图标,是选中而不是启动这个app,只要做如下操作:
Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY); Intent mainIntent = new Intent(); mainIntent.setAction(Intent.ACTION_MAIN); mainIntent.addCategory(Intent.CATEGORY_LAUNCHER); pickIntent.putExtra(Intent.EXTRA_INTENT, mainIntent); pickIntent.putExtra(Intent.EXTRA_TITLE, "选择应用程序"); // 设置界面title
在响应这个action的activity中的click处理函数中去获得这个对应app的intent,然后返回即可:
setResult(Activity.RESULT_OK, intent);finish();
四、主页面的展示
到这里我们走到最后一步了,主页面的展示,展示是一个动态添加view的过程
LayoutInflater inflater = LayoutInflater.from(this);View shortcut_view = inflater.inflate(R.layout.display_item, null);ImageView img = (ImageView) shortcut_view .findViewById(R.id.shortcut_img);img.setImageDrawable(appIcon);TextView tv = (TextView) shortcut_view.findViewById(R.id.shortcut_label);tv.setText(applabel);tv.setVisibility(View.INVISIBLE);tv.setOnFocusChangeListener(this);shortcut_view.setFocusable(true);shortcut_view.setOnClickListener(this);shortcut_view.setOnFocusChangeListener(this);shortcut_view.setTag(data);shortcut_view.setBackgroundResource(R.drawable.launcher_iv_border);LinearLayout.LayoutParams llparams = new LinearLayout.LayoutParams(120, 120);llparams.setMargins(10, 10, 10, 10);appContainerLayout.addView(shortcut_view, llparams);
display_item.xml是每一个动态添加的快捷方式的布局信息
<?xml version="1.0" encoding="utf-8"?><RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="wrap_content"android:layout_height="wrap_content" ><ImageView android:id="@+id/shortcut_img" android:layout_width="wrap_content"android:layout_height="wrap_content" android:layout_alignParentTop="true" /><TextView android:id="@+id/shortcut_label" android:layout_width="fill_parent" android:layout_height="wrap_content" android:layout_alignParentBottom="true" android:gravity="center_horizontal" android:background="#a0000000" android:textColor="#ffffff" android:textSize="20dp"/></RelativeLayout>
我们还想要做一个简单的动态效果,当光标聚焦时才显示包名,因此为TextView添加了一个FocusChangeListener,并把默认状态设成INVISIBLE
public void onFocusChange(View arg0, boolean arg1) { // TODO Auto-generated method stub TextView tv = (TextView) arg0.findViewById(R.id.shortcut_label); if (arg1) { tv.setVisibility(View.VISIBLE); } else { tv.setVisibility(View.INVISIBLE); } }
- 如何做一个应用程序的快捷方式入口
- Ubuntu下如何在桌面创建一个应用程序的“快捷方式”?
- Linux系统:Ubuntu下如何在桌面创建一个应用程序的“快捷方式”?
- 如何将VC做的应用程序改为一个服务程序
- 如何读取快捷方式的信息和生成一个快捷方式?
- Android应用程序的入口
- C++应用程序的入口
- android应用程序的入口
- Android应用程序的入口
- android 笔记 【一个应用程序的入口 ——Application】
- 应用程序快捷方式的安全隐患
- Android 应用程序的快捷方式
- 如何在Ubuntu的桌面创建应用程序的快捷方式
- 一个apk多个入口,在桌面上创建多个应用图标的桌面快捷方式
- 如何修改android主界面上默认的应用程序快捷方式
- HOWTO:InstallShield中如何制作应用程序的卸载快捷方式
- Android在桌面添加两个快捷方式,如何区分从哪个入口进去的?
- 应用程序的主入口点
- Leetcode Sort List
- Apache Commons Pool试用小记
- GCD(Grand Central Dispatch)教程
- XTPToolKitPro
- jquery确认框和消息提示
- 如何做一个应用程序的快捷方式入口
- application Assembly里少J2EE modules
- Equals 方法和 HashCode方法
- 设计模式及各大原则简介
- Oracle错误一览表
- flume监控指标详解
- Quartz任务调度快速入门
- 浅谈数据库设计技巧(上)
- Activiti5 邮件服务 email发送服务配置