When I click a button in a widget, a Toast appears. But when I use a configuration activit to set the button's caption and then I click the button, the Toast doesn't appear. Why?
public class MyWidget extends AppWidgetProvider {
public static String ACTION_WIDGET_CONFIGURE = "ConfigureWidget";
public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Intent intent = new Intent(context, MyWidget.class);
intent.setAction(ACTION_WIDGET_RECEIVER);
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
remoteViews.setOnClickPendingIntent(R.id.btn_widget, actionPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews); //update our widget
}
#Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
}
#Override
public void onDisabled(Context context) {
super.onDisabled(context);
}
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
}
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_WIDGET_RECEIVER))
{
Toast.makeText(context, "You have just clicked the button!", Toast.LENGTH_LONG).show();
}
super.onReceive(context, intent);
}
Appwidget-provider xml:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="#layout/widget_layout"
android:minHeight="72dp"
android:minWidth="72dp"
android:configure="com.bfarago.tutorials.widget.ConfigActivity"
>
</appwidget-provider>
Manifest:
<activity
android:name=".ConfigActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<receiver android:name="MyWidget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.bfarago.tutorials.widget.MyWidget.ACTION_WIDGET_RECEIVER"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="#xml/widget_info"/>
</receiver>
Configuration Activity:
public class ConfigActivity extends Activity {
Button btn;
EditText et;
Context c;
AppWidgetManager awm;
int awID;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.config);
btn = (Button)findViewById(R.id.btn);
et = (EditText)findViewById(R.id.et);
c = ConfigActivity.this;
//Getting info about the widget that launched this Activity
Intent i = getIntent();
Bundle extras = i.getExtras();
if (extras != null)
{
awID = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
else
{
finish();
}
awm = AppWidgetManager.getInstance(c);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
String newcaption = et.getText().toString();
RemoteViews views = new RemoteViews(c.getPackageName(), R.layout.widget_layout);
views.setTextViewText(R.id.btn_widget, newcaption);
views.setTextColor(R.id.btn_widget, Color.RED);
awm.updateAppWidget(awID, views);
Intent result = new Intent();
result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, awID);
setResult(RESULT_OK, result);
finish();
}
});
}
}
If I remove the line android:configure="com.bfarago.tutorials.widget.ConfigActivity" from the appwidgetprovider xml, I see the Toast.
Your configure Activity's onClick calls updateAppWidget without having called setOnClickPendingIntent on the RemoteViews it passes in, so once it has run, there will be no click event from your widget. Fix it to be the same as your onUpdate method, or better yet, refactor the code so there's only one function that creates the RemoteViews and calls updateAppWidget.
Related
I saw similar questions here on SO, but nothing seems to work in my case...
I created an appwidget with an AdapterViewFlipper (Simple ViewAnimator that will animate between two or more views that have been added to it). The appwidget has a Next button that enables the user to navigate to the next view on the widget.
It all works fine when I first add the appwidget. But if the smartphone reboots, the Next button of the widget no longer works on my Samsung S4 (the method onReceive is called, but nothings happens, it doesn't navigate to the next view and is stuck at the first view). I have to delete the widget and add it again in order for it to work...
I suspect that it is a problem of Touchwiz since I tested it on another phone (Moto G) and it worked fine.
Here are some portions of my code :
AppWidgetProvider
public class AppWidgetProvider extends AppWidgetProvider {
public static final String NEXT_ACTION = VersionUtil.getPackageName() + ".action.NEXT";
private static final String TAG = DailyAppWidget.class.getSimpleName();
#Override
public void onEnabled(Context context) {
// Enter relevant functionality for when the first widget is created
}
#Override
public void onDisabled(Context context) {
// Enter relevant functionality for when the last widget is disabled
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId, colorValue);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId, int primaryColor) {
Intent intent = new Intent(context, ViewFlipperWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
// When intents are compared, the extras are ignored, so we need to embed the extras
// into the data so that the extras will not be ignored.
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
// Instantiate the RemoteViews object for the app widget layout.
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.app_widget);
// open the activity from the widget
Intent intentApp = new Intent(context, MainActivity.class);
intentApp.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intentApp, 0);
rv.setOnClickPendingIntent(R.id.widget_title, pendingIntent);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
rv.setRemoteAdapter(R.id.adapter_flipper, intent);
} else {
rv.setRemoteAdapter(appWidgetId, R.id.adapter_flipper, intent);
}
// Bind the click intent for the next button on the widget
final Intent nextIntent = new Intent(context,
AppWidgetProvider.class);
nextIntent.setAction(AppWidgetProvider.NEXT_ACTION);
nextIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
final PendingIntent nextPendingIntent = PendingIntent
.getBroadcast(context, 0, nextIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.widget_btn_next, nextPendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, mRemoteViews);
}
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(NEXT_ACTION)) {
RemoteViews rv = new RemoteViews(context.getPackageName(),
R.layout.daily_app_widget);
rv.showNext(R.id.adapter_flipper);
int appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
Log.e(TAG, "onReceive APPWIDGET ID " + appWidgetId);
AppWidgetManager.getInstance(context).partiallyUpdateAppWidget(
appWidgetId, rv);
}
super.onReceive(context, intent);
}
Service
public class FlipperRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
private Context mContext;
private int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
private static final String TAG = "FILPPERWIDGET";
public FlipperRemoteViewsFactory(Context context, Intent intent) {
mContext = context;
mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
//... get the data
}
#Override
public void onCreate() {
Log.e(TAG, "onCreate()");
}
#Override
public void onDataSetChanged() {
Log.i(TAG, "onDataSetChanged()");
}
#Override
public void onDestroy() {
}
#Override
public int getCount() {
//... return size of dataset
}
#Override
public RemoteViews getViewAt(int position) {
Log.i(TAG, "getViewAt()" + position);
RemoteViews page = new RemoteViews(mContext.getPackageName(), R.layout.app_widget_item);
//... set the data on the layout
return page;
}
#Override
public RemoteViews getLoadingView() {
Log.i(TAG, "getLoadingView()");
return new RemoteViews(mContext.getPackageName(), R.layout.appwidget_loading);
}
#Override
public int getViewTypeCount() {
Log.i(TAG, "getViewTypeCount()");
return 1;
}
#Override
public long getItemId(int position) {
Log.i(TAG, "getItemId()");
return position;
}
#Override
public boolean hasStableIds() {
Log.i(TAG, "hasStableIds()");
return true;
}
}
Manifest
<receiver android:name=".AppWidgetProvider"
android:label="#string/app_name"
android:enabled="#bool/is_at_least_12_api">
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/app_widget_info" />
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
</receiver>
<!-- Service serving the RemoteViews to the collection widget -->
<service android:name=".ViewFlipperWidgetService"
android:permission="android.permission.BIND_REMOTEVIEWS"
android:exported="false" />
app wigdet info
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="#layout/app_widget"
android:initialLayout="#layout/app_widget"
android:minHeight="110dp"
android:minWidth="250dp"
android:previewImage="#drawable/widget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="14400000"
android:widgetCategory="home_screen" />
Any help would be appreciated !
Depends on the launcher, there is no guarantee that your AppWidget will be updated immediately after the device started. It may be refreshed immeidately, or wait till the updatePeriodMillis passed after system started.
To solve your problem, define a BroadcastReceiver that will trigger the update of AppWidget after the reboot.
In AndroidManifest.xml, define the BootReceiver to get the boot_complete message.
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver android:name=".BootReceiver" android:enabled="true" android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
And define the BootReceiver.java to start your AppWidgetUpdateService
public class BootReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent){
//start appwidget update service
}
}
I have create a widget in android , whenever i click on Widget TextView one service get starts but at the same time i want to change the icon which is shown on the right side.
I can set a onclick over Widget TextView using
remoteViews.setOnClickPendingIntent(R.id.widgetTxt,pendingIntent);
but i don't know where i can change the icon when the TextView get clicks
image
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {
// Here i am trying to set a onclick over TextView
Intent intent = new Intent(context,MyService.class);
PendingIntent pendingIntent = PendingIntent.getService(context,0 ,
intent, 0);
remoteViews.setOnClickPendingIntent(R.id.MyWidgetTxt,pendingIntent);
}
When an icon itself gets clicked , it changes too and i have set its code in onReceive
try this :
In manifest.xml
<receiver android:name="TestwidgetProvider"
android:label="#string/widget_title" android:exported="false" android:icon="#drawable/test">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.imranandroid.demo.ACTION_ON_ImG_CLICK"/>
<action android:name="android.appwidget.action.APPWIDGET_DELETED"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/widget_info" />
</receiver>
In AppWidgetProvider.java :
public class TestwidgetProvider extends AppWidgetProvider {
public static final String TAG_IMAGE_CLICK = "com.imranandroid.demo.ACTION_ON_ImG_CLICK";
public static RemoteViews rview;
public static int ii=0;
#Override
public void onUpdate(Context paramContext, AppWidgetManager appWidgetManager,
int[] appWidgetIds){
//REMOVE YOUR CODE FROM HERE
updateWidgetState(paramContext, "");
}
#Override
public void onReceive(Context paramContext, Intent paramIntent)
{
String str = paramIntent.getAction();
if (paramIntent.getAction().equals(TAG_IMAGE_CLICK)) {
updateWidgetState(paramContext, str);
}
else
{
super.onReceive(paramContext, paramIntent);
}
}
static void updateWidgetState(Context paramContext, String paramString)
{
RemoteViews localRemoteViews = buildUpdate(paramContext, paramString); //CALL HERE
ComponentName localComponentName = new ComponentName(paramContext, TestwidgetProvider.class);
AppWidgetManager.getInstance(paramContext).updateAppWidget(localComponentName, localRemoteViews);
}
private static RemoteViews buildUpdate(Context paramContext, String paramString)
{
rview = new RemoteViews(paramContext.getPackageName(), R.layout.widget_layoutmain);
Intent active = new Intent(paramContext, TestwidgetProvider.class); //YOUR WIDGET NAME
active.setAction(TAG_IMAGE_CLICK);
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(paramContext, 0, active, 0);
rview.setOnClickPendingIntent(R.id.MyWidgetTxt, actionPendingIntent);
if (paramString.equals(TAG_IMAGE_CLICK)) {
if(ii==0)
{
rview.setImageViewResource(R.id.ImageView01a, R.drawable.off);
ii=1;
}
else
{
rview.setImageViewResource(R.id.ImageView01a, R.drawable.on);
ii=0;
}
}
return rview;
}
}
I have this widget that toggles sound on off but instead of that I want to call another activity (MYxz.class) please tell me what should I change here...
public class AppWidget extends AppWidgetProvider {
#Override
public void onReceive(Context ctxt, Intent intent)
{
if(intent.getAction()==null)
{
ctxt.startService(new Intent(ctxt,ToggleService.class));
}
else
{
super.onReceive(ctxt, intent);
}
}
#Override
public void onUpdate(Context context,AppWidgetManager appWidgetManager, int [] appWidgetIds)
{
context.startService(new Intent(context,ToggleService.class));
//RemoteViews buildUpdate(context);
}
public static class ToggleService extends IntentService
{
public ToggleService() {
super("AppWidget$ToggleService");
}
#Override
protected void onHandleIntent(Intent intent)
{
ComponentName me = new ComponentName(this,AppWidget.class);
AppWidgetManager mgr= AppWidgetManager.getInstance(this);
mgr.updateAppWidget(me,buildUpdate(this));
}
private RemoteViews buildUpdate(Context context)
{
RemoteViews updateViews=new RemoteViews(context.getPackageName(),R.layout.widget);
AudioManager audioManager=(AudioManager)context.getSystemService(Activity.AUDIO_SERVICE);
if(audioManager.getRingerMode()==AudioManager.RINGER_MODE_SILENT)
{
updateViews.setImageViewResource(R.id.phoneState,R.drawable.silent);
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
else {
updateViews.setImageViewResource(R.id.phoneState,R.drawable.phone123);
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
}
Intent i=new Intent(this, AppWidget.class);
PendingIntent pi= PendingIntent.getBroadcast(context,0, i,0);
updateViews.setOnClickPendingIntent(R.id.phoneState,pi);
return updateViews;
}
}
}
Yes possible see example:
Upadte your manifest.xml
<receiver android:name=".AppWidget"
android:label="Caller"
android:icon="#drawable/ic_launcher" >
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.app.example.MyWidget.ACTION_WIDGET_CLICK_RECEIVER"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_provider"
/>
</receiver>
<service android:name=".AppWidget$ToggleService" />
and Update your AppWidgetProvider:
public class MyWidget extends AppWidgetProvider {
public static String ACTION_WIDGET_CLICK_RECEIVER = "ActionReceiverWidget";
public static int appid[];
public static RemoteViews rview;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds){
updateWidgetState(context, "");
}
#Override
public void onReceive(Context paramContext, Intent paramIntent)
{
String str = paramIntent.getAction();
if (paramIntent.getAction().equals(ACTION_WIDGET_CLICK_RECEIVER)) {
updateWidgetState(paramContext, str);
}
else
{
if ("android.appwidget.action.APPWIDGET_DELETED".equals(str))
{
int i = paramIntent.getExtras().getInt("appWidgetId", 0);
if (i == 0)
{
}
else
{
int[] arrayOfInt = new int[1];
arrayOfInt[0] = i;
onDeleted(paramContext, arrayOfInt);
}
}
super.onReceive(paramContext, paramIntent);
}
}
static void updateWidgetState(Context paramContext, String paramString)
{
RemoteViews localRemoteViews = buildUpdate(paramContext, paramString);
ComponentName localComponentName = new ComponentName(paramContext, MyWidget.class);
AppWidgetManager.getInstance(paramContext).updateAppWidget(localComponentName, localRemoteViews);
}
private static RemoteViews buildUpdate(Context paramContext, String paramString)
{
// Toast.makeText(paramContext, "buildUpdate() ::"+paramString, Toast.LENGTH_SHORT).show();
rview = new RemoteViews(paramContext.getPackageName(), R.layout.widget_layout);
Intent active = new Intent(paramContext, MyWidget.class);
active.setAction(ACTION_WIDGET_RECEIVER);
PendingIntent configPendingIntent = PendingIntent.getActivity(paramContext, 0, active, 0);
// upadte this R.id.buttonus1 with your layout or image id on which click you want to start Activity
Intent configIntent = new Intent(paramContext, Caller2.class);
configIntent.setAction((ACTION_WIDGET_CLICK_RECEIVER);
PendingIntent configPendingIntent = PendingIntent.getActivity(paramContext, 0, configIntent, 0);
rview.setOnClickPendingIntent(R.id.Phonestatexx, configPendingIntent);
if(parmString.equals(ACTION_WIDGET_CLICK_RECEIVER))
{
//open Activity here..
//your code for update and what you want on button click
//
}
return rview;
}
#Override
public void onEnabled(Context context){
super.onEnabled(context);
// Toast.makeText(context, "onEnabled() ", Toast.LENGTH_SHORT).show();
}
// Called each time an instance of the App Widget is removed from the host
#Override
public void onDeleted(Context context, int [] appWidgetId){
super.onDeleted(context, appWidgetId);
// Toast.makeText(context, "onDeleted() ", Toast.LENGTH_SHORT).show();
}
// Called when last instance of App Widget is deleted from the App Widget host.
#Override
public void onDisabled(Context context) {
super.onDisabled(context);
// Toast.makeText(context, "onDisabled() ", Toast.LENGTH_SHORT).show();
}
}
Instead of:
Intent active = new Intent(paramContext, AppWidget.class);
You use:
Intent active = new Intent(paramContext, YOURCLASS.class);
before you create the pending intent, #imran khan helped me but there are some tweaks you should do 2...this should fire up the Activity you need.
With using pendingIntents you can call an intent (to your activity or sth else) when a widget item clicked. this may help:
http://www.vogella.de/articles/AndroidWidgets/article.html
i want to create a widget that when clicked on to open a dialog with a autocompletetextview(FROM THE main.class) and execute functions from mainclass.. here is my widget class and please tell me what to put in android manifest also. thx
public class AppWidget extends AppWidgetProvider
{
#Override
public void onReceive(Context ctxt, Intent intent)
{
if(intent.getAction()==null)
{
ctxt.startService(new Intent(ctxt,ToggleService.class));
}
else
{
super.onReceive(ctxt, intent);
}
}
#Override
public void onUpdate(Context context,AppWidgetManager appWidgetManager, int [] appWidgetIds)
{
context.startService(new Intent(context,ToggleService.class));
//RemoteViews buildUpdate(context);
}
public static class ToggleService extends IntentService
{
public ToggleService() {
super("AppWidget$ToggleService");
}
#Override
protected void onHandleIntent(Intent intent)
{
ComponentName me = new ComponentName(this,AppWidget.class);
AppWidgetManager mgr= AppWidgetManager.getInstance(this);
mgr.updateAppWidget(me,buildUpdate(this));
}
private RemoteViews buildUpdate(Context context)
{
RemoteViews updateViews=new RemoteViews(context.getPackageName(),R.layout.widget);
Intent i=new Intent(this, AppWidget.class);
PendingIntent pi= PendingIntent.getBroadcast(context,0, i,0);
updateViews.setOnClickPendingIntent(R.id.phoneState,pi);
return updateViews;
}
}
}
widgetxml//
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ImageView
android:id="#+id/phoneState"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:clickable="true"
android:layout_centerInParent="true"
android:src="#drawable/ic_launcher"
/>
</RelativeLayout>
// and widget_provider.xml in res/xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="79px"
android:minHeight="79px"
android:updatePeriodMillis="1800000"
android:initialLayout="#layout/widget">
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Loading..." />
// and part from my manifest
<receiver android:name=".AppWidget"
android:label="Caller"
android:icon="#drawable/ic_launcher" >
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_provider"
/>
</receiver>
<service android:name=".AppWidget$ToggleService" />
Upadte your manifest.xml
<receiver android:name=".AppWidget"
android:label="Caller"
android:icon="#drawable/ic_launcher" >
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.app.example.MyWidget.ACTION_WIDGET_CLICK_RECEIVER"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_provider"
/>
</receiver>
<service android:name=".AppWidget$ToggleService" />
and Update your AppWidgetProvider:
public class MyWidget extends AppWidgetProvider {
public static String ACTION_WIDGET_CLICK_RECEIVER = "ActionReceiverWidget";
public static int appid[];
public static RemoteViews rview;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds){
updateWidgetState(context, "");
}
#Override
public void onReceive(Context paramContext, Intent paramIntent)
{
String str = paramIntent.getAction();
if (paramIntent.getAction().equals(ACTION_WIDGET_CLICK_RECEIVER)) {
updateWidgetState(paramContext, str);
}
else
{
if ("android.appwidget.action.APPWIDGET_DELETED".equals(str))
{
int i = paramIntent.getExtras().getInt("appWidgetId", 0);
if (i == 0)
{
}
else
{
int[] arrayOfInt = new int[1];
arrayOfInt[0] = i;
onDeleted(paramContext, arrayOfInt);
}
}
super.onReceive(paramContext, paramIntent);
}
}
static void updateWidgetState(Context paramContext, String paramString)
{
RemoteViews localRemoteViews = buildUpdate(paramContext, paramString);
ComponentName localComponentName = new ComponentName(paramContext, MyWidget.class);
AppWidgetManager.getInstance(paramContext).updateAppWidget(localComponentName, localRemoteViews);
}
private static RemoteViews buildUpdate(Context paramContext, String paramString)
{
// Toast.makeText(paramContext, "buildUpdate() ::"+paramString, Toast.LENGTH_SHORT).show();
rview = new RemoteViews(paramContext.getPackageName(), R.layout.widget_layout);
Intent active = new Intent(paramContext, MyWidget.class);
active.setAction(ACTION_WIDGET_RECEIVER);
active.putExtra("msg", "Message for Button 1");
PendingIntent configPendingIntent = PendingIntent.getActivity(paramContext, 0, active, 0);
rmViews.setOnClickPendingIntent(R.id.buttonus1, configPendingIntent);
if(parmString.equals(ACTION_WIDGET_CLICK_RECEIVER))
{
//open a dialog with a autocompletetextview
//your code for update and what you want on button click
}
return rview;
}
#Override
public void onEnabled(Context context){
super.onEnabled(context);
// Toast.makeText(context, "onEnabled() ", Toast.LENGTH_SHORT).show();
}
// Called each time an instance of the App Widget is removed from the host
#Override
public void onDeleted(Context context, int [] appWidgetId){
super.onDeleted(context, appWidgetId);
// Toast.makeText(context, "onDeleted() ", Toast.LENGTH_SHORT).show();
}
// Called when last instance of App Widget is deleted from the App Widget host.
#Override
public void onDisabled(Context context) {
super.onDisabled(context);
// Toast.makeText(context, "onDisabled() ", Toast.LENGTH_SHORT).show();
}
}
I wrote an AppWidget that has a configuration activity(I used the same configuration activity of the app itself)
When adding the Widget to the home screen while on debug mode I pass the widget id(using put extra) to the intent. when clicking on the widget itself(to load the prefs' activity I break at the onCreate method, at the parts where I'm calling intent.getExtras or intent.getIntExtra - I get null.
I wanted to use the following code but couldn;t understand how:
passing-widget-id-to-activity:
The issue was that android does caching with PendingIntents. The solution was to add the FLAG_UPDATE_CURRENT flag which causes it to update the cached PendingIntent.
PendingIntent configPendingIntent = PendingIntent.getActivity(context, REQUEST_CODE_ONE, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
here is my code:
Manifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.dryrun" android:versionCode="3"
android:versionName="1.1" android:installLocation="auto">
<uses-sdk android:minSdkVersion="8" />
<application android:icon="#drawable/ic_launcher_test"
android:label="#string/app_name" android:theme="#android:style/Theme.NoTitleBar.Fullscreen"
android:debuggable="true"><!-- different< android:theme="#style/Theme.NoBackground" -->
<!-- Main Activity -->
<activity android:name=".MyActivity"
android:configChanges="orientation"> <!--android:screenOrientation="portrait" -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!-- Preferences -->
<activity android:name=".Preferences.EditPreferences"
android:configChanges="orientation">
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
</activity>
<!-- Widgets -->
<!-- Widget-->
<receiver android:name=".Widget.testWidget" android:label="#string/app_widget_">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<!--action
android:name="com.test.dryrun.Widget.testWidget.PREFENCES_WIDGET_CONFIGURE" /-->
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/test_widget__provider" />
</receiver>
<service android:name=".Widget.testWidget$WidgetService" />
<uses-permission android:name="android.permission.BIND_REMOTEVIEWS"></uses-permission>
</application>
</manifest>
appwidget_provider xml
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="146dip"
android:updatePeriodMillis="0"
android:initialLayout="#layout/test_widget_"
/>
Widget Class
public class testWidget extends AppWidgetProvider {
public static String PREFENCES_WIDGET_CONFIGURE = "ActionConfigureWidget";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
Intent svcIntent = new Intent(context, WidgetService.class);
context.startService(svcIntent);
}
#Override
public void onReceive(Context context, Intent intent)
{
RemoteViews remoteViews = new RemoteViews(
context.getPackageName(), R.layout.test_widget);
// v1.5 fix that doesn't call onDelete Action
final String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_DELETED.equals(action))
{
final int appWidgetId = intent.getExtras().getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
if (appWidgetId != AppWidgetManager.INVALID_APPWIDGET_ID)
{
this.onDeleted(context, new int[] { appWidgetId });
}
}
else
{
super.onReceive(context, intent);
}
}
//public void updateWidget()
/**
* #param context
* #param remoteViews
*/
public static void updateWidget(Context context, RemoteViews remoteViews)
{
String Prefix = context.getString(R.string._prefix);
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String ToShow = prefs.getString(context.getString(
R.string.Widget_string),
context.getString(R.string.default_string));
String pkgName = context.getPackageName();
int resID = context.getResources().getIdentifier(Prefix + ToShow, "drawable", pkgName);
WidgetController widgetController = WidgetController.getInstance();
widgetController.setRemoteViewImageViewSource(remoteViews, R.id.WidgetImage, resID);
}
public static class WidgetService extends Service
{
#Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
// Update the widget
RemoteViews remoteView = buildRemoteView(this);
// Push update to homescreen
WidgetController.getInstance().pushUpdate(
remoteView,
getApplicationContext(),
testWidget.class);
// No more updates so stop the service and free resources
stopSelf();
}
public RemoteViews buildRemoteView(Context context)
{
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.test_widget_);
Intent runConfigtest = new Intent(context, EditPreferences.class);
runConfigtest.setAction(testWidget.PREFENCES_WIDGET_CONFIGURE);
//old code-what you get in all the widget examples
PendingIntent runtestPendingIntent = PendingIntent.getActivity(context, 0, runConfigtest, 0);
//new code - this is how you should write it
PendingIntent runtestPendingIntent = PendingIntent.getActivity(context, 0, runConfigtest, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.WidgetImage, runtestPendingIntent);
updateWidget(context, remoteViews);
return remoteViews;
}
#Override
public void onConfigurationChanged(Configuration newConfig)
{
int oldOrientation = this.getResources().getConfiguration().orientation;
if(newConfig.orientation != oldOrientation)
{
// Update the widget
RemoteViews remoteView = buildRemoteView(this);
// Push update to homescreen
WidgetController.getInstance().pushUpdate(
remoteView,
getApplicationContext(),
testWidget.class);
}
}
#Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
}
}
Prefences class
public class EditPreferences extends PreferenceActivity implements OnSharedPreferenceChangeListener
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
addPreferencesFromResource(R.xml.preferences);
Intent intent = getIntent();
m_extras = intent.getExtras();
mAppWidgetId = intent.getIntExtra("widget_id", defaultVal);
}
private Bundle m_extras;
#Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key)
{
if(key.equals(getString(R.string.rlvntString)))
{
Context ctx = getApplicationContext();
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(ctx);
setResult(RESULT_CANCELED);
if (m_extras != null)
{
mAppWidgetId = m_extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
RemoteViews views = new RemoteViews(ctx.getPackageName(),
R.layout.test_widget);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
else
{
RemoteViews views = new RemoteViews(ctx.getPackageName(),
R.layout.test_widget);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
}
}
I needed to change the next thing:
//old code-what you get in all the widget examples
PendingIntent runtestPendingIntent = PendingIntent.getActivity(context, 0, runConfigtest, 0);
//new code - this is how you should write it
PendingIntent runtestPendingIntent = PendingIntent.getActivity(context, 0, runConfigtest, PendingIntent.FLAG_UPDATE_CURRENT);
now it works