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.
Related
I have no idea why this is happening. I'm making widgets which show the best currency rate for the currencies that the user chooses. I've noticed after a reboot, they sometimes turn into a clock and a calendar widget. Here's my code. I assume it could be something with my Intents or OnReceive() but I'm not sure what.
public class LightRowWidget extends RowWidget {
List<CurrencyObject> currencyObjects = new ArrayList<>();
public LightRowWidget() {
super(R.layout.widget_row_layout, R.color.white, Constants.FULL_OPACITY, R.color.black);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
if (appWidgetIds != null && appWidgetIds.length > 0) {
for (int appWidgetId : appWidgetIds) {
// Create currencyObjects. They're used to assign the correct value
// to the correct texView
CurrencyObject currObj1 = new CurrencyObject(
R.id.currency1, R.id.currency1_buy, R.id.currency1_sell);
currencyObjects.add(currObj1);
CurrencyObject currObj2 = new CurrencyObject(R.id.currency2, R.id.currency2_buy, R.id.currency2_sell);
currencyObjects.add(currObj2);
// Register an onClickListener to Update the current widget on a click
Intent clickIntent = new Intent(context, LightRowWidget.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
onUpdate(context, appWidgetManager, appWidgetId, currencyObjects, clickIntent);
}
//start an intent that will schedule the alarm for the next update
Intent startIntent = new Intent(context, LightRowWidget.class);
scheduleNextUpdate(context, startIntent, appWidgetIds);
}
and Here is my RowWidget class with the relevant code.
public abstract class RowWidget extends AppWidgetProvider implements WidgetInterface{
public RowWidget(int layout, int background_color, int background_opacity, int text_color){
super();
this.layout = layout;
this.background_color=background_color;
this.background_opacity=background_opacity;
this.text_color=text_color;
}
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int appWidgetId, List<CurrencyObject> currencyObjects, Intent clickIntent) {
theAppWidgetManager = appWidgetManager;
//Get the current name of class
String currentClass = this.getClass().getName();
switch(currentClass){
case("foobar"):
configure_class=Constants.FOUR_ROW_CONFIGURE;
break;
case("foo"):
configure_class=Constants.ROW_APP_WIDGET_LIGHT_CONFIGURE;
break;
case("bar"):
configure_class=Constants.ROW_APP_WIDGET_DARK_CONFIGURE;
break;
case("barfoo"):
configure_class=Constants.TWO_ROW_CONFIGURE;
break;
}
// There may be multiple widgets active, so update all of them
// Get the preferred Currencies
Set<String> preferredCurrencies = AppWidgetConfigure.loadCurrencyPref(context,appWidgetId, configure_class);
// Inflate the layout
RemoteViews view = new RemoteViews(context.getPackageName(), layout);
// if the preferred Currencies have been declared already
if(preferredCurrencies!= null){
// Set the currencies for each object
for(String currency: preferredCurrencies){
if(currencyCount<currencyObjects.size()){
currencyObjects.get(currencyCount).setCurrencyType(currency);
currencyCount+=1;
}
}
}
else{
for(CurrencyObject curObj:currencyObjects){
curObj.setCurrencyType("RUB");
}
}
// Open up the Currency fragment on the click of the widget
Intent configIntent = new Intent(context, MainActivity.class);
configIntent.putExtra("LaunchCurrency", true);
configIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent configPendingIntent = PendingIntent.getActivity(context, 0, configIntent, 0);
view.setOnClickPendingIntent(R.id.row_widget_layout, configPendingIntent);
// Update the widget whenever refresh button clicked
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,
0, clickIntent, PendingIntent.FLAG_UPDATE_CURRENT);
view.setOnClickPendingIntent(R.id.refresh, pendingIntent);
makeRequest(context, theDate, view, currencyObjects, appWidgetId);
currencyCount = 0;
}
//Handle receiving the intent
#Override
public void onReceive(Context context, Intent intent){
if (intent.getAction().equals(ACTION_APPWIDGET_UPDATE)) {
AppWidgetManager manager = AppWidgetManager.getInstance(context);
// Get id's
int[] allWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
onUpdate(context, manager, allWidgetIds);
}
else{
super.onReceive(context, intent);
}
}
EDIT: Widgets transform to a lot of different widgets that are already on my screen.
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 am trying to create a simple widget. I wanted that, when touchet, to show a toast. But it does not show anything. I don't know where I'm wrong, it looks quite well(maybe i have forgotten something i didn't notice).
Code:
static String clAc = "CLICKED";
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
Intent intent = new Intent(context, LocationWidget.class);
intent.setAction(clAc);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0, intent,0);
Paper.init(context);
String title = Paper.book().read("content");
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.location_widget);
views.setTextViewText(R.id.appwidget_text, title);
views.setOnClickPendingIntent(R.id.layout_wrapper, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, 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(intent.getAction().contentEquals(clAc))
Toast.makeText(context, "clicked",Toast.LENGTH_LONG).show();
}
Try to update not each appWidgetId, but all appWidgetIds with your logic.
I want to add a button in my widget so that it can run a function(change APN and display a changed message in the widget) by press a button. In fact, the function is worked since I have tested in an activity. Did anyone have idea how to do it? thanks!
Regards,
Bill Chan
Well, there is couple of ways.
For example you can make something like this inside registered AppWidgetProvider:
public static String ACTION_WIDGET_RECEIVER = "Action!";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
Intent active = new Intent(context, ThisClass.class);
active.setAction(ACTION_WIDGET_RECEIVER);
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context,
0, active, 0);
remoteViews.setOnClickPendingIntent(R.id.button, actionPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}
#Override
public void onReceive(Context context, Intent intent) {
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 {
if (intent.getAction().equals(ACTION_WIDGET_RECEIVER)) {
doYourStuff();
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.