I am sending an action with a pendingIntent but onRecieve() cant see this action ? how can I handle it ?
and I am not taking any error. and when I look the logs. I have seen only UPDATE ,ENABLED,DISABLE,DELETED actions
public class WidgetDeneme extends AppWidgetProvider {
final String TAG = WidgetDeneme.class.getSimpleName();
final String APPWIDGET_BUTTON_CLICK = "android.appwidget.action.APPWIDGET_BUTTON_CLICK";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
Log.e(TAG,TAG);
final int N = appWidgetIds.length;
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
// Create an Intent to launch ExampleActivity
Intent intent = new Intent(context,WidgetDeneme.class);
intent.setAction(APPWIDGET_BUTTON_CLICK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
RemoteViews views = new RemoteViews(context.getPackageName(), PendingIntent.FLAG_UPDATE_CURRENT);
views.setOnClickPendingIntent(R.id.imageView, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG,intent.getAction());
super.onReceive(context, intent);
}
}
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".WidgetDeneme" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_BUTTON_CLICK" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/appwidget_info" />
</receiver>
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
</activity>
</application>
Make sure you create RemoteViews using the correct layout
// Create an Intent to launch ExampleActivity
Intent intent = new Intent(context,WidgetDeneme.class);
intent.setAction(APPWIDGET_BUTTON_CLICK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// 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.imageView, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
Note R.layout.widget instead of PendingIntent.FLAG_UPDATE_CURRENT. Make sure you actually use the name you gave to the layout, you will find it in the res/layout folder. See Android developer page for more information.
Related
I've an app widget which I would like to print text("OnClicked") to console(or toast) ONLY when the widget is clicked. i.e, I would NOT want the text to be printed when the device is restarted as currently happening.
Is there a way to trigger some method ONLY when the widget is clicked? If so, then how?
In a case that I want to do my action only when the widget is clicked: Do I need to set updatePeriodMillis by 0 value? (android:updatePeriodMillis="0")
This is the implementation of my appwidgetprovider
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// Get all ids
ComponentName thisWidget = new ComponentName(context,
MyWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.my_widget_provider_layout);
// Register an onClickListener
Intent intent = new Intent(context, MyWidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.main_layout, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
Log.d("TAG", "OnClicked");
}
and this is the manifest part:
<receiver android:name="com.example.MyWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/my_widget_info" />
</receiver>
I have simple app with widget. Widget works good for some time. After open and close another app (e.g. some game for the most cases) my widget stops responding to clicks. Do you know how to fix widget freezing please?
I folowed some similar situation, but with no success: Android widget not responding to touches, Android widget buttons stop working, Android Widget stops working randomly, atc.
My actual Widget.class:
public class Widget extends AppWidgetProvider{
private DBManager dbManager;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
String URI_SCHEME = "A";
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
// Create an Intent to launch ExampleActivity
Intent intent = new Intent(context, MainOverview.class);
Intent intent2 = new Intent(context, AddFragment.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent2.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent2.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetId);
intent2.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent2 = PendingIntent.getActivity(context, 0, intent2, 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.widget_all, pendingIntent);
views.setOnClickPendingIntent(R.id.widget_add, pendingIntent2);
Uri data = Uri.withAppendedPath(
Uri.parse(URI_SCHEME + "://widget/id/")
,String.valueOf(appWidgetId));
intent.setData(data);
intent2.setData(data);
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM", Locale.ENGLISH);
final Calendar calendar = new GregorianCalendar();
String text_date = sdf.format(calendar.getTime());
CharSequence sumd = (CharSequence) text_date;
views.setTextViewText(R.id.widget_date, sumd);
dbManager = new DBManager(context);
dbManager.open();
int totalPayed = dbManager.getTotalPayed(text_date);
CharSequence sumw = Integer.toString(totalPayed);
views.setTextViewText(R.id.widget_summary, sumw);
dbManager.close();
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
// Update the widgets via the service
context.startService(intent);
context.startService(intent2);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
#Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
}
}
My actual widget_provider.xml:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="#layout/widget"
android:minHeight="40dp"
android:minWidth="110dp"
android:resizeMode="horizontal|vertical"
android:previewImage="#drawable/logo"
android:updatePeriodMillis="36000000" >
</appwidget-provider>
My actual part of AndroidManifest.xml:
<receiver android:name=".Widget"
android:label="#string/app_name">
<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>
Ok so I've tried almost everything that comes to my mind but this button on my widget doesn't responds at all when touched. I want to open another class and associated xml when the button is clicked but the event does not responds..
following is my onUpdate() code
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, Launch.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget1);
views.setOnClickPendingIntent(R.id.button, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
<receiver
android:name="com.example.widgetexample.ExampleAppWidgetProvider"
android:label="8-bit cloud widget 1" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/widget1_inf" />
</receiver>
The application runs successfully after the error that it stopped un expectedly.widget's adds to the screen but the button doesnt works..p.s Im new to android.Thanks in advance
I'm a little confused with Android app widgets. I understand that I can create a button to start an activity, but I don't see how I can create a button to edit the text of a TextView inside the widget.
Can someone please tell me what I'm missing?
Thanks a lot in advance.
EDIT:
I don't mean for the user to input the new text, I mean for the application to change the text automatically, without any UI (i.e., dialog boxes or activities).
EDIT:
OK, so you set a getBroadcast PendingIntent on your button with setOnClickPendingIntent and perform your update (or call your update method) with the new text from the receiver. Your AppWidgetProvider class can be your receiver (you can catch your intent in onReceive), otherwise you create a new class that extends BroadcastReceiver.
EDIT2 (sample code):
I didn't run/compile this code so hopefully it will not have errors.
This is a simple helper method to get a basic update pending intent with a custom action:
public PendingIntent getRefreshPendingIntent(Context context, int appWidgetId){
Intent intent = new Intent("my.package.ACTION_UPDATE_WIDGET");
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Catch the custom action in onReceive in your overridden AppWidgetProvider class
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
//handle other appwidget actions
if (intent.getAction().equals("my.package.ACTION_UPDATE_WIDGET")) {
//some code here that will update your widget
}
//handle other appwidget actions
}
You will also need to add an IntentFilter for the custom action to your manifest in the appwidget receiver declaration
<receiver
android:name="my.package.MyWidgetProviderClass"
android:label="MyWidget">
<intent-filter>
<action android:name="my.package.ACTION_UPDATE_WIDGET"/>
<!-- other intent filters -->
</intent-filter>
<!-- meta data pointing to widget xml file -->
</receiver>
Finally you apply the pending intent to your RemoteViews where ever you are building it so when the button is clicked it will send the my.package.ACTION_UPDATE_WIDGET action, which will be caught by your AppWidgetProvider, where you can (or call a method to) perform your AppWidget update
myRemoteViews.setOnClickPendingIntent(R.id.id_of_update_button, getRefreshPendingIntent(context, appWidgetId);
This code updates the widget when you click on it , you can edit it and change the listener to your button :
public class MyWidgetProvider extends AppWidgetProvider {
private static final String ACTION_CLICK = "ACTION_CLICK";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// Get all ids
ComponentName thisWidget = new ComponentName(context,
MyWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {
// Create some random data
int number = (new Random().nextInt(100));
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
Log.w("WidgetExample", String.valueOf(number));
// Set the text
remoteViews.setTextViewText(R.id.update, String.valueOf(number));
// Register an onClickListener
Intent intent = new Intent(context, MyWidgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.update, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
}
the complete tutorial is here.
I'm trying to create my first AppWidget using the AlarmManager class so that I can update more frequently than every 30 minutes. I followed this tutorial as a basis for setting up my widget, but for some reason I cannot get the updates to begin properly. It appears as I am never receiving any APPWIDGET_ENABLED intents, which would fire off the onEnabled event callback in my AppWidgetProvider.
Here is the manifest definition for my AppWidgetProvider:
<receiver
android:name="com.myapp.android.appwidget.MarketTimingAppWidgetProvider"
android:label="#string/appwidget_markettiming_label">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="#string/appwidget_markettiming_updateintent" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/appwidget_markettiming_info" />
</receiver>
Here is the code for my AppWidgetProvider:
public class MarketTimingAppWidgetProvider extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
Log.d("myLogger", "onUpdate");
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
Log.d("myLogger", "Updating Widget: " + appWidgetId);
updateWidget(context, appWidgetManager, appWidgetId);
}
}
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.d("myLogger", "onEnabled running");
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 1);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
1000, createClockIntent(context));
}
public void onDisabled(Context context) {
super.onDisabled(context);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(createClockIntent(context));
}
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Log.d("myLogger", "Intent Received " + intent.getAction());
String widgetIntent = context.getResources().getString(R.string.appwidget_markettiming_updateintent);
// This code fires when my custom intent is received
if(widgetIntent.equals(intent.getAction())) {
ComponentName thisAppWidget = new ComponentName(context.getPackageName(), getClass().getName());
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
for(int appWidgetId: ids) {
updateWidget(context, appWidgetManager, appWidgetId);
}
}
}
private void updateWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_markettiming);
views.setTextViewText(R.id.widget_text, "Update: " +
DateFormat.getDateTimeInstance(
DateFormat.LONG, DateFormat.LONG).format(new Date()));
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
private PendingIntent createClockIntent(Context context) {
String updateIntent = context.getResources().getString(R.string.appwidget_markettiming_updateintent);
Log.d("myLogger", "my intent: " + updateIntent);
Intent intent = new Intent(updateIntent);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
}
When I look in LogCat the only intent that is ever recieved by my onReceive method is the initial APPWIDGET_UPDATE intent, and the only callback ever executed is the onUpdate callback. I've tried including the APPWIDGET_ENABLED intent in my appwidget intent-filter (although the docs tell me that this should be automatically received by my widget). It didn't work. Is there just something I'm missing here?
There is an error in your manifest. Action name in this element:
<action android:name="#string/appwidget_markettiming_updateintent" />
should be replaced by actual string, not the reference. So it should be something like this:
<action android:name="com.myapp.android.appwidget.action.MARKETTIMING_UPDATE" />
or whatever you have in your values/something.xml inside the <string name="appwidget_markettiming_updateintent"> element.
The problem is that the BroadcastReceiver does not receives the broadcasts from AlarmManager. I've created a project with your code, replaced only this string in manifest (and added the appropriate value to values/strings.xml of course) and all works fine.
In addition, you may want to replace the second parameter of alarmManager.setRepeating() by just System.currentTimeMillis() + 1000 and remove all those extra Calendar-related stuff.
Apparently uninstalling it from the emulator and then re-installing it did the trick. Now when I add a widget the APPWIDGET_ENABLE intent is received, and when I remove it the APPWIDGET_DISABLED intent is fired like I would expect. I'm still having an issue where the alarm manager does not actually fire off my custom Intent like I expect, but that's a separate issue I'll need to research.