这是安卓系统移植开发--Launcher3在桌面上添加默认的appWidget
为什么有这篇文章
Launcher3相对于Launcher2改变了很多,网上大部分的资料也是说的4.4版本以前的Launcher2,按照以前Launcher2的修改方式对Launcher3是无效的,比如本文要讲述的在桌面添加appWidget.
上正题
Launcher3桌面的加载过程
Launcher3在首次安装的时候,会检查是否存在相对应的数据库launcher.db,如果不存在,就会从布局文件default_workspace_xxx.xml加载。如果数据库存在,就不会再加载xml文件了。
下面以default_workspace_4x4.xml为例,如下:
<!-- Hotseat --> <include launcher:workspace="@xml/dw_phone_hotseat"/> <!--添加widget--> <resolve launcher:screen="0" launcher:x="0" launcher:y="0" launcher:spanX="2" launcher:spanY="2"> <appwidget launcher:packageName="com.android.alarmclock" launcher:className="com.android.alarmclock.AnalogAppWidgetProvider" /> /> </resolve>
HotSeat是可以生效的,但是appWidget不显示,尝试了很多种方式,都不行。
解决思路
- 前面说了,Launcher3在启动时会把数据加载到数据库中,既然在xml配置文件中不起作用,那么很可能是没有加载到数据库,我导出了数据库,一看,果然没有。
- 既然不能自动加载,那么我们是不是可以手动插入一条数据呢?尝试了一下,是行得通的。
方案代码
步骤一
workspace的展示需要两个重要的过程,loadWorkspace()和bindWorkspace(),顾名思义分别是加载workspace需要的数据和数据与workspace的位置绑定的两个方法。这两个过程在LauncherModel.java文件中。我们需要在loadWorkspace()方法中把数据添加进去。具体在哪个位置呢?在loadWorkspace()方法有一行
LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary();
的后面。
代码:
LauncherAppState.getLauncherProvider().loadDefaultFavoritesIfNecessary(); //在这里进行添加--bianjb //在这里添加一条数据,应该可以的--bianjbLauncherProvider.DatabaseHelper helper = new LauncherProvider.DatabaseHelper (context); SQLiteDatabase db = helper.getWritableDatabase(); ContentValues values = new ContentValues(); values.put("_id", 5);//id号 values.put("container", -100);//窗口,workspace是-100 values.put("cellX", 0);//x坐标 values.put("cellY", 0);//y坐标 values.put("spanX", 4);//x扩展 values.put("spanY", 4);//y扩展 values.put("itemType", 4);//类型为4,根据你要添加的进行调整 //appWidgetProvider也是需要要添加哪个widget进行调整 values.put("appWidgetProvider", "com.android.deskclock/com.android.alarmclock" + ".DigitalAppWidgetProvider"); values.put("modified", 0);//上一次修改时间,可以不写 values.put("restored", 0); values.put("profileId", 0); values.put("rank", 0); values.put("options", 0); long insert = db.insert(LauncherProvider.TABLE_FAVORITES, null, values); db.close(); Log.e("LauncherModel", insert > 0 ? "插入成功" : "插入失败");
步骤二
注意了,这里我们使用了DataBaseHelper来创建数据库,这个类是LaucherProvider的内部类,源代码中是private,所以我们还需要修改该类为public
步骤三
因为我们手动添加到数据库,在加载过程中会检查是否有对应的screenId,而此时保存screenId的集合是空的。这部分检查代码是由LauncherModel的checkItemPlacement()方法来完成的,仔细阅读代码就会发现,真正保存screenId的集合是由一个变量叫做sBgWorkspaceScreens的变量保存,我们只需要在checkItemPlacement方法调用前为它手动添加一个长整形0L,就可以了。