从 Activity 手动更改小部件状态
Posted
技术标签:
【中文标题】从 Activity 手动更改小部件状态【英文标题】:Manually change widget state from Activity 【发布时间】:2012-07-18 13:14:36 【问题描述】:我的应用有一个小部件,当我们点击它时它会点亮 LED 闪光灯,当我们再次点击它时它会关闭它。
这是代码(感谢来自 post 的 Kartik):
WidgetProvider.java
public class WidgetProvider extends AppWidgetProvider
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds)
Intent receiver = new Intent(context, WidgetReceiver.class);
receiver.setAction("COM_FLASHLIGHT");
receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
receiver, 0);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget);
views.setOnClickPendingIntent(R.id.imageButtonWidget, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, views);
WidgetReceiver.java
public class WidgetReceiver extends BroadcastReceiver
public static boolean isLightOn = false;
public static Camera camera;
@Override
public void onReceive(Context context, Intent intent)
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget);
if (isLightOn)
views.setImageViewResource(R.id.imageButtonWidget,
R.drawable.widget_lamp_button_default);
else
views.setImageViewResource(R.id.imageButtonWidget,
R.drawable.widget_lamp_button_checked);
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
appWidgetManager.updateAppWidget(new ComponentName(context,
WidgetProvider.class), views);
if (isLightOn)
if (camera != null)
camera.stopPreview();
camera.release();
camera = null;
isLightOn = false;
else
// Open the default i.e. the first rear facing camera.
camera = Camera.open();
if (camera == null)
Toast.makeText(context, "R.string.no_camera",
Toast.LENGTH_SHORT).show();
else
// Set the torch flash mode
Parameters param = camera.getParameters();
param.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
try
camera.setParameters(param);
camera.startPreview();
isLightOn = true;
catch (Exception e)
Toast.makeText(context, "R.string.no_flash",
Toast.LENGTH_SHORT).show();
现在我想从我的应用程序中关闭小部件。在我的应用程序的主要活动中使用此代码,我可以释放小部件拍摄的相机:
MainActivity.java
//Stop widget camera
if (WidgetReceiver.isLightOn)
Camera a = WidgetReceiver.camera;
a.stopPreview();
a.release();
a = null;
WidgetReceiver.isLightOn=false;
但问题是小部件仍设置为选中的可绘制对象 (R.drawable.widget_lamp_button_checked
)。所以 FlashLight 已经很好地关闭了,但我仍然需要强制小部件将其可绘制设置为未选中的 (R.drawable.widget_lamp_button_default
)。
我该怎么做?
编辑:问题已解决
WidgetProvider.java
public class WidgetProvider extends AppWidgetProvider
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds)
// Set widget's drawable to unchecked
RemoteViews views2 = new RemoteViews(context.getPackageName(),
R.layout.widget);
AppWidgetManager mManager = AppWidgetManager.getInstance(MainActivity
.getContext());
ComponentName cn = new ComponentName(MainActivity.getContext(),
WidgetProvider.class);
views2.setImageViewResource(R.id.imageButtonWidget,
R.drawable.widget_lamp_button_default);
mManager.updateAppWidget(cn, views2);
// Widget OnClick Behavior
Intent receiver = new Intent(context, WidgetReceiver.class);
receiver.setAction("COM_FLASHLIGHT");
receiver.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
receiver, 0);
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget);
views.setOnClickPendingIntent(R.id.imageButtonWidget, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, views);
WidgetReceiver.java -> 保持不变
MainActivity.java
public class MainActivity extends Activity
private static Context mContext;
public static Context getContext()
return mContext;
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
mContext = this;
//Stop widget camera
if (WidgetReceiver.isLightOn)
Camera a = WidgetReceiver.camera;
a.stopPreview();
a.release();
a = null;
WidgetReceiver.isLightOn=false;
// Fire Widget's update with Intent
Intent intent = new Intent(this, WidgetProvider.class);
intent.setAction("android.appwidget.action.APPWIDGET_UPDATE");
// Use an array and EXTRA_APPWIDGET_IDS instead of
// AppWidgetManager.EXTRA_APPWIDGET_ID,
// since it seems the onUpdate() is only fired on that:
int[] ids = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ;
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
sendBroadcast(intent);
【问题讨论】:
【参考方案1】:在 AppWidgetProvider 的 onReceive() 方法中,使用 AppWidgetManager
类的 updateAppWidget
方法向您的 AppWidgetProvider 发送广播并更新您的小部件:
@Override
public void onReceive(Context context, Intent intent)
...
views = new RemoteViews(context.getPackageName(),
R.layout.yourwidgetlayout);
AppWidgetManager mManager = AppWidgetManager.getInstance(App
.getContext());
ComponentName cn = new ComponentName(App.getContext(),
YourAppWidgetProvider.class);
//change your views,here I change text of text view witch it's id is "widgettextview"
views.setTextViewText(R.id.widgettextview, "lastWord");
mManager.updateAppWidget(cn, views);
...
这里是应用定义:
public class App extends Application implements OnInitListener
private static Context mContext;
public void onCreate()
super.onCreate();
mContext = this;
public static Context getContext()
return mContext;
【讨论】:
抱歉,我不明白App
类的用法。为什么要使用与TextToSpeech
api 相关的OnInitListener
?
好的,感谢您的回答,我已经解决了我的问题,但我没有使用您的 App
课程,但我从 MainActivity
课程中获得了上下文(这可能是您的意思和我不明白?)。无论如何,问题已解决(见帖子),感谢您的回答:)。以上是关于从 Activity 手动更改小部件状态的主要内容,如果未能解决你的问题,请参考以下文章