这几天,项目中有个新需求,需要按照模块添加不同的快捷方式到桌面上,从而方便用户的使用。特意进行了研究并分析了下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,删除主应用的快捷方式,添加这个界面的快捷方式。
于是一个骚当的快捷方式实现了。