How add app widget provider class - android

https://developer.android.com/guide/topics/appwidgets/index.html
It explains how to declare it in Manifest:
<receiver android:name="ExampleAppWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/example_appwidget_info" /> </receiver>
And later it says how to add class:
public class ExampleAppWidgetProvider extends AppWidgetProvider {
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, ExampleActivity.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
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.appwidget_provider_layout);
views.setOnClickPendingIntent(R.id.button, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
} }
And it says I need to declare the class as a broadcast receiver.
So My question is: I have the receiver in my app, but how do I add the class and declare it as a broadcast receiver?
It would be helpful if someone posted an example code of receiver with class, so I know how to put it together.
I'm sorry if this is a stupid question, I'm just new to this all.

Right from the docs:
The AppWidgetProvider class extends BroadcastReceiver as a convenience
class to handle the App Widget broadcasts. The AppWidgetProvider
receives only the event broadcasts that are relevant to the App
Widget, such as when the App Widget is updated, deleted, enabled, and
disabled.
In other words: Since your ExampleAppWidgetProvider is inheriting from AppWidgetProvider class it's also a BroadcastReceiver since the AppWidgetProvider extends android.content.BroadcastReceiver. So there's no need to declare your class explicity as a broadcast receiver. Furthermore that's what the docs say (once again):
You must declare your AppWidgetProvider class implementation as a
broadcast receiver using the receiver element in the AndroidManifest
And as I see it, you already did that. ;)

Related

How can i update a widget only when i press a button in an activity from within the main app

I have made an app consisting of 5 activities . I just wanted to know how I could update a widget only when I press a button in the present in an activity in the main app
You need a reciever for your widget declared in the manifest.xml:
<receiver
android:label="MyIP Widget"
android:icon="#drawable/ic_launcher"
android:name="Widget" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/example_appwidget_info" />
</receiver>
That block should be inside the application block.
In my example the widget updates upon connectivity state change. You can replace that with a custom intent. And, from your activity, you need to send that intent to update the widget, something like this:
Intent i = new Intent();
i.setAction(CUSTOM_INTENT);
context.sendBroadcast(i);
where
public static final String CUSTOM_INTENT = "jason.wei.custom.intent.action.TEST";
you can pick the name that you want.
And make sure to add the same name in the reciever:
<action android:name="jason.wei.custom.intent.action.TEST" />
UPDATE:
to receive you broadcast, you need this method in your Widget class
public class Widget extends AppWidgetProvider {
...
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context,intent);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context.getApplicationContext());
ComponentName thisWidget = new ComponentName(context.getApplicationContext(), Widget.class);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
if (appWidgetIds != null && appWidgetIds.length > 0) {
onUpdate(context, appWidgetManager, appWidgetIds);
}
}
The code above may look a bit complex but it is needed to update all the instances of your widget (the user may have your widget on different home screens or even at one screen).
As you can see, it calls the onUpdate method, where you set the actions you want to be executed to update the widget:
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
//your update code here
}

listview in app widget android

hi friends enter link description here
this link to create list view widget for my app, but here i want to add a button below the list view ,which on click will open my app,
using the below code to acheive this,because it worked for me on other app, but not with this example, how to do that .
class widgetprovider
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) {
// which layout to show on widget
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget_layout);
Intent informationIntent = new Intent(context,info.class);
PendingIntent infoPendingIntent = PendingIntent.getActivity(context,0, informationIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.btnSeeMore,infoPendingIntent);
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);
}
manifest added a activity
<activity android:name=".info" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.INFO" />
</intent-filter>
</activity>
when on click it should open my app,how to do that please help, thank you
finaly i solved what i want to get,
just wrote a button click code onReceive & it worked
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(DATA_FETCHED)) {
Log.i("inside action", "DATA_FETCHED");
int appWidgetId = intent.getIntExtra(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
RemoteViews remoteViews = updateWidgetListView(context, appWidgetId);
Intent informationIntent = new Intent(context,MainActivity.class);
PendingIntent infoPendingIntent = PendingIntent.getActivity(context,0, informationIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.txtSeeMore,infoPendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
You need to define how the PendingIntent you are setting will be handled, by overriding the onReceive method inside your provider :
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(ACTION_NAME)) {
// Open your activity here.
}
}
If every item in your ListView needs a different extra to help the onReceive create the proper Intent, you can use a FillInIntent for each item of the ListView, in getViewAt :
// Set the onClickFillInIntent
final Intent fillInIntent = new Intent();
final Bundle extras = new Bundle();
extras.putInt(YourWidgetProvider.ACTION_EXTRA_ITEM, event.getId()); // retrieve this in onReceive with intent.getIntExtra(ACTION_EXTRA_ITEM, -1)
fillInIntent.putExtras(extras);
rv.setOnClickFillInIntent(R.id.listview_main_layout, fillInIntent);
return rv;
Also, don't forget to add your Provider and your RemoteViewsService to your Manifest :
<receiver
android:name="com.example.YourWidgetProvider"
android:label="#string/widget_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/provider_definition_in_xml" />
</receiver>
<service android:name="com.example.YourRemoteViewsService"
android:permission="android.permission.BIND_REMOTEVIEWS"
android:exported="false" />
EDIT :
To handle clicks on buttons in the main widget (not in the collection view), it's even easier :
rv.setOnClickPendingIntent(R.id.button_id, PendingIntent.getBroadcast(context, 0,
new Intent(context, YourWidgetProvider.class)
.setAction(ACTION_NAME),
PendingIntent.FLAG_UPDATE_CURRENT));
The ACTION_NAME needs to be different from the name you use for the clicks on the collection view, of course, since it needs to produce a different Intent.
I hope this helps !

Android Widget Service Class to bind Collection not being Called By Provider

Please bear with me because I am new to Android development.
I am building a widget that opens up a Configuration Activity upon placement on the home screen. When I am finished configuration and have pressed "done", the widget provider (onUpdate) is supposed to call the widget service class to bind a list of drawables to a gridview. However, the service class is not being called and the gridview is coming up empty. Any help on this is appreciated, code is included below:
*Note: i have a main.xml that has the gridview in it and another xml that has the template (imageView and textView) the gridview cell.
Manifest:
<service android:name=".WidgetService" android:permission="android.permission.BIND_REMOTEVIEWS" android:exported="false" />
<receiver android:name=".WidgetProvider" android:label="#string/app_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="#xml/button_widget_provider" />
</receiver>
Provider:
public class WidgetProvider extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int i=0; i < appWidgetIds.length; i++){
Intent intent = new Intent(context, WidgetService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
remoteViews.setRemoteAdapter(appWidgetIds[i], R.id.gridview, intent);
appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
......(omitted code)}
Service:
public class WidgetService extends RemoteViewsService {
#Override
public RemoteViewsFactory onGetViewFactory(Intent intent){
return new VZRemoteViewsFactory(this.getApplicationContext(), intent);
}
}
class VZRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory{
public VZRemoteViewsFactory(Context context, Intent intent){
thisContext = context;
appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
public void onCreate(){
// code to add drawables to list here
}
public RemoteViews getViewAt(int position){
RemoteViews remoteView = new RemoteViews(thisContext.getPackageName(), R.layout.vzwidget_item);
// setting the image view resource this way for now just for testing
remoteView.setImageViewResource(R.id.launcher_icon, R.drawable.vzicon);
remoteView.setTextViewText(R.id.textview, "test");
return remoteView;
}
.....(omitted code)}
Thank You!
From my experience (and looking at my own just written widget) - OnUpdate is called right when the configuration activity is launched, and after you publish the results from this activity, the following intent action is given to the appWidgetProvider - android.appwidget.action.APPWIDGET_UPDATE_OPTIONS (tested on jellybean).
This might not be the most proper way to handle this, but this is how I am handling this -
when the configuration activity publishes the result - I start up my remote view service and start sending views with the proper widgetid.

Android: Widget onReceive() not getting called

I have a widget whose layout has an imageView. The view needs to be changed based on some activity. So, whenever that happens, I am calling a sendBroadcast() with the action set to UPDATE_WIDGET. However, the onReceive() in the widget code is not getting called. Below is my code.
public class TaskWidget extends AppWidgetProvider {
...
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "widget update", 2000).show();
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.searchwidget);
if (intent.getAction().equals(UPDATE_WIDGET)) {
views.setImageViewResource(R.id.newImage, R.drawable.Pic1);
}
super.onReceive(context, intent);
}
}
In the manifest,
<receiver
android:name="com.rahul.testwidget.TaskWidget"
android:label="Task Widget" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.rahul.UPDATE_WIDGET" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget" />
</receiver>
you have to update your widget layout
use this code just befor super.onReceive(context, intent);
ComponentName widget = new ComponentName(context, SimpleWidget.class);
AppWidgetManager.getInstance(context).updateAppWidget(widget, views);
I think your action name must be com.rahul.UPDATE_WIDGET instead of UPDATE_WIDGET.
If you are sending the broadcast from a listener on your widget you need to create a PendingIntent for a Broadcast.
PendingIntent sentPI = PendingIntent.getBroadcast(activity, 0, intent,PendingIntent.FLAG_CANCEL_CURRENT);
Also, you don't seem to be able to attach 2 pending intents to a button in the widget.

Android broadcast receiver not firing up for updating AppWidget

I am trying to test my app Widget and have registered the receiver in the manifest as follows:
<receiver android:name=".MyUtilityWidget" android:label="#string/widget_name">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider" android:resource="#xml/widget_config" />
</receiver>
The MyUtility code:
public class MyUtilityWidget extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
my Main Code here.... (widget stuff)
}
My widget starts and executes once fine (hence I leave the code out of here). However the broadcast receiver is not working and I receive no broadcasts. In fact LogCat shows the intent is never executed. So, my code block only executes once on apk deployment and never again (widget text shows, but never updates every 30m as I have set).
Config here...
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dip"
android:minHeight="72dip"
android:updatePeriodMillis="1800000"
android:initialLayout="#layout/widget_message"
/>
Also updatePeriodMillis cannot be less than 30 minutes? This is a very annoying issue when debugging, as I have to wait around 30 minutes each run to check if the intent fired!
Any help appreciated.
You need to grab hold of your widget via RemoteViews and update it accordingly. It doesn't just update automatically.
Try something like this:
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this
.getApplicationContext());
ComponentName thisWidget = new ComponentName(getApplicationContext(),
MyWidgetProvider.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
final int N =allWidgetIds2.length;
// Perform this loop procedure for each App Widget that belongs to this provider
for (int i=0; i<N; i++) {
int appWidgetId = allWidgetIds2[i];
RemoteViews widgetView = new RemoteViews(getPackageName(), R.layout.widget_layout);
widgetView.setTextViewText(R.id.some_text_view, "some text");

Categories

Resources