最近组织上派遣了我一个任务,最终目的只有一个,就是看看launcher你的wallpaper设置的流程。
废话不多说,直接看源码。
tips:在com.android.launcher2.Launcher类内有一个方法叫做startWallpaper(),很明显此方法就是设置壁纸的关键所在。
要说我是怎么知道的,大概老外起名字也不是随便起的,要是找类似的功能,比如创建快捷方式,在Launcher类里
按快捷键CTRL+O 键入对应的英文比如(*shortcut*),列出来的方法看名字也能猜出来对吧。同上,wallpaper就是这么找到的。
private void startWallpaper() {
showWorkspace(true); final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER); Intent chooser = Intent.createChooser(pickWallpaper, getText(R.string.chooser_wallpaper)); // NOTE: Adds a configure option to the chooser if the wallpaper supports it // Removed in Eclair MR1 // WallpaperManager wm = (WallpaperManager) // getSystemService(Context.WALLPAPER_SERVICE); // WallpaperInfo wi = wm.getWallpaperInfo(); // if (wi != null && wi.getSettingsActivity() != null) { // LabeledIntent li = new LabeledIntent(getPackageName(), // R.string.configure_wallpaper, 0); // li.setClassName(wi.getPackageName(), wi.getSettingsActivity()); // chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { li }); // } startActivityForResult(chooser, REQUEST_PICK_WALLPAPER); }
以上代码中Intent的chooser静态方法没有使用过,没有关系,看对应的api就是了。
public static createChooser ( target, title)
Added in
Convenience function for creating a Intent.
Builds a new Intent that wraps the given target intent, also optionally supplying a title. If the target intent has specified or , then these flags will also be set in the returned chooser intent, with its ClipData set appropriately: either a direct reflection of if that is non-null, or a new ClipData build from .
Parameters
target | The Intent that the user will be selecting an activity to perform. |
---|---|
title | Optional title that will be displayed in the chooser. |
Returns
- Return a new Intent object that you can hand to and related methods.
很明显这个方法是将该IntentFIlter中符合该Intent的activity全都列出来,然后第二个参数就是展示的chooser的标题。
当点击对应的item就会打开对应的activity,而launcher源码中存在一个对应的activity,清单文件中有提及到。
因此顺藤摸瓜,看看设置壁纸是如何实现的。找到WallpaperChooser类,查看源码
public class WallpaperChooser extends Activity { private static final String TAG = "Launcher.WallpaperChooser"; @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.wallpaper_chooser_base); Fragment fragmentView = getFragmentManager().findFragmentById(R.id.wallpaper_chooser_fragment); Log.i(TAG, "wallpaper"+(fragmentView==null)); // TODO: The following code is currently not exercised. Leaving it here in case it // needs to be revived again. if (fragmentView == null) { /* When the screen is XLarge, the fragment is not included in the layout, so show it * as a dialog */ DialogFragment fragment = WallpaperChooserDialogFragment.newInstance(); fragment.show(getFragmentManager(), "dialog"); } }}
事实上在对应的layout上有如下
实际是使用了WallpaperChooserDialogFragment,注释说了如果是Xlarge屏幕,没有显示该fragment,则获得WallpaperChooserDialogFragment对象
大概看到应该是在倒数第二句话中使用了一个fragment 选择壁纸。继续找到WallpaperChooserDialogFragment.类,果然
private void selectWallpaper(int position) { try { WallpaperManager wpm = (WallpaperManager) getActivity().getSystemService( Context.WALLPAPER_SERVICE); wpm.setResource(mImages.get(position)); Activity activity = getActivity(); activity.setResult(Activity.RESULT_OK); activity.finish(); } catch (IOException e) { Log.e(TAG, "Failed to set wallpaper: " + e); } } // Click handler for the Dialog's GridView @Override public void onItemClick(AdapterView parent, View view, int position, long id) { selectWallpaper(position); }
这一段就是真正的实现壁纸设置的方法。使用WallpaperManager.setResource(arg0)设置。
activity.setResult(Activity.RESULT_OK);将会在Launcher你的onActivityResult方法接收到,
此时也就是设置了对应的壁纸。