我尝试创建一个小部件,在点击调用Configuration活动的例程时,在更新上调用Configuration活动上的另一个例程,更新必须在30分钟以下,并且所有创建的实例必须单独工作(在onUpdate和in的onClick)。
下面的代码:点击不起作用(看不到Toast Message等功能) 更新适用于第一个实例,但有多个小部件实例,它工作正常: 如果我在10秒之间创建2个实例(并且刷新设置为20秒),则每10秒钟更新一次。
这是我的清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.fraschi.controllogiardinowg"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="it.fraschi.controllogiardinowg.Configurazione"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</intent-filter>
</activity>
<receiver android:name="it.fraschi.controllogiardinowg.ControlloWidget" android:label="@string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<intent-filter>
<action android:name="it.fraschi.controllogiardinowg.ControlloWidget.ACTION_WIDGET_CLICKED"/>
</intent-filter>
<intent-filter>
<action android:name="it.fraschi.controllogiardinowg.ControlloWidget.MY_OWN_WIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="@xml/widget_provider" />
</receiver>
</application>
</manifest>
这是我的配置:
package it.fraschi.controllogiardinowg;
import java.util.Calendar;
import java.util.Random;
import android.os.Bundle;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.RemoteViews;
import android.widget.Spinner;
import android.widget.Toast;
import android.widget.AdapterView.OnItemSelectedListener;
public class Configurazione extends Activity {
private static final String PREFS_NAME = "it.fraschi.android.ControlloGiardinoWG";
public static final String NOME = "nome_";
private static long millis = 60000;
private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private int selectedTextColor;
private int selectedBackgroundColor;
public Configurazione() {
super();
}
@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
// Set the result to CANCELED. This will cause the widget host to cancel
// out of the widget placement if they press the back button.
setResult(RESULT_CANCELED);
// Set the view layout resource to use.
setContentView(R.layout.activity_configurazione);
// Find the widget id from the intent.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
// If they gave us an intent without the widget id, just bail.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
finish();
}
//final Spinner backgroundColorSelector = (Spinner)findViewById(R.id.backgroundColor);
final Button saveButton = (Button)findViewById(R.id.btnSalva);
final Button cancelButton = (Button)findViewById(R.id.btnCancel);
final EditText editNome = (EditText)findViewById(R.id.editNome);
/*textColorSelector.setOnItemSelectedListener(new OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> parentView, View selectedItemView, int position, long id) {
selectedTextColor = Integer.parseInt(getResources().getStringArray(R.array.textColorsValues)[textColorSelector.getSelectedItemPosition()]);
}
@Override
public void onNothingSelected(AdapterView<?> parentView) {}
});*/
saveButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
final Context context = Configurazione.this;
//prepare Alarm Service to trigger Widget
Intent intent = new Intent(ControlloWidget.MY_WIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(Configurazione.this, mAppWidgetId, intent, 0);
AlarmManager alarmManager = (AlarmManager)getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 30);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), millis, pendingIntent);
//ControlloWidget.SaveAlarmManager(alarmManager, pendingIntent);
///
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
prefs.putString(NOME + mAppWidgetId, editNome.getText().toString());
prefs.commit();
// Push widget update to surface with newly set prefix
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ControlloWidget.updateAppWidget(context, appWidgetManager, mAppWidgetId);
// Make sure we pass back the original appWidgetId
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
});
cancelButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
finish();
}
});
}
/*@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.configurazione, menu);
return true;
}*/
static String getName(Context context, String prefKey ,int appWidgetId) {
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
String valuename = prefs.getString(prefKey + appWidgetId, "Non Trovato");
return valuename;
}
static String getColor(Context context, String prefKey, int appWidgetId){
///Test
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
String nome = prefs.getString(prefKey + appWidgetId, "Non Trovato");
///
int number = (new Random().nextInt(100));
String color = "DaConf"+Integer.toString(number)+nome;
Toast.makeText(context, "ESEGUITO", Toast.LENGTH_LONG).show();
return color;
}
}
那是我的小工具:
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Random;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Environment;
import android.os.StatFs;
import android.widget.RemoteViews;
import android.widget.Toast;
public class ControlloWidget extends AppWidgetProvider {
public static String ACTION_WIDGET_CLICKED = "it.fraschi.controllogiardinowg.ESEGUI";
public static String MY_WIDGET_UPDATE = "it.fraschi.controllogiardinowg.ControlloWidget.MY_OWN_WIDGET_UPDATE";
static String strWidgetText = "";
public static Boolean choice = false;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
//super.onReceive(context, intent);
String currentDateTimeString = DateFormat.getDateTimeInstance().format(new Date());
if(MY_WIDGET_UPDATE.equals(intent.getAction())){
Bundle extras = intent.getExtras();
if(extras!=null) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisAppWidget = new ComponentName(context.getPackageName(),
ControlloWidget.class.getName());
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
choice=false;
onUpdate(context, appWidgetManager, appWidgetIds);
}
Toast.makeText(context, "WIDGET UPDATE" +currentDateTimeString, Toast.LENGTH_LONG).show();
}
//Test Click
if(ACTION_WIDGET_CLICKED.equals(intent.getAction())){
Bundle extras = intent.getExtras();
if(extras!=null) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
ComponentName thisAppWidget = new ComponentName(context.getPackageName(),
ControlloWidget.class.getName());
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
choice=true;
onUpdate(context, appWidgetManager, appWidgetIds);
}
Toast.makeText(context, "WIDGET PREMUTO", Toast.LENGTH_LONG).show();
}
//TestClick
}
@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
//super.onEnabled(context);
Toast.makeText(context, "onEnabled()", Toast.LENGTH_LONG).show();
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
// TODO Auto-generated method stub
//super.onUpdate(context, appWidgetManager, appWidgetIds);
final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
// Create an Intent to launch ExampleActivity
Intent intent = new Intent(context, ControlloWidget.class);
intent.setAction(ACTION_WIDGET_CLICKED);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetId, intent,
PendingIntent.FLAG_UPDATE_CURRENT);
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.btnEsegui, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
//updateAppWidget(context, appWidgetManager, appWidgetId);
//Toast.makeText(context, "onUpdate(): " + String.valueOf(i) + " : " + String.valueOf(appWidgetId), Toast.LENGTH_LONG).show();
}
RemoteViews remoteWidget = new RemoteViews(context.getPackageName(),R.layout.widget);
}
public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,int appWidgetId){
//TestOnClick
RemoteViews remoteWidget = new RemoteViews(context.getPackageName(),R.layout.widget);
///
Intent esegui = new Intent(context, ControlloWidget.class);
esegui.setAction(ACTION_WIDGET_CLICKED);
//Intent esegui = new Intent(ControlloWidget.ACTION_WIDGET_CLICKED);
PendingIntent pendingEsegui = PendingIntent.getBroadcast(context, appWidgetId, esegui, 0);
remoteWidget.setOnClickPendingIntent(R.id.btnEsegui, pendingEsegui);
//
//
if (choice){
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget);
updateViews.setTextViewText(R.id.btnEsegui, "[" + String.valueOf(appWidgetId) + "]" + strWidgetText +
Configurazione.getColor(context, Configurazione.NOME, appWidgetId));
appWidgetManager.updateAppWidget(appWidgetId, updateViews);
Toast.makeText(context, "onClick(): " + String.valueOf(appWidgetId) + "\n" + strWidgetText,
Toast.LENGTH_LONG).show();
}else{
int number = (new Random().nextInt(100));
strWidgetText = Integer.toString(number);
RemoteViews updateViews = new RemoteViews(context.getPackageName(), R.layout.widget);
updateViews.setTextViewText(R.id.btnEsegui, "[" + String.valueOf(appWidgetId) + "]" + strWidgetText +
Configurazione.getName(context, Configurazione.NOME, appWidgetId));
appWidgetManager.updateAppWidget(appWidgetId, updateViews);
Toast.makeText(context, "updateAppWidget(): " + String.valueOf(appWidgetId) + "\n" + strWidgetText,
Toast.LENGTH_LONG).show();
}
}
static AlarmManager myAlarmManager;
static PendingIntent myPendingIntent;
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
//super.onDeleted(context, appWidgetIds);
myAlarmManager.cancel(myPendingIntent);
Toast.makeText(context, "onDeleted()", Toast.LENGTH_LONG).show();
}
static void SaveAlarmManager(AlarmManager tAlarmManager, PendingIntent tPendingIntent){
myAlarmManager = tAlarmManager;
myPendingIntent = tPendingIntent;
}
}
*
答案 0 :(得分:1)
对于30分钟和多个实例的定时,我决定只为所有实例使用一个定时器。
在配置类的基础上创建代码:
private static long millis = 20000;
SharedPreferences read = context.getSharedPreferences(PREFS_NAME, 0);
String firstinstance = read.getString("FirstInstance", "KO");
if (firstinstance.equals("KO")) {
SharedPreferences.Editor write = context.getSharedPreferences(
PREFS_NAME, 0).edit();
write.putString("FirstInstance", "OK");
write.commit();
Intent intent = new Intent(ControlloWidget.MY_WIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(
Configurazione.this, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 10);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), millis, pendingIntent);
ControlloWidget.SaveAlarmManager(alarmManager, pendingIntent);
}
将该过程恢复为WidgetClass的禁用:
@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
//super.onDisabled(context);
SharedPreferences.Editor write = context.getSharedPreferences(PREFS_NAME, 0).edit();
write.putString("FirstInstance", "KO" );
write.commit();
myAlarmManager.cancel(myPendingIntent);
}
static void SaveAlarmManager(AlarmManager tAlarmManager, PendingIntent tPendingIntent){
myAlarmManager = tAlarmManager;
myPendingIntent = tPendingIntent;
}
现在,设置按钮操作和我自己的更新: 班级声明:
public static String ACTION_WIDGET_CLICKED = "your.packagename.ACTION_WIDGET_CLICKED";
public static String MY_WIDGET_UPDATE = "your.packagename.MY_WIDGET_UPDATE";
onReceive方法:
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
choice = false;
// ////Toast.makeText(context, intent.getAction(),
// ////Toast.LENGTH_LONG).show();
// choice=false;
Bundle extras = intent.getExtras();
if (MY_WIDGET_UPDATE.equals(intent.getAction())) {
choice = false;
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
ComponentName thisAppWidget = new ComponentName(
context.getPackageName(), ControlloWidget.class.getName());
int[] appWidgetIds = appWidgetManager
.getAppWidgetIds(thisAppWidget);
onUpdate(context, appWidgetManager, appWidgetIds);
// ////Toast.makeText(context, "AUTOUPDATE",
// ////Toast.LENGTH_LONG).show();
} else
if (ACTION_WIDGET_CLICKED.equals(intent.getAction())) {
// choice =true;
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
ComponentName thisAppWidget = new ComponentName(
context.getPackageName(), ControlloWidget.class.getName());
int[] appWidgetIds = appWidgetManager
.getAppWidgetIds(thisAppWidget);
int appWidgetId = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
// ////////
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget);
remoteViews.setTextViewText(R.id.btnEsegui,
Configurazione.getName(context, "nome", appWidgetId));
// ACTION CODE HERE
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
Log.d("LOG_Esecuzione",
"Log Esecuzione, Widget n." + String.valueOf(appWidgetId));
}
}
然后onUpdate和updateAppWidget方法:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
// super.onUpdate(context, appWidgetManager, appWidgetIds);
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,int appWidgetId){
//TestOnClick
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget);
Intent myIntent = new Intent(context, ControlloWidget.class);
myIntent.setAction(ACTION_WIDGET_CLICKED);
myIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,appWidgetId,
myIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.btnEsegui, pendingIntent);
remoteViews.setTextViewText(R.id.btnEsegui,Configurazione.getName(context, "nome", appWidgetId));
//On Update Code, Requested Action when onUpdate is called (for all widget), it also refresh pending intent
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
Log.d("LOG_UPDATE", "Log Update, Widget n."+String.valueOf(appWidgetId));
}
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
对于单独的实例是必要的:
关于intentcreation :(在updateAppWidget上)
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget);
Intent myIntent = new Intent(context, ControlloWidget.class);
myIntent.setAction(ACTION_WIDGET_CLICKED);
//The line below is the appWidgetId Specification
myIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,appWidgetId,
myIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.btnEsegui, pendingIntent);
接收广播:( on onReceive)
if (ACTION_WIDGET_CLICKED.equals(intent.getAction())){
//Commented are not used on that example
//AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
//ComponentName thisAppWidget = new ComponentName(context.getPackageName(), ControlloWidget.class.getName());
//int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisAppWidget);
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
现在我们可以调用任何传递appWidgetId和Context的例程来运行... 例如:
Action.SomeAction(context,appWidgetId);
对于UPDATE TIMER,也可以(不使用首选项):
像其他意图一样
可以使用putExtra
然后广播:
在广播接收上检索int
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, -1);
但现在我们不会调用onUpdate
方法,而是直接调用updateAppWidget
使用该备选解决方案每个小部件都有自己的时间刷新(可能是可配置的)
我希望同时只激活一个计时器进程并在第一个实例小部件更新时间更新所有小部件