当前位置: 首页 > wzjs >正文

绵阳网站建设价格培训班有哪些

绵阳网站建设价格,培训班有哪些,购物网站怎么做推广,花店o2o的特色提示:Android 平台,静态壁纸实现方案 文章目录 需求:Android 实现壁纸 设置场景 参考资料实现方案直接调用系统 API,WallpaperManager 来实现 wallpaperManager.setResource系统源码分析系统app WallpaperPickerWallpaperPickerActivity ->…

提示:Android 平台,静态壁纸实现方案

文章目录

  • 需求:Android 实现壁纸 设置
    • 场景
  • 参考资料
  • 实现方案
    • 直接调用系统 API,WallpaperManager 来实现 wallpaperManager.setResource
    • 系统源码分析
      • 系统app WallpaperPicker
      • WallpaperPickerActivity ->WallpaperCropActivity
        • onClick 底部壁纸图片点击事件
      • AlphaDisableableButton
        • actionbar_set_wallpaper.xml
      • DialogUtils
        • DialogUtils ->executeCropTaskAfterPrompt
      • WallpaperManagerCompat
      • WallpaperPicker 源码小结
    • WallpaperManager
  • 拓展
    • 放置默认壁纸 供选择
    • 配置壁纸资源包
    • 加载壁纸配置
  • 总结


需求:Android 实现壁纸 设置

最近看到一个友商实现了一个功能,壁纸作为单独apk 拎出来作为一个apk 单独出现形式,比较有意义。 自己也实现一个,实现需求同时,分析源码实现方案 和 流程。

#需求
将壁纸设置作为一个apk形式,实现壁纸设置功能

场景

很多平板方案,将这个功能单独实现,作为一个app,方便客户使用。
这里只是用一个静态壁纸设置实现的方式,来初步了解Android壁纸相关内容。

参考资料

android WallpaperPicker7.0源码分析
Android 切换壁纸代码流程追踪:
Android 12新特性之获取壁纸主色调并设置系统主题色

实现方案

直接调用系统 API,WallpaperManager 来实现 wallpaperManager.setResource

WallpaperManager wallpaperManager = WallpaperManager.getInstance(this);
try {wallpaperManager.setResource(R.drawable.picture);
} catch (IOException e) {e.printStackTrace();
}

设置静态壁纸有很多途径,但归根结底都是一下三种方法:

  • 使用WallpaperManager的setResource(int ResourceID)方法
  • 使用WallpaperManager的setBitmap(Bitmap bitmap)方法
  • 使用WallpaperManager的setStream(InputStream data)方法

可以参考WallpaperManager 源码分析,源码代码量还好,不多。

\frameworks\base\core\java\android\app\WallpaperManager.java 

在这里插入图片描述

系统源码分析

系统app WallpaperPicker

我们先看一下如何进入到WallpaperPicker 的, 实际上 我们设置壁纸两个入口:

  • 首页 长按,设置壁纸
  • 进入设置目录,进入壁纸设置【接下来从设置入口进行分析】
    在这里插入图片描述

![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/a1222db5ee604392b1faf8bdb67ace90.png

在这里插入图片描述

在这里插入图片描述

一路跟踪界面,我们发现了以下几个类,可以看出最终是从设置跳转到了一个wallpaperpicker 的包中。

com.android.settings/.Settings$WallpaperSettingsActivity 
com.android.wallpaperpicker/.WallpaperPickerActivity  

系统里面搜索结果如下:
在这里插入图片描述
可以肯定的是 wallpaperpicker 就是一个单独apk, 将这个apk 源码进行分析下。

WallpaperPickerActivity ->WallpaperCropActivity

上面已经分析了,系统对应的壁纸选择跳转到一个apk 进行选择,对应的Activity 为 WallpaperPickerActivity

public class WallpaperPickerActivity extends WallpaperCropActivityimplements OnClickListener, OnLongClickListener, ActionMode.Callback {static final String TAG = "WallpaperPickerActivity";
onClick 底部壁纸图片点击事件

这里突破点是左上角设置壁纸图标,当无壁纸选中 默认情况是不可点击的,下面壁纸选项点击选中时候左上角 设置壁纸按钮可点击了。
看该方法的注释:

Called when a wallpaper tile is clicked 也就是点击后底部弹框的操作 
 /*** Called when a wallpaper tile is clicked*/@Overridepublic void onClick(View v) {if (mActionMode != null) {// When CAB is up, clicking toggles the item insteadif (v.isLongClickable()) {onLongClick(v);}return;}WallpaperTileInfo info = (WallpaperTileInfo) v.getTag();if (info.isSelectable() && v.getVisibility() == View.VISIBLE) {selectTile(v);setWallpaperButtonEnabled(true);}info.onClick(this);}public void setWallpaperButtonEnabled(boolean enabled) {mSetWallpaperButton.setEnabled(enabled);}mSetWallpaperButton = findViewById(R.id.set_wallpaper_button);

在 WallpaperPickerActivity 类中并没有找到 mSetWallpaperButton 定义地方,只是找到加载地方 findViewById,那么去父类 WallpaperCropActivity.java 看看


protected View mSetWallpaperButton;// WallpaperCropActivity.java  类中,也是通过findViewById 来加载,并声明它是一个View 
mSetWallpaperButton = findViewById(R.id.set_wallpaper_button);那这个set_wallpaper_button 对应的到底是什么,继续找

在这里插入图片描述

这里看到了 在一个布局文件和上面所讲WallpaperPickerActivity 、WallpaperCropActivity 两个类加载了。
看看布局文件如下

<com.android.wallpaperpicker.AlphaDisableableButtonxmlns:android="http://schemas.android.com/apk/res/android"style="@style/ActionBarSetWallpaperStyle"android:id="@+id/set_wallpaper_button"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingRight="20dp"android:drawableLeft="@drawable/ic_actionbar_accept"android:drawablePadding="8dp"android:gravity="start|center_vertical"android:text="@string/wallpaper_instructions"android:enabled="false" />

具体分析 如下 分析,AlphaDisableableButton 相关内容

AlphaDisableableButton

上面找到了AlphaDisableableButton , 其实就是一个自定义的View,看代码。


/*** A Button which becomes translucent when it is disabled*/
public class AlphaDisableableButton extends Button {public static float DISABLED_ALPHA_VALUE = 0.4f;public AlphaDisableableButton(Context context) {this(context, null);}public AlphaDisableableButton(Context context, AttributeSet attrs) {this(context, attrs, 0);}public AlphaDisableableButton(Context context, AttributeSet attrs, int defStyleAttr) {super(context, attrs, defStyleAttr);setLayerType(LAYER_TYPE_HARDWARE, null);}@Overridepublic void setEnabled(boolean enabled) {super.setEnabled(enabled);if(enabled) {setAlpha(1.0f);} else {setAlpha(DISABLED_ALPHA_VALUE);}}
}

备注:AlphaDisableableButton 类源码如上,就是一个自定义View,如上类说明:不可见的时候透明状态。

A Button which becomes translucent when it is disabled 
actionbar_set_wallpaper.xml

上面已经分析到了AlphaDisableableButton 源码和布局文件,那这个xml 又是哪里加载的。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

这里说明WallpaperPickerActivity 、 WallpaperCropActivity 加载这个布局文件,不就是显示ActionBar 嘛,如 加载说明:

Show the custom action bar view

DialogUtils

承接上述分析 ,actionbar 点击后,也就是 设置壁纸按钮 点击,弹出选择框逻辑

actionBar.getCustomView().setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {actionBar.hide();// Never fade on finish because we return to the app that started us (e.g.// Photos), not the home screen.cropImageAndSetWallpaper(imageUri, null, false /* shouldFadeOutOnFinish */);}});cropImageAndSetWallpaper(imageUri, null, false /* shouldFadeOutOnFinish */);@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)public void cropImageAndSetWallpaper(Uri uri,CropAndSetWallpaperTask.OnBitmapCroppedHandler onBitmapCroppedHandler,boolean shouldFadeOutOnFinish) {。。。。。。。。。。。。。。DialogUtils.executeCropTaskAfterPrompt(this, cropTask, getOnDialogCancelListener());}
DialogUtils ->executeCropTaskAfterPrompt

接下来就是dialog 具体源码如下:


/*** Utility class used to show dialogs for things like picking which wallpaper to set.*/
public class DialogUtils {/*** Calls cropTask.execute(), once the user has selected which wallpaper to set. On pre-N* devices, the prompt is not displayed since there is no API to set the lockscreen wallpaper.** TODO: Don't use CropAndSetWallpaperTask on N+, because the new API will handle cropping instead.*/public static void executeCropTaskAfterPrompt(Context context, final AsyncTask<Integer, ?, ?> cropTask,DialogInterface.OnCancelListener onCancelListener) {if (Utilities.isAtLeastN()) {new AlertDialog.Builder(context).setTitle(R.string.wallpaper_instructions).setItems(R.array.which_wallpaper_options, new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int selectedItemIndex) {int whichWallpaper;if (selectedItemIndex == 0) {whichWallpaper = WallpaperManagerCompat.FLAG_SET_SYSTEM;} else if (selectedItemIndex == 1) {whichWallpaper = WallpaperManagerCompat.FLAG_SET_LOCK;} else {whichWallpaper = WallpaperManagerCompat.FLAG_SET_SYSTEM| WallpaperManagerCompat.FLAG_SET_LOCK;}cropTask.execute(whichWallpaper);}}).setOnCancelListener(onCancelListener).show();} else {cropTask.execute(WallpaperManagerCompat.FLAG_SET_SYSTEM);}}
}

其实这个类说得很明白了,就是设置壁纸用的。
这里 我们记住 我们选择的是第三个选项,也就是 桌面壁纸和锁屏壁纸,参数flag 不一样而已

   whichWallpaper = WallpaperManagerCompat.FLAG_SET_SYSTEM| WallpaperManagerCompat.FLAG_SET_LOCK;

WallpaperManagerCompat

DialogUtils 源码分析到了 源码 ,那就继续追踪到 WallpaperManagerCompat

 whichWallpaper = WallpaperManagerCompat.FLAG_SET_SYSTEM| WallpaperManagerCompat.FLAG_SET_LOCK;cropTask.execute(whichWallpaper);

public abstract class WallpaperManagerCompat {public static final int FLAG_SET_SYSTEM = 1 << 0; // TODO: use WallpaperManager.FLAG_SET_SYSTEMpublic static final int FLAG_SET_LOCK = 1 << 1; // TODO: use WallpaperManager.FLAG_SET_LOCKprivate static WallpaperManagerCompat sInstance;private static final Object sInstanceLock = new Object();public static WallpaperManagerCompat getInstance(Context context) {synchronized (sInstanceLock) {if (sInstance == null) {if (Utilities.isAtLeastN()) {sInstance = new WallpaperManagerCompatVN(context.getApplicationContext());} else {sInstance = new WallpaperManagerCompatV16(context.getApplicationContext());}}return sInstance;}}public abstract void setStream(InputStream stream, Rect visibleCropHint, boolean allowBackup,int whichWallpaper) throws IOException;public abstract void clear(int whichWallpaper) throws IOException;
}

发现这里 WallpaperManagerCompat 类还是一个抽象类,那么实际的控制其实是 WallpaperManagerCompatVN 、WallpaperManagerCompatV16, 继续看其中代码如下


public class WallpaperManagerCompatV16 extends WallpaperManagerCompat {protected WallpaperManager mWallpaperManager;public WallpaperManagerCompatV16(Context context) {mWallpaperManager = WallpaperManager.getInstance(context.getApplicationContext());}@Overridepublic void setStream(InputStream data, Rect visibleCropHint, boolean allowBackup,int whichWallpaper) throws IOException {mWallpaperManager.setStream(data);}@Overridepublic void clear(int whichWallpaper) throws IOException {mWallpaperManager.clear();}
}public class WallpaperManagerCompatVN extends WallpaperManagerCompatV16 {public WallpaperManagerCompatVN(Context context) {super(context);}@Overridepublic void setStream(final InputStream data, Rect visibleCropHint, boolean allowBackup,int whichWallpaper) throws IOException {try {// TODO: use mWallpaperManager.setStream(data, visibleCropHint, allowBackup, which)// without needing reflection.Method setStream = WallpaperManager.class.getMethod("setStream", InputStream.class,Rect.class, boolean.class, int.class);setStream.invoke(mWallpaperManager, data, visibleCropHint, allowBackup, whichWallpaper);} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {// Fall back to previous implementation (set both)super.setStream(data, visibleCropHint, allowBackup, whichWallpaper);}}@Overridepublic void clear(int whichWallpaper) throws IOException {try {// TODO: use mWallpaperManager.clear(whichWallpaper) without needing reflection.Method clear = WallpaperManager.class.getMethod("clear", int.class);clear.invoke(mWallpaperManager, whichWallpaper);} catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {// Fall back to previous implementation (set both)super.clear(whichWallpaper);}}
}哈哈,这里最终调用的其实是 WallpaperManagerCompatVNWallpaperManagerCompatV16  类的 setStream 方法。 再最终调用的就是 WallpaperManager 类的 setStream 方法。 

WallpaperPicker 源码小结

上面的代码流程分析,最终共调用到了Framework层的WallpaperManager类的 setStream 方法。

WallpaperManager

上面已经分析到了 最终调用到 WallpaperManager 服务,通过反射调用
如下 类说明

/*** Provides access to the system wallpaper. With WallpaperManager, you can* get the current wallpaper, get the desired dimensions for the wallpaper, set* the wallpaper, and more.** <p> An app can check whether wallpapers are supported for the current user, by calling* {@link #isWallpaperSupported()}, and whether setting of wallpapers is allowed, by calling* {@link #isSetWallpaperAllowed()}.*/
@SystemService(Context.WALLPAPER_SERVICE)
public class WallpaperManager {.....
}

提供了系统壁纸入口,可以获取当前壁纸、设置壁纸…, app 可以检查当前用户是否允许设置壁纸,是否有权限等。继续分析源码 ,查看部分方法如下
在这里插入图片描述

这里看到设置壁纸的三种类型方法,如上文开始的分析,

归根结底都是一下三种方法:

  • 使用WallpaperManager的setResource(int ResourceID)方法
  • 使用WallpaperManager的setBitmap(Bitmap bitmap)方法
  • 使用WallpaperManager的setStream(InputStream data)方法

尝试三种方案,设置静态壁纸就是很简单的逻辑了,直接调用api ,反射或者拿到framework.jar,调用API 直接调用的事情了。 如下,某个友商做出来的效果,实际效果大家可以自己随便做了。

在这里插入图片描述

拓展

如上通过WallerpaperPicker 包分析了壁纸设置的整体流程,如果只是需要定制壁纸选择需求可以显示图片并调用api 反射或者 api 调用实现需求;
如果需要添加壁纸选择怎么办呢? 那只需要在 app 里面配置资源包即可。
思路如下:

放置默认壁纸 供选择

在 资源包中添加壁纸图片
在这里插入图片描述

配置壁纸资源包

在这里插入图片描述

加载壁纸配置

在这里插入图片描述
在这里插入图片描述

总结

  • 这里实现了静态壁纸设置的方法,就是一个反射或者api 调用。 实际 逻辑比较简单的
  • 这里只是从系统app WallpaperPicker,通过界面,反推实现设置静态壁纸的逻辑和分析代码层面的流程和业务。 实际上 WallpaperPicker App有很多设计思想和架构设计,这里暂不深究。
  • 如果客户定制,需要动态壁纸功能。这里暂不分析,后续有机会实现下,暂不提供解决方案。

文章转载自:

http://OKZ8B2BR.wxfjx.cn
http://wAuvTQk8.wxfjx.cn
http://ximV5QKy.wxfjx.cn
http://LsoTKX27.wxfjx.cn
http://NE10fYof.wxfjx.cn
http://tQOpqMWZ.wxfjx.cn
http://7Xl3W9Nx.wxfjx.cn
http://a4snXO5A.wxfjx.cn
http://AIe4KIDt.wxfjx.cn
http://76EBASHt.wxfjx.cn
http://jXOk6woR.wxfjx.cn
http://x43qFhFr.wxfjx.cn
http://Pr7V2ETL.wxfjx.cn
http://UkG5cdyC.wxfjx.cn
http://E5q5b5ss.wxfjx.cn
http://oZOXE9Nw.wxfjx.cn
http://ce7weLmY.wxfjx.cn
http://gth407mE.wxfjx.cn
http://0N01GNVc.wxfjx.cn
http://P10uk7Vf.wxfjx.cn
http://K031oxHS.wxfjx.cn
http://NnR9fc23.wxfjx.cn
http://S9fyjzub.wxfjx.cn
http://dzVgyiAr.wxfjx.cn
http://vascalqX.wxfjx.cn
http://SCtUbw2u.wxfjx.cn
http://YvuYmkg2.wxfjx.cn
http://5dAwKyK8.wxfjx.cn
http://OZiUmp3s.wxfjx.cn
http://LOnVazpk.wxfjx.cn
http://www.dtcms.com/wzjs/761229.html

相关文章:

  • 工业设计ai软件郑州seo优化外包顾问
  • 江门网站推广哪里专业国际化网站
  • 像美团这种网站怎么做的个人新闻类网站模板免费下载
  • 岳阳市规划局建设工程公示网站关键词挖掘站长
  • 怎么打开网站去除wordpress阅读更多字段
  • 佛山建网站哪里好网站域名申请好了怎么建设网站
  • 南通网站建设排名公司怎么做家政的网站
  • 怎么做服装外贸网站郴州网
  • 电子商务网站建设教学实施建设外贸网站营销推广
  • 网站建设实验感想相城区网站建设
  • 网络管理系统怎么打开连云港seo优化
  • 网站建设经费预算网页设计与制作课程建设规划
  • 花店网站建设规划书创建网站销售产品
  • 深圳整站优化云南app开发制作
  • 08 iis创建网站公司徽标设计图片
  • 西安app开发公司排名网站建设及优化心得体会
  • 做家政网站求人做网站
  • 杭州画廊网站建设台州网站关键字优化
  • 网站开发项目组成员软件开发属于技术服务吗
  • 市工商局网站建设情况知名建筑类的网站
  • 做网站中心图片软件制作工具
  • 班级网站建设方案企业网站营销的优缺点
  • 中交建设集团网站科技画4k纸科幻画
  • 成都公司网站如何用虚拟主机做网站
  • 教学类网站开发软件外包公司
  • 网站建设与管理ppt模板下载加强网站建设的意义
  • 做电池的外贸网站天空建筑网站
  • wordpress设置视频台州百度搜索优化
  • app ui设计网站全球最大源码共享网站
  • 石家庄做网站汉狮网络上海建设银行官方网站