android 壁纸设置分析

最近组织上派遣了我一个任务,最终目的只有一个,就是看看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 Intent createChooser (Intent target, CharSequence title)

Added in  API level 1

Convenience function for creating a ACTION_CHOOSER Intent.

Builds a new ACTION_CHOOSER Intent that wraps the given target intent, also optionally supplying a title. If the target intent has specifiedFLAG_GRANT_READ_URI_PERMISSION or FLAG_GRANT_WRITE_URI_PERMISSION, then these flags will also be set in the returned chooser intent, with its ClipData set appropriately: either a direct reflection of getClipData() if that is non-null, or a new ClipData build from getData().

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 Context.startActivity() and related methods.

很明显这个方法是将该IntentFIlter中符合该Intent的activity全都列出来,然后第二个参数就是展示的chooser的标题。

当点击对应的item就会打开对应的activity,而launcher源码中存在一个对应的activity,清单文件中有提及到。
  <activity
            android:name="com.android.launcher2.WallpaperChooser"
            style="@style/Theme.WallpaperPicker"
            android:label="@string/pick_wallpaper"
            android:icon="@drawable/ic_launcher_wallpaper"
            android:finishOnCloseSystemDialogs="true"
            android:process=":wallpaper_chooser">
            <intent-filter>
                <action android:name="android.intent.action.SET_WALLPAPER" />
                <category android:name="android.intent.category.DEFAULT" />
            </intent-filter>
            <meta-data android:name="android.wallpaper.preview"
                android:resource="@xml/wallpaper_picker_preview" />
        </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上有如下

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <fragment class="com.android.launcher2.WallpaperChooserDialogFragment"
        android:id="@+id/wallpaper_chooser_fragment"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
</FrameLayout>
实际是使用了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方法接收到,

此时也就是设置了对应的壁纸。


android 壁纸设置分析http://blog.csdn.net/q13073451412/article/details/9063283

你可能感兴趣的:(android,壁纸,wallpaper,chooser)