`

2011.10.19(3)——— android 一个便签的Widget例子

阅读更多
2011.10.19(3)——— android 一个便签的Widget例子

参考:http://blog.csdn.net/silenceburn/article/details/6093074

写一个widget的大致流程:

1. AppWidgetProvider 的实现 

2. widget外观布局定义文件

3. 新增widget时的配置Activity的实现(可选)

4. widget 参数配置文件 

5. 修改AndroidManifest.xml


3是可选的 例如http://www.cnblogs.com/TerryBlog/archive/2010/07/29/1788319.html就没有Activity界面


首先 搭一个Widget的框架

1、AppWidgetProvider 的实现
package com.lp.love;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;

public class LoveNote extends AppWidgetProvider{

	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		// TODO Auto-generated method stub
		super.onDeleted(context, appWidgetIds);
		System.out.println("onDeleted");
	}

	@Override
	public void onDisabled(Context context) {
		// TODO Auto-generated method stub
		super.onDisabled(context);
		System.out.println("onDisabled");
	}

	@Override
	public void onEnabled(Context context) {
		// TODO Auto-generated method stub
		super.onEnabled(context);
		System.out.println("onEnabled");
	}

	@Override
	public void onReceive(Context context, Intent intent) {
		// TODO Auto-generated method stub
		super.onReceive(context, intent);
		System.out.println("onReceive");
	}

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
		// TODO Auto-generated method stub
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		System.out.println("onUpdate");
	}

}


2. widget外观布局定义文件
这个就是在桌面你的widget的样子 我们的是一张图片

<?xml version="1.0" encoding="utf-8"?>
<ImageView xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/img"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:src="@drawable/sketchy_paper_008"
    android:clickable="true"/>


3、新增widget时的配置Activity的实现(可选)
package com.lp.love;

import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageButton;

/**
 * 该activity在系统新增widget时 被调用
 * 
 * @author lp
 * lipeng88213@126.com
 * http://lipeng88213.iteye.com/
 * 2011-10-19
 * 下午05:35:48
 */
public class ShowActivity extends Activity{

	
	private int mAppWidgetId;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.show);
		
		System.out.println("Activity");
		
		Intent intent = getIntent();
		Bundle extras = intent.getExtras();
		//得到widget传过来的id 每一个widget就有一个id 都不相同
		if (extras != null) {
			mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
					AppWidgetManager.INVALID_APPWIDGET_ID);
		}
		System.out.println(mAppWidgetId);
		// If they gave us an intent without the widget id, just bail.
		if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
			finish();
		}
		//最后我们必须返回一个RESULT_OK的Intent,并结束当前Activity,系统才会认为配置成功,在桌面上放置这个widget{
		Intent resultValue = new Intent();
		resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
				mAppWidgetId);

		setResult(RESULT_OK, resultValue);
		finish();
		//}
	}

}



4. widget 参数配置文件

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
	android:minWidth="72dp" android:minHeight="72dp"
	android:updatePeriodMillis="86400000" android:initialLayout="@layout/img"
	android:configure="com.lp.love.ShowActivity">
</appwidget-provider>


minWidth minHeight 用来指定widget的大小,如果我们只占用一个格子,也就是俗称的1X1,

那么72dp的长宽是android平台推荐的一个最佳实践值。

initialLayout 参数关联了我们编写好的 layout 文件,指定widget的样子

configure 参数关联了我们编写好的配置用Activity 当然这个也是可选的

updatePeriodMills 指定widget的刷新周期,

5、修改清单文件

声明一个receiver,过滤 android.appwidget.action.APPWIDGET_UPDATE ,

并且用metadata关联到我们自己编写的 appWidgetProvider 实现。

声明一个activity关联到我们的配置类 ShowActivity,过滤 android.appwidget.action.APPWIDGET_CONFIGURE。

最后修改一下应用图标,此图标会出现在系统的新增widget列表中。


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="com.lp.love"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="7" />

    <application android:icon="@drawable/sketchy_paper_008" android:label="@string/app_name">
		<receiver android:name=".LoveNote">
			<intent-filter>
				<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
			</intent-filter>
			<meta-data android:name="android.appwidget.provider"
				android:resource="@xml/widget_lovenote" />
		</receiver>

		<activity android:name=".ShowActivity">
			<intent-filter>
				<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
			</intent-filter>
		</activity>

    </application>
</manifest>


好了 上面的 就是一个基本的Widget了 [/size]



下面  我们来增加功能 使其具有便签的功能

主要更改了Activity


ShowActivity.java


package com.lp.love;

import android.app.Activity;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RemoteViews;

/**
 * 该activity在系统新增widget时 被调用
 * 
 * @author lp
 * lipeng88213@126.com
 * http://lipeng88213.iteye.com/
 * 2011-10-19
 * 下午05:35:48
 */
public class ShowActivity extends Activity implements OnClickListener{

	
	private int mAppWidgetId;
	private ImageButton btn_msg;
	private ImageButton btn_pc;
	private ImageButton btn_email;
	private ImageButton btn_home;
	
	private EditText et;
	
	private final String mPerfName = "com.lp.love";
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.show);
		
		System.out.println("Activity");
		
		Intent intent = getIntent();
		Bundle extras = intent.getExtras();
		//得到widget传过来的id 每一个widget就有一个id 都不相同
		if (extras != null) {
			mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,
					AppWidgetManager.INVALID_APPWIDGET_ID);
		}
		System.out.println(mAppWidgetId);
		// If they gave us an intent without the widget id, just bail.
		if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
			finish();
		}
		
		btn_msg = (ImageButton)findViewById(R.id.btn_msg);
		btn_pc = (ImageButton)findViewById(R.id.btn_pc);
		btn_email = (ImageButton)findViewById(R.id.btn_email);
		btn_home = (ImageButton)findViewById(R.id.btn_home);
		
		btn_msg.setOnClickListener(this);
		btn_pc.setOnClickListener(this);
		btn_email.setOnClickListener(this);
		btn_home.setOnClickListener(this);
		
		et = (EditText)findViewById(R.id.msg);
		
	}
	@Override
	public void onClick(View v) {
		//桌面显示的图标 这个是默认的
		int iconId = R.drawable.sketchy_paper_008;
		
		switch(v.getId()){
			case R.id.btn_msg:
				iconId = R.drawable.sketchy_paper_003;
				break;
			case R.id.btn_pc:
				iconId = R.drawable.sketchy_paper_004;
				break;
			case R.id.btn_email:
				iconId = R.drawable.sketchy_paper_007;
				break;
			case R.id.btn_home:
				iconId = R.drawable.sketchy_paper_011;
				break;
		}
		
		String msg = et.getText().toString();
		//保存消息{
		SharedPreferences.Editor prefs = this.getSharedPreferences(mPerfName, 0).edit();
		prefs.putString("note" + mAppWidgetId, msg);
		prefs.commit();
		//}
		
		//处理桌面widget的点击事件{
		
		//获取 RemoteViews 关联到我们的widget,设置widget的imageSrc为新的图片,
		RemoteViews views = new RemoteViews(this.getPackageName(), R.layout.img);
		views.setImageViewResource(R.id.img, iconId);
		//当被点击的时候 就相当于要修改 所以我们需要建一个修改的Activity
		Intent intent = new Intent(this, LoveNoteEdit.class);
		/**
		 * 注意这里我们使用intent.setAction(mPerfName + mAppWidgetId);为每个widget赋予了独一无二的Action。

			否则获得的pendingIntent实际是同一个实例,仅extraData不同,根据创建pendingIntent方法的不同,
			
			extraData可能会被覆盖或者只初始化一次不再改变(getActivity的最后一个参数flags决定)。
			
			这样我们在pendingIntent中就只能得到第一个新增的widget的Id,或者最后一次新增的widget的Id,
			
			这显然不是我们希望看到的。
		 */
		intent.setAction(mPerfName + mAppWidgetId);
		intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,mAppWidgetId);
		PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
				intent, 0);
		views.setOnClickPendingIntent(R.id.img, pendingIntent);

		
		//设置完成后需要获取AppWidgetManager,对指定的widget进行更新,才能使设置生效。
		AppWidgetManager appWidgetManager = AppWidgetManager
				.getInstance(this);
		appWidgetManager.updateAppWidget(mAppWidgetId, views);
		
		
		//}

		//最后我们必须返回一个RESULT_OK的Intent,并结束当前Activity,系统才会认为配置成功,在桌面上放置这个widget{
		Intent resultValue = new Intent();
		resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
				mAppWidgetId);

		setResult(RESULT_OK, resultValue);
		finish();
		//}
	}

}


然后 新增了一个Edit的Activity
package com.lp.love;

import android.app.Activity;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.RemoteViews;

/**
 * 修改
 * 
 * @author lp
 * lipeng88213@126.com
 * http://lipeng88213.iteye.com/
 * 2011-10-19
 * 下午06:27:15
 */
public class LoveNoteEdit extends Activity implements OnClickListener{

	
	private int mAppWidgetId;
	private ImageButton btn_msg;
	private ImageButton btn_pc;
	private ImageButton btn_email;
	private ImageButton btn_home;
	
	private EditText et;
	
	private final String mPerfName = "com.lp.love";
	
	private SharedPreferences mPref;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
		
		setContentView(R.layout.show);
		
		System.out.println("Activity");
		
		Intent t = getIntent();
		System.out.println(t.getAction());
		mAppWidgetId = t.getExtras().getInt(
				AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
		
		mPref = getSharedPreferences(mPerfName, 0);
		String noteContent = mPref.getString("note" + mAppWidgetId, "");
		
		
		btn_msg = (ImageButton)findViewById(R.id.btn_msg);
		btn_pc = (ImageButton)findViewById(R.id.btn_pc);
		btn_email = (ImageButton)findViewById(R.id.btn_email);
		btn_home = (ImageButton)findViewById(R.id.btn_home);
		
		btn_msg.setOnClickListener(this);
		btn_pc.setOnClickListener(this);
		btn_email.setOnClickListener(this);
		btn_home.setOnClickListener(this);
		
		et = (EditText)findViewById(R.id.msg);
		et.setText(noteContent);
		
	}
	@Override
	public void onClick(View v) {
		//桌面显示的图标 这个是默认的
		int iconId = R.drawable.sketchy_paper_008;
		
		switch(v.getId()){
			case R.id.btn_msg:
				iconId = R.drawable.sketchy_paper_003;
				break;
			case R.id.btn_pc:
				iconId = R.drawable.sketchy_paper_004;
				break;
			case R.id.btn_email:
				iconId = R.drawable.sketchy_paper_007;
				break;
			case R.id.btn_home:
				iconId = R.drawable.sketchy_paper_011;
				break;
		}
		
		String msg = et.getText().toString();
		//保存消息{
		SharedPreferences.Editor prefs = mPref.edit();
		prefs.putString("note" + mAppWidgetId, msg);
		prefs.commit();
		//}
		
		//处理桌面widget的点击事件{
		
		RemoteViews views = new RemoteViews(this.getPackageName(), R.layout.img);
		views.setImageViewResource(R.id.img, iconId);

		
		//设置完成后需要获取AppWidgetManager,对指定的widget进行更新,才能使设置生效。
		AppWidgetManager appWidgetManager = AppWidgetManager
				.getInstance(this);
		appWidgetManager.updateAppWidget(mAppWidgetId, views);
		
		
		//}
		
		this.finish();
	}

}



PendingIntent: 参考http://yinter.iteye.com/blog/803839
http://www.7dot9.com/2011/04/android-pendingintent%E7%9A%84%E4%B8%80%E4%BA%9B%E5%B0%8F%E8%BF%B7%E6%83%91/
RemoteViews:参考:
http://www.android123.com.cn/androidkaifa/320.html
AppWidgetManager: 参考:http://www.cnblogs.com/TerryBlog/archive/2010/07/29/1788319.html


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics