Luncher修改wallpaper(壁纸)源码跟踪(代码实现过程分析)

简介:

http://blog.csdn.net/aomandeshangxiao/article/details/6767423

http://blog.csdn.net/aomandeshangxiao/article/details/6768249


  以下将为大家简单的分析一下源代码中luncher修改壁纸的过程(以下代码均来自Luncher源代码):

      一.当我们在luncher界面按下menu的时候,第三个选项就是Wallpaper,定义如下(源码1116行,局部),menu.add第二项既是选择wallpaper:

[java]  view plain copy
  1. public boolean onCreateOptionsMenu(Menu menu) {  
  2.        if (isWorkspaceLocked()) {  
  3.            return false;  
  4.        }  
  5.   
  6.        super.onCreateOptionsMenu(menu);  
  7.   
  8.        menu.add(MENU_GROUP_ADD, MENU_ADD, 0, R.string.menu_add)  
  9.                .setIcon(android.R.drawable.ic_menu_add)  
  10.                .setAlphabeticShortcut('A');  
  11.        menu.add(MENU_GROUP_WALLPAPER, MENU_WALLPAPER_SETTINGS, 0, R.string.menu_wallpaper)  
  12.                 .setIcon(android.R.drawable.ic_menu_gallery)  
  13.                 .setAlphabeticShortcut('W');  

        二.当我们按下Wallpaper触发什么事件呢?看一下代码(源代码1171行):

[java]  view plain copy
  1. @Override  
  2.    public boolean onOptionsItemSelected(MenuItem item) {  
  3.        switch (item.getItemId()) {  
  4.            case MENU_ADD:  
  5.                addItems();  
  6.                return true;  
  7.            case MENU_WALLPAPER_SETTINGS:  
  8.                startWallpaper();  
  9.                return true;  
  10.            case MENU_SEARCH:  
  11.                onSearchRequested();  
  12.                return true;  
  13.            case MENU_NOTIFICATIONS:  
  14.                showNotifications();  
  15.                return true;  
  16.        }  
  17.   
  18.        return super.onOptionsItemSelected(item);  
  19.    }  

我们看到:

而它调用的事件是

[java]  view plain copy
  1. startWallpaper();  

你们看到的图片跟我的都不一样,呵呵,这是因为我写了一个很简单的demo,然后就系统给调用了,所以你们看到一个比你们多了一个wallpaperdemo。在下一篇日志中,我会说下这个demo是如何实现的。

三.下面让我们看下startWallpaper()这个方法(源代码1370行):

[java]  view plain copy
  1. private void startWallpaper() {  
  2.         closeAllApps(true);  
  3.         final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);  
  4.         Intent chooser = Intent.createChooser(pickWallpaper,  
  5.                 getText(R.string.chooser_wallpaper));  
  6.         // NOTE: Adds a configure option to the chooser if the wallpaper supports it  
  7.         //       Removed in Eclair MR1  
  8. //        WallpaperManager wm = (WallpaperManager)  
  9. //                getSystemService(Context.WALLPAPER_SERVICE);  
  10. //        WallpaperInfo wi = wm.getWallpaperInfo();  
  11. //        if (wi != null && wi.getSettingsActivity() != null) {  
  12. //            LabeledIntent li = new LabeledIntent(getPackageName(),  
  13. //                    R.string.configure_wallpaper, 0);  
  14. //            li.setClassName(wi.getPackageName(), wi.getSettingsActivity());  
  15. //            chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[] { li });  
  16. //        }  
  17.         startActivityForResult(chooser, REQUEST_PICK_WALLPAPER);  
  18.     }  
很多人可能会对他是如何实现跳转设置的呢?Intent.createChooser()这个方法的实现原理赶到好奇,因为你在Luncher源代码里面找不到Live Wallpapers和Galleryde的实现。因为他是通过一个类似广播的机制。

下一篇日志http://blog.csdn.net/aomandeshangxiao/article/details/6768249 中,将为大家详细介绍Intent.createChooser()的用法。


我所写的简单的小例子:http://download.csdn.net/detail/aomandeshangxiao/3593740


简单的分析了一下源代码,在

[java]  view plain copy
  1. final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);  
  2.         Intent chooser = Intent.createChooser(pickWallpaper,  
  3.                 getText(R.string.chooser_wallpaper));  

处百思不得其解,后来在网上找,也没有很透彻的解释。先看下它的官方文档吧:

[java]  view plain copy
  1. public static Intent createChooser (Intent target, CharSequence title)  
  2. Since: API Level 1  
  3.   
  4. Convenience function for creating a ACTION_CHOOSER Intent.  
  5. Parameters  
  6. target  The Intent that the user will be selecting an activity to perform.  
  7. title   Optional title that will be displayed in the chooser.  
  8. Returns  
  9.   
  10.     * Return a new Intent object that you can hand to Context.startActivity() and related methods.   


在google上面也找了下,慢慢的有些明白,在一篇文章中看到这么一段话:

这里是要找到所有能处理Intent.ACTION_SET_WALLPAPER请求的activity,其字符串表示为android.intent.action.SET_WALLPAPER。使用Eclipse搜索之后,在以下应用的AndroidManifest.xml文件都找到了能处理这个请求的activity:
packages/apps/Gallery
packages/apps/Launcher2
packages/wallpapers/LivePicker
再看看下面的这个图:


壁纸对应的是Launcher2里面的WallpaperChooser.activity。动态壁纸对应的是packages/wallpapers/LivePicker的LiveWallpaperListActivity,他们的共同点 就是在AndroidManifest.xml都有
[html]  view plain copy
  1. <intent-filter>  
  2.                <action android:name="android.intent.action.SET_WALLPAPER" />  
  3.                <category android:name="android.intent.category.DEFAULT" />  
  4.            </intent-filter>  

如下定义,或许你有了些许明白,看下 http://groups.google.com/group/android-developers/browse_thread/thread/9d376a94066057a4 这里面的解释,我英语不是太好,按照我自己的理解就是,你如果像下面这样
[html]  view plain copy
  1. Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);  
  2.         Intent chooser = Intent.createChooser(pickWallpaper,  
建立一个intent chooser,系统会寻找所有activity,然后把有
[html]  view plain copy
  1. <intent-filter>  
  2.                <action android:name="android.intent.action.SET_WALLPAPER" />  
  3.                <category android:name="android.intent.category.DEFAULT" />  
  4.            </intent-filter>  
定义的activity形成列表提供给使用者。为了验证我的想法,个人写了一个很简单的小例子,MainActivity代码如下:
[java]  view plain copy
  1. public class MainActivity extends Activity {  
  2.     /** Called when the activity is first created. */  
  3. private Button button;  
  4.     @Override  
  5.     public void onCreate(Bundle savedInstanceState) {  
  6.         super.onCreate(savedInstanceState);  
  7.         setContentView(R.layout.main);  
  8.           
  9.         button=(Button)findViewById(R.id.wallpaperButton);  
  10.         button.setOnClickListener(new View.OnClickListener() {  
  11.   
  12. @Override  
  13. public void onClick(View v) {  
  14. // TODO Auto-generated method stub  
  15. final Intent pickWallpaper = new Intent(Intent.ACTION_SET_WALLPAPER);  
  16.        Intent chooser = Intent.createChooser(pickWallpaper,"tese the ACTION_SET_WALLPAPER");  
  17.        startActivity(chooser);  
  18. }  
  19. });  
  20.     }  
  21. }  
还有一个demo,代码如下
[java]  view plain copy
  1. public class Demo extends Activity {  
  2.   
  3.   
  4. @Override  
  5. protected void onCreate(Bundle savedInstanceState) {  
  6. // TODO Auto-generated method stub  
  7. super.onCreate(savedInstanceState);  
  8. setContentView(R.layout.demo);  
  9. }  
  10. }  

demo.xml文件里面只有一个textview很简单。
然后是AndroidManifest.xml文件:
[java]  view plain copy
  1. <?xml version="1.0" encoding="utf-8"?>  
  2. <manifest xmlns:android="http://schemas.android.com/apk/res/android"  
  3.       package="cn.demo"  
  4.       android:versionCode="1"  
  5.       android:versionName="1.0">  
  6.   
  7.   
  8.   
  9.   
  10.     <application android:icon="@drawable/icon" android:label="@string/app_name">  
  11.         <activity android:name=".MainActivity"  
  12.                   android:label="@string/app_name">  
  13.             <intent-filter>  
  14.                 <action android:name="android.intent.action.MAIN" />  
  15.                 <category android:name="android.intent.category.LAUNCHER" />  
  16.             </intent-filter>  
  17.         </activity>  
[java]  view plain copy
  1. <activity android:name=".Demo">  
[java]  view plain copy
  1. <intent-filter>  
[java]  view plain copy
  1.             <action android:name="android.intent.action.SET_WALLPAPER" />  
  2.             <category android:name="android.intent.category.DEFAULT" />  
  3.         </intent-filter>  
  4.     </activity>  
  5. </application>  
  6. /manifest>  



注意:
 
[html]  view plain copy
  1. </activity>  
  2. <activity android:name=".Demo">  
  3. <intent-filter>  
  4.                 <action android:name="android.intent.action.SET_WALLPAPER" />  
  5.                 <category android:name="android.intent.category.DEFAULT" />  
  6.             </intent-filter>  
  7.         </activity>  


我在这里面加了intent适配器 
<action android:name="android.intent.action.SET_WALLPAPER" />


运行下程序,点击button按钮,效果如下:




我这个网速太不给力了,弄的心烦意燥,大家看到我自己写的demo在图片中得到了显示,这也是在上一篇 http://blog.csdn.net/aomandeshangxiao/article/details/6767423中给大家看的图片,为什么我的选项多了一个。说到这里,想必大家都明白了这个原理了,中秋节还有几分钟就要到了,祝福大家中秋愉快。


上面所说的简单的小例子下载地址:http://download.csdn.net/detail/aomandeshangxiao/3593740


相关文章
|
API Android开发 开发者
Android 12 适配指南——SplashScreen
Android 12(API 31)引入了 SplashScreen 相关API,用于开发Android应用的启动页。 SplashScreen相关API的引入影响在Andorid 12设备上运行的所有应用。若开发者未进行SplashScreen的适配工作,在应用冷启动和温启动时,可能会呈现两个启动页先后出现的情况(Android SplashScreen启动页 + Android应用自定义开发的启动页或引导页)。
2625 0
Android 12 适配指南——SplashScreen
|
项目管理 Python
深入理解Python中的os.chdir()方法
`os.chdir()`是Python中用于改变当前工作目录的方法,简化文件和目录操作。语法为`os.chdir(path)`,`path`是目标目录路径。示例中展示了如何切换及检查工作目录。它常用于脚本执行、文件操作和多项目管理。注意目标目录必须存在,否则会抛出异常。相关方法有`os.getcwd()`获取当前目录和`os.path.join()`拼接路径。使用时结合异常处理可提升效率。参考[Python官方文档](https://docs.python.org/3/library/os.html)。
708 3
|
6月前
|
存储 算法 C++
Windows共享文件:探秘C++实现的B树索引算法奇境
在数字化时代,Windows共享文件的高效管理至关重要。B树算法以其自平衡多路搜索特性,在文件索引与存储优化中表现出色。本文探讨B树在Windows共享文件中的应用,通过C++实现具体代码,展示其构建文件索引、优化数据存储的能力,提升文件检索效率。B树通过减少磁盘I/O操作,确保查询高效,为企业和个人提供流畅的文件共享体验。
|
算法
shape_predictor
【6月更文挑战第19天】
261 8
|
Web App开发 JavaScript 开发者
Vue工具和生态系统:什么是Vue DevTools?如何使用它?
Vue Devtools是Vue.js官方的浏览器扩展,用于简化应用调试和优化。可在Chrome和Firefox等浏览器上安装,集成到开发者工具中。安装步骤包括下载源码、npm安装、修改manifest.json并加载编译后的扩展。启用后,开发者能查看Vue组件树,检查属性,并在允许的情况下编辑data,提升开发效率。
285 0
|
Python
【Python笔记】pip intall -e命令:让你的工程直接使用开源包的源码,可断点调试,修改源码!
【Python笔记】pip intall -e命令:让你的工程直接使用开源包的源码,可断点调试,修改源码!
960 0
|
SQL 自然语言处理 分布式计算
antlr4 简单实用入门——(一)
antlr4 简单实用入门——(一)
1016 0
|
前端开发
ant design upload实现多个文件一次上传(全网首发)
ant design upload实现多个文件一次上传(全网首发)
1473 0