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 !
Related
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
}
I've created a simple widget have only a button and textView. When I add my widget first time to the homescreen a FC message coming and widget will added. And button click toast message won't work. Only i need to have a toast message when clicking the widget button. I've gone through lots of tutorials but couldn't figure out whats the problem. Any genius who'd like to help..really appriciate the help..Thanks..
widgetProvider.java
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, widgetProvider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);
views.setOnClickPendingIntent(R.id.button1, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
Toast.makeText(context, "Button Clicked", Toast.LENGTH_SHORT).show();
}
}
}
AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<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/widgetprovider" />
</receiver>
</application>
your onUpdate is never called since you overriden the onReceive method.
I tried a lot to change my widget view's image when i click on it but it doesn't work. It's my code:
public class myAppWidgetProvider extends AppWidgetProvider {
public static String ACTION_WIDGET_REFRESH = "ActionReceiverRefresh";
//...
#Override
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];
Intent intent = new Intent(context, myAppWidgetProvider.class);
intent.setAction(ACTION_WIDGET_REFRESH);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
rv.setOnClickPendingIntent(R.id.imageView, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, rv);
}
And in onReceive i want to receive it when i click widget's view, but it doesn't work:
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
final String action = intent.getAction();
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
RemoteViews rmv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
//and this change doesn't work :(( \/
rmv.setImageViewResource(R.id.imageView, R.drawable.button_power_on_small);
}
}
It's my android manifest receiver:
<receiver android:name="myAppWidgetProvider" android:exported="false" android:icon="#drawable/button_power_off">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.xxx.xxx.myAppWidgetProvider.ACTION_WIDGET_REFRESH"/>
<action android:name="android.appwidget.action.APPWIDGET_DELETED"/>
<action android:name="android.media.RINGER_MODE_CHANGED"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="#xml/widget_info_provider" />
</receiver>
I will be grateful if someone suggest me some solution.
Change
<action android:name="com.xxx.xxx.myAppWidgetProvider.ACTION_WIDGET_REFRESH"/>
to
<action android:name="ActionReceiverRefresh"/>
Your BroadcastReceiver is looking for the wrong action string. Remember that AndroidManifest is an XML file. You have to put the actual value of the String; pointing to a Java constant doesn't work.
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.
I'm creating a widget for my app but it refuses to work.
This widget launching an configuration activity when it's being created, and when you click it, it should start a IntentService I've created.
But when I click it, it doesn't start the service! I tried to change this pending intent to an intent that would launch Google and it works.
Some code:
AppWidgetProvider XML
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:configure="com.eladaharon.android.lary.widget.LaryWidgetConfigurationActivity"
android:initialLayout="#layout/widget_1x1"
android:minHeight="72dp"
android:minWidth="72dp"
android:updatePeriodMillis="86400000" >
</appwidget-provider>
Manifest declaration
<activity
android:name=".widget.LaryWidgetConfigurationActivity"
android:configChanges="orientation|keyboard" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>
<service android:icon="#drawable/icon" android:enabled="true" android:name="widget.LaryWidgetCheckService" />
<!-- Broadcast Receiver that will process AppWidget updates -->
<receiver android:name=".widget.LaryWidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="android.appwidget.action.APPWIDGET_DELETED" />
<action android:name="android.appwidget.action.APPWIDGET_ENABLED" />
<action android:name="android.appwidget.action.APPWIDGET_DISABLED" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_provider" />
</receiver>
AppWidgetProvider class
public class LaryWidgetProvider 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 service
Intent intent = new Intent(context, LaryWidgetCheckService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent pendingIntent = PendingIntent.getService(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.widget_1x1);
views.setOnClickPendingIntent(R.id.widget_check_button, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
public void onEnabled(Context context) {
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(
new ComponentName("com.eladaharon.android.lary.widget",
".SalaryWidgetConfigurationActivity"),
PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
PackageManager.DONT_KILL_APP);
}
public void onDisabled(Context context) {
PackageManager pm = context.getPackageManager();
pm.setComponentEnabledSetting(
new ComponentName("com.eladaharon.android.lary.widget",
".LaryWidgetConfigurationActivity"),
PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
PackageManager.DONT_KILL_APP);
}
public void onDeleted(Context context, int[] appWidgetIds)
{
Editor edit = context.getSharedPreferences(Constants.PREFERNCES_WIDGET_PREFERENCES, Context.MODE_PRIVATE).edit();
final int N = appWidgetIds.length;
for (int i=0; i<N; i++)
{
edit.remove(String.valueOf(appWidgetIds[i]));
}
edit.commit();
}
public static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
// Create an Intent to launch service
Intent intent = new Intent(context, LaryWidgetCheckService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent pendingIntent = PendingIntent.getService(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.widget_1x1);
views.setOnClickPendingIntent(R.id.widget_check_button, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app widget
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
Handler that being called on the configuration activity end
private Handler mHandler = new Handler(){
#Override
public void handleMessage(Message msg){
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(LaryWidgetConfigurationActivity.this);
LaryWidgetProvider.updateAppWidget(LaryWidgetConfigurationActivity.this, appWidgetManager,
mAppWidgetId);
// Make sure we pass back the original appWidgetId
Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();
}
};
The service I want to run on click
public class LaryWidgetCheckService extends IntentService {
private int mAppWidgetId;
public LaryWidgetCheckService(String name) {
super("WorkplaceService");
}
#Override
protected void onHandleIntent(Intent intent) {
Bundle extras = intent.getExtras();
if (extras != null) {
mAppWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);
}
// If they gave us an intent without the widget id, just bail.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
return;
}
// Running some code
}
}
Thanks in advance!!
I hate this world!!!
If you'll look again in the manifest you can notice that I wrote widget.SERVICENAME instead of .widget.SERVICENAME!!!
I've Spent a whole day on this!
Thanks for everyone who tried to help!
Widget runs in another process, and you are sending an explicit intent that will works only inside your application. The reason of why the intent to launch google page in the web browser is because this is another type of intent that will involve broadcast receiver and it's propagated system wide to see if someone responds.
I think that you must declare a broadcast receiver in your service and fire that intent from your widget.