I have an app widget that sends a broadcast, then a broadcast receiver will start a service, the problem is when clicking the widget it would only work at the first time, then I have to open the app to stop the service.
this the widget code:
public class Widget extends AppWidgetProvider {
int appWidgetId;
RemoteViews views;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i = 0; i < appWidgetIds.length; i++) {
appWidgetId = appWidgetIds[i];
views = new RemoteViews(context.getPackageName(), R.layout.widget);
Intent bIntent = new Intent(context,BroadCast.class);
PendingIntent pIntent = PendingIntent.getBroadcast(context, 0, bIntent,0);
views.setOnClickPendingIntent(R.id.widgetbtn, pIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
The broadcast:
public class BroadCast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent serviceIntent=new Intent(context,Service.class);
if (!isServiceOn) {
context.startService(serviceIntent);
} else {
context.stopService(serviceIntent);
}
}
}
But it works fine when I send the broadcast from the main activity.
Related
Here i have made one widget and added its click listener where i'm starting one service.It works perfectly.But once user force stops application from appinfo my widget's click is not responding.I m not getting why this is happening.Help on this will be appreciated.Thank you
My app widget class code:
MyWidget.java:
public class MyWidget extends AppWidgetProvider {
static Context cont;
static SharedPreferences preferences;
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
cont = context;
Intent intent2 = new Intent();
intent2.setAction("....");
PendingIntent pendingIntent = PendingIntent.
getBroadcast(context, 0,
intent2, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_widget);
views.setOnClickPendingIntent(R.id.appwidget_text, pendingIntent);
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) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
context.startService(new Intent(context, MyService.class));
}
#Override
public void onEnabled(Context context) {
.................. }
#Override
public void onDisabled(Context context) {
.................}
Always use an explicit Intent whenever possible. Your code would not work on Android 8.0 and higher, where implicit broadcasts are banned. And an explicit Intent can move your app out of the stopped state.
I need to create Widgets in my android app similar work flow of contact widgets in android. But the problem facing is if there are n widgets of the same application each widgets have different functionality. how to differentiate the button click on each widgets.?
public class MyWidgetActivity extends AppWidgetProvider {
private static final String MyOnClick = "myOnClickTag";
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
CharSequence widgetText = MyWidgetActivityConfigureActivity.loadTitlePref(context, appWidgetId);
// Construct the RemoteViews object
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.simple_widget);
views.setTextViewText(R.id.appwidget_text, widgetText);
views.setOnClickPendingIntent(R.id.actionButton, getPendingSelfIntent(context, MyOnClick,views.getLayoutId()));
// 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) {
updateAppWidget(context, appWidgetManager, appWidgetId);
// Tell the AppWidgetManager to perform an update on the current app
// widget
}
}
#Override
public void onDeleted(Context context, int[] appWidgetIds) {
// When the user deletes the widget, delete the preference associated with it.
for (int appWidgetId : appWidgetIds) {
MyWidgetActivityConfigureActivity.deleteTitlePref(context, appWidgetId);
}
}
#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 onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (MyOnClick.equals(intent.getAction()))
{
int appWidgetId = intent.getIntExtra(EXTRA_APPWIDGET_ID,0);
Log.e("KOKOKOKO :: ",""+appWidgetId);
MyWidgetActivityConfigureActivity.loadIdPrefCallQuick(context,appWidgetId);
//your onClick action is here
Toast.makeText(context,"Quick Action Triggered",Toast.LENGTH_SHORT).show();
}
super.onReceive(context, intent);
}
static PendingIntent getPendingSelfIntent(Context context, String action, int appWidgtId)
{
// if we brodcast than definetly we have to define ONRECEIVE
Intent intent = new Intent(context, MyWidgetActivity.class);
intent.putExtra(EXTRA_APPWIDGET_ID,appWidgtId);
intent.setAction(action);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
}
Instead of this code (static PendingIntent getPendingSelfIntent) :
return PendingIntent.getBroadcast(context, 0, intent, 0);
You should do this :
return PendingIntent.getBroadcast(context, appWidgtId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
This way you should get unique intent and also unique appWidgtId.
It is important to set requestCode (2nd attribute of getBroadcast), so it wouldn't conflict.
How can we updating the View of a Home Screen Widget on the onReceive method of AppWidgetProvider?.I am trying to update the listview of my Home screen widget but it seems that I cant access the listview of my AppWidgetProvider on onReceive method.My problem is when i changes in my application and come back to the home screen that the widget has no modification.Here is a sample code of my onReceive
public class WidgetTaskSchedular extends AppWidgetProvider {
private final String TAG = "CalendarViewSample:"
+ this.getClass().getName();
static int ID;
int[] sameid=new int[1];
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if(intent.getAction().equals("update_widget"))
{
Log.i(TAG,"AppWidgetIds:"+ID);
for(int i=0;i<1;i++)
{
sameid[i]=ID;
Log.i(TAG,"SameId:"+sameid[i]);
onUpdate(context, AppWidgetManager.getInstance(context),sameid);
}
}
}
public static String EXTRA_WORD=
"com.capsone.testing.calendar.WORD";
#SuppressWarnings("deprecation")
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i=0; i<appWidgetIds.length; i++) {
ID=appWidgetIds[i];
Log.i(TAG,"LengthofWidget:"+appWidgetIds.length);
Log.i(TAG,"TestAppWidget:"+appWidgetIds[i]);
Intent intentWidgetService=new Intent(context, WidgetService.class);
intentWidgetService.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
intentWidgetService.setData(Uri.parse(intentWidgetService.toUri(Intent.URI_INTENT_SCHEME)));
RemoteViews remoteView=new RemoteViews(context.getPackageName(),
R.layout.widgetlayout);
remoteView.setRemoteAdapter(appWidgetIds[i], R.id.listWidget,
intentWidgetService);
Intent clickIntent=new Intent(context, ActionBarActivity.class);
PendingIntent clickPendingIntent=PendingIntent
.getActivity(context, 0,
clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteView.setPendingIntentTemplate(R.id.listWidget, clickPendingIntent);
ComponentName component=new ComponentName(context,WidgetTaskSchedular.class);
appWidgetManager.updateAppWidget(component, remoteView);
}
}
}
MainActivity class:
In this main class i change some modification and broadcast this to widget class using on pause method:
#Override
public void onPause() {
super.onPause();
Intent updateWidget = new Intent(getActivity(), WidgetTaskSchedular.class);
updateWidget.setAction("update_widget");
PendingIntent pending = PendingIntent.getBroadcast(getActivity(), 0, updateWidget, PendingIntent.FLAG_CANCEL_CURRENT);
try {
pending.send();
} catch (CanceledException e) {
e.printStackTrace();
}
}
I'm trying How do I run an Activity from a button on a widget in Android? in order to launch my application on click on an image button. When i un-comment the code it switches the images but when i try to use this code it does nothing. I'd like to kick off my application instead.
public class MyWidgetIntentReceiver extends BroadcastReceiver {
private static int clickCount = 0;
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("pl.looksok.intent.action.CHANGE_PICTURE")){
updateWidgetPictureAndButtonListener(context);
}
}
private void updateWidgetPictureAndButtonListener(Context context) {
Log.i("PROJECTCARUSO", "updateWidgetPictureAndButtonListener");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
// remoteViews.setImageViewResource(R.id.widget_button, getImageToSet());
//
// //REMEMBER TO ALWAYS REFRESH YOUR BUTTON CLICK LISTENERS!!!
// remoteViews.setOnClickPendingIntent(R.id.widget_button, MyWidgetProvider.buildButtonPendingIntent(context));
//
// MyWidgetProvider.pushWidgetUpdate(context.getApplicationContext(), remoteViews);
Intent intentClick = new Intent(context, FragmentChange.class);
PendingIntent pendingIntent = PendingIntent.getActivity (context, 0,
intentClick, 0);
remoteViews.setOnClickPendingIntent (R.id.widget_button, pendingIntent);
}
private int getImageToSet() {
clickCount++;
return clickCount % 2 == 0 ? R.drawable.app_icon : R.drawable.energy;
}
}
Here's what i finally got to work:
public class WidgetProvider extends AppWidgetProvider {
public static String SWITCH_WIDGET_UPDATE = "MainActivity.Switch";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.i("PROJECTCARUSO","onUpdate");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
remoteViews.setOnClickPendingIntent(R.id.widget_button, buildButtonPendingIntent(context));
Intent intentClick = new Intent(context, FragmentChange.class);
PendingIntent pendingIntent = PendingIntent.getActivity (context, 0, intentClick, 0);
remoteViews.setOnClickPendingIntent (R.id.widget_button, pendingIntent);
pushWidgetUpdate(context, remoteViews);
}
public static PendingIntent buildButtonPendingIntent(Context context) {
Intent intent = new Intent();
intent.setAction("CHANGE_PICTURE");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
ComponentName myWidget = new ComponentName(context, WidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
}
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
}
}
Why doesn't recieve get called when I click on Button wid??
Code:
public class Widget extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int i = 0; i < appWidgetIds.length; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, Widget.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.wid, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
Log.d("ARH","CLICKK");
}
Becuase I need a button to manual refresh the widget but it seems that Log.d("ARH","CLICKK"); only gets called when i add the Widget.
Thanks!
You using a PendingIntent to call an Activity but your Widget class is not an activity.
If you want to update to your widget, then you need to use getBroadcast that sends an APPWIDGET_UPDATE action.