android 壁纸设置分析

原创
2013/06/09 15:26
阅读数 3.2K

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

很明显这个方法是将该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

展开阅读全文
打赏
0
5 收藏
分享
加载中
怎么设置锁屏?
2016/06/13 14:23
回复
举报
59
2016/06/13 14:23
回复
举报
Mr_Qi博主
话说csdn和osc的代码着色都是要手动选择的是吗,蛋疼~~~~
2013/06/09 15:27
回复
举报
更多评论
打赏
3 评论
5 收藏
0
分享
返回顶部
顶部