【转】Android 快捷方式的创建
http://blog.csdn.net/lenmoyouzi/article/details/16939977
一、在日常开发中,我们经常会遇到这样的需求就是网桌面添加快捷方式:常见的快捷方式有两种:一是APP的快捷方式,一是widget插件的快捷方式。下面详细介绍这两种情况的应用:
参考网站:http://www.cnblogs.com/lhxin/archive/2012/05/30/2526525.html
http://blog.csdn.net/xubin341719/article/details/7059285
二、APP的快捷方式:
1、 app快捷方式的实现又有两种情况,一是直接在桌面生成;一是通过长按桌面,在弹出的快捷菜单中生成。
2、直接生成快捷方式主要是通过发送系统广播InstallShortcutReceiver实现的。
我们先来看一下InstallShortcutReceiver的源代码。位于packages\apps\Launcher2\src\com\android\launcher2下面:
![](https://code.csdn.net/assets/CODE_ico.png)
- /*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
- package com.android.launcher2;
- import java.util.ArrayList;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.widget.Toast;
- import com.android.launcher.R;
- public class InstallShortcutReceiver extends BroadcastReceiver {
- public static final String ACTION_INSTALL_SHORTCUT =
- "com.android.launcher.action.INSTALL_SHORTCUT";
- // A mime-type representing shortcut data
- public static final String SHORTCUT_MIMETYPE =
- "com.android.launcher/shortcut";
- private final int[] mCoordinates = new int[2];
- public void onReceive(Context context, Intent data) {
- if (!ACTION_INSTALL_SHORTCUT.equals(data.getAction())) {
- return;
- }
- int screen = Launcher.getScreen();
- if (!installShortcut(context, data, screen)) {
- // The target screen is full, let's try the other screens
- for (int i = 0; i < Launcher.SCREEN_COUNT; i++) {
- if (i != screen && installShortcut(context, data, i)) break;
- }
- }
- }
- private boolean installShortcut(Context context, Intent data, int screen) {
- String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
- if (findEmptyCell(context, mCoordinates, screen)) {
- Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
- if (intent != null) {
- if (intent.getAction() == null) {
- intent.setAction(Intent.ACTION_VIEW);
- }
- // By default, we allow for duplicate entries (located in
- // different places)
- boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
- if (duplicate || !LauncherModel.shortcutExists(context, name, intent)) {
- LauncherApplication app = (LauncherApplication) context.getApplicationContext();
- app.getModel().addShortcut(context, data,
- LauncherSettings.Favorites.CONTAINER_DESKTOP, screen, mCoordinates[0],
- mCoordinates[1], true);
- Toast.makeText(context, context.getString(R.string.shortcut_installed, name),
- Toast.LENGTH_SHORT).show();
- } else {
- Toast.makeText(context, context.getString(R.string.shortcut_duplicate, name),
- Toast.LENGTH_SHORT).show();
- }
- return true;
- }
- } else {
- Toast.makeText(context, context.getString(R.string.out_of_space),
- Toast.LENGTH_SHORT).show();
- }
- return false;
- }
- private static boolean findEmptyCell(Context context, int[] xy, int screen) {
- final int xCount = LauncherModel.getCellCountX();
- final int yCount = LauncherModel.getCellCountY();
- boolean[][] occupied = new boolean[xCount][yCount];
- ArrayList<ItemInfo> items = LauncherModel.getItemsInLocalCoordinates(context);
- ItemInfo item = null;
- int cellX, cellY, spanX, spanY;
- for (int i = 0; i < items.size(); ++i) {
- item = items.get(i);
- if (item.container == LauncherSettings.Favorites.CONTAINER_DESKTOP) {
- if (item.screen == screen) {
- cellX = item.cellX;
- cellY = item.cellY;
- spanX = item.spanX;
- spanY = item.spanY;
- for (int x = cellX; x < cellX + spanX && x < xCount; x++) {
- for (int y = cellY; y < cellY + spanY && y < yCount; y++) {
- occupied[x][y] = true;
- }
- }
- }
- }
- }
- return CellLayout.findVacantCell(xy, 1, 1, xCount, yCount, occupied);
- }
- }
通过以上源代码的阅读,我相信你基本了解创建的原理了。那么我们来实现自动创建快捷方式的逻辑。在activity中创建的代码:
![](https://code.csdn.net/assets/CODE_ico.png)
- private void createShortcut() {
- Intent shortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
- shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.app_name));
- shortcut.putExtra("duplicate", false);//设置是否重复创建
- Intent intent = new Intent(Intent.ACTION_MAIN);
- intent.addCategory(Intent.CATEGORY_LAUNCHER);
- intent.setClass(this, WelcomeActivity.class);//设置第一个页面
- shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);
- ShortcutIconResource iconRes = Intent.ShortcutIconResource.fromContext(this, R.drawable.logo);
- shortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes);
- sendBroadcast(shortcut);
- }
如果在创建快捷方式的时候,我们没有指定“duplicate"属性,我们又不想重复创建,那么我们在创建之前就要判断是否存在快捷方式:
![](https://code.csdn.net/assets/CODE_ico.png)
- // 判读是否已经存在快捷方式
- public boolean isExistShortCut() {
- boolean isInstallShortcut = false;
- final ContentResolver cr = MainActivity.this.getContentResolver();
- // 本人的2.2系统是”com.android.launcher2.settings”,网上见其他的为"com.android.launcher.settings"
- final String AUTHORITY = "com.android.launcher2.settings";
- final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/favorites?notify=true");
- Cursor c = cr.query(CONTENT_URI, new String[] { "title", "iconResource" }, "title=?", new String[] { getString(R.string.app_name) }, null);
- if (c != null && c.getCount() > 0) {
- isInstallShortcut = true;
- System.out.println("已经存在快捷方式");
- }
- return isInstallShortcut;
- }
注意要添加上对应的权限:<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
三、通过系统长按方式实现的原理和上面差不多。单实现起来稍微要简单些。
首先在注册activity时,需要添加一个action为android.intent.action.CREATE_SHOERTCUT的intentFilter.如下所示:
![](https://code.csdn.net/assets/CODE_ico.png)
- <activity android:name="ShortCutTest">
- <intent-filter>
- <action android:name="android.intent.action.CREATE_SHORTCUT"/>
- </intent-filter>
- </activity>
接下来就是就是设置快捷方式的图标、名称、事件等属性。这里图表的生成,android里提供了专门的方法来生成。
![](https://code.csdn.net/assets/CODE_ico.png)
- public class ShortCutTest extends Activity{
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- // TODO Auto-generated method stub
- super.onCreate(savedInstanceState);
- createShortCut();
- }
- public void createShortCut(){
- Intent addShortCut;
- //判断是否需要添加快捷方式
- if(getIntent().getAction().equals(Intent.ACTION_CREATE_SHORTCUT)){
- addShortCut = new Intent();
- //快捷方式的名称
- addShortCut.putExtra(Intent.EXTRA_SHORTCUT_NAME , "我的快捷方式");
- //显示的图片
- Parcelable icon = ShortcutIconResource.fromContext(this, R.drawable.icon);
- addShortCut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
- //快捷方式激活的activity,需要执行的intent,自己定义
- addShortCut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent());
- //OK,生成
- setResult(RESULT_OK, addShortCut);
- }else{
- //取消
- setResult(RESULT_CANCELED);
- }
- }
- }
四、快捷方式的手机适配问题:
在开发中我们还会遇到这样的情况,一个APP要创建多个快捷方式,但是对应的快捷方式打开的activity的类名又是一样的,
例如:打开的都是activity都是com.test.MainActivity,然后根据传入的参数选择具体哪个tab下面的界面。例如创建语句为:
![](https://code.csdn.net/assets/CODE_ico.png)
- ComponentName componentName = new ComponentName(context.getPackageName(), "com.test.MainActivity");
- Intent shortcutIntent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
- shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, res.getString(nameResourceId));
- shortcutIntent.putExtra("duplicate", duplicate); // 是否允许重复创建
- shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_MAIN).setComponent(componentName).putExtra("tab_contact_flag", tabPosition));
- shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON, ((BitmapDrawable) res.getDrawable(iconResourceId)).getBitmap());
- context.sendBroadcast(shortcutIntent);
问题在于手机的适配,大部分手机会直接根据我们传入的:Intent.EXTRA_SHORTCUT_NAME对应的值去获取ApplicationInfo 的title.一些手机却根据我们传入的activity去找activity对应的name。由于我们传入的activity类名一样,所以获取到的ApplicationInfo 的title也是一样的。这时候的解决办法为跟activity取一个别名。
![](https://code.csdn.net/assets/CODE_ico.png)
- <activity-alias
- android:name="com.test.tmpcontacts"
- android:clearTaskOnLaunch="true"
- android:icon="@drawable/ic_launcher_shortcut_contact"
- android:label="@string/shortcut_contact"
- android:launchMode="singleTask"
- android:targetActivity="com.test.MainActivity" >
- <intent-filter>
- <action android:name="android.intent.action.CREATE_SHORTCUT" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity-alias>
在传递应用包名的时候,就传递我们取的别名
【转】Android 快捷方式的创建相关推荐
- Android 快捷方式的创建与查询 快捷方式问题大全 获取快捷方式在Launcher数据库中的信息 Failed to find provider info for com.android.la
/*** 创建添加快捷方式* 其中需要设置的有:* 1. 快捷方式的标题* 2. 快捷方式的图标* 3. 点击快捷方式后的跳转*/public static void createShortcut(C ...
- Android 快捷方式的创建
一.在日常开发中,我们经常会遇到这样的需求就是网桌面添加快捷方式:常见的快捷方式有两种:一是APP的快捷方式,一是widget插件的快捷方式.下面详细介绍这两种情况的应用: 参考网站:http://w ...
- android判断和创建快捷方式(4.03测试通过)
android判断和创建快捷方式(4.03测试通过) 整理了网上的创建方式的代码,对于快捷方式的判断使用系统api获取当前启动器来处理,这样系统定制过或者启动器不一样也没关系 . 一.加权限和声明目标 ...
- java创建android快捷方式_Android 通过应用程序创建快捷方式
Android 快捷方式是桌面最基本的组件.它用于直接启动某一应用程序的某个组件. 一般情况下,可以在Launcher的应用程序列表上,通过长按某一个应用程序的图标在左面上创建改该应用程序 ...
- android 快捷方式 未安装该应用程序,android,解决手动创建的桌面快捷方式无法跳转到制定的activity的问题,提示未安装应用程序...
android,解决手动创建的桌面快捷突变无法跳转到制定的activity的问题 第一步也是最关键的一步: mainfest.xml中: android:name=".activity.No ...
- android 查询快捷方式,android桌面快捷方式的创建和查询
桌面快捷方式的创建 // 内置的在2.1上不行 // Intent intent = new Intent(Intent.ACTION_CREATE_SHORTCUT); Intent intent ...
- Android ShortCut快捷方式的创建/删除和判断
ShortCut 快捷方式的创建和判断 一.相关介绍 1. 快捷方式的创建.删除通过广播实现 2. 也就是要传一个intent 3. 接受intent的这个广播接收器负责把intent传的数据写入到l ...
- Android 快捷方式
Android 快捷方式是桌面最基本的组件.它用于直接启动某一应用程序的某个组件. 一般情况下,可以在Launcher的应用程序列表上,通过长按某一个应用程序的图标在左面上创建改该应用程序的快捷方式. ...
- Android~快捷方式兼容适配
文章目录 背景 一.适配思路 二.实现细节 1.判断快捷方式是否存在 2.创建快捷方式 3.修改删除快捷方式 总结 背景 2022年了,你们的APP创建快捷方式适配得怎么样了?最近收到用户反馈公司AP ...
最新文章
- 亚马逊员工因龙卷风身亡 贝索斯庆祝载人飞行惹众怒
- iOS底层探索之类的加载(一):read_images分析
- XP照片缩略图和照片本身显示不一致,如何解决防范?
- 计算机组成原理第五章考试题,计算机组成原理第五章部分课后题答案(唐朔飞版).doc...
- 戴尔便携式计算机 故障,老DELL笔记本电脑常见故障“通病”问题
- 【数学】欧拉恒等式:史上最完美的数学公式,没有之一!
- 微信屏蔽的是域名还是服务器ip,域名从未使用也会被微信屏蔽,这个你怎么看?...
- 运营数据分析步骤与方法解读
- 项目管理/思维技术实战专家陈永生
- fwr310虚拟服务器设置,fast迅捷FWR310无线路由器设置图文教程
- [精简]RuoYi开发实战-搭建开发环境
- Element-ui 一些容易忽略的知识点
- java cloud五大神兽_SpringCloud五大神兽之Eureka
- 开车遇暴雨请戴墨镜!快转起,很多人会感激你的!
- canvas+js实现简单的双人坦克对战小游戏
- Python 使用 twitter API 获取twitter用户信息
- NS3 Tutorial 中文版:第四章 概念概述
- 【yolov5检测代码简化】Yolov5 detect.py推理代码简化,输入图片,输出图片和结果
- 引用qcustomplot编译错误undefined reference to `_imp___ZN8QPrinterC1ENS_11PrinterModeE'
- PCB设计FAQ集锦
热门文章
- Cervical Cancer mechanism
- 基于Flink秒级计算时CPU监控图表数据中断问题
- Robotframework SSHLibrary库关键字
- shell单例-处理方案
- ASP.NET 2.0 正式版中无刷新页面的开发
- R语言文件下载:谁来帮我把这个128个音频下载一下
- c#_Math.Sign()
- winform_界面美化设计_显示/隐藏侧边栏
- wcf 返回图片_WCF实现上传图片功能
- 强化学习ppt_机器学习原理、算法与应用配套PPT第四部分(深度学习概论、自动编码器、强化学习、聚类算法、半监督学习等)...