android 5.1 壁纸路径,RTFSC – Android5.1 壁纸设置流程简析 – RustFisher

Android5.1 壁纸设置流程浅析

Ubuntu14.04  Android5.1  Source Insight3

这里只是简单分析一下5.1里是如何设置壁纸的;这个流程和4.4有一些不同。但基本都是找个地方存放壁纸文件,需要的时候读取,设置的时候更新

这里只看设置的过程。权当参考。

机器使用launcher3,在桌面上长按,底部显示设置壁纸的入口。

进入设置壁纸界面,观察log可知,此界面属于Trebuchet。也是launcher3

点击设置壁纸按钮,发现整个标题栏都有响应。在以下文件中可以找到相关定义:

/*— ↓ — WallpaperPickerActivity.java *********/

//Action bar//Show the custom action bar view

final ActionBar actionBar =getActionBar();

actionBar.setCustomView(R.layout.actionbar_set_wallpaper);

actionBar.getCustomView().setOnClickListener(newView.OnClickListener() {

@Overridepublic voidonClick(View v) {if (mSelectedTile != null) {

WallpaperTileInfo info=(WallpaperTileInfo) mSelectedTile.getTag();

info.onSave(WallpaperPickerActivity.this);

}else{//no tile was selected, so we just finish the activity and go back

setResult(Activity.RESULT_OK);

finish();

}

}

});

mSetWallpaperButton=findViewById(R.id.set_wallpaper_button);/*— ↑ — (packages/apps/Trebuchet/WallpaperPicker/src/com/android/launcher3/) *********/

整个 actionBar都拿来响应点击。info是 WallpaperTileInfo抽象类的对象,有5个子类。

这样系统能根据图片来选择使用哪一个子类。再调用 onSave方法。以FileWallpaperInfo类为例。

它复写了 onSave方法

/*— ↓ — WallpaperPickerActivity.java *********/@Overridepublic voidonSave(WallpaperPickerActivity a) {

a.setWallpaper(Uri.fromFile(mFile),true);

}/*— ↑ — (packages/apps/Trebuchet/WallpaperPicker/src/com/android/launcher3/) *********/

因为WallpaperPickerActivity 继承自 WallpaperCropActivity

setWallpaper方法在 WallpaperCropActivity中找到;传入了Uri和一个boolean值

/*↓ — WallpaperCropActivity.java *********/

protected void setWallpaper(Uri uri, final booleanfinishActivityWhenDone) {int rotation = getRotationFromExif(this, uri);

BitmapCropTask cropTask= newBitmapCropTask(this, uri, null, rotation, 0, 0, true, false, null);final Point bounds =cropTask.getImageBounds();

Runnable onEndCrop= newRunnable() {public voidrun() {

updateWallpaperDimensions(bounds.x, bounds.y);if(finishActivityWhenDone) {

setResult(Activity.RESULT_OK);

finish();

}

}

};

cropTask.setOnEndRunnable(onEndCrop);

cropTask.setNoCrop(true);

cropTask.execute();

}/*↑ — (packages/apps/trebuchet/wallpaperpicker/src/com/android/launcher3) *********/

以上代码可以看出,它启动了一个异步任务  BitmapCropTask extends AsyncTask ;把一些列参数都传入了cropTask

启动一个线程onEndCrop,等待任务结束

进入BitmapCropTask看,系统做了什么工作

这是setWallpaper使用的构造方法

/*↓ — WallpaperCropActivity.java *********/

publicBitmapCropTask(Context c, Uri inUri,

RectF cropBounds,int rotation, int outWidth, intoutHeight,boolean setWallpaper, booleansaveCroppedBitmap, Runnable onEndRunnable) {

mContext=c;

mInUri=inUri;

init(cropBounds, rotation,

outWidth, outHeight, setWallpaper, saveCroppedBitmap, onEndRunnable);

}//……

private void init(RectF cropBounds, int rotation, int outWidth, intoutHeight,boolean setWallpaper, booleansaveCroppedBitmap, Runnable onEndRunnable) {

Log.d(“rust”,”init after bitmapcroptask”);

mCropBounds=cropBounds;

mRotation= rotation; //传入各项参数

mOutWidth =outWidth;

mOutHeight=outHeight;

mSetWallpaper=setWallpaper;

mSaveCroppedBitmap=saveCroppedBitmap;

mOnEndRunnable=onEndRunnable;

}//…… 在这里处理任务,启动 cropBitmap()

@OverrideprotectedBoolean doInBackground(Void… params) {returncropBitmap();

}//……

public booleancropBitmap() {boolean failure = false;

WallpaperManager wallpaperManager= null;if(mSetWallpaper) {

wallpaperManager=WallpaperManager.getInstance(mContext.getApplicationContext());

}if (mSetWallpaper &&mNoCrop) {try{

InputStream is= regenerateInputStream(); //获得InputStream

if (is != null) {

wallpaperManager.setStream(is);//把is写进去,从这里进入到wallpaperManager

Utils.closeSilently(is);

}

}catch(IOException e) {

Log.w(LOGTAG,“cannot write stream to wallpaper”, e);

failure= true;

}return !failure;

}else { //顺利的话不会进入这里//……//Helper to setup input stream

privateInputStream regenerateInputStream() {if (mInUri == null && mInResId == 0 && mInFilePath == null && mInImageBytes == null) {

Log.w(LOGTAG,“cannot read original file, no input URI, resource ID, or ” +

“image byte array given”);

}else{try{

String filepath=mInFilePath;if(mInUri != null){

filepath=DrmHelper.getFilePath(mContext, mInUri);

}if(DrmHelper.isDrmFile(filepath)){byte[] bytes =DrmHelper.getDrmImageBytes(filepath);return new ByteArrayInputStream(bytes); //返回一个ByteArray

}/*↑ — (packages/apps/trebuchet/wallpaperpicker/src/com/android/launcher3) *********/

调用了wallpaperManager.setStream(is);进入 WallpaperManager.java 看看

/*↓ — WallpaperManager.java *********/

public void setStream(InputStream data) throws IOException { //luncher3 里直接调用了这个方法

if (sGlobals.mService == null) { //WallpaperCropActivity 调用

Log.w(TAG, “WallpaperService not running”);return;

}try{

ParcelFileDescriptor fd= sGlobals.mService.setWallpaper(null); //利用service得到fd

if (fd == null) { //这里要去WallpaperManagerService里找到对应方法

return;

}

FileOutputStream fos= null;try{

fos= newParcelFileDescriptor.AutoCloseOutputStream(fd);

setWallpaper(data, fos);//写入壁纸数据

} finally{if (fos != null) {

fos.close();

}

}

}catch(RemoteException e) {//Ignore

}

}//…… 在这里写入壁纸,写入过程结束,Manager完成任务

private voidsetWallpaper(InputStream data, FileOutputStream fos)throwsIOException {byte[] buffer = new byte[32768];intamt;while ((amt=data.read(buffer)) > 0) {

fos.write(buffer,0, amt);

}

}/*↑ — (framework/base/core/java/android/app) *********/

再来看Globals extends IWallpaperManagerCallback.Stub

包含成员变量 IWallpaperManager mService,通过

Globals(Looper looper) {

IBinder b=ServiceManager.getService(Context.WALLPAPER_SERVICE);

mService=IWallpaperManager.Stub.asInterface(b);

}

调用 WallpaperManagerService.java 里的setWallpaper方法

Service的作用

进入WallpaperManagerService看看,是如何返回ParcelFileDescriptor值的

/*↓ — WallpaperManagerService.java *********/

public ParcelFileDescriptor setWallpaper(String name) { //供 WallpaperManager 调用

checkPermission(android.Manifest.permission.SET_WALLPAPER);synchronized(mLock) {if (DEBUG) Slog.v(TAG, “setWallpaper”);int userId =UserHandle.getCallingUserId();

WallpaperData wallpaper=mWallpaperMap.get(userId);if (wallpaper == null) {throw new IllegalStateException(“Wallpaper not yet initialized for user ” +userId);

}final long ident =Binder.clearCallingIdentity();try{

ParcelFileDescriptor pfd=updateWallpaperBitmapLocked(name, wallpaper);if (pfd != null) {//启动下面的方法

wallpaper.imageWallpaperPending = true;

}return pfd; //返回ParcelFileDescriptor值给WallpaperManager

} finally{

Binder.restoreCallingIdentity(ident);

}

}

}

ParcelFileDescriptor updateWallpaperBitmapLocked(String name, WallpaperData wallpaper) {if (name == null) name = “”;try{

File dir= getWallpaperDir(wallpaper.userId); //找到壁纸

if (!dir.exists()) {

dir.mkdir();

FileUtils.setPermissions(

dir.getPath(),

FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,-1, -1);

}

File file= new File(dir, WALLPAPER); //创建一个新的文件

ParcelFileDescriptor fd =ParcelFileDescriptor.open(file,

MODE_CREATE|MODE_READ_WRITE|MODE_TRUNCATE);if (!SELinux.restorecon(file)) {return null;

}

wallpaper.name=name;return fd; //返回ParcelFileDescriptor值

} catch(FileNotFoundException e) {

Slog.w(TAG,“Error setting wallpaper”, e);

}return null;

}private static File getWallpaperDir(int userId) { //取得壁纸文件

returnEnvironment.getUserSystemDirectory(userId);

}/*↑ — (framework/base/services/core/java/com/android/server/wallpaper/) *********/

至此一个简单的流程就结束了

我们可反过来看

壁纸文件是存在 Environment.getUserSystemDirectory(userId) 这个路径下

WallpaperManagerService取到这个文件后,将其打开为ParcelFileDescriptor形式,交给WallpaperManager

WallpaperManager把launcher传来的数据写入这个文件中

小结一下:

选定壁纸,点击按钮,launcher把壁纸信息给WallpaperManager;

WallpaperManagerService把存放壁纸的文件打开,交给WallpaperManager

WallpaperManager把壁纸信息写入;一次设置壁纸的动作就完成了

这里传输数据使用到engine,一个挺有意思的东西。

50f956be8dd27126429a3f87b061141a.gif

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434454.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

android电梯程序设计,课内资源 - 基于Android实现的电梯调度模拟

一、使用说明1.1 项目简介某一楼有20层,操作者可以通过使用5部电梯从起始楼层来到达指定的楼层。本项目通过实现电梯调度,来模拟实现操作系统的调度过程,并且学习Android环境下使用Java的多线程编程方法以及调度算法。1.2 项目要求操作者可以…

asp.net 根据当前时间计算是否股票、期货、黄金交易日期

很简单的一个方法: 股票:每周1到周五,上午9:30到11:30 下午13:00 到15:00 期货:每周1到周五,上午9:00到11:30 下午13:30到15:00 黄金:每周1到周五,上午9:00到11:30 下午13:30到15:…

android mac 照片恢复,如何找回Android手机删除的照片?这方法你肯定不知道

安卓手机怎么恢复误删的照片?如何找回Android手机照片?现在大多数人都喜欢用手机拍照存照片,慢慢的,手机中的照片自然而然就会变多,而照片是最占内存的。当你照片达到一定数量,内存快满的时候,连照片都拍不了。所以就…

nubia android root权限,获取中兴NX403a (Nubia Z5S Mini Android 4.2)ROOT权限教程,新手必看...

中兴NX403a (Nubia Z5S Mini Android 4.2)如何获取ROOT权限?用什么ROOT工具最简单?请跟着小编一起来看看如何用奇兔刷机对中兴NX403a (Nubia Z5S Mini Android 4.2)进行一键ROOT,小编特别亲手制作了详细的中兴NX403a (Nubia Z5S Mini Android 4.2) ROOT教程图解&a…

A20 编译

android 源码编译分为 2 个部分,一部分是 linux 内核编译,这部分包括 uboot,另一部分是 android 源码编译。所以编译时各自单独编译,编译成功能,最近单独打包成最终烧录的镜像文件。2.1 源码结构说明首先把源码包 A20-…

apache OFBiz的安装

去官网下载OFBiz的代码包。解压这个代码包进入到命令行,输入以下命令 ant build-all 这时候会自动进行安装。这个过程大概有10多分钟。 运行startofbiz脚本。由于我是windows,所以运行startofbiz.bat。在网址输入http://localhost:8080/ecommerce/可以…

android 沉浸栏灰色,Android 沉浸栏实践——踩坑

当前开发环境:Android Studio 2.1.3,compileSdkVersion 24,buildToolsVersion "24.0.2",support:appcompat-v7:24.2.0首先放个图,这就是我要做成的效果,Toolbar 和 Status Bar 一体共用背景图&am…

android实现文本输入,Android实现智能提示的文本输入框AutoCompleteTextView

今天我们要讲一个十分简单的内容,就是一个安卓控件的使用,用法很简单,但是很常用的一个。这里我用两种不同的写法来处理。当然,无论用哪一种写法,效果都是一样的。我们先来看效果图。要实现这种效果十分简单。需要一个…

ibatis的简介与初步搭建应用

一、ibatis的简介 ibatis是什么东西就不介绍了,自己去找谷老师。 这里讲下自己的使用体会。之前自己学过Hibernate,是看尚学堂的视频教学的,看完以后发现Hibernate体系中的内容真的很多,什么N-N关联、HSQL、缓存管理等等&#xff…

VOIP,PSTN,ISDN

近来在电视、杂志特集等展露头脚的「IP电话」,因其通话费用低廉而有口皆碑。IP电话利用的IP网络在互联网的世界里是众所周知的。互联网被认为基本上是免费的网络。接下来以此开放的技术和构想作为基础而登场的就是IP电话。IP电话与构成 所谓的IP电话 所谓的IP电话就…

svn在linux下的使用(svn命令行)ubuntu 删除 新增 添加 提交 状态查询 恢复

合并步骤:(1)先切换到分支;(2)svn merge trunk . (3)svn sw trunk (4)svn merge --reintegrate branch . svn merge http://59.251.189.152:8989/svn/ron/tru…

计算机组装与维护模拟测试题三答案,春季高考信息技术模拟题3(计算机组装与维修部分含答案)...

36.计算机硬件系统的核心部件是A.主板B.CPUC.内存D.硬盘 37.北桥芯片的功能不包括A.对CPU类型和主频的支持B.对ECC纠错的支持C.对内存类型和最大容量的支持D.对USB接口的支持 38.操作…

wince6下usb摄像头(UVC)使用指南

转自:http://hi.baidu.com/cahbb/blog/item/6d76093498fe0790a61e120e.html 在搭好了wince6的开发环境之后,下一步试验一下wince6下使用摄像头的方法。搜集了不少资料,从中学习了很多有用的东西,在这给记录下来,方便…

使用SqlCommandBuilder

使用命令构造器添加行 View Code using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Data; using System.Data.SqlClient;namespace PersistAddsBuilder {class Program{static void Main(string[] args){string connStri…

Asterisk权威指南/第二章 Asterisk架构

Asterisk和其他传统的PBX完全不同,因为Asterisk的拨号计划以同样的方式处理所有的入局信道(incoming channels)。 传统的PBX在逻辑上区分工作站信道(连接电话机)和电话局信道(连接到外部世界)。…

x-lite asterisk 成功实现视频通话

首先,在此感谢asterisk协会的各位大牛们,没有他们的帮助,我也不可能在这么短的时间内实现,x-liteasterisk音视频通话。在此将实现的过程记录如下,分享给asterisk的爱好者们。 1. 修改asterisk服务器的sip.conf文件&…

axure 链接html文件,通过WuliHub免费托管原型Axure HTML文件

产品经理常用的工具就是Axure,通过Axure把想法转化成包含交互的原型线框图。在工作中,我们用HTML文件传递不仅会遇到某些浏览器无法打开的问题,而且没有办法及时更新内容。所以,介绍一种简单的并且免费的方式来方便管理HTML原型&a…

Asterisk SIP连通测试(X-Lite eyebeam)

Step1:设置 sip.conf rootUbuntu:/etc/asterisk# vim sip.conf [general] //类似与全局变量 context default srvlookup yes //DNS SRV记录查询 [111] secretaaa //密码&#xf…

html多出的空白页怎么删除,word多出一页空白页怎么删除,这4个方法总有一个能解决,真实挂机网赚项目...

信赖大多数人都碰到过这样的难题,在编辑Word文档的时刻,是不是在中心或者是最后一页,莫名其妙的泛起空白页,而且这个空白页怎么删都删不掉。不要着急,今天就给人人分享4种简朴又好用的解决方式,总有一种能让…

linq to json for sl

一.Linq to JSON是用来干什么的?Linq to JSON是用来操作JSON对象的.可以用于快速查询,修改和创建JSON对象.当JSON对象内容比较复杂,而我们仅仅需要其中的一小部分数据时,可以考虑使用Linq to JSON来读取和修改部分的数据而非反序列化全部. 二.创建JSON数组和对象在进行Linq to…