I've been searching for a while on here, but can't find a solution to this. I have a home screen widget with a configuration screen that saves some parameters inside the preferences. The configuration part works flawlessly, but I cannot for the life of me get the setOnClickPendingIntent to register. No error messages.
AndroidManifest.xml
<receiver android:name=".TrunkWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="ActionTrunkButtonClicked" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/trunk_widget_info" />
</receiver>
My App widget provider:
public class TrunkWidget extends AppWidgetProvider {
private SharedPreferences pref;
private final String clickAction = "ActionTrunkButtonClicked";
// UPDATE FUNCTION
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.trunk_widget);
// Instruct the widget manager to update the widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#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) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.trunk_widget);
// Register an onClickListener
Intent intent = new Intent(context, TrunkWidget.class);
intent.setAction(clickAction);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
//Set pendingIntent
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.my_btn, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
String action = intent.getAction();
String actionName = clickAction;
if (actionName.equals(action)) {
//DO STUFF
}
}
I'm pulling my hair on this...if anyone has any idea, I'd be grateful.
Thanks!
Nevermind. I moved this part :
// Register an onClickListener
Intent intent = new Intent(context, TrunkWidget.class);
intent.setAction(clickAction);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
//Set pendingIntent
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.my_btn, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
From onUpdate() to updateAppWidget() and now it works. I'm leaving this here in case someone needs it.
Related
I Have a widget that upon button press I send broadcast to service. But I am not receving any broadcast in my onReceive().
My intention is basically on widget button click, it tellls service to perform some action.
But I am unable to receive any broadcast from widget in service.
Here is my widget code -
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews remoteViews;
ComponentName componentName;
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
componentName = new ComponentName(context, MyWidgetProvider.class);
remoteViews.setOnClickPendingIntent(R.id.play,getPendingSelfIntent(context, "PLAY",componentName));
appWidgetManager.updateAppWidget(componentName, remoteViews);
}
#Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews;
ComponentName componentName;
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
componentName = new ComponentName(context, MyService.class);
if (intent.getAction().equals("PLAY")) {
Log.d("hi","PLAY0");
remoteViews.setOnClickPendingIntent(R.id.engine_lock_unlock,getPendingSelfIntent(context,"PLAY",componentName));
serviceIntent = new Intent(context,MyService.class);
serviceIntent.setAction("PLEASE_PLAY");
Log.d("hi","PLAY1");
context.sendBroadcast(serviceIntent);
}
appWidgetManager.updateAppWidget(componentName, remoteViews);
}
protected PendingIntent getPendingSelfIntent(Context context, String action, ComponentName componentName) {
Intent intent = new Intent(context, MyWidgetProvider.class);
intent.setAction(action);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, componentName);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
In MyService,
public class ServiceWidgetReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("hi","PLAY2");
if (intent.getAction().equals("PLEASE_PLAY")) {
}
}
}
My MAnifest looks like this -
<receiver android:name=".widget.MyWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/homescreen_widget_preview" />
</receiver>
<receiver android:name=".service.MyService$ServiceWidgetReceiver" />
I only get the logs -
PLAY0
PLAY1
Why I dont get my broadcast???
Seams that your receiver has no intent-filter provided. Try to add this in your mainfest file:
<receiver android:name=".service.MyService$ServiceWidgetReceiver">
<intent-filter>
<action android:name="PLEASE_PLAY" />
</intent-filter>
</receiver>
I assume that you have implement the action in intent-filter like Myon said, but the still no broadcast to the onReceive. you may try this:
protected PendingIntent getPendingSelfIntent(Context context, String action, ComponentName componentName) {
Intent intent = new Intent(context, MyWidgetProvider.class);
intent.setAction(action);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, componentName);
//this line replace the original
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
Actually, i have facing the similar problem yesterday that my widget work fine on my android 5.1 phone. However, I find it cannot perform click on android 7.0 sony phone. I still trying to find out whether is the sony phone os problem or android 7.0 or after problem because after the upgrade of the 7.0 or after, there is so many different issues appeared as they changed quite a lot in the API. Anyway, I used the PendingIntent.FLAG_UPDATE_CURRENT solved the problem I have on 7.0
I just think will directly register the receiver class to manifest like this be work. The service binded doesnt directly affect the receive, as the only thing affect the receiver is context. So, maybe just the receive class is enough.
<receiver android:name="packageName.ServiceWidgetReceiver">
<intent-filter>
<action android:name="PLEASE_PLAY" />
</intent-filter>
</receiver>
I found out the mistake I was doing. I had to registerreceiver and unregister it in Service itself rather in Manifest.
This worked for me.
I have an Android app whose service is started when app starts and when app is killed, service is also destroyed.
I have a home screen widget starting alongside with app. It has 3 imageviews - "Play","Next","Previous".
On press of any of these imageview in widget, they need to talk to service and service talks to library etc.
When service has an answer, it responds to widget with status OK or NO. Based on the response, I need to update the imageviews.
When the app is killed, I need to gray out my widget fully. In this situation, when I click on the greyed out widget, I need to start the app. Could anyone help me please
how I could achieve this.
Here is my widget code -
public class MyWidgetProvider extends AppWidgetProvider {
private Intent serviceIntent;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews remoteViews;
ComponentName componentName;
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
componentName = new ComponentName(context, ControlScreenWidgetProvider.class);
remoteViews.setOnClickPendingIntent(R.id.PLAY,getPendingSelfIntent(context, "PLAY",componentName));
remoteViews.setOnClickPendingIntent(R.id.NEXT,getPendingSelfIntent(context, "NEXT",componentName));
remoteViews.setOnClickPendingIntent(R.id.PREVIOUS,getPendingSelfIntent(context, "PREVIOUS",componentName));
appWidgetManager.updateAppWidget(componentName, remoteViews);
}
#Override
public void onReceive(Context context, Intent intent)
{
super.onReceive(context, intent);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews;
ComponentName componentName;
remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
componentName = new ComponentName(context, MyWidgetProvider.class);
if ("PLAY".equals(intent.getAction())) {
remoteViews.setOnClickPendingIntent(R.id.PLAY,getPendingSelfIntent(context, "PLAY",componentName));
// Dont know what to do here
}
else if ("NEXT".equals(intent.getAction())) {
remoteViews.setOnClickPendingIntent(R.id.lock_door,getPendingSelfIntent(context, "NEXT",componentName));
// Dont know what to do here
}
else if ("PREVIOUS".equals(intent.getAction())) {
remoteViews.setOnClickPendingIntent(R.id.lock_door,getPendingSelfIntent(context, "PREVIOUS",componentName));
// Dont know what to do here
}
appWidgetManager.updateAppWidget(componentName, remoteViews);
}
protected PendingIntent getPendingSelfIntent(Context context, String action, ComponentName componentName) {
Intent intent = new Intent(context, MyWidgetProvider.class);
intent.setAction(action);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, componentName);
return PendingIntent.getService(context, 0, intent, 0);
}
}
I am new to Android(started yesterday :))
I am trying to make a simple home-screen widget with a TextView that changes it's value when you tap on it.
Things aren't going so well. It only works after I tap it 3 times and then it works once and never works again. Also the debugger always crashes after I "step over" for the first time.
Manifest:
<application
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name">
<receiver android:name=".GeeDeeBeeDee"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_CLICK" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/gee_dee_bee_dee_info" />
</receiver>
</application>
Widget class:
public class GeeDeeBeeDee extends AppWidgetProvider {
private int DayType = 0;
public static String APPWIDGET_CLICK = "android.appwidget.action.APPWIDGET_CLICK";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// There may be multiple widgets active, so update all of them
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
updateAppWidget(context, appWidgetManager, appWidgetIds[i]);
and then:
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,int appWidgetId)
{
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.gee_dee_bee_dee);
Intent intent = new Intent(APPWIDGET_CLICK);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, appWidgetId, intent, 0);
views.setOnClickPendingIntent(R.id.appwidget_text, pendingIntent );
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override
public void onReceive(Context context, Intent intent)
{
int widgetId = 0;
if (APPWIDGET_CLICK.equals(intent.getAction()))
{
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.gee_dee_bee_dee);
if(DayType == 0)
remoteViews.setTextViewText(R.id.appwidget_text, "0");
else if(DayType == 1)
remoteViews.setTextViewText(R.id.appwidget_text, "1");
else if(DayType == 2)
remoteViews.setTextViewText(R.id.appwidget_text, "2");
if(DayType > 2)
DayType = 0;
Bundle extras = intent.getExtras();
if(extras!=null)
{
widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
if(widgetId > 0)
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
else
super.onReceive(context, intent);
}
Can anyone help, please? Thank you in advance.
I believe the problem is in your onUpdate() method. You may want to check this link: Android: How to update widget text on creation
I hope it will help you.
I am new to this and this is a big headache for me. I have a widget with a provider, a config and an extra activity which is called when you click on the widget. I need to determine the widget ID in the activity.
In the provider I set it to call the activity from onUpdate with a .setOnClickPendingIntent, and in the intent I add the widget ID. When I try to get the widget ID from the intent in the activity, it is always 0 (but the activity is called fine). I can retrieve the ID in the config but not in the activity with the same code.
I'm sure it will be something basic/an amateur mistake. Your help is appreciated!
Truncated code:
Provider:
public static String ACTION_WIDGET_CLICK = "ClickWidget";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
ComponentName thisWidget = new ComponentName(context,
HelloWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Intent clickIntent = new Intent(context, test.class);
clickIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
clickIntent.setAction(ACTION_WIDGET_CLICK);
PendingIntent clickPendingIntent = PendingIntent.getActivity(context, 0, clickIntent, 0);
views.setOnClickPendingIntent(R.id.update, clickPendingIntent);
appWidgetManager.updateAppWidget(widgetId, views);
}
}
So on click, it will call the pendingIntent which will call the activity defined by ACTION_WIDGET_CLICK. Manifest:
<activity android:name=".test">
<intent-filter>
<action
android:name="com.example.widget_create.HelloWidgetProvider.ACTION_WIDGET_CLICK"/>
</intent-filter>
</activity>
So this calls the test actvity:
public class test extends Activity {
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent clickIntent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
}
It doesn't receive the extras and then the widget ID gets set to 0
If the same value is given by getExtras in (for example) the activity, you must change the requestCode (perhaps to the widgetid)
Intent clickIntent = new Intent(context,ActivityName.class);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,myWidgetId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, myWidgetId, clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.layout,pendingIntent);
Can you copy/paste what you get into the console log please ?
Check your Manifest file for the android:name tag, it must be android:name=".Test" with an uppercase.
At onUpdateyou are passing IDS (array of ID)
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
while at your activity your are asking por ID (just one ID)
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
As you are inside a for looping throught every widget ID, you should change the intent at the provider with:
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
Notice the EXTRA_APPWIDGET_ID and the widgetId value instead of the old appWidgetIds.
I'm working on an android widget and it works great in API Level 5 or greater. It's not supported at all in API Level 1 or 2. It should work absolutely fine in 3 and 4 but for some reason the widget doesn't update.
The onUpdate method gets called and executes without errors; however, in 3 and 4 it doesn't change the text of the widget. I'm pretty much at a loss. Any thoughts?
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
DataAccess helper = new DataAccess(context);
String text = helper.getCurrentText();
helper.close();
if (text != null)
views.setTextViewText(R.id.widget_text, text);
Intent intent = new Intent(context, WidgetDetailsActivity.class);
PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.widget, pending);
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
Try this:
At the end of your update method you need to call the super.
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
DataAccess helper = new DataAccess(context);
String text = helper.getCurrentText();
helper.close();
if (text != null)
views.setTextViewText(R.id.widget_text, text);
Intent intent = new Intent(context, WidgetDetailsActivity.class);
PendingIntent pending = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.widget, pending);
appWidgetManager.updateAppWidget(appWidgetIds, views);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
You need to start service on update method and put your all code in service also,here I give onReceive and service demo
context.startService(new Intent(context, UpdateService.class));
public static class UpdateService extends Service {
#Override
public void onStart(Intent intent, int startId) {
// Build the widget update for today
RemoteViews updateViews = buildUpdate(this);
// Push update for this widget to the home screen
ComponentName thisWidget = new ComponentName(this,
Widget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(this);
manager.updateAppWidget(thisWidget, updateViews);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
#Override
public void onReceive(Context context, Intent intent) {
final RemoteViews remoteViews = buildUpdate(context);
ComponentName cn = new ComponentName(context, Widget.class);
AppWidgetManager.getInstance(context).updateAppWidget(cn, remoteViews);
super.onReceive(context, intent);
}
where buildUpdate is method for your widget updating code