I've seen a lot of answer here, none of them worked..! I just want a textview to get updated instantly once I click a button next to it.! I've tried to print a toast message and it shows normally, but updating views is the problem.
My Code
public class FollowersWidget extends AppWidgetProvider {
public static String REFRESH_ACTION = "android.appwidget.action.APPWIDGET_UPDATE";
int x = 0;
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(REFRESH_ACTION)) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.followers_widget);
x++;
views.setTextViewText(R.id.textv_count, x + "");
int[] appWidgetId = AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, FollowersWidget.class));
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.followers_widget);
try {
String count = MyConfigureActivity.getNumCount(context, appWidgetId);
views.setTextViewText(R.id.textv_count, count );
views.setOnClickPendingIntent(R.id.refreshButton,getRefreshPendingIntent(context, appWidgetId));
} catch (Exception e) {
e.printStackTrace();
}
appWidgetManager.updateAppWidget(appWidgetId, views);
}
public static PendingIntent getRefreshPendingIntent(Context context, int appWidgetId) {
Intent intent = new Intent(REFRESH_ACTION);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
// other widget methods..
..
.
}
My Manifest
<receiver android:name=".FollowersWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/followers_info"/>
</receiver>
I figured it out finally, I've seen a lot of ways to handle the onClick on widgets, but this way that worked out for me and it updates views intantally.
Code
public class TestWidget extends AppWidgetProvider {
public static String REFRESH_ACTION = "android.appwidget.action.APPWIDGET_UPDATE";
static private RemoteViews views;
private int x = 0;
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equalsIgnoreCase(REFRESH_ACTION)) {
views = new RemoteViews(context.getPackageName(), R.layout.test_widget);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, TestWidget.class));
x++;
views.setTextViewText(R.id.textv_count, x + "");
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
}
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, int appWidgetId) {
views = new RemoteViews(context.getPackageName(), R.layout.test_widget);
views.setTextViewText(R.id.textv_count, x + "");
views.setOnClickPendingIntent(R.id.button, getPenIntent(context));
appWidgetManager.updateAppWidget(appWidgetId, views);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
static private PendingIntent getPenIntent(Context context) {
Intent intent = new Intent(context, TestWidget.class);
intent.setAction(REFRESH_ACTION);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
Just check out following code:
public class WidgetExample extends AppWidgetProvider {
public static final String REFRESH_ACTION = "YOUR_REFRESH_ACTION";
public static final String VALUE_KEY = "VALUE_KEY";
public static final String PREFERENCE_FILE_KEY = "PREFERENCE_FILE_KEY";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent != null) {
if (intent.getAction() != null) {
if (intent.getAction().equals(REFRESH_ACTION)) {
int value = readValue(context) + 1;
saveValue(context , value);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, WidgetExample.class));
for (int id : appWidgetIds) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.followers_widget);
views.setTextViewText(R.id.textv_count, String.valueOf(value));
views.setOnClickPendingIntent(R.id.button_refresh, getRefreshPendingIntent(context));
appWidgetManager.updateAppWidget(id, views);
}
}
}
}
}
#Override
public void onEnabled(Context context) {
int value = readValue(context);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, WidgetExample.class));
for (int id : appWidgetIds) {
final RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.followers_widget);
views.setTextViewText(R.id.textv_count, String.valueOf(value));
views.setOnClickPendingIntent(R.id.button_refresh, getRefreshPendingIntent(context));
appWidgetManager.updateAppWidget(id, views);
}
}
private void saveValue(Context context, int value) {
SharedPreferences sharedPref = context.getSharedPreferences(PREFERENCE_FILE_KEY, Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt(VALUE_KEY, value);
editor.apply();
}
private int readValue(Context context) {
SharedPreferences sharedPref = context.getSharedPreferences(PREFERENCE_FILE_KEY, Context.MODE_PRIVATE);
return sharedPref.getInt(VALUE_KEY, 0);
}
public static PendingIntent getRefreshPendingIntent(Context context) {
Intent intent = new Intent(REFRESH_ACTION);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}
Related
public class VWid extends AppWidgetProvider {
public static String WIDGET_UPDATE = "WIDGET_UPDATE";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (WIDGET_UPDATE.equals(intent.getAction())) {
Toast.makeText(context, "onReceiver()", Toast.LENGTH_LONG).show();
}
}
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];
int k, p;
SimpleDateFormat dateFormat = new SimpleDateFormat("MM-dd-yyyy hh:mm a");
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
int k = audioManager.getStreamVolume(AudioManager.STREAM_SYSTEM);
Toast.makeText(getActivity(), k+"", Toast.LENGTH_LONG).show();
Intent imageview2Intent= new Intent(context, VWid.class);
PendingIntent pendingIntent2= PendingIntent.getBroadcast(context,0, imageview2Intent,0);
views.setOnClickPendingIntent(R.id.imagebuttonrefresh, pendingIntent2); //
views.setTextViewText(R.id.textview1, "Last Refresh: " + dateFormat.format(new Date()).toString());
pushWidgetUpdate(context, views);
}
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
ComponentName myWidget = new ComponentName(context, VWid.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
Log.d("UPDATED", "testing");
}
}
When I first add the widget to my homescreen, textview1 displays: Last Refresh: {current date and time}. It also displays the system volume in a Toast.
Let's say I increase/decrease the system volume, when I hit refresh the onUpdate() function should fire showing the updated Toast and also updating the textview1 text to the new data and time but that's not happening.
How can I modify the code so I can achieve a refresh, in essence calling the onUpdate() function.
Try this:
public class WidgetProvider extends AppWidgetProvider {
public static final String REFRESH_ACTION = "com.packagename.REFRESH_ACTION";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(WidgetProvider.REFRESH_ACTION)) {
Bundle extras = intent.getExtras();
if (extras != null) {
int[] appWidgetIds = extras.getIntArray(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds != null && appWidgetIds.length > 0) {
Toast.makeText(context, "REFRESH", Toast.LENGTH_SHORT).show();
this.onUpdate(context, AppWidgetManager.getInstance(context), appWidgetIds);
}
}
}
}
#Override
public void onUpdate(final Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int N = appWidgetIds.length;
for (int i = 0; i < N; ++i) {
RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Intent intentServiceCall = new Intent(context, WidgetService.class);
intentServiceCall.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
//Refresh
Intent refreshIntent = new Intent(context, WidgetProvider.class);
refreshIntent.setAction(WidgetProvider.REFRESH_ACTION);
refreshIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
intentServiceCall.setData(Uri.parse(intentServiceCall.toUri(Intent.URI_INTENT_SCHEME)));
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, refreshIntent, PendingIntent.FLAG_UPDATE_CURRENT);
rv.setOnClickPendingIntent(R.id.ivRefreshWidget, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds[i], rv);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
Change this section :
Intent imageview2Intent= new Intent(context, VWid.class);
imageview2Intent.setAction(WIDGET_UPDATE);
PendingIntent pendingIntent2= PendingIntent.getBroadcast(context,0, imageview2Intent,0);
views.setOnClickPendingIntent(R.id.imagebuttonrefresh, pendingIntent2); //
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (WIDGET_UPDATE.equals(intent.getAction())) {
pushWidgetUpdate(context);
}
}
I am trying to make a home screen widget which will toggle on and off the gps (Location in settings). I still don't understand how to handle a button click event.
I took this code from a tutorial online.
public class LocationWidget extends AppWidgetProvider {
private static String SYNC_CLICKED = "automaticWidgetSyncButtonClick";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int count = appWidgetIds.length;
String status;
LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
for (int i = 0; i < count; i++) {
int widgetId = appWidgetIds[i];
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
status = "OFF";
} else {
status = "ON";
}
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.activity_main);
remoteViews.setTextViewText(R.id.textView, status);
Intent intent = new Intent(context, LocationWidget.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.actionButton, pendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.activity_main);
remoteViews.setTextViewText(R.id.textView, "Button clicked");
Log.v("ACTION", intent.getAction());
}
}
Inside onReceive, Log.v returns "ACTION﹕android.appwidget.action.APPWIDGET_UPDATE". So I need help to make the button behave the way i want when clicked. Can someone explain how and why?
i will open my heplactivity you can change and add your setting intent
appwidget.java
public class MyWidget extends AppWidgetProvider {
Button btnhelp;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Intent configIntent = new Intent(context, HelpActivity.class);
PendingIntent configPendingIntent = PendingIntent.getActivity(context, 0, configIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.btnhelp, configPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}
}
manifest
<receiver android:name=".MyWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="#xml/widget_info" />
</receiver>
resource xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="#layout/widget_layout"
android:minHeight="70dp"
android:minWidth="70dp"
android:updatePeriodMillis="300000"></appwidget-provider>
layout xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="8dip"
android:background="#drawable/ic_dashboard_help"
android:clickable="true">
<Button
android:id="#+id/btnhelp"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_margin="4dip"
android:background="#android:color/transparent" />
</LinearLayout>
I got it.
public class LocationWidget extends AppWidgetProvider {
public static String WIDGET_BUTTON = "MY_PACKAGE_NAME.WIDGET_BUTTON";
private static final String ACTION_CLICK = "ACTION_CLICK";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int count = appWidgetIds.length;
String status;
LocationManager manager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
for (int i = 0; i < count; i++) {
int widgetId = appWidgetIds[i];
if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
status = "OFF";
} else {
status = "ON";
}
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.activity_main);
if (status == "ON") {
remoteViews.setInt(R.id.actionButton, "setBackgroundColor", Color.GREEN);
remoteViews.setTextViewText(R.id.actionButton, "Location Service On");
}
if (status == "OFF") {
remoteViews.setInt(R.id.actionButton, "setBackgroundColor", Color.RED);
remoteViews.setTextViewText(R.id.actionButton, "Location Service Off");
}
Intent intent = new Intent(context, LocationWidget.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
String buttonclick = "buttonclick";
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.actionButton, getPendingSelfIntent(context, buttonclick));
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
}
protected PendingIntent getPendingSelfIntent(Context context, String action) {
Intent intent = new Intent(context, LocationWidget.class);
intent.setAction(action);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.activity_main);
if (intent.getAction() == "buttonclick") {
Log.v("ACTION", "buttonclick");
Intent callGPSSettingIntent = new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS);
callGPSSettingIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(callGPSSettingIntent);
}
}
}
You should be able to do
if( intent.getAction() == <action_type> )
{
/*Handling code here*/
}
I created simple example widget and simple configuration activity for it. I need to invoke configuration activity for each widget instance after user clicks on widets. Each instance should have separate settings and after click, configuration activity should be filled with settings got from this specific instance used to invoke config dialog, allowing to change settings for this specific instance only (other existing widget instanced should stay untouched).
So, my widget code:
package com.example.michal.widgettest2;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
/**
* Implementation of App Widget functionality.
* App Widget Configuration implemented in {#link MyWidgetConfigureActivity MyWidgetConfigureActivity}
*/
public class MyWidget extends AppWidgetProvider
{
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
// There may be multiple widgets active, so update all of them
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++)
{
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, MyWidgetConfigureActivity.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.my_widget);
views.setOnClickPendingIntent(R.id.widget_container, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
#Override
public void onDeleted(Context context, int[] appWidgetIds)
{
// When the user deletes the widget, delete the preference associated with it.
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++)
{
MyWidgetConfigureActivity.deleteTitlePref(context, appWidgetIds[i]);
}
}
#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
}
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId)
{
CharSequence widgetText = MyWidgetConfigureActivity.loadTitlePref(context, appWidgetId);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_widget);
views.setTextViewText(R.id.appwidget_text, widgetText);
Intent intent = new Intent(context, MyWidgetConfigureActivity.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.widget_container, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
My config activity code:
package com.example.michal.widgettest2;
import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
/**
* The configuration screen for the {#link MyWidget MyWidget} AppWidget.
*/
public class MyWidgetConfigureActivity extends Activity
{
int mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID;
EditText mAppWidgetText;
private static final String PREFS_NAME = "com.example.michal.widgettest2.MyWidget";
private static final String PREF_PREFIX_KEY = "appwidget_";
public MyWidgetConfigureActivity()
{
super();
}
#Override
public void onCreate(Bundle icicle)
{
super.onCreate(icicle);
// Set the result to CANCELED. This will cause the widget host to cancel
// out of the widget placement if the user presses the back button.
setResult(RESULT_CANCELED);
setContentView(R.layout.my_widget_configure);
mAppWidgetText = (EditText) findViewById(R.id.appwidget_text);
findViewById(R.id.add_button).setOnClickListener(mOnClickListener);
// Find the widget id from the intent.
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null)
{
mAppWidgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID);
}
// If this activity was started with an intent without an app widget ID, finish with an error.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID)
{
finish();
return;
}
mAppWidgetText.setText(loadTitlePref(MyWidgetConfigureActivity.this, mAppWidgetId));
}
View.OnClickListener mOnClickListener = new View.OnClickListener()
{
public void onClick(View v)
{
final Context context = MyWidgetConfigureActivity.this;
// When the button is clicked, store the string locally
String widgetText = mAppWidgetText.getText().toString();
saveTitlePref(context, mAppWidgetId, widgetText);
// It is the responsibility of the configuration activity to update the app widget
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
MyWidget.updateAppWidget(context, 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();
}
};
// Write the prefix to the SharedPreferences object for this widget
static void saveTitlePref(Context context, int appWidgetId, String text)
{
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
prefs.putString(PREF_PREFIX_KEY + appWidgetId, text);
prefs.commit();
}
// Read the prefix from the SharedPreferences object for this widget.
// If there is no preference saved, get the default from a resource
static String loadTitlePref(Context context, int appWidgetId)
{
SharedPreferences prefs = context.getSharedPreferences(PREFS_NAME, 0);
String titleValue = prefs.getString(PREF_PREFIX_KEY + appWidgetId, null);
if (titleValue != null)
{
return titleValue;
} else
{
return context.getString(R.string.appwidget_text);
}
}
static void deleteTitlePref(Context context, int appWidgetId)
{
SharedPreferences.Editor prefs = context.getSharedPreferences(PREFS_NAME, 0).edit();
prefs.remove(PREF_PREFIX_KEY + appWidgetId);
prefs.commit();
}
}
Unfortunately, it does not work as should. The settings displayed on configuration activity are not from widget that was used to invoke config activity and update goes to incorrect widget instance.
Probably I have ommited something, can you provide any tips what's wrong?
[edit]
Updated code:
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds)
{
// There may be multiple widgets active, so update all of them
final int N = appWidgetIds.length;
for (int i = 0; i < N; i++)
{
int appWidgetId = appWidgetIds[i];
//Intent intent = new Intent(context, MyWidgetConfigureActivity.class);
//intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
//PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pendingIntent = getUniquePI(context,null,appWidgetId);
RemoteViews views = new RemoteViews(context.getPackageName(),R.layout.my_widget);
views.setOnClickPendingIntent(R.id.widget_container, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId)
{
CharSequence widgetText = MyWidgetConfigureActivity.loadTitlePref(context, appWidgetId);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.my_widget);
views.setTextViewText(R.id.appwidget_text, widgetText);
//Intent intent = new Intent(context, MyWidgetConfigureActivity.class);
//intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,appWidgetId);
//PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
PendingIntent pendingIntent = getUniquePI(context,null,appWidgetId);
views.setOnClickPendingIntent(R.id.widget_container, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
Now my widget does not respond to click events (config activity is not showing). What's wrong?
Use below sample step by step.
Step 1
Create Service UpdateWidgetService.java
public class UpdateWidgetService extends Service {
public UpdateWidgetService() {
}
public static final String SKIP = "skip";
public static final String OPENAPP = "openapp";
#Override
public int onStartCommand(Intent pIntent, int flags, int startId) {
String command = pIntent.getAction();
int appWidgetId = pIntent.getExtras().getInt(AppWidgetManager.EXTRA_APPWIDGET_ID);
RemoteViews remoteView = new RemoteViews(getApplicationContext().getPackageName(), R.layout.widget);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
if(command.equals(SKIP)){
/**Do the SKIP click work here*/
return START_NOT_STICKY;
}else if(command.equals(OPENAPP)){
/**Do the OPENAPP click work here*/
Intent mAct=new Intent(this, OPENAPP.class);
mAct.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(mAct);
return START_NOT_STICKY;
}
remoteView.setTextViewText(R.id.widet_ibtn_skip, "MyTextHere");
remoteView.setTextViewText(R.id.widget_tv_title, "Title");
remoteView.setOnClickPendingIntent(R.id.widet_ibtn_skip,WallWidgetProvider.makeControlPendingIntent(getApplicationContext(),SKIP,appWidgetId));
remoteView.setOnClickPendingIntent(R.id.widget_tv_title,WallWidgetProvider.makeControlPendingIntent(getApplicationContext(),OPENAPP,appWidgetId));
appWidgetManager.updateAppWidget(appWidgetId, remoteView);
return super.onStartCommand(pIntent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
}
Step 2
Create WidgetProvider as WallWidgetProvider.java
public class WallWidgetProvider extends AppWidgetProvider{
public static final int UPDATE_RATE = 1000;
#Override
public void onDeleted(Context context, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
setCounterAlarm(context, appWidgetId, -1);
}
super.onDeleted(context, appWidgetIds);
}
#Override
public void onDisabled(Context context) {
context.stopService(new Intent(context,UpdateWidgetService.class));
super.onDisabled(context);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
PrefrenceSettings ps=new PrefrenceSettings(context);
for (int appWidgetId : appWidgetIds) {
setCounterAlarm(context, appWidgetId, UPDATE_RATE);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
public static void setCounterAlarm(Context context, int appWidgetId, int updateRate) {
PendingIntent newPending = makeControlPendingIntent(context,UpdateWidgetService.UPDATE,appWidgetId);
AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (updateRate >= 0) {
alarms.setInexactRepeating(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime(), updateRate, newPending);
} else {
// on a negative updateRate stop the refreshing
alarms.cancel(newPending);
}
}
public static PendingIntent makeControlPendingIntent(Context context, String command, int appWidgetId) {
Intent active = new Intent(context,UpdateWidgetService.class);
active.setAction(command);
active.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
//this Uri data is to make the PendingIntent unique, so it wont be updated by FLAG_UPDATE_CURRENT
//so if there are multiple widget instances they wont override each other
Uri data = Uri.withAppendedPath(Uri.parse("widget://widget/id/#"+command+appWidgetId), String.valueOf(appWidgetId));
active.setData(data);
return(PendingIntent.getService(context, 0, active, PendingIntent.FLAG_UPDATE_CURRENT));
}
}
Hope you should know how to use these two class in your project, These classes generate unique identification of each Widget.
When I add my widget from the widget page on my phone, it plays the toast message "Button Clicked." The toast is only suppose to be displayed once you push the button, and it works, but it also is displayed when the widget is added to the screen..
I am guessing it may have to do with the super, but I am not exactly sure.
Code:
#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, Provider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.onoffbutton, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(AppWidgetManager.ACTION_APPWIDGET_UPDATE)) {
Toast.makeText(context, "Button Clicked", Toast.LENGTH_SHORT).show();
System.out.println("Click!");
}
}
EDIT:
public static String BUTTON_CLICK = "android.appwidget.action.BUTTON_CLICK";
#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, Provider.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
Intent clickIntent = new Intent(context, Provider.class);
clickIntent.setAction(BUTTON_CLICK);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget);
views.setOnClickPendingIntent(R.id.onoffbutton, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
#Override
public void onReceive(Context context, Intent clickIntent) {
super.onReceive(context, clickIntent);
if (clickIntent.getAction().equals(BUTTON_CLICK)) {
Toast.makeText(context, "Button Clicked", Toast.LENGTH_SHORT).show();
System.out.println("Click!");
}
}
That's because you have same action for widget update
Make a separate intent action for button(BTN_ACTION for example). In onReceive() check which i=action intent has and if intent.getAction().equals(BTN_ACTION) - handle button click.
I'm trying to make a widget containing a textview change its text to a random number on clicking the widget. It gives a problem displaying widget. I have this code:
public class WidgetConfig extends AppWidgetProvider{
public static String RandomClick = "RandomClick";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
RemoteViews updateViews;
ComponentName watchWidget;
updateViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
watchWidget = new ComponentName(context, WidgetConfig.class);
updateViews.setOnClickPendingIntent(R.id.randomnumber,getPendingSelfIntent(context, RandomClick));
appWidgetManager.updateAppWidget(watchWidget,updateViews);
Random r = new Random();
int randomInt = r.nextInt(6);
String randomStringInt = String.valueOf(randomInt);
final int N = appWidgetIds.length;
for (int i=0;i<N;i++){
int appWidgetID = appWidgetIds[i];
RemoteViews v = new RemoteViews(context.getPackageName(),R.layout.widget_layout);
v.setTextViewText(R.id.randomnumber, randomStringInt);
appWidgetManager.updateAppWidget(appWidgetID, v);
}
}
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals(RandomClick)){
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews updateViews;
ComponentName watchWidget;
updateViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
watchWidget = new ComponentName(context, WidgetConfig.class);
Random r = new Random();
int randomInt = r.nextInt(6);
String randomStringInt = String.valueOf(randomInt);
updateViews.setTextViewText(R.id.randomnumber, randomStringInt);
appWidgetManager.updateAppWidget(watchWidget, updateViews);
}
super.onReceive(context, intent);
}
protected PendingIntent getPendingSelfIntent(Context context, String action){
Intent intent = new Intent(context, getClass());
intent.setAction(action);
return PendingIntent.getBroadcast(context, 0, intent, 0);
}
}
In which randomnumber is just the textview in widget_layout.xml:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#drawable/backgroundshape"
android:layout_margin="8dp"
android:onClick="ClickRandom">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New Text"
android:minHeight="56dp"
android:minWidth="56dp"
android:gravity="center"
android:id="#+id/randomnumber"
android:textSize="24dp"/>
</LinearLayout>
Help much appreciated. Thank you!
I have uploaded the complete work.You can even download the code from this link.Well this is the code which i have used.When you click on the widget it will automatically generate a random no and update ui.I have also uploaded an image which shows the output also.
MainActivity.java
public class MainActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(this, "App widget ready to be added!",
Toast.LENGTH_LONG).show();
finish();
}
WidgetConfig.java
public class WidgetConfig extends AppWidgetProvider {
#Override
public void onUpdate(Context ctxt, AppWidgetManager mgr,
int[] appWidgetIds) {
ComponentName me=new ComponentName(ctxt, WidgetConfig.class);
mgr.updateAppWidget(me, buildUpdate(ctxt, appWidgetIds));
}
private RemoteViews buildUpdate(Context ctxt, int[] appWidgetIds) {
RemoteViews updateViews=new RemoteViews(ctxt.getPackageName(),
R.layout.widget);
Intent i=new Intent(ctxt, WidgetConfig.class);
i.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
i.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pi=PendingIntent.getBroadcast(ctxt, 0 , i,
PendingIntent.FLAG_UPDATE_CURRENT);
int v = (int)(Math.random()*6);
String rs = Integer.toString(v);
CharSequence cs = rs.subSequence(0, 1);
updateViews.setTextViewText(R.id.textView1,cs);
updateViews.setOnClickPendingIntent(R.id.textView1, pi);
updateViews.setOnClickPendingIntent(R.id.background, pi);
return(updateViews);
}
}