第四章管理Android系统桌面
第一节管理壁纸
初识Android壁纸
在Android中,壁纸分为静态与动态两种。静态壁纸是一张图片,而动态壁纸则以动画为表现形式,或者可以对用户的操作作出反应。这两种形式看似差异很大,其实二者的本质是统一的。它们都以一个Service的形式运行在系统后台,并在一个类型为TYPE_WALLPAPER 的窗口上绘制内容。
?Android壁纸的实现与管理分为三个层次:
?WallpaperService与Engine。同SystemUI一样,壁纸运行在一个Android服务之中,这个服务的
名字叫做WallpaperService。当用户选择了一个壁纸之后,此壁纸所对应的WallpaperService便会启动并开始进行壁纸的绘制工作,因此继承并定制WallpaperService是开发者进行壁纸开发的第一步。Engine是WallpaperService中的一个内部类,实现了壁纸窗口的创建以及Surface的维护工作。另外,Engine提供了可供子类重写的一系列回调,用于通知壁纸开发者关于壁纸的生命周期、Surface状态的变化以及对用户的输入事件进行响应。可以说,Engine类是壁纸实现的核心所在。
壁纸开发者需要继承Engine类,并重写其提供的回调以完成壁纸的开发。这一层次的内容主要体现了壁纸的实现原理。
?WallpaperManagerService,这个系统服务用于管理壁纸的运行与切换,并通过WallpaperManager
类向外界提供操作壁纸的接口。当通过WallpaperManagaer的接口进行壁纸的切换时,WallpaperManagerService会取消当前壁纸的WallpaperService的绑定,并启动新壁纸的WallpaperService。另外,Engine类进行窗口创建时所使用的窗口令牌也是由WallpaperManagerService提供的。这一层次主要体现了Android对壁纸的管理方式。
?WindowManagerService,用于计算壁纸窗口的层级显示、可见性以及为壁纸应用窗口动画。这一
层次主要体现了Android对壁纸窗口的管理方式。
调用系统自带的壁纸选择功能
Intent chooseIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
startActivity(Intent.createChooser (chooseIntent, "选择壁纸"));
将Activity的背景设置为壁纸背景
方法有两种,一种是在Activity中用代码进行设置,另一种是在AndroidManifest.xml中修改
方法一:Activity中设置:
@Override
protected void onCreate(Bundle savedInstanceState) {
setTheme(android.R.style.Theme_Wallpaper_NoTitleBar_Fullscreen);
super.onCreate(savedInstanceState);
setContentView(https://www.doczj.com/doc/7d19066286.html,yout.activity_main);
}
方法二:AndroidManifest.xml修改theme:
android:theme="@android:style/Theme.Wallpaper.NoTitleBar"/> 设置Android静态壁纸 WallpaperManager(壁纸管理器),如其名,就是手机壁纸相关的一个API ?WallpaperManager的基本用法 设置壁纸的相关方法: ?setBitmap(Bitmap bitmap):将壁纸设置为bitmap所代表的位图 ?setResource(int resid):将壁纸设置为resid资源所代表的图片 ?setStream(InputStream data):将壁纸设置为data数据所代表的图片 其他方法: ?clear():清除壁纸,设置回系统默认的壁纸 ?getDesiredMinimumHeight():最小壁纸高度 ?getDesiredMinimumWidth():最小壁纸宽度 ?getDrawable():获得当前系统壁纸,如果没有设置壁纸,则返回系统默认壁纸 ?getWallpaperInfo():加入当前壁纸是动态壁纸,返回动态壁纸信息 ?peekDrawable():获得当前系统壁纸,如果没设置壁纸的话返回null ?通过WallpaperManager设置静态壁纸的准备工作: (1)设置壁纸需要的权限 (2)获得WallpaperManager对象 主要常用的是以下二种调用办法: WallpaperManager wpManager =WallpaperManager.getInstance(this); WallpaperManager wpManager = (WallpaperManager) getActivity().getSystemService(Context.WALLPAPER_SERVICE); ?壁纸设置 壁纸包括两种类型,一种是系统壁纸(FLAG_SYSTEM),一种是锁屏壁纸(FLAG_LOCK)。设置壁纸,可以是setBitmap,也可以是setResource,还可以是setStream,并指定壁纸类型,默认会同时设置到系统壁纸和锁屏壁纸。 ?通过资源文件 public void setResource(@RawRes int resid) throws IOException { setResource(resid, FLAG_SYSTEM | FLAG_LOCK); } public int setResource(@RawRes int resid, @SetWallpaperFlags int which) android.app.WallpaperManager.FLAG_LOCK是设置锁屏壁纸 android.app.WallpaperManager.FLAG_SYSTME是设置系统壁纸 ?通过bitmap 方法一: public void setBitmap(Bitmap bitmap) throws IOException 方法二: public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup) throws IOException 第一个fullImage是一个bitmap。 第二个visibleCrpHint是参数是传一个矩形区域。解释是说传递的应该是fullImage这张图片想要显示的矩形区域作为壁纸,如果你知道手机和图片的宽高比也可以传null,则显示整张图片。 第三个allowBackup参数的含义是如果传ture,则允许系统备份壁纸图片。false则不允许。 public int setBitmap(Bitmap fullImage, Rect visibleCropHint, boolean allowBackup, @SetWallpaperFlags int which) throws IOException ?通过InputStream流设置壁纸 剩下2个方法的参数同bitmap一样。 设置动态壁纸 ?动态壁纸为:在手机上点击Menu→Wallpapers→Live wallpapers→然后打开自己的程序 ?动态壁纸是通过Android中的WallpaperService服务启动并开始进行壁纸的绘制工作,其中内部类Engine,实现了壁纸窗口的创建以及Surface的维护工作。 ?操作步骤: 1.开发一个子类继承WallpaperService基类 2.继承WallpaperService基类时必须重写onCreateEngine ()方法,返回WallpaperService.Engine子类 对象 3.实现WallpaperService.Engine子类,该类通过相关方法的实现,完成壁纸的动画和绘制工作 当壁纸的显示、状态或大小变化是,会调用Engine的onCreate, onDestroy, onVisibilityChanged, onSurfaceChanged, onSurfaceCreated 和onSurfaceDestroyed方法。有了这些方法,动态壁纸才能展现出动画效果。而通过设置setTouchEventsEnabled(true),并且调用onTouchEvent(MotionEvent event)方法,来激活触摸事件。 class MyEngine extends Engine{ @Override public void onCreate(SurfaceHolder surfaceHolder) { super.onCreate(surfaceHolder); 当引擎初始化时被调用,此时绘制surface还未被创建 可以进行paint等的初始化工作 } @Override public void onVisibilityChanged(boolean visible) { super.onVisibilityChanged(visible); 当壁纸可见或隐藏时被调用,应该暂停你的动画,不再绘制任何东西,以节省CPU(比如说移除Runnable等)。 } @Override public void onSurfaceCreated(SurfaceHolder holder) { super.onSurfaceCreated(holder); 当surface被创建时被调用 } @Override public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) { super.onSurfaceChanged(holder, format, width, height); 当surface的图形结构发生变化(大小、格式) } @Override public void onSurfaceDestroyed(SurfaceHolder holder) { super.onSurfaceDestroyed(holder); 当surface被销毁时被调用 } @Override public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { super.onOffsetsChanged(xOffset, yOffset, xOffsetStep, yOffsetStep, xPixelOffset, yPixelOffset); 当壁纸发生偏移变化,例如用户左右滑动主屏幕,这个可以用来创建一个平行滑动的效果,就是用户滑动时,壁纸同时发生偏移。 } @Override public void onTouchEvent(MotionEvent event) { super.onTouchEvent(event); 当显示壁纸时,用户跟主屏幕有触摸交互时被调用 } @Override public void onDestroy() { super.onDestroy(); 引擎销毁时被调用。此方法调用之后,引擎变得不可用。 } } 4.配置AndroidManifest.xml,声明上述中的自定义的service android:name=".MyLwp" android:enabled="true" android:permission="android.permission.BIND_WALLPAPER"> //否则该壁纸只能预览,不能被实际应用 //这表明当你设置动态壁纸时这个Service才启动 //< intent-?lter >这个标签告诉Android它是个什么样的服务 android:name="android.service.wallpaper" android:resource="@xml/livewallpapervideo"/> //< meta-data>标签让它知道在哪能找到关于wallpaper的额外信息 一定要添加的几个地方:permission、intent-filter、meta-data。 ?动态壁纸的Service与普通的Service的区别: 需要指定两项: (1)设置动态壁纸需要在MyWallpaperService中声明 android:permission="android.permission.BIND_W ALLPAPER权限 (2)为动态壁纸指定meta-data配置 android:description="@string/app_name" android:settingsActivity="com.example.liuwei.wallpagerdemo.SettingActivity" android:thumbnail="@mipmap/star" /> 其中description(应用描述),settingsActivity(应用指定的壁纸设置页面),thumbnail(应用图标)三个属性自定义设置。 第二节管理快捷方式 Android快捷方式可以通过长按桌面来添加,也有的是第一次运行时候询问是否需要安装,有的直接放在桌面(MIUI是直接放在桌面的),那么为了驱动用户使用,有些应用在安装以后便直接安装了快捷方式,还有些应用是在用户第一次进入的时候,询问用户是否安装快捷方式。 Android7.0之前的快捷方式管理 创建应用程序快捷方式主要有以下几种: 1.在launcher的应用程序列表上,长按某一应用程序图标创建快捷方式到桌面 2.在桌面上长按在弹出框中选择快捷方式->应用程序->将添加快捷方式的程序 3.通过程序运行时自动创建 Launcher为了应用程序能够定制自己的快捷图标,就注册了一个BroadcastReceiver专门接收其他应用程序发来的快捷图标定制信息。所以只需要根据该BroadcastReceiver构造出相对应的Intent并装入我们的定制信息,最后调用sendBroadcast 方法就可以创建一个快捷图标了。一般创建应用快捷图标有如下两种方案: 1.通过向launcher发送Broadcast让launcher创建快捷方式 1)首先需要添加权限 2)编写创建快捷方式的代码 2.为应用程序的组件注册某一个符合特定条件的IntentFilter,然后可以直接在Launcher 的桌面添加启动该组件的快捷方式(在长按桌面弹出的WIDGETS中手动选择添加)。 1)首先在应用的AndroidManifest.xml中需要创建快捷方式的Activity中增加如下action:
2)设置快捷方式的图标、名称、事件等属性
第二种方式和第一种有些类似,不过我们不用广播的方式让给launcher创建,而是通过注册IntentFilter,由于“添加快捷方式”Action是由Launcher通过startActivity-ForResult这一方法发出的,在Activity启动后把初始化的快捷方式Intent返回给Launcher应用程序,设置结果值为RESULT_OK表示正常返回。
适用于Android 7.1(API25)以上的快捷方式管理
对于App的快捷方式,ios和android都可以创建快捷方式,但是在ios中默认为每一个app 添加了一个“分享”的快捷方式,尤其是在3D Touch的加持下,快捷方式的可玩性更高。之所以叫快捷方式,是因为用户可以在不打开app的情况下,长按app启动图标,快速打开指定的页面,非常直接的一种方式,节省了一些不必要的操作
如果你的应用的目标是Android 7.1(API级别25)或更高,则可以在应用中定义特定操作的快捷方式。这些快捷方式可以显示在支持的启动器中。快捷方式可让您的用户在应用内快速启动常用或推荐的任务。每个快捷方式引用一个或多个Intent,当用户选择快捷方式时,每个Intent都将在您的应用程序中启动特定的操作。
目前支持两种类型快捷方式,一类是通过长按应用图标弹出的App shortcuts,一类是添加到桌面中显示的Pinned shortcuts(固定快捷键),App shortcuts支持动态添加,更新,删除,禁用,Pinned shortcuts仅支持动态添加,更新,但无法通过程序移除,只能禁用。