android 多个shortCut快捷方式实现以及对58同城快捷方式的实现思路的研究

简介: 这几天,项目中有个新需求,需要按照模块添加不同的快捷方式到桌面上,从而方便用户的使用。特意进行了研究并分析了下58上面桌面快捷方式的实现。 首先多个shortcut的实现: ...

这几天,项目中有个新需求,需要按照模块添加不同的快捷方式到桌面上,从而方便用户的使用。特意进行了研究并分析了下58上面桌面快捷方式的实现。

首先多个shortcut的实现:

<activity
            android:name="com.soyoungboy.android.demo.MainActivity"
            android:configChanges="keyboardHidden|orientation"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
        <!-- 瀑布流 -->
        <activity
            android:name="com.soyoungboy.android.demo.pinterest.PinterestActivity"
            android:icon="@drawable/sinkingview_charming"
            android:launchMode="singleInstance"
            android:process=":process.sub"
            android:theme="@android:style/Theme.Light.NoTitleBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>

重点是这里:

 android:icon="@drawable/sinkingview_charming"
  android:launchMode="singleInstance" -->必须这么写
  android:process=":process.sub"--->指定新的进程给对应的activity

<intent-filter>
 <action android:name="android.intent.action.MAIN" />
 </intent-filter>

也可指定android:icon来对应这个Activity对应的快捷方式图标。

如果有<category android:name="android.intent.category.LAUNCHER" />  ,那么快捷方式将在启动时创建,也可不设置这行,通过代码去实现。

ShortCutUtils.java

import java.util.List;

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


public class ShortCutUtils {

    /**
     * 快捷方式添加的action
     */
    private final static String SHORTCUT_ADD_ACTION = "com.android.launcher.action.INSTALL_SHORTCUT";
    /**
     * 快捷方式删除的action
     */
    private final static String SHORTCUT_DEL_ACTION = "com.android.launcher.action.UNINSTALL_SHORTCUT";
    /**
     * 读取数据库需要的权限
     */
    private final static String READ_SETTINGS_PERMISSION = "com.android.launcher.permission.READ_SETTINGS";

    /**
     * 添加快捷方式到桌面,添加快捷方式需要添加用户权限 <uses-permission
     * android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
     * 
     * <br>
     * <b> 当应用内部需要多个快捷方式时 :</b><br>
     * android:taskAffinity="" <br>
     * action android:name="android.intent.action.MAIN"<br>
     * android:launchMode="singleTask"
     * 
     * @param context
     * @param className
     * @param resourceId 快捷方式的图标
     * @param appName 快捷方式的名字
     * @param extra
     */

    public static void addShortCut(Context context, String className,
            int resourceId, String appName, String extra) {
        Intent shortCutIntent = new Intent(SHORTCUT_ADD_ACTION);

        try {
            if (appName == null) {
                // 获取当前应用名称
                appName = obtatinAppName(context);
            }
        } catch (NameNotFoundException e) {
            Log.e("ShortCutUtils==>addShortCut",
                    "NameNotFoundException :" + e.toString());
        }
        // 添加快捷方式的名字
        shortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, appName);
        // 不允许重复添加
        shortCutIntent.putExtra("duplicate", false);
        if (className == null) {
            className = context.getClass().getName();
        }
        // 在里面的intent添加参数
        shortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,
                new Intent().setClassName(context.getPackageName(), className)
                        .putExtra("ShortCutExtra", extra));
        // 添加快捷方式的图标
        ShortcutIconResource iconRes = Intent.ShortcutIconResource.fromContext(
                context, resourceId);
        shortCutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconRes);
        context.sendBroadcast(shortCutIntent);
    }

    /**
     * 删除桌面上的快捷方式,需要添加权限 <uses-permission
     * android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
     * 
     * @param context
     * @param className
     * @param appName
     */
    public static void delShortcut(Context context, String className,
            String appName) {
        Intent shortcut = new Intent(SHORTCUT_DEL_ACTION);
        try {
            if (appName == null) {
                // 获取当前应用名称
                appName = obtatinAppName(context);
            }
        } catch (NameNotFoundException e) {
            Log.e("ShortCutUtils==>delShortcut",
                    "NameNotFoundException :" + e.toString());
        }
        // 快捷方式名称
        shortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, appName);
        if (className == null) {
            className = context.getClass().getName();
        }
        shortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(
                Intent.ACTION_MAIN).addCategory(Intent.CATEGORY_LAUNCHER)
                .setClassName(context.getPackageName(), className));
        context.sendBroadcast(shortcut);
    }

    /**
     * 判断桌面上是否有快捷方式,调用此方法需要添加权限 <uses-permission
     * android:name="com.android.launcher.permission.READ_SETTINGS" />
     * 
     * @param context
     * @return
     * @throws NameNotFoundException
     */
    public static boolean hasShortcut(Context context, String appName) {
        String AUTHORITY = getAuthorityFromPermission(context,
                READ_SETTINGS_PERMISSION);

        if (AUTHORITY == null) {
            return false;
        }
        Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY
                + "/favorites?notify=true");
        try {
            if (appName == null) {
                // 获取当前应用名称
                appName = obtatinAppName(context);
            }
        } catch (NameNotFoundException e) {
            Log.e("ShortCutUtils==>hasShortcut",
                    "NameNotFoundException :" + e.toString());
        }
        Cursor c = context.getContentResolver().query(CONTENT_URI,
                new String[] { "title" }, "title=?", new String[] { appName },
                null);
        if (c != null && c.getCount() > 0) {
            return true;
        }
        return false;
    }

    /**
     * android系统桌面的基本信息由一个launcher.db的Sqlite数据库管理,里面有三张表
     * 其中一张表就是favorites。这个db文件一般放在data
     * /data/com.android.launcher(launcher2)文件的databases下 但是对于不同的rom会放在不同的地方
     * 例如MIUI放在data/data/com.miui.home/databases下面
     * htc放在data/data/com.htc.launcher/databases下面
     * 
     * @param context
     * @param permission
     *            读取设置的权限 READ_SETTINGS_PERMISSION
     * @return
     */
    private static String getAuthorityFromPermission(Context context,
            String permission) {
        if (TextUtils.isEmpty(permission)) {
            return null;
        }
        List<PackageInfo> packs = context.getPackageManager()
                .getInstalledPackages(PackageManager.GET_PROVIDERS);
        if (packs == null) {
            return null;
        }
        for (PackageInfo pack : packs) {
            ProviderInfo[] providers = pack.providers;
            if (providers != null) {
                for (ProviderInfo provider : providers) {
                    if (permission.equals(provider.readPermission)
                            || permission.equals(provider.writePermission)) {
                        return provider.authority;
                    }
                }
            }
        }
        return null;
    }

    /**
     * 获取应用的名称
     * 
     * @param context
     * @return
     * @throws NameNotFoundException
     */
    private static String obtatinAppName(Context context)
            throws NameNotFoundException {
        PackageManager packageManager = context.getPackageManager();
        return packageManager.getApplicationLabel(
                packageManager.getApplicationInfo(context.getPackageName(),
                        PackageManager.GET_META_DATA)).toString();
    }
}

Activity中创建快捷方式:
这是Activity oncreate()里面的代码:

if (!ShortCutUtils.hasShortcut(getApplicationContext(), "瀑布流")) {
            ShortCutUtils.addShortCut(getApplicationContext(),
                    "com.soyoungboy.android.demo.pinterest.PinterestActivity2",
                    R.drawable.sinkingview_charming, "瀑布流", "PinterestActivity2");
        }


这样就会针对这个Activity创建快捷方式,如果点击启动我们设置在ShortCutIntent中对应的Activity的界面。从而实现多icon,多个执行入口的功能。


然后我们分析下58同城骚当的快捷方式,当然在没看到内部实现远离之前,我是这么认为的。

首先看下界面:

点击后:

后续就是进入对应模块界面了,我就不截图了。

然后反编译下代码,看下怎么实现的。

配置文件里面有如下内容:

  <activity android:theme="@style/DialogActivity" android:name="com.wuba.plugins.ThirdFolderActivity" android:taskAffinity="com.wuba.affinity_third_folder" android:screenOrientation="portrait" android:configChanges="locale|keyboardHidden">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />
                <action android:name="android.intent.action.MAIN" />
            </intent-filter>
        </activity>

然后分析LauchActivity的java文件:

<activity android:label="@string/app_name" android:name="com.wuba.activity.launch.LaunchActivity" android:screenOrientation="portrait" android:configChanges="locale|keyboardHidden">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

由上面看出是程序入口:
LauchActivity反编译后的代码片段:

package com.wuba.activity.launch;

import android.app.Activity;
import android.app.Dialog;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.text.TextUtils;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewStub;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import com.networkbench.agent.impl.NBSAppAgent;
import com.wuba.actionlog.ActionLogObservService;
import com.wuba.actionlog.OpenClientIntentService;
import com.wuba.activity.home.a.c.a;
import com.wuba.activity.recruit.RecruitCateActivity;
import com.wuba.activity.webactivity.CategoryListActivity;
import com.wuba.activity.webactivity.GroupBuyHomeActivity;
import com.wuba.android.lib.util.commons.f;
import com.wuba.android.lib.util.commons.h;
import com.wuba.android.lib.util.commons.j;
import com.wuba.android.lib.util.commons.k;
import com.wuba.android.lib.util.commons.m;
import com.wuba.application.WubaHybridApplication;
import com.wuba.f.a.a;
import com.wuba.f.a.g;
import com.wuba.f.a.i;
import com.wuba.f.a.l;
import com.wuba.fragment.InfoListFragmentActivity;
import com.wuba.frame.parse.beans.au;
import com.wuba.frame.parse.beans.au.a;
import com.wuba.home.HomeActivity;
import com.wuba.model.bw;
import com.wuba.plugins.weather.WeatherDetailActivity;
import com.wuba.utils.at;
import com.wuba.utils.bc;
import com.wuba.utils.bf;
import com.wuba.utils.r;
import com.wuba.views.bm;
import com.wuba.views.bm.a;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class LaunchActivity extends com.wuba.activity.a
{
  public static boolean g;
  private static final String h = h.a(LaunchActivity.class);
  boolean b = false;
  public ImageView c;
  public TextView d;
  public boolean e = true;
  public boolean f;
  private Thread i;
  private Bitmap j;
  private String k;
  private Handler l = new a(this);
  private Runnable m = new c(this);

  static
  {
    g = false;
  }

  private void c()
  {
    if ((this.j != null) && (!this.j.isRecycled()))
    {
      this.j.recycle();
      this.j = null;
    }
  }

  private static String d(String paramString)
  {
    if ((!TextUtils.isEmpty(paramString)) && (paramString.startsWith("<font")))
      try
      {
        Matcher localMatcher = Pattern.compile("size=\\d+").matcher(paramString);
        if (localMatcher.find())
        {
          String str1 = localMatcher.group();
          String str2 = str1.substring(1 + str1.indexOf("="));
          return str2;
        }
      }
      catch (Exception localException)
      {
        return "24";
      }
    return "24";
  }

  private void d()
  {
    String str1;
    if (!this.b)
    {
      this.b = true;
      if (bf.c(this) == 1)
      {
        str1 = bf.b(this);
        if (!TextUtils.isEmpty(str1))
          bf.n(this, "");
      }
    }
    try
    {
      float f1 = bc.b(str1);
      if (f1 < 4900.0F)
        com.wuba.c.a.a(getContentResolver(), false);
      if (f1 == 4700.0F)
      {
        SharedPreferences localSharedPreferences = getSharedPreferences("com.wuba_other_file", 0);
        str2 = localSharedPreferences.getString("MD5PWD", "");
        str3 = localSharedPreferences.getString("USERNAME", "");
        str4 = localSharedPreferences.getString("USERID", "");
        new StringBuilder("userName:").append(str3).append(",md5pwd:").append(str2);
        localbw = bw.a(this);
      }
    }
    catch (Exception localException1)
    {
      try
      {
        String str2;
        String str3;
        String str4;
        bw localbw;
        localbw.b = new f().b(new String(com.wuba.android.lib.util.commons.b.a("Mm1oc2ktMXNzM0A9c21AI3NqPTQ4KnNqdzAyamg=".toCharArray())), str2);
        label180: localbw.c = str4;
        localbw.a = str3;
        localbw.d();
        while (true)
        {
          this.i = new Thread(new com.wuba.j.c(this));
          this.i.start();
          bw.a(this).f();
          return;
          localException1 = localException1;
          localException1.getMessage();
        }
      }
      catch (Exception localException2)
      {
        break label180;
      }
    }
  }

  public final void a()
  {
    g = true;
    Intent localIntent1 = getIntent();
    Bundle localBundle = localIntent1.getExtras();
    boolean bool;
    String str7;
    String str8;
    String str9;
    Intent localIntent6;
    if (localBundle == null)
    {
      bool = false;
      if (!bool)
        break label245;
      if (!bf.bb(this))
        bf.bc(this);
      String str6 = localBundle.getString("jump_protocol");
      str7 = localBundle.getString("pre_key_third_folder_city_id");
      str8 = localBundle.getString("pre_key_third_folder_city_dir");
      str9 = localBundle.getString("pre_key_third_folder_city_name");
      if (TextUtils.isEmpty(str6))
        break label184;
      localIntent6 = com.wuba.trade.api.b.c.b(this, str6);
      if (localIntent6 != null)
        break label148;
      localIntent6 = new Intent();
      localIntent6.setClass(this, HomeActivity.class);
      label111: localIntent6.putExtra("third_folder_shortcut_intent", true);
      startActivity(localIntent6);
      finish();
    }
    label148: label184: label245: for (int n = 1; ; n = 0)
    {
      if (n == 0)
        break label251;
      return;
      bool = at.b(localBundle);
      break;
      localIntent6.putExtra("pre_key_third_folder_city_id", str7);
      localIntent6.putExtra("pre_key_third_folder_city_dir", str8);
      localIntent6.putExtra("pre_key_third_folder_city_name", str9);
      break label111;
      String str10 = localBundle.getString("third_folder_class_name");
      Intent localIntent5 = new Intent();
      if (!TextUtils.isEmpty(str10))
        localIntent5.setClassName(this, str10);
      while (true)
      {
        startActivity(localIntent5);
        finish();
        break;
        localIntent5.setClass(this, HomeActivity.class);
      }
    }
    label251: String str1 = localIntent1.getStringExtra("random_num");
    if ((localIntent1.getBooleanExtra("is_notify_distribute", false)) && (!bf.a(this, str1)))
    {
      startActivity((Intent)localIntent1.getParcelableExtra("intent"));
      finish();
      overridePendingTransition(a.a.slide_in_right, a.a.slide_out_right);
      return;
    }
    if ((localBundle != null) && (at.c(localBundle)))
    {
      String str2 = localBundle.getString("shortcut_protocol");
      if (!TextUtils.isEmpty(str2))
      {
        Intent localIntent4 = com.wuba.trade.api.b.c.b(this, str2);
        localIntent4.addFlags(335544320);
        startActivity(localIntent4);
        finish();
        overridePendingTransition(a.a.slide_in_right, a.a.slide_out_right);
        return;
      }
      Intent localIntent3 = new Intent();
      String str3 = localIntent1.getStringExtra("shortcut_intent_class");
      String str4;
      au localau;
      if ("CategoryListActivity".equals(str3))
      {
        str3 = CategoryListActivity.class.getCanonicalName();
        localIntent3.setClassName(this, str3);

        str4 = localBundle.getString("shortcut_title");
        if ((!localBundle.containsKey("intent_data_tag_string")) || (TextUtils.isEmpty(localBundle.getString("intent_data_tag_string"))))
          break label630;
        localau = at.a(localBundle);
        if (localau != null)
          break label551;
        localIntent3.setClass(this, HomeActivity.class);
      }
      while (true)
      {
        finish();
        overridePendingTransition(0, 0);
        return;
        if ("GroupBuyHomeActivity".equals(str3))
        {
          str3 = GroupBuyHomeActivity.class.getCanonicalName();
          break;
        }
        if ("InfoListActivityGroup".equals(str3))
        {
          str3 = InfoListFragmentActivity.class.getCanonicalName();
          break;
        }
        if (!"RecruitCateActivity".equals(str3))
          break;
        str3 = RecruitCateActivity.class.getCanonicalName();
        break;
        label551: localau.q = au.a.e;
        if (!TextUtils.isEmpty(str4))
          localau.e = str4;
        String str5 = localBundle.getString("cate_id");
        localIntent3.putExtra("list_name", localBundle.getString("list_name"));
        localIntent3.putExtra("cate_id", str5);
        localIntent3.putExtra("jump_bean", localau);
        startActivity(localIntent3);
      }
      label630: if (WeatherDetailActivity.class.getCanonicalName().equals(str3))
      {
        localIntent3.setClass(this, WeatherDetailActivity.class);
        localBundle.putBoolean("shortcut_intent", true);
      }
      while (true)
      {
        localIntent3.putExtras(localBundle);
        startActivity(localIntent3);
        break;
        if (!RecruitCateActivity.class.getCanonicalName().equals(str3))
        {
          localIntent3.setClass(this, HomeActivity.class);
          continue;
        }
        if (TextUtils.isEmpty(str4))
          continue;
        localBundle.putString("shortcut_title", str4);
      }
    }
    Intent localIntent2 = new Intent();
    if ((!j.b(getApplicationContext(), "has_used_app")) || (bf.L(this)))
    {
      j.b(getApplicationContext(), "has_used_app", true);
      j.b(getApplicationContext(), "from_launch", true);
      localIntent2.setClass(this, LeadingActivity.class);
    }
    while (true)
    {
      startActivity(localIntent2);
      finish();
      overridePendingTransition(0, 0);
      return;
      j.l(getApplicationContext(), "from_launch");
      localIntent2.setClass(this, HomeActivity.class);
    }
  }

  protected void onActivityResult(int paramInt1, int paramInt2, Intent paramIntent)
  {
    if (paramInt1 == 100)
      d();
  }

  public void onBackPressed()
  {
  }

  protected void onCreate(Bundle paramBundle)
  {
    String str1 = com.wuba.android.lib.util.commons.e.b + "/shared_prefs/com.wuba.xml";
    String str2 = com.wuba.android.lib.util.commons.e.b + "/shared_prefs/com.wuba_new_v5.xml";
    File localFile1 = new File(str1);
    File localFile2 = new File(str2);
    if ((localFile1.exists()) && (!localFile2.exists()));
    while (true)
    {
      String str6;
      String str7;
      try
      {
        com.wuba.android.lib.util.c.b.a(localFile1, localFile2);
        Iterator localIterator = com.wuba.databaseprovider.c.f(getContentResolver()).entrySet().iterator();
        if (!localIterator.hasNext())
          continue;
        Map.Entry localEntry = (Map.Entry)localIterator.next();
        str6 = (String)localEntry.getKey();
        str7 = (String)localEntry.getValue();
        if (!str6.equals("ISLOGIN"))
          break label366;
        if (!"true".equals(str7))
          break label360;
        bool2 = true;
        j.b(this, str6, bool2);
        new StringBuilder("Key=").append((String)localEntry.getKey()).append("---->value=").append((String)localEntry.getValue());
        continue;
      }
      catch (IOException localIOException)
      {
        localIOException.getMessage();
        bf.a(this, getSharedPreferences("wuba_main", 0).getString("versionName", ""));
      }
      super.onCreate(paramBundle);
      if ((com.wuba.j.i.b(getApplicationContext()) != 1) && (!WubaHybridApplication.a))
        break;
      bm.a locala1 = new bm.a(this);
      bm.a locala2 = locala1.a("提示");
      locala2.a = "系统出了点小问题,请重新启动应用";
      locala2.c = new e(this);
      locala2.a("确定", new d(this));
      bm localbm = locala1.a();
      localbm.setCanceledOnTouchOutside(false);
      localbm.show();
      return;
      label360: boolean bool2 = false;
      continue;
      label366: if (str6.equals("ISAUTOLOGIN"))
      {
        if (TextUtils.isEmpty(str7));
        for (int n = 0; ; n = Integer.valueOf(str7).intValue())
        {
          j.b(this, str6, n);
          break;
        }
      }
      j.b(this, str6, str7);
    }
    NBSAppAgent.setLicenseKey("11b451575622485ea9a046de024fa83d").withCrashReportEnabled(false).withLocationServiceEnabled(true).start(this);
    if ((getIntent() != null) && (getIntent().getBooleanExtra("launcht_activity_theme", false)))
      setTheme(a.l.Theme_Launch_NORMAL);
    while (true)
    {
      WubaHybridApplication localWubaHybridApplication = (WubaHybridApplication)getApplication();
      String str3 = bf.a(localWubaHybridApplication);
      label533: Intent localIntent3;
      label633: String str4;
      String str5;
      if (com.wuba.android.lib.util.commons.e.c.equals(str3))
      {
        bf.e(localWubaHybridApplication, false);
        new StringBuilder("WubaPersistentUtils.versionIsUpdate(this)=").append(bf.L(localWubaHybridApplication));
        bf.a(localWubaHybridApplication, 0);
        localWubaHybridApplication.a(false);
        Context localContext = getApplicationContext();
        String[] arrayOfString = new String[1];
        arrayOfString[0] = bf.W(getApplicationContext());
        com.wuba.utils.a.a(localContext, "main", "loading", arrayOfString);
        new ActionLogObservService();
        ActionLogObservService.a(this, 25);
        localIntent3 = getIntent();
        if (localIntent3.getBooleanExtra("shortcut_intent", false))
        {
          if (!localIntent3.getBooleanExtra("weather_shortcut_intent", false))
            break label1122;
          com.wuba.utils.a.a(this, "start", "desktopicon", new String[] { "weather" });
        }
        com.wuba.utils.a.a(this, "start", "connect", new String[0]);
        if (!TextUtils.isEmpty(bf.q(this)))
          bf.m(this, "");
        bw.a(this);
        ((WubaHybridApplication)getApplication()).d();
        setContentView(a.i.launch);
        getFilesDir().getAbsolutePath();
        str4 = getFilesDir() + File.separator + "loadingImg";
        if (!new File(str4 + File.separator + "loading_img.jpg").exists())
          break label1153;
        str5 = str4 + File.separator + "loading_img.jpg";
        label793: this.k = str5;
        if (!TextUtils.isEmpty(this.k))
          break label1231;
        bf.g(this, "0", "0");
        this.e = false;
        ((ViewStub)findViewById(a.g.launch_native_stub)).inflate();
        label838: com.wuba.utils.q.e = true;
      }
      try
      {
        boolean bool1 = "mounted".equals(Environment.getExternalStorageState());
        if (bool1);
        while (true)
        {
          r.a(this);
          if (!com.wuba.android.lib.util.d.i.e(this))
            break label1288;
          OpenClientIntentService.a(this, "launcher");
          new c.a(com.wuba.activity.home.a.c.a(this), 0).start();
          return;
          setTheme(a.l.Theme_Launch);
          break;
          if (k.a(str3))
          {
            bf.a(localWubaHybridApplication, com.wuba.android.lib.util.commons.e.c);
            bf.e(localWubaHybridApplication, true);
            bf.a(localWubaHybridApplication, null, null, null);
            bf.a(localWubaHybridApplication, 1);
            bf.a(localWubaHybridApplication, false);
            localWubaHybridApplication.a(true);
            break label533;
          }
          if (!bc.a(str3, com.wuba.android.lib.util.commons.e.c))
            break label533;
          if (bc.a(str3))
          {
            Intent localIntent1 = new Intent("com.android.launcher.action.UNINSTALL_SHORTCUT");
            Intent localIntent2 = new Intent();
            localIntent2.setAction("android.intent.action.MAIN");
            localIntent2.addCategory("android.intent.category.LAUNCHER");
            localIntent2.setComponent(new ComponentName(localWubaHybridApplication.getApplicationContext().getPackageName(), "com.wuba.activity.main.LaunchActivity"));
            localIntent1.putExtra("android.intent.extra.shortcut.INTENT", localIntent2);
            localWubaHybridApplication.sendBroadcast(localIntent1);
            bf.z(localWubaHybridApplication, "");
            bf.a(localWubaHybridApplication, null, null, null);
          }
          bf.b(localWubaHybridApplication, str3);
          bf.m(localWubaHybridApplication, str3);
          bf.Q(localWubaHybridApplication);
          bf.a(localWubaHybridApplication, com.wuba.android.lib.util.commons.e.c);
          bf.e(localWubaHybridApplication, true);
          bf.a(localWubaHybridApplication, false);
          bf.a(localWubaHybridApplication, 1);
          localWubaHybridApplication.a(true);
          break label533;
          label1122: com.wuba.utils.a.a(this, "start", "desktopicon", new String[] { localIntent3.getExtras().getString("list_name") });
          break label633;
          label1153: if (new File(str4 + File.separator + "loading_img.png").exists())
          {
            str5 = str4 + File.separator + "loading_img.png";
            break label793;
          }
          str5 = null;
          break label793;
          label1231: this.e = true;
          m.a().a(this.m);
          break label838;
          if (com.wuba.android.lib.util.c.b.a(getFilesDir()) > 500L)
            continue;
          Toast.makeText(this, "没有闪存或SD卡,可能看不到图片", 1).show();
        }
      }
      catch (Exception localException)
      {
        while (true)
        {
          localException.getMessage();
          continue;
          label1288: OpenClientIntentService.a(this);
        }
      }
    }
  }

  public void onDestroy()
  {
    c();
    View localView = findViewById(a.g.launch_native_layout);
    if ((localView != null) && (localView.getParent() != null))
    {
      localView.setBackgroundColor(-1);
      ImageView localImageView = (ImageView)localView.findViewById(a.g.launch_native_logo);
      if (localImageView != null)
        localImageView.setImageBitmap(null);
      ((ViewGroup)localView.getParent()).removeView(localView);
    }
    super.onDestroy();
  }

  protected void onNewIntent(Intent paramIntent)
  {
    super.onNewIntent(paramIntent);
    bf.a(this, paramIntent.getStringExtra("random_num"));
  }

  protected void onResume()
  {
    super.onResume();
    d();
  }
}

可以看出红色粗体的那块代码就是卸载当前快捷方式的代码;那么快捷方式在那里创建的呢?那么那个半透明的界面是怎么出来的呢?

不急不急:

通过检索看到b.java文件:

package com.wuba.thirdapps;

import android.content.Context;
import android.content.Intent;
import android.content.Intent.ShortcutIconResource;
import android.content.res.Resources;
import android.os.Build;
import android.os.Build.VERSION;
import com.wuba.android.lib.util.commons.e;
import com.wuba.application.WubaHybridApplication;
import com.wuba.f.a.f;
import com.wuba.f.a.k;
import com.wuba.g.az;
import com.wuba.model.bo;
import com.wuba.utils.at;
import com.wuba.utils.ax;
import com.wuba.utils.bf;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.message.BasicNameValuePair;

final class b
  implements Runnable
{
  b(ThirdAppApplication paramThirdAppApplication, Context paramContext)
  {
  }

  public final void run()
  {
    try
    {
      com.wuba.a locala = ((WubaHybridApplication)(WubaHybridApplication)this.a.getApplicationContext()).c;
      BasicNameValuePair[] arrayOfBasicNameValuePair = new BasicNameValuePair[4];
      arrayOfBasicNameValuePair[0] = new BasicNameValuePair("ua", ax.d(Build.MANUFACTURER + "#" + Build.MODEL));
      arrayOfBasicNameValuePair[1] = new BasicNameValuePair("ver", ax.d(Build.VERSION.RELEASE));
      arrayOfBasicNameValuePair[2] = new BasicNameValuePair("sdkver", ax.d(Build.VERSION.SDK));
      arrayOfBasicNameValuePair[3] = new BasicNameValuePair("channelid", e.d);
      HttpGet localHttpGet = locala.b.a("http://platform.58.com/api/speedy", arrayOfBasicNameValuePair);
      bo localbo = (bo)locala.b.a(localHttpGet, new az());
      if ((localbo != null) && (localbo.a))
      {
        Context localContext = this.a;
        String str = localContext.getResources().getString(a.k.app_third_folder_name);
        if (!at.a(localContext.getApplicationContext(), str))
        {
          com.wuba.utils.a.a(localContext.getApplicationContext(), "main", "tools", new String[0]);
          Intent localIntent1 = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
          localIntent1.putExtra("android.intent.extra.shortcut.NAME", str);
          localIntent1.putExtra("duplicate", false);
          Intent localIntent2 = new Intent();
          localIntent2.setAction("android.intent.action.MAIN");
          localIntent2.setClassName(localContext, "com.wuba.plugins.ThirdFolderActivity");
          localIntent1.putExtra("android.intent.extra.shortcut.INTENT", localIntent2);
          localIntent1.putExtra("android.intent.extra.shortcut.ICON_RESOURCE", Intent.ShortcutIconResource.fromContext(localContext, a.f.wb_app_third_icon));
          localContext.sendBroadcast(localIntent1);
          new Thread(new com.wuba.utils.d(localContext, str)).start();
        }
      }
      bf.bc(this.a);
      return;
    }
    catch (Exception localException)
    {
    }
  }
}

创建快捷方式,点击快捷方式跳转到ThirdFolderActivity.java界面
由此可知快捷方式是ThirdFolderActivity界面创建的,并且确定点击快捷方式显示的Activity就是ThirdFolderActivity,通过wb_app_third_icon查看drawable下面的资源文件也确定这是58快捷方式的对应的界面。

 

那么就可知道58骚当入口的实现其实是这样子的:

1,ThirdFolderActivity界面就是点击快捷方式显示的那个半透明的显示7个模块图标的界面,当然跳转肯定是intent的拉。

2,界面半透明效果,style文件如下:

<style name="DialogActivity" parent="@android:style/Theme.Dialog">
        <item name="android:windowBackground">@*android:color/transparent</item>
        <item name="android:windowFrame">@null</item>
        <item name="android:windowNoTitle">true</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowAnimationStyle">@*android:style/Animation.Dialog</item>
    </style>

3,删除主应用的快捷方式,添加这个界面的快捷方式。

于是一个骚当的快捷方式实现了。

 

相关文章
|
7月前
|
Android开发
Android Launcher研究(二)-----------Launcher为何物,究竟是干什么
Android Launcher研究(二)-----------Launcher为何物,究竟是干什么
215 2
|
JSON JavaScript 前端开发
Android 缩减、混淆处理和优化应用研究(二)
Android 缩减、混淆处理和优化应用研究(二)
115 1
|
IDE Java 编译器
Android 缩减、混淆处理和优化应用研究(一)
Android 缩减、混淆处理和优化应用研究(一)
|
Android开发
flutter中实现仿Android端的onResume和onPause方法
flutter中实现仿Android端的onResume和onPause方法
|
7月前
|
Java Android开发
Android桌面快捷方式图标生成与删除 使用Intent与launcher交互
Android桌面快捷方式图标生成与删除 使用Intent与launcher交互
119 1
|
7月前
|
Linux 开发工具 Android开发
Android Launcher研究(一)-----------图文详解手把手教你在Windows环
Android Launcher研究(一)-----------图文详解手把手教你在Windows环
65 0
|
7月前
|
定位技术 API 数据库
基于Android的在线移动电子导航系统的研究与实现(论文+源码)_kaic
基于Android的在线移动电子导航系统的研究与实现(论文+源码)_kaic
|
Ubuntu Linux Android开发
Android研究系列(1)
最近下班之后的研究基本上都放在了安卓和ios的研究之上,从原先的小米2s各种刷机各种刷ram,到下载大型单机游戏侠盗飞车大三基本上把安卓玩了个遍。不过也是很长时间没有玩手机这一层了,最近和同事聊起来安卓和ios,感觉其实ios 更像linux或者说ubuntu(自己用的ubuntu最多),而安卓更像wiondows,就从数据垃圾处理这一层来说,卸载windows的应用C盘必然会留下相应的数据垃圾,这一点不就是安卓的弊病么,windows越用越卡,安卓何尝不是。最近在刷ios,了解ios的更多信息,同时也欢迎各位给出批评指正。这一期的文章总共分为图片不知道图片多少篇,看自己研究到什么时候,什么
|
XML API Android开发
Android长按图标展示快捷方式
这个特性,可以追溯到Android 7.1,也就是在7.1之后的系统,如果app支持,可以通过长按app图标展示一些快捷操作
186 0
|
缓存 JSON Java
java 实现读取txt文件,反射创建对象,android 手机缓存文件目录
java 实现读取txt文件,反射创建对象,android 手机缓存文件目录
450 1
java 实现读取txt文件,反射创建对象,android 手机缓存文件目录