桌面快捷方式的问题-创建-删除-判断

遇到了红米note1,我才知道了什么是开启一次应用创建一个创建一个快捷方式。

…………………………

版权声明:本文为博主原创文章,未经博主允许不得转载。

目录(?)[-]

  1. 背景
  2. 实现
    1. 增加快捷方式
    2. 删除快捷方式
    3. 快捷方式修改
    4. 快捷方式存在判断
  3. 兼容与注意事项
    1. 兼容
    2. 注意事项
  4. 参考
  5. 附录

原文来自http://blog.zanlabs.com/2015/03/14/android-shortcut-summary/

将近二个多月没写博客了。
之前一段时间一直在搞红包助手,就没抽时间写博客,但写这个真的是很好玩。没想到居然在Android上实现模拟点击,从而实现自动抢红包,有兴趣的同学可以参考https://github.com/waylife/RedEnvelopeAssistant ,代码已经开源。
红包助手还有一些问题,但是现在基本的抢红包基本没问题了。目前正在对它进行优化以及较低版本的一些适配,还有项目的国际化工作。
废话不多说了,下面是Andrioid开发过程中快捷方式相关的事与坑。
数据来源于上次组内自己的CodeReview总结。

背景

一般情况下,为了让用户更方便的打开应用,程序会在桌面上生成一些快捷方式。
本来呢,如果是原生的桌面,其实是十分简单,直接调用系统相关的API就行了。但是众多的系统厂商以及众多第三方自己定制的桌面(Launcher),导致在适配、兼容方面存在很多问题。
比如,有些桌面无法删除快捷方式(比如小米),有些桌面无法生成快捷方式(比如锤子),有些系统无法更新桌面图标(比如华为荣耀6)。
在升级、降级的时候快捷方式发生变化;比如,全部变成应用的主图标,升级、降级后点击快捷方式没有反应,删除应用后无法删除快捷方式。
很多问题都是需要解决的,虽然有些由于系统限制,没有办法搞定所有的,但是仍然需要寻求一个最优的方案。这也就是本文需要讨论的问题。
本文说指的快捷方式是指应用桌面快捷方式,不包含长按弹出的生成快捷方式。
快捷方式所有信息都是存在于launcher的favorite表。一般需要用到的字段为_id,title,intent,iconResource,icon,分别表示 快捷方式名称,快捷方式intent,快捷方式图标(本地),快捷方式图标(data二进制压缩数据)。

两个intent数据如下

数据可以通过SQLite Editor查看,需要已经ROOT的手机

实现

增加快捷方式

在AndroidManifest.xml增加权限

[html] view plain copy

  1. <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />

同时,根据Intent是隐式还是显示在相关的Activity声明相关的intent-filter。
相关代码:

删除快捷方式

跟增加快捷方式一样,也是需要增加权限的。加上

[html] view plain copy

  1. <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />

相关代码:

快捷方式修改

需要增加权限

[html] view plain copy

  1. <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
  2. <uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" />

如果适配所有桌面,请添加附录中第二条所列出的权限。
系统并没有提供API去更改桌面快捷方式。只能通过其他猥琐的办法了,可行的的办法之一就是通过ContentProvider去更改数据库相关的信息。当然有人会说了,先删掉快捷方式,再重新创建不就行了?这是个办法。但是有些系统是无法删除快捷方式的;另外,删除快捷方式与创建快捷方式都是通过广播实现的,这个地方需要控制两者的时间间隔。权衡之后,选用第一种办法相对稳妥。
废话不多少,上代码。

[java] view plain copy

  1. /**
  2. * 更新桌面快捷方式图标,不一定所有图标都有效<br/>
  3. * 如果快捷方式不存在,则不更新<br/>.
  4. */
  5. public static void updateShortcutIcon(Context context, String title, Intent intent,Bitmap bitmap) {
  6. if(bitmap==null){
  7. XLog.i(TAG, "update shortcut icon,bitmap empty");
  8. return;
  9. }
  10. try{
  11. final ContentResolver cr = context.getContentResolver();
  12. StringBuilder uriStr = new StringBuilder();
  13. String urlTemp="";
  14. String authority = LauncherUtil.getAuthorityFromPermissionDefault(context);
  15. if(authority==null||authority.trim().equals("")){
  16. authority = LauncherUtil.getAuthorityFromPermission(context,LauncherUtil.getCurrentLauncherPackageName(context)+".permission.READ_SETTINGS");
  17. }
  18. uriStr.append("content://");
  19. if (TextUtils.isEmpty(authority)) {
  20. int sdkInt = android.os.Build.VERSION.SDK_INT;
  21. if (sdkInt < 8) { // Android 2.1.x(API 7)以及以下的
  22. uriStr.append("com.android.launcher.settings");
  23. } else if (sdkInt < 19) {// Android 4.4以下
  24. uriStr.append("com.android.launcher2.settings");
  25. } else {// 4.4以及以上
  26. uriStr.append("com.android.launcher3.settings");
  27. }
  28. } else {
  29. uriStr.append(authority);
  30. }
  31. urlTemp=uriStr.toString();
  32. uriStr.append("/favorites?notify=true");
  33. Uri uri = Uri.parse(uriStr.toString());
  34. Cursor c = cr.query(uri, new String[] {"_id", "title", "intent" },
  35. "title=?  and intent=? ",
  36. new String[] { title, intent.toUri(0) }, null);
  37. int index=-1;
  38. if (c != null && c.getCount() > 0) {
  39. c.moveToFirst();
  40. index=c.getInt(0);//获得图标索引
  41. ContentValues cv=new ContentValues();
  42. cv.put("icon", flattenBitmap(bitmap));
  43. Uri uri2=Uri.parse(urlTemp+"/favorites/"+index+"?notify=true");
  44. int i=context.getContentResolver().update(uri2, cv, null,null);
  45. context.getContentResolver().notifyChange(uri,null);//此处不能用uri2,是个坑
  46. XLog.i(TAG, "update ok: affected "+i+" rows,index is"+index);
  47. }else{
  48. XLog.i(TAG, "update result failed");
  49. }
  50. if (c != null && !c.isClosed()) {
  51. c.close();
  52. }
  53. }catch(Exception ex){
  54. ex.printStackTrace();
  55. XLog.i(TAG, "update shortcut icon,get errors:"+ex.getMessage());
  56. }
  57. }
  58. private static byte[] flattenBitmap(Bitmap bitmap) {
  59. // Try go guesstimate how much space the icon will take when serialized
  60. // to avoid unnecessary allocations/copies during the write.
  61. int size = bitmap.getWidth() * bitmap.getHeight() * 4;
  62. ByteArrayOutputStream out = new ByteArrayOutputStream(size);
  63. try {
  64. bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
  65. out.flush();
  66. out.close();
  67. return out.toByteArray();
  68. } catch (IOException e) {
  69. XLog.w(TAG, "Could not write icon");
  70. return null;
  71. }
  72. }

快捷方式存在判断

需要增加的权限同修改快捷方式
虽然说通过SharePreference来保证快捷方式不会重复创建,以及通过shortcutIntent.putExtra(“duplicate”, false)也可以确保,但是为了万无一失,还是可以通过去查询数据判断快捷方式是否存在,来避免重复创建。 代码如下:

[java] view plain copy

  1. /**
  2. * 检查快捷方式是否存在 <br/>
  3. * <font color=red>注意:</font> 有些手机无法判断是否已经创建过快捷方式<br/>
  4. * 因此,在创建快捷方式时,请添加<br/>
  5. * shortcutIntent.putExtra("duplicate", false);// 不允许重复创建<br/>
  6. * 最好使用{@link #isShortCutExist(Context, String, Intent)}
  7. * 进行判断,因为可能有些应用生成的快捷方式名称是一样的的<br/>
  8. * 此处需要在AndroidManifest.xml中配置相关的桌面权限信息<br/>
  9. * 错误信息已捕获<br/>
  10. */
  11. public static boolean isShortCutExist(Context context, String title) {
  12. boolean result = false;
  13. try {
  14. final ContentResolver cr = context.getContentResolver();
  15. StringBuilder uriStr = new StringBuilder();
  16. String authority = LauncherUtil.getAuthorityFromPermissionDefault(context);
  17. if(authority==null||authority.trim().equals("")){
  18. authority = LauncherUtil.getAuthorityFromPermission(context,LauncherUtil.getCurrentLauncherPackageName(context)+".permission.READ_SETTINGS");
  19. }
  20. uriStr.append("content://");
  21. if (TextUtils.isEmpty(authority)) {
  22. int sdkInt = android.os.Build.VERSION.SDK_INT;
  23. if (sdkInt < 8) { // Android 2.1.x(API 7)以及以下的
  24. uriStr.append("com.android.launcher.settings");
  25. } else if (sdkInt < 19) {// Android 4.4以下
  26. uriStr.append("com.android.launcher2.settings");
  27. } else {// 4.4以及以上
  28. uriStr.append("com.android.launcher3.settings");
  29. }
  30. } else {
  31. uriStr.append(authority);
  32. }
  33. uriStr.append("/favorites?notify=true");
  34. Uri uri = Uri.parse(uriStr.toString());
  35. Cursor c = cr.query(uri, new String[] { "title" },
  36. "title=? ",
  37. new String[] { title }, null);
  38. if (c != null && c.getCount() > 0) {
  39. result = true;
  40. }
  41. if (c != null && !c.isClosed()) {
  42. c.close();
  43. }
  44. } catch (Exception e) {
  45. e.printStackTrace();
  46. result=false;
  47. }
  48. return result;
  49. }
  50. /**
  51. * 不一定所有的手机都有效,因为国内大部分手机的桌面不是系统原生的<br/>
  52. * 更多请参考{@link #isShortCutExist(Context, String)}<br/>
  53. * 桌面有两种,系统桌面(ROM自带)与第三方桌面,一般只考虑系统自带<br/>
  54. * 第三方桌面如果没有实现系统响应的方法是无法判断的,比如GO桌面<br/>
  55. * 此处需要在AndroidManifest.xml中配置相关的桌面权限信息<br/>
  56. * 错误信息已捕获<br/>
  57. */
  58. public static boolean isShortCutExist(Context context, String title, Intent intent) {
  59. boolean result = false;
  60. try{
  61. final ContentResolver cr = context.getContentResolver();
  62. StringBuilder uriStr = new StringBuilder();
  63. String authority = LauncherUtil.getAuthorityFromPermissionDefault(context);
  64. if(authority==null||authority.trim().equals("")){
  65. authority = LauncherUtil.getAuthorityFromPermission(context,LauncherUtil.getCurrentLauncherPackageName(context)+".permission.READ_SETTINGS");
  66. }
  67. uriStr.append("content://");
  68. if (TextUtils.isEmpty(authority)) {
  69. int sdkInt = android.os.Build.VERSION.SDK_INT;
  70. if (sdkInt < 8) { // Android 2.1.x(API 7)以及以下的
  71. uriStr.append("com.android.launcher.settings");
  72. } else if (sdkInt < 19) {// Android 4.4以下
  73. uriStr.append("com.android.launcher2.settings");
  74. } else {// 4.4以及以上
  75. uriStr.append("com.android.launcher3.settings");
  76. }
  77. } else {
  78. uriStr.append(authority);
  79. }
  80. uriStr.append("/favorites?notify=true");
  81. Uri uri = Uri.parse(uriStr.toString());
  82. Cursor c = cr.query(uri, new String[] { "title", "intent" },
  83. "title=?  and intent=?",
  84. new String[] { title, intent.toUri(0) }, null);
  85. if (c != null && c.getCount() > 0) {
  86. result = true;
  87. }
  88. if (c != null && !c.isClosed()) {
  89. c.close();
  90. }
  91. }catch(Exception ex){
  92. result=false;
  93. ex.printStackTrace();
  94. }
  95. return result;
  96. }

兼容与注意事项

兼容

所有的快捷方式Intent如果不是之前版本的存在很大问题,绝对不要改变参数,否则升级或者降级时快捷方式会出现问题;
同时,尽可能的采用隐式调用,自定义CATEGORY,而不是自定义ACTION,ACTION参数一定要为ACTION_MAIN,否则有些手机在卸载时无法删除快捷方式(WTF)。

注意事项

  • 【所有】activity路径的变更导致老版本升级之后快捷方式无法使用
    —> 1.一旦使用确定了activity的包路径,之后就不要再变更;
    —> 2.尽可能使用隐式调用,但是如果之前已经发出去的版本,为了兼容性,就必须一直使用老的方式,新版本的尽可能的不要更改方式,如果用户降级,老版本快捷方式会无法使用。
  • 【部分】多个快捷方式指向一个activity导致部分手机(三星SII)升级时图标变成应用图标
    —> 尽可能的避免多个快捷方式指向同一个activity,可能通过多个activity再跳转过去
  • 【部分】应用删除时无法删除快捷方式。与系统桌面Launcher实现有关。
    —> 为了适配所有Launcher,Intent Action使用Intent.ACTION_MAIN。如果是隐式调用,尽可能自定义CATEGORY,而不是自定义ACTION。
  • 【部分】应用升级时需要删除老版本部分快捷方式,但是部分手机无法删除
    —> 无解
  • 【部分】第三方桌面无法生成、删除、更新快捷方式
    —> 呵呵,一般来说生成没有问题,但是删除,更新大部分桌面会有问题。尽可能避免这些操作。或者专门适配该桌面,成本较高。
  • 【部分】部分桌面无法实时更新图标,需要重启
    —> 无解,尝试过重启Launcher,但是结果是之前的快捷方式也消失了。只有重启手机,按理来说应该是有方式触发Launcher进行刷新的。
    以上【所有】【部分】,分别表示必定出现,部分出现。

参考

  1. http://grepcode.com/search/?query=InstallShortcutReceiver
  2. http://developer.android.com/index.html

附录

  1. 完整代码可参考https://gist.github.com/waylife/437a3d98a84f245b9582
  2. 通用更新快捷方式权限列表

[html] view plain copy

  1. <uses-permission android:name="com.android.launcher.permission.READ_SETTINGS" />
  2. <uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS" />
  3. <uses-permission android:name="com.android.launcher2.permission.READ_SETTINGS" />
  4. <uses-permission android:name="com.android.launcher2.permission.WRITE_SETTINGS" />
  5. <uses-permission android:name="com.android.launcher3.permission.READ_SETTINGS" />
  6. <uses-permission android:name="com.android.launcher3.permission.WRITE_SETTINGS" />
  7. <uses-permission android:name="org.adw.launcher.permission.READ_SETTINGS" />
  8. <uses-permission android:name="org.adw.launcher.permission.WRITE_SETTINGS" />
  9. <uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" />
  10. <uses-permission android:name="com.htc.launcher.permission.WRITE_SETTINGS" />
  11. <uses-permission android:name="com.qihoo360.launcher.permission.READ_SETTINGS" />
  12. <uses-permission android:name="com.qihoo360.launcher.permission.WRITE_SETTINGS" />
  13. <uses-permission android:name="com.lge.launcher.permission.READ_SETTINGS" />
  14. <uses-permission android:name="com.lge.launcher.permission.WRITE_SETTINGS" />
  15. <uses-permission android:name="net.qihoo.launcher.permission.READ_SETTINGS" />
  16. <uses-permission android:name="net.qihoo.launcher.permission.WRITE_SETTINGS" />
  17. <uses-permission android:name="org.adwfreak.launcher.permission.READ_SETTINGS" />
  18. <uses-permission android:name="org.adwfreak.launcher.permission.WRITE_SETTINGS" />
  19. <uses-permission android:name="org.adw.launcher_donut.permission.READ_SETTINGS" />
  20. <uses-permission android:name="org.adw.launcher_donut.permission.WRITE_SETTINGS" />
  21. <uses-permission android:name="com.huawei.launcher3.permission.READ_SETTINGS" />
  22. <uses-permission android:name="com.huawei.launcher3.permission.WRITE_SETTINGS" />
  23. <uses-permission android:name="com.fede.launcher.permission.READ_SETTINGS" />
  24. <uses-permission android:name="com.fede.launcher.permission.WRITE_SETTINGS" />
  25. <uses-permission android:name="com.sec.android.app.twlauncher.settings.READ_SETTINGS" />
  26. <uses-permission android:name="com.sec.android.app.twlauncher.settings.WRITE_SETTINGS" />
  27. <uses-permission android:name="com.anddoes.launcher.permission.READ_SETTINGS" />
  28. <uses-permission android:name="com.anddoes.launcher.permission.WRITE_SETTINGS" />
  29. <uses-permission android:name="com.tencent.qqlauncher.permission.READ_SETTINGS" />
  30. <uses-permission android:name="com.tencent.qqlauncher.permission.WRITE_SETTINGS" />
  31. <uses-permission android:name="com.huawei.launcher2.permission.READ_SETTINGS" />
  32. <uses-permission android:name="com.huawei.launcher2.permission.WRITE_SETTINGS" />
  33. <uses-permission android:name="com.android.mylauncher.permission.READ_SETTINGS" />
  34. <uses-permission android:name="com.android.mylauncher.permission.WRITE_SETTINGS" />
  35. <uses-permission android:name="com.ebproductions.android.launcher.permission.READ_SETTINGS" />
  36. <uses-permission android:name="com.ebproductions.android.launcher.permission.WRITE_SETTINGS" />
  37. <uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS" />
  38. <uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS" />
  39. <uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS" />
  40. <uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS" />
  41. <uses-permission android:name="telecom.mdesk.permission.READ_SETTINGS" />
  42. <uses-permission android:name="telecom.mdesk.permission.WRITE_SETTINGS" />
  43. <uses-permission android:name="dianxin.permission.ACCESS_LAUNCHER_DATA" />
import java.util.List;

import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.database.Cursor;
import android.net.Uri;
import android.text.TextUtils;
import android.util.Log;

public class launcherUtil {

    private static String AUTHORITY = null;

    public static boolean isShortCutExist(Context context, String title) {

        boolean isInstallShortcut = false;

        if (null == context || TextUtils.isEmpty(title))
            return isInstallShortcut;

        if (TextUtils.isEmpty(AUTHORITY))
            AUTHORITY = getAuthorityFromPermission(context);

        final ContentResolver cr = context.getContentResolver();

        if (!TextUtils.isEmpty(AUTHORITY)) {
            try {
                final Uri CONTENT_URI = Uri.parse(AUTHORITY);

                Cursor c = cr.query(CONTENT_URI, new String[] { "title",
                        "iconResource" }, "title=?", new String[] { title },
                        null);

                // XXX表示应用名称。
                if (c != null && c.getCount() > 0) {
                    isInstallShortcut = true;
                }
                if (null != c && !c.isClosed())
                    c.close();
            } catch (Exception e) {
                // TODO: handle exception
                Log.e("isShortCutExist", e.getMessage());
            }

        }
        return isInstallShortcut;

    }

    public static String getCurrentLauncherPackageName(Context context) {

        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        ResolveInfo res = context.getPackageManager()
                .resolveActivity(intent, 0);
        if (res == null || res.activityInfo == null) {
            // should not happen. A home is always installed, isn‘t it?
            return "";
        }
        if (res.activityInfo.packageName.equals("android")) {
            return "";
        } else {
            return res.activityInfo.packageName;
        }
    }

    public static String getAuthorityFromPermissionDefault(Context context) {

        return getThirdAuthorityFromPermission(context,
                "com.android.launcher.permission.READ_SETTINGS");
    }

    public static String getThirdAuthorityFromPermission(Context context,
            String permission) {
        if (TextUtils.isEmpty(permission)) {
            return "";
        }

        try {
            List packs = context.getPackageManager()
                    .getInstalledPackages(PackageManager.GET_PROVIDERS);
            if (packs == null) {
                return "";
            }
            for (PackageInfo pack : packs) {
                ProviderInfo[] providers = pack.providers;
                if (providers != null) {
                    for (ProviderInfo provider : providers) {
                        if (permission.equals(provider.readPermission)
                                || permission.equals(provider.writePermission)) {
                            if (!TextUtils.isEmpty(provider.authority)// 精准匹配launcher.settings,再一次验证
                                    && (provider.authority)
                                            .contains(".launcher.settings"))
                                return provider.authority;
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static String getAuthorityFromPermission(Context context) {
        // 获取默认
        String authority = getAuthorityFromPermissionDefault(context);
        // 获取特殊第三方
        if (authority == null || authority.trim().equals("")) {
            String packageName = getCurrentLauncherPackageName(context);
            packageName += ".permission.READ_SETTINGS";
            authority = getThirdAuthorityFromPermission(context, packageName);
        }
        // 还是获取不到,直接写死
        if (TextUtils.isEmpty(authority)) {
            int sdkInt = android.os.Build.VERSION.SDK_INT;
            if (sdkInt < 8) { // Android 2.1.x(API 7)以及以下的
                authority = "com.android.launcher.settings";
            } else if (sdkInt < 19) {// Android 4.4以下
                authority = "com.android.launcher2.settings";
            } else {// 4.4以及以上
                authority = "com.android.launcher3.settings";
            }
        }
        authority = "content://" + authority + "/favorites?notify=true";
        return authority;

    }
}
时间: 2024-10-24 11:26:44

桌面快捷方式的问题-创建-删除-判断的相关文章

快捷方式 创建 删除 判断

MainActivity public class MainActivity extends ListActivity {     /**安装包所在路径*/     private String path = Environment.getExternalStorageDirectory().getAbsolutePath();     /**安装包的文件名*/     private String fileName = "bqt.apk";     private boolean i

QQ是怎样实现好友桌面快捷方式的?

QQ是怎样实现好友桌面快捷方式的? 不知道什么时候,QQ推出了好友桌面快捷方式.方便用户和最常保持联系的好友一键联系.核心功能一:若QQ启动了.则双击快捷方式直接打开好友聊天界面:核心功能二:若QQ未启动,则双击快捷方式后启动QQ后打开好友聊天界面. 但其是怎样实现的呢?让我们一起挖一挖. 一.QQ好友桌面快捷方式操作演示        直接上图,非常明了,只是多解释. 二.QQ好友桌面快捷方式的Windows实现 上图是桌面好友快捷方式的几个关键属性.解析例如以下: 1).目标--关联的进程.

Android桌面快捷方式

Android创建桌面的快捷方式 概述 :创建桌面快捷方式相当与创建一个程序的入口,就像我们程序在安装完毕后会自动创建一个图标到桌面.其实创建桌面快捷方式跟创建一个程序入口差不多,但是像QQ会话一样创建一个QQ好友的会话快捷方式,就得动态的创建图标,名字了. 1.首先权限是必不可少的 <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" /> 2.然后就是在你项目配置

Android应用添加(创建)和删除及判断是否存在桌面快捷方式

Android应用添加(创建)和删除及判断是否存在桌面快捷方式-Android新手入门-eoe 移动开发者论坛 - Powered by Discuz! Android桌面程序提供了应用添加和删除桌面快捷方式的功能以及判断快捷方式是否存在, 只要传入快捷方式标题.图标及点击快捷方式执行的应用Intent即可.代码如下: 1.Android添加桌面快捷方式 /** * 为当前应用添加桌面快捷方式 * * @param cx * @param appName *            快捷方式名称

Android创建和删除桌面快捷方式

有同学方反馈创建快捷方式后,点击快捷方式后不能启动程序或者提示"未安装程序",貌似是新的rom在快捷方式这块做过修改(由于此文是11年5月所出,估计应该是2.0或2.1的rom),现已修正,HTC G11 2.3.5rom测试通过. 1,判断是否已经创建了快捷方式(在某些机型中需要判断) 1 2 3 4 5 6 7 8 9 10 11 12 13 private boolean hasShortcut() {         boolean isInstallShortcut = fa

Android 添加、移除和判断 桌面快捷方式图标

思路: Launcher为了应用程序能够定制自己的快捷图标,就注册了一个 BroadcastReceiver 专门接收其他应用程序发来的快捷图标定制信息.所以只需要根据该 BroadcastReceiver 构造出相对应的Intent并装入我们的定制信息,最后调用 sendBroadcast 方法就可以创建一个快捷图标了. 步骤: 创建快捷方式必须要有权限: 创建快捷方式的广播的 Intent 的 action 设置 com.android.launcher.action.INSTALL_SHO

java实现软件程序开机自动启动和创建程序的桌面快捷方式源代码

一.java实现.exe程序的开机自动启动 1.描述 自己在eclipse编写的java项目用exe4j Wizard打包成一个.exe可执行文件,并让用户可以开机自动启动. 2.步骤 1.   获得本软件中.exe可执行文件的路径 2.   在Windows系统中的开机启动栏存放该.exe可执行文件的快捷方式,即可实现开机自动启动. 3.代码 private void startFolderMethod() { String path = System.getProperty("user.di

WPF 创建桌面快捷方式

#region 创建桌面快捷方式 string deskTop = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Desktop); string dirPath = System.Environment.CurrentDirectory; string exePath = Assembly.GetExecutingAssembly().Location; System.Diagnostics.FileVers

cxfreeze打包python程序的方法说明(生成安装包,实现桌面快捷方式、删除快捷方式)

一.cxfreeze基础 1.cxfreeze功能 python代码文件转exe方法有三种,分别是cx_freeze,py2exe,PyInstaller,这三种方式各有千秋,本人只用过py2exe和cxfreeze,这里重点说明cxfreeze. 2.安装包下载地址 https://sourceforge.net/projects/cx-freeze/files/ 3.cxfree的官方说明文档 http://cx-freeze.readthedocs.io/en/latest/distuti