您的位置:首页 > 移动开发

Android:AppWidget是如何放到桌面上的

2010-03-10 09:54 483 查看
今天接到部门头头给下达的一个任务:研究如何让桌面上的AppWidget不能删除。仔细研究AppWidget包的文档后发现,如果不修改桌面程序的代码不可能实现。OK,那就看看桌面程序的源代码吧。

Android中默认桌面的代码包为com.android.launcher。源代码网址为http://git.android.kernel.org/platform/packages/apps/launcher.git . 下载下来啃吧。

分析代码结构,首先是分析AndroidManifest.xml文件,看看哪个类是桌面程序的入口。在该文件中发现如下代码。

<activity
android:name="Launcher"
android:launchMode="singleTask"
android:clearTaskOnLaunch="true"
android:stateNotNeeded="true"
android:theme="@style/Theme"
android:screenOrientation="nosensor"
android:windowSoftInputMode="stateUnspecified|adjustPan">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME"/>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.MONKEY" />
</intent-filter>
</activity>


这说明,Launcher这个类是桌面的主要类。 而联想到添加和删除Widget的操作过程可以确定长点击事件的处理是这两个功能的起始点。下面请看onLongClick函数

public boolean onLongClick(View v) {
if (mDesktopLocked) {
return false;
}

if (!(v instanceof CellLayout)) {
v = (View) v.getParent();
}

CellLayout.CellInfo cellInfo = (CellLayout.CellInfo) v.getTag();

// This happens when long clicking an item with the dpad/trackball
if (cellInfo == null) {
return true;
}

if (mWorkspace.allowLongPress()) {
if (cellInfo.cell == null) {
if (cellInfo.valid) {
// User long pressed on empty space
mWorkspace.setAllowLongPress(false);
showAddDialog(cellInfo);//从这里开始添加Widget的动作
}
} else {
Log.i(LOG_TAG_TEST, cellInfo.cell.getClass().getName());
if (!(cellInfo.cell instanceof Folder)) {
// User long pressed on an item
if(cellInfo.cell instanceof AppWidgetHostView)
{
AppWidgetHostView adv=(AppWidgetHostView)cellInfo.cell;
if(adv.getAppWidgetInfo().provider.getClassName().equals("AdAppWidgetProvider"))
{
Log.i(LOG_TAG_TEST, "Cannot Remove Advertisment Widget");
return false;
}
}

//下面这一句是删除动作的开始,因此在其前边添加了代码处理Widget信息
mWorkspace.startDrag(cellInfo);
}
}
}
return true;
}


OK,任务完成!

那么接下来不妨仔细看看AppWidget到底是怎么添加到桌面上的。开始跟踪代码:

1、使用如下代码打开系统的选择Widget的Activity

int appWidgetId = Launcher.this.mAppWidgetHost.allocateAppWidgetId();
Intent pickIntent = new Intent(AppWidgetManager.ACTION_APPWIDGET_PICK);
pickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
// add the search widget
ArrayList customInfo =
new ArrayList();
AppWidgetProviderInfo info = new AppWidgetProviderInfo();
info.provider = new ComponentName(getPackageName(), "XXX.YYY");
info.label = getString(R.string.group_search);
info.icon = R.drawable.ic_search_widget;
customInfo.add(info);
pickIntent.putParcelableArrayListExtra(
AppWidgetManager.EXTRA_CUSTOM_INFO, customInfo);
ArrayList customExtras = new ArrayList();
Bundle b = new Bundle();
b.putString(EXTRA_CUSTOM_WIDGET, SEARCH_WIDGET);
customExtras.add(b);
pickIntent.putParcelableArrayListExtra(
AppWidgetManager.EXTRA_CUSTOM_EXTRAS, customExtras);
// start the pick activity
startActivityForResult(pickIntent, REQUEST_PICK_APPWIDGET);


2、从返回的Intent中得到AppWidget详细信息,如果需要config则显示config activity。

3、由AppWidgetHost根据AppWidgetID和provider info生成AppWidgetHostView,然后将AppWidgetHostView添加到桌面的Viewgroup中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: