My widget consists two relative layouts. I have made both the layouts clickable. Following are the id's of the layout:
android:id="#+id/upper_layout"
android:id="#+id/bottom_layout"
Now, what I need is that if a user clicks on the upper_layout, bottom_layout should be invisible.
Here, is what I have tried so far but it's not working. Can u check what I am doing wrong?
Or, maybe suggest some other ways to achieve this.
Code :
public class BobsWidget extends AppWidgetProvider {
public static String ACTION_WIDGET_RECEIVER = "Clicked";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.main);
Intent active = new Intent(context, BobsWidget.class);
active.setAction(ACTION_WIDGET_RECEIVER);
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context,
0, active, 0);
remoteViews.setOnClickPendingIntent(R.id.upper_layout,
actionPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// check, if our Action was called
if (intent.getAction().equals(ACTION_WIDGET_RECEIVER)) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.main);
remoteViews.setViewVisibility(R.id.bottom_layout, View.INVISIBLE);
}
super.onReceive(context, intent);
}
}
You have several inbuilt widget features available in Anndroid 3.0 or more versions.Check this link
I think you forgot to update the widget.
Have you tried something like this ?
remoteViews.setViewVisibility(R.id.bottom_layout, View.INVISIBLE);
final ComponentName provider = new ComponentName(context, this.getClass());
appWidgetManager.updateAppWidget(provider, views);
Related
I'm trying to have my widget use an onClick action to prompt a refresh. I found some demo code that works, but it opens a URI in browser. I'm having trouble replacing the URI action with something simpler, like displaying a toast. I've marked the line that I'm trying to change, but I don't know how to make Android set a different action other than Action.VIEW.
public class NewAppWidget extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
//I AM TRYING TO CHANGE THIS INTENT
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://google.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.refresh, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override //Nothing changed here
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
}
The specific lines are
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://google.com/"));
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
I got this to work completely unexpectedly. I followed this post but left my intent declarations where they were. The resulting lines were:
Intent intent = new Intent(context, NewAppWidget.class);
intent.setAction(refresh);
intent.putExtra("appWidgetId", appWidgetId);
views.setOnClickPendingIntent(R.id.refresh, PendingIntent.getBroadcast(context,0,intent, PendingIntent.FLAG_UPDATE_CURRENT));
appWidgetManager.updateAppWidget(appWidgetId, views);
followed by onReceive:
#Override
public void onReceive(Context context, Intent intent) {
if(refresh.equals(intent.getAction())) {
Toast.makeText(context, "Clicked", Toast.LENGTH_LONG).show();
}
}
Edit for clarity: intent.getAction() needs to be a registered action within the receiver's intent filter.
I've created widget which can be multiple instantiated with different settings stored in SharedPreferences. After solving initial problem with non-updating widgets directly after Configuration Activity (Multiple, configurable widgets - update issue ) everything seems to be working fine. But. When Home Screen application is killed/rebooted (Trebuchet in my case, Android 4.3 & 4.2.2) widget is not refreshed and onClick listeners are gone (onUpdate action is not triggered). I see only non-responsive, empty WigdetView with default, non-updated layout from xml. What is more weird - after phone reboot or after add another instance of my widget - everything works fine again.
I've tried many different ways to solve this strange issue (like single reference to RemoteViews, use Service instead of AsyncTask etc) - but none of this ideas solved the problem..
There are a lot of important logic in code, shortcut:
AppWidgetProvider:
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
// ASYNCTASK WAY
new DownloadTask(context, appWidgetManager).execute("http://sampleurl/");
/*
// OR SERVICE WAY
// SERVICE LOGIC IS ALMOST THE SAME AS IN DownloadTask
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
Intent intent = new Intent(context.getApplicationContext(), UpdateWidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
context.startService(intent);
*/
}
#Override
public void onReceive(Context context, Intent intent){
Bundle extras = intent.getExtras();
int mAppWidgetId=0;;
if (extras != null) {
mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
String action = intent.getAction();
if (action.equals("PreferencesUpdated")) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_lay);
views.setViewVisibility(R.id.menuLayout, View.GONE);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
int[] appWidgetIds = new int[] {mAppWidgetId};
onUpdate(context, appWidgetManager, appWidgetIds);
}
else if (action.equals("ShowMenu")) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_lay);
views.setViewVisibility(R.id.menuLayout, View.VISIBLE);
appWidgetManager.updateAppWidget(mAppWidgetId, views);
}
super.onReceive(context, intent);
}
DownloadTask
public DownloadTask(Context context, AppWidgetManager appWidgetManager) {
this.context = context;
this.appWidgetManager = appWidgetManager;
}
#Override
protected String doInBackground(String... url) {
// 1. DOWNLOAD FILE
// 2. PROCESS FILE, ADD TO DATABASE, ETC
// 3. UPDATE ALL WIDGETS
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {
SharedPreferences settings = context.getSharedPreferences(PREFS_NAME, 0);
int myPref= settings.getInt("myPref"+widgetId, -1);
if(myPref!= -1){
Log.d("DownloadTask", "widget id:"+widgetId);
updateWidget(db, widgetId, selectedStation);
}
}
db.close();
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
//SHOW PROGRESSBAR (LOADER) ON ALL WIDGETS
//ADD onClicks
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_lay);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {
views.setViewVisibility(R.id.progressLayout, View.VISIBLE);
views.setOnClickPendingIntent(R.id.linearLayout1, getMenuPendingIntent(context, widgetId));
views.setOnClickPendingIntent(R.id.refreshButton, getRefreshPendingIntent(context, widgetId));
views.setOnClickPendingIntent(R.id.settingsButton, getSettingsPendingIntent(context, widgetId));
appWidgetManager.updateAppWidget(widgetId, views);
}
}
#Override
protected void onPostExecute(String result) {
super.onPostExecute(result);
//HIDE PROGRESSBAR (LOADER) ON ALL WIDGETS
ComponentName thisWidget = new ComponentName(context, MyWidget.class);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_lay);
views.setViewVisibility(R.id.progressLayout, View.INVISIBLE);
appWidgetManager.updateAppWidget(thisWidget, views);
if (exception){
Toast.makeText(context, context.getString(R.string.net_exc), Toast.LENGTH_LONG).show();
}
}
public void updateWidget(MySQLiteHelper db, int widgetId, int myPref){
// UPDATE SINGLE WIDGET
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_lay);
views.setTextViewText(R.id.someText, "someText");
// ETC
appWidgetManager.updateAppWidget(widgetId, views);
}
I really hope that you guys can help me, cause I'm stuck.
ps. This is expected behaviour that all widgets are refreshed together.
After having had a similar problem, my widget not working after restart of the launcher/homescreen, here a possible solution:
Whenever accessing your RemoteViews, set the .setOnClickPendingIntent(...) again.
So basically speaking, in your onReceive() where you modify your RemoteViews add the corresponding lines to add the PendingIntents, too, and everywhere else where you might modify those.
PS:
You can drop your for loop iterating over ALL widgetIds and just use
void AppWidgetManager.updateAppWidget(ComponentName provider, RemoteViews views)
to update all your views at once.
Hello friends I am trying to update a widget every user changes the text of texview Anyone can tell me how to do that? I do not know how to do it.
public class MyWidget extends AppWidgetProvider {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
if (intent.getAction().equals(MyService.NEW_DATA)) {
RemoteViews remote = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
remote.setTextViewText(R.id.txtValue, text)
ComponentName widget = new ComponentName(context, MyWidget.class);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
appWidgetManager.updateAppWidget(widget, remote);
}
}}
I think the problem is that you call
super.onReceive(context, intent);
Try not calling it. Everything else looks fine.
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.
Hi i've never worked with widgets before but what i'm looking to do is create a very simple widget i basically want to make a 1 by 1 widget that has just an icon, just an image set as the background no text nothing just a small icon and when the icon is pressed i want to open an activity. Basically i want to make a second icon like in the app drawer in a widget form that opens another activity rather than the main one.
Any help is greatly appreciated
My provider ended up looking like this after a lot of research and playing
public class WidgetProvider extends AppWidgetProvider {
#Override
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, ClassToLaunchHere.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.widget, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
Couple of app widget implementations that show the easiest way to do that are visible at https://github.com/commonsguy/cw-advandroid/tree/master/AppWidget.
Specifically, https://github.com/commonsguy/cw-advandroid/blob/master/AppWidget/PairOfDice/src/com/commonsware/android/appwidget/dice/AppWidget.java shows how to use a PendingIntent as the onClick target for a Button. You can make your PendingIntent start an Activity and you should be good to go.
Declare a Variable
public static String YOUR_AWESOME_ACTION = "YourAwesomeAction";
then add onUpdate and onReceive
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
ComponentName thisWidget = new ComponentName(context, DigitalClock.class);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.digital_clock);
for (int widgetId : appWidgetManager.getAppWidgetIds(thisWidget)) {
remoteViews.setOnClickPendingIntent(R.id.imageView, getPendingSelfIntent(context, YOUR_AWESOME_ACTION));
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
}
}
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
if (YOUR_AWESOME_ACTION.equals(intent.getAction())) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.digital_clock);
ComponentName watchWidget = new ComponentName(context, DigitalClock.class);
appWidgetManager.updateAppWidget(watchWidget, remoteViews);
Intent ntent = new Intent(context, MainActivity.class);
ntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(ntent);
//Toast.makeText(context, YOUR_AWESOME_ACTION, Toast.LENGTH_SHORT).show();
}
}
protected PendingIntent getPendingSelfIntent(Context context, String action) {
Intent intent = new Intent(context, getClass());
intent.setAction(action);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
and add activity on Manifest
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
hope this will help