I created a class that downloads some text from the internet and I want to take that text and update a TextView in my widget. I know that the event (OnDownloadCompleteListener) is getting triggered because I'm Logging it but I can't figure out how to update the TextView from within that event. I know it's a newbie mistake, just not sure what I'm missing.
public class Widget extends AppWidgetProvider{
InternetText internettext; //Handles downloading the text from the internet
RemoteViews views;
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
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, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
// Get the layout for the App Widget and attach an on-click listener
// to the button
views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.tvWidgetVerse, pendingIntent);
internettext = new InternetText(context);
internettext.setOnDownloadCompleteListener(new OnDownloadCompleteListener() {
#Override
public void onEvent() {
TheText thetext = internettext.downloadedText(); //The text object
Log.i("", "Widget Text Downloaded " + thetext.getText()); //This fires so I know we've downloaded the text
TextStyling textStyle = new TextStyling();
//*****THIS IS WHERE I'M HAVING THE PROBLEM********
views.setTextViewText(R.id.tvWidgetText, Html.fromHtml(textStyle.boldWords(thetext.getText()))); //this never updates
}
});
internettext.getText();
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
Ok, I figured it out. I have to call appWidgetManager.updateAppWidget() from within the event. I knew it was a no-brainer...
appWidgetManager.updateAppWidget(appWidgetId, views);
which also means I have to make appWidgetManager and appWidgetId final
public void onUpdate(Context context, final AppWidgetManager appWidgetManager, int[] appWidgetIds) {
...
}
Related
Good Day! I want to add text from inside application to widget, i have a main activity and it has list view and lots of text contents and it has a button to add the text to widget via shared preference, it's works fine when i close the widget and recreate it only, otherwise it's not automatically refresh.if anyone know; how to solve this please help me. here i attached the widget code below.
public class WidgetMaster extends AppWidgetProvider {
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
Intent intentHome = new Intent(context, MainActivity.class);
PendingIntent pendingIntentHome = PendingIntent.getActivity(context, 0, intentHome, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_master);
views.setOnClickPendingIntent(R.id.wid_home, pendingIntentHome);
final SharedPreferences sharedPreferencestoWi = context.getSharedPreferences(String.valueOf(R.string.addTextToWidgetPref), MODE_PRIVATE);
String forWidget = sharedPreferencestoWi.getString("textToWidget", "");
String dum = "add from reading";
if(forWidget.equals("")){
views.setTextViewText(R.id.dum_appwidget_text, dum);
appWidgetManager.updateAppWidget(appWidgetId, views);
} else {
views.setTextViewText(R.id.appwidget_text, forWidget);
views.setViewVisibility(R.id.appwidget_text, 0);
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 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
}
}
How do you update the widget from mainActivity?
In the widget configuration file you can specify a fixed update interval. The smallest update interval is 1800000 milliseconds (30 minutes).
But its better to update widget programmatically, to do this You should send a broadCast to update widget and use a
method like alarmManager or Handler for a repeating task for example you can use the following broadCast to update widget form mainActivity:
Intent intent = new Intent(this, WidgetMaster.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
int[] ids = AppWidgetManager.getInstance(getApplication())
.getAppWidgetIds(new ComponentName(getApplication(),WidgetMaster.class));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
sendBroadcast(intent);
I want my activity "but1" to update the text on my widget button through button in my but1 activity. I've tried and it shows no error but still the widget doesn't updates. Is it something Im missing in manifest file?Moreover the log cat also doesnt show any problem
following is my code in But1.class
et1.setOnClickListener(new OnClickListener() {
Intent in=new Intent();
Bundle extras=in.getExtras();
if(extras!=null)
{
awID=extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID,AppWidgetManager.INVALID_APPWIDGET_ID);
}
aw=AppWidgetManager.getInstance(context);
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
RemoteViews rv=new RemoteViews(context.getPackageName(),R.layout.activity_main);
rv.setTextViewText(R.id.button1, "Mughazf,f,jvnl");
aw.updateAppWidget(awID, rv);
Intent result=new Intent();
result.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, awID);
setResult(RESULT_OK,r
esult);
and my widget is:
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onUpdate(context, appWidgetManager, appWidgetIds);
final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, But1.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.activity_main);
views.setOnClickPendingIntent(R.id.button2, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
Problem should be with the Widget App ID . You need to keep remembering the Widget ID to update it later.
Your Widget Provider onUpdate() method should store the Widget id in shared preference or database
I am using shared preference here,
SharedPreferences prefs = context.getSharedPreferences("private preference", Context.MODE_PRIVATE);
// here i am saving one widget id. change your logic to store all the widget id's
prefs.edit().putInt("WidgetId",appWidgetId).commit();
Then when the Activity is launched and button clicked. You can update the widget layout like this
First Read the Widget ID from shared Preference
SharedPreferences prefs = getSharedPreferences("private preference", Context.MODE_PRIVATE);
int awID = prefs.getInt("WidgetId", AppWidgetManager.INVALID_APPWIDGET_ID);
Then, create the instance of RemoteView and set the new text to the TextView
RemoteViews rv=new RemoteViews(getPackageName(),R.layout.widget_layout);
rv.setTextViewText(R.id.textView1, "Some one updated Me");
Then , get the instance of AppWidget Manager
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
And, Finally update the Widget with new RemoteView Layout.
appWidgetManager.updateAppWidget(awID, rv);
So, awID - is the Widget Id what we got from onUpdate method.
This should work. Let me know if you see any issue.
I am trying to make a widget for my app, and I want it to be with a buttonm progress bar and text view, which would later be changed, so I need to somehow work with the views themselves, like I can from an activity, show a view, hide a view, change a button background etc...
I tried tweaking with the sample code from the Android documentations, but I can only start an activity with this
public class WidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, ActivityMain.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
views.setOnClickPendingIntent(R.id.sync_button, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
}
Does the widget need to be connected to an activity in order to make actions (connect to the internet, write in the database, write in the objects of the apps instance (if there is one))? And can I work with views the way I am asking?
Outside of setting on-click PendingIntents on views, there isn't much you can do inside of a widget. The standard recipe is:
Make a PendingIntent that sends a broadcast (PendingIntent.getBroadcast()) and set it on the appropriate view in your widget.
In the BroadcastReceiver that receives the intent, you update the widget to show a spinner and start a Service to do whatever long-running work you want to do (e.g connect to the internet).
Once that work is done, you can update your widget again and remove the spinner.
I have an appwidget which contains a listview and a buton
the listview gives data from remote mysql database mysql and it display it
but the button I want to us it to refresh listview from appwidget directly and don't wait for time defined in appwidgetinfo
here is my widgetprovider class :
public class WidgetProvider extends AppWidgetProvider {
// String to be sent on Broadcast as soon as Data is Fetched
// should be included on WidgetProvider manifest intent action
// to be recognized by this WidgetProvider to receive broadcast
public static final String DATA_FETCHED = "com.wordpress.laaptu.DATA_FETCHED";
/*
* this method is called every 30 mins as specified on widgetinfo.xml this
* method is also called on every phone reboot from this method nothing is
* updated right now but instead RetmoteFetchService class is called this
* service will fetch data,and send broadcast to WidgetProvider this
* broadcast will be received by WidgetProvider onReceive which in turn
* updates the widget
*/
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++) {
Intent serviceIntent = new Intent(context, RemoteFetchService.class);
serviceIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
appWidgetIds[i]);
context.startService(serviceIntent);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
private RemoteViews updateWidgetListView(Context context, int appWidgetId) {
// which layout to show on widget
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
// RemoteViews Service needed to provide adapter for ListView
Intent svcIntent = new Intent(context, WidgetService.class);
// passing app widget id to that RemoteViews Service
svcIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
// setting a unique Uri to the intent
// don't know its purpose to me right now
svcIntent.setData(Uri.parse(svcIntent.toUri(Intent.URI_INTENT_SCHEME)));
// setting adapter to listview of the widget
remoteViews.setRemoteAdapter(appWidgetId, R.id.listViewWidget,
svcIntent);
// setting an empty view in case of no data
remoteViews.setEmptyView(R.id.listViewWidget, R.id.empty_view);
return remoteViews;
}
/*
* It receives the broadcast as per the action set on intent filters on
* Manifest.xml once data is fetched from RemotePostService,it sends
* broadcast and WidgetProvider notifies to change the data the data change
* right now happens on ListProvider as it takes RemoteFetchService
* listItemList as data
*/
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(DATA_FETCHED)) {
int appWidgetId = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
RemoteViews remoteViews = updateWidgetListView(context, appWidgetId);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
}
I used the code-source of this tutorial here
I added the button in the layout with refresh_button id
but I don't know how to launch update of listview when user press it
how can I fix this issue
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetIds[i], R.id.listViewWidget);
add the above code in AppWidgetProvider.onUpdate method this will give call to your onDataSetChanged() method with the help of that you can refresh the listview
I had the same problem but finally solved it
i am developing android widget and i displayed some data on that widget from web service and its working fine.Hear is the code for that.
CODE
public class WatchWidget extends AppWidgetProvider{
private static final String TAG = "WatchWidget";
#Override
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds ){
Log.i(TAG, "* onUpdate");
EBWeaterData ebwd=new EBWeaterData();
EBWeatreUtils.getWeatherFeeds(context, ebwd, "my url to get data");
RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.main);
RemoteViews newView = new RemoteViews(context.getPackageName(), R.layout.test);
//get data
String day=ebwd.getDay_1()+ebwd.getDay_suffix_1()+" "+ebwd.getDay_name_1();
String minmaxtemp="Max Temp "+ebwd.getDay_max_temp_1()+"°C "+"Min Temp "+ebwd.getDay_min_temp_1()+"°C";
//set dat to views
newView.setTextViewText(R.id.textView_day_name, day);
newView.setTextViewText(R.id.textView_minmaxtemp, minmaxtemp);
newView.setImageViewResource(R.id.ImageView_icon, R.drawable.sunny);
views.addView(R.id.view_container, newView);
ComponentName thisWidget = new ComponentName(context,WatchWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(thisWidget, views);
}
}
i have a button on that widget now i want to update the widget view with different values when user clicks on the button.I know I have to do with it pendingIntent like following.
Intent intent = new Intent(context, activitytogetNewdata.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.imageView1, pendingIntent);
But it will start another activity i dont want to go to anther activity.I just need to do is to update the same widget view with new values after button click.Any Idea??
I have found the problem of my code.when i going to update my view using pendingintent it will dynamically add view on each and every button click because i have used 2 layout hear so i solved the problem as follows.(i use one layout instead of using two)
CODE
public class WatchWidget extends AppWidgetProvider{
private static final String TAG = "WatchWidget";
#Override
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds ){
Log.i(TAG, "* onUpdate");
EBWeaterData ebwd=new EBWeaterData();
EBWeatreUtils.getWeatherFeeds(context, ebwd, "my url to get data");
RemoteViews newView = new RemoteViews(context.getPackageName(), R.layout.test);
//get data
String day=ebwd.getDay_1()+ebwd.getDay_suffix_1()+" "+ebwd.getDay_name_1();
String minmaxtemp="Max Temp "+ebwd.getDay_max_temp_1()+"°C "+"Min Temp "+ebwd.getDay_min_temp_1()+"°C";
//set dat to views
newView.setTextViewText(R.id.textView_day_name, day);
newView.setTextViewText(R.id.textView_minmaxtemp, minmaxtemp);
newView.setImageViewResource(R.id.ImageView_icon, R.drawable.sunny);
ComponentName thisWidget = new ComponentName(context,WatchWidget.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(thisWidget, newView);
}
Go through this tutorial.
Visit http://www.developer.com/ws/android/programming/Handling-User-Interaction-with-Android-App-Widgets-3837531.htm
They have solved the problem what you have.