From: http://blog.youkuaiyun.com/zircon_1973/article/details/7773254
首先要知道Launcher,就是主屏幕,它是Android系统启动后所加载的第一个程序,如下,主屏幕分成两部分,Workspace和Hotseats,而shortcut就是添加在workspace上的,这上面还可以添加诸如widget、文件夹等。这儿说的shortcut是指跳转到具体功能的快捷方式,而不是简单的程序的入口图标,APIDemos中有一个添加shortcut的例子,我们稍后分析它。
这儿以Android2.3的模拟器分析添加shortcut有关的源码,要添加shortcut,一般是摁menu键选择Add或长摁主屏幕,弹出菜单选择相应的shortcut,如下:
关于获取Android的源码和将源码导入到eclipse中,可以参看我前面的文章,首先找到Launcher的源码,在<源码目录>\packages\apps\Launcher2下。
1、从manifest文件中可以知道主屏幕就是Launcher.java这个activity,可以看下其布局文件,找到onOptionsItemSelected()方法,跟下去在onCreateDialog()方法中
- case DIALOG_CREATE_SHORTCUT:
- return new CreateShortcut().createDialog();
- builder.setAdapter(mAdapter, this);
在其adapter中,发现其每一列就是个textview,通过:
- textView.setCompoundDrawablesWithIntrinsicBounds(item.image, null, null, null);
- Intent pickIntent = new Intent(Intent.ACTION_PICK_ACTIVITY);
- ...
- startActivityForResult(pickIntent, REQUEST_PICK_SHORTCUT);
2、这个dialog样式的activity经常可以碰到,比如有时你点击一个链接,如果你装了多个浏览器,就会弹出这个activity让你选择哪个浏览器。其实就是ActivityPicker.java这个类。
跟踪其onCreate()方法:
- // Build list adapter of pickable items
- List<PickAdapter.Item> items = getItems();
- mAdapter = new PickAdapter(this, items);
- // Add any injected pick items
- final Intent intent = getIntent();
- ArrayList<String> labels = intent.getStringArrayListExtra(Intent.EXTRA_SHORTCUT_NAME);
- List<ResolveInfo> list = packageManager.queryIntentActivities(baseIntent, 0 /* no flags */);
- Collections.sort(list, new ResolveInfo.DisplayNameComparator(packageManager));
3、点击这个picker中ApiDemos,触发onclick(),会带着指向有Intent.ACTION_CREATE_SHORTCUT的activity的Intent返回到Launcher.java中。在onActivityResult()方法中跟下去:
- case REQUEST_PICK_SHORTCUT:
- processShortcut(data);
- break;
我们则进到else中,我们会发现它会启动刚返回的那个activity,所以我们点击创建ApiDemos的shortcut时,它会先启动下这个具有Intent.ACTION_CREATE_SHORTCUT的activity,再退出。接着再返回到Launcher.java中,继续跟下去,completeAddShortcut()方法就是具体的将这个shortcut添加到workspace上的方法,继续跟踪addShortcut()方法到infoFromShortcutIntent()中:
- Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
- String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
- Parcelable bitmap = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON);
- ..
- Parcelable extra = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE);
4、继续跟踪completeAddShortcut()中的createShortcut()方法,发现shortcut也是个textview,只不过这次是把icon添加到了text的上方,点击这个shortcut触发onclick(),就会启动你的具体功能的activity:
- Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
下面再看ApiDemos中那个例子,在app/LauncherShortcuts.java中,首先在manifest中:
- <activity-alias android:name=".app.CreateShortcuts"
- android:targetActivity=".app.LauncherShortcuts"
- android:label="@string/sample_shortcuts">
- <!-- This intent-filter allows your shortcuts to be created in the launcher. -->
- <intent-filter>
- <action android:name="android.intent.action.CREATE_SHORTCUT" />
- <category android:name="android.intent.category.DEFAULT" />
- </intent-filter>
- </activity-alias>
- setResult(RESULT_OK, intent);
有时我们会看到有些应用一安装完就在桌面添加了一个shortcut或是程序中可以点击一下按钮就在桌面创建一个shortcut,这时我们要用到Launcher中的一个广播接收者,在Launcher的manifest文件中:
- <receiver
- android:name="com.android.launcher2.InstallShortcutReceiver"
- android:permission="com.android.launcher.permission.INSTALL_SHORTCUT">
- <intent-filter>
- <action android:name="com.android.launcher.action.INSTALL_SHORTCUT" />
- </intent-filter>
- </receiver>
下面通过一个例子来说明下用法:通过点击一个按钮在桌面创建一个shortcut。
TestCreateShortcut.java
- public class TestCreateShortcut extends Activity {
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.test_shortcut);
- Button button = (Button) findViewById(R.id.install);
- button.setOnClickListener(new OnClickListener() {
- @Override
- public void onClick(View v) {
- Intent intent = new Intent();
- //install_shortcut action
- intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
- //点击shortcut时进入的activity,这里是自己
- intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(
- TestCreateShortcut.this, TestCreateShortcut.class));
- //shortcut的name
- intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "MyShortcut");
- Parcelable iconResource = Intent.ShortcutIconResource
- .fromContext(TestCreateShortcut.this, R.drawable.icon);
- //shortcut的icon
- intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
- iconResource);
- //是否可以重复放置shortcut,默认true
- intent.putExtra("duplicate", false);
- sendBroadcast(intent);
- }
- });
- }
- }
- <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>