一、桌面组件widget
1、新建一个Android工程,命名为WidgetDemo
2、建立widget布局文件
在res / layout下新建一个widget.xml布局文件
<?xml version="1.0"encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="fill_parent" android:layout_height="fill_parent" android:background="@drawable/sunset" > <TextView android:id="@+id/may1st" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="@string/hello" android:textSize="12px" android:textColor="#ff0000" /> </LinearLayout>
在res 下建立xml文件夹,然后在此文件夹下新建widget_provider.xml文件
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:minWidth="146dp" android:minHeight="72dp" android:updatePeriodMillis="1000" android:initialLayout="@layout/widget"> </appwidget-provider>该文件主要是用来对widget的样式进行配置。
其中,android:minWidth和android:minHeight可以理解为手机屏幕上的格子数,而一个格子的宽度和高度都为72dp,所以这里android:minWidth="146dp"和android:minHeight="146dp"表示该widget在手机屏幕上宽占两个格子,高度占一个格子。
4、WidgetDemo.java代码如下
public class WidgetDemo extends AppWidgetProvider { private static final String CLICK_NAME_ACTION = "com.terry.action.widget.click"; public static boolean isChange = true; private static RemoteViews rv; /** * 调用机会: 1.达到指定的更新时候 2.用户向桌面添加appwidget时辰 * 体系会发出一个android.appwidget.action.APPWIDGET_UPDATE广播 * 按照AndroidManifest.xml注册信息,启动widgetProvider,然后AppWidgetProvider接管 * 到广播后,调用onUpdate办法初始化 */ @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { System.out.println("onUpdate" + appWidgetIds.length); final int N = appWidgetIds.length; for (int i = 0; i < N; i++) { int appWidgetId = appWidgetIds[i]; AppWidget(context, appWidgetManager, appWidgetId); } } /** * 接管广播,当点击TextView时,AppWidgetService会广播一个事务 */ @Override public void onReceive(Context context, Intent intent) { super.onReceive(context, intent); System.out.println("onReceive:" + intent.getAction()); if (rv == null) { rv = new RemoteViews(context.getPackageName(), R.layout.main); } if (intent.getAction().equals(CLICK_NAME_ACTION)) { if (isChange) { rv.setTextViewText(R.id.TextView01, context.getResources() .getString(R.string.load)); } else { rv.setTextViewText(R.id.TextView01, context.getResources() .getString(R.string.change)); } Toast.makeText(context, Boolean.toString(isChange), Toast.LENGTH_LONG).show(); isChange = !isChange; // AppwidgetManager实例,更新appwidget AppWidgetManager appWidgetManger = AppWidgetManager .getInstance(context); int[] appIds = appWidgetManger.getAppWidgetIds(new ComponentName( context, widgetProvider.class)); appWidgetManger.AppWidget(appIds, rv); } } public static void AppWidget(Context context, AppWidgetManager appWidgeManger, int appWidgetId) { // 创建长途视图实例 rv = new RemoteViews(context.getPackageName(), R.layout.main); // 创建点击意图对象 Intent intentClick = new Intent(CLICK_NAME_ACTION); PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0); // 绑定TextView点击事务 rv.setOnClickPendingIntent(R.id.TextView01, pendingIntent); // 通知AppWidgetService appWidgeManger.AppWidget(appWidgetId, rv); } /** * 删除appwidget时调用 * 体系会发出一个android.appwidget.action.APPWIDGET_DELETED广播 * 然后才调用onDeleted(Context context, int[] appWidgetIds) */ @Override public void onDeleted(Context context, int[] appWidgetIds) { super.onDeleted(context, appWidgetIds); System.out.println("onDeleted"); } /** * 第一个appwidget被创建时调用 * 体系会发出一个android.appwidget.action.APPWIDGET_ENABLED广播 * 然后才调用onEnabled(Context context) */ @Override public void onEnabled(Context context) { super.onEnabled(context); System.out.println("onEnabled"); } /** * 最后一个appwidget被删除 * 体系会发出一个android.appwidget.action.APPWIDGET_DISABLED广播 * 然后才调用onDisabled(Context context) */ @Override public void onDisabled(Context context) { super.onDisabled(context); System.out.println("onDisabled"); } }
5、修改配置文件AndroidManifest.xml
由于使用了reciever和“android.appwidget.action.APPWIDGET_UPDATE”,所以需要在AndroidManifest.xml中进行注册。
<?xml version="1.0"encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.rui" android:versionCode="1" android:versionName="1.0"> <application android:icon="@drawable/icon"android:label="@string/app_name"> <receiver android:name=".WidgetDemo" android:label="@string/app_name"> <!-- 这个必须要加上,不然widget不会被创建 --> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/> </intent-filter> <intent-filter> <action android:name="com.terry.action.widget.click"/> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_provider"/> </receiver>
6、设置应用安装位置
由于手机只会列出安装于手机内存中的APP,故还需要在AndroidManifest.xml文件的android:installLocation="auto"
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.rui" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
http://blog.csdn.net/shakespeare001/article/details/8171065
做好上述工作后,就可以进行测试了。
二、快捷方式shortcut
(可参考http://www.blogjava.net/sxyx2008/archive/2011/12/13/366228.html)
在Android中创建ShortCut大概有两种方法。
第一种方法就是参照api demos中写的那个,通过设置setResult(RESULT_OK, intent);来创建ShortCut,这种方式在稍后分析。
本文以Broadcast方式方式来介绍Android中ShortCut的创建。
在创建或删除ShortCut的时候先需要在AndroidManifest.xml中增加两个权限
<!-- 创建桌面快捷方式的权限 -->
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
另外记得在创建或删除ShortCut的Intent中设置Action为
com.android.launcher.action.INSTALL_SHORTCUT(创建)
com.android.launcher.action.UNINSTALL_SHORTCUT(删除)
这样发送出去的广播才能被Android系统接受到
详细代码:
package com.zhy.shortcut; import android.app.Activity; import android.content.ComponentName; import android.content.Intent; import android.content.SharedPreferences; import android.content.SharedPreferences.Editor; import android.os.Bundle; import android.preference.PreferenceManager; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; public class ShortCutActivity extends Activity { private static final String CREATE_SHORTCUT_ACTION = "com.android.launcher.action.INSTALL_SHORTCUT"; private static final String DROP_SHORTCUT_ACTION = "com.android.launcher.action.UNINSTALL_SHORTCUT"; private static final String PREFERENCE_KEY_SHORTCUT_EXISTS = "IsShortCutExists"; Button button; // 获取默认的SharedPreferences SharedPreferences sharedPreferences ; // 从SharedPreferences获取是否存在快捷方式 若不存在返回false 程序第一次进来肯定返回false boolean exists ; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this); exists = sharedPreferences.getBoolean(PREFERENCE_KEY_SHORTCUT_EXISTS, false); //创建桌面快捷方式 //若第一次启动则创建,下次启动则不创建 if (!exists) { setUpShortCut(); } setContentView(R.layout.main); button = (Button) findViewById(R.id.dropShortCut); button.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { tearDownShortCut(); } }); } /** * 创建桌面快捷方式 */ private void setUpShortCut() { Intent intent = new Intent(CREATE_SHORTCUT_ACTION); // 设置快捷方式图片 intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,Intent.ShortcutIconResource.fromContext(this, R.drawable.logo)); // 设置快捷方式名称 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "sina"); // 设置是否允许重复创建快捷方式 false表示不允许 intent.putExtra("duplicate", false); // 设置快捷方式要打开的intent // 第一种方法创建快捷方式要打开的目标intent Intent targetIntent = new Intent(); // 设置应用程序卸载时同时也删除桌面快捷方式 targetIntent.setAction(Intent.ACTION_MAIN); targetIntent.addCategory("android.intent.category.LAUNCHER"); ComponentName componentName = new ComponentName(getPackageName(), this.getClass().getName()); targetIntent.setComponent(componentName); // 第二种方法创建快捷方式要打开的目标intent /* * Intent * targetIntent=getPackageManager().getLaunchIntentForPackage(getPackageName * ()); */ intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, targetIntent); // 发送广播 sendBroadcast(intent); Editor editor = sharedPreferences.edit(); editor.putBoolean(PREFERENCE_KEY_SHORTCUT_EXISTS, true); editor.commit(); } /** * 删除桌面快捷方式 */ private void tearDownShortCut() { Intent intent = new Intent(DROP_SHORTCUT_ACTION); // 指定要删除的shortcut名称 intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "sina"); String appClass = getPackageName() + "." + this.getLocalClassName(); ComponentName component = new ComponentName(getPackageName(), appClass); intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,new Intent().setAction(Intent.ACTION_MAIN).setComponent(component)); sendBroadcast(intent); } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.zhy.shortcut" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="8" /> <!-- 创建桌面快捷方式的权限 --> <uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/> <uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:label="@string/app_name" android:name=".ShortCutActivity" > <intent-filter > <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>