Android Widget Manager - java

I am working on a widget and did this with help of an tutorial,
basically I have an image view a textview another textview as a widget,
when I click on the last textview a random number appears on the first textview.
Now how could I give the textview just a number without pushing on that button and without that for loop.
So the same functionality without the click / update.
public class SimpleWidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
final int count = appWidgetIds.length;
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.simple_widget);
for (int i = 0; i < count; i++) {
int widgetId = appWidgetIds[i];
String number = String.format("%03d", (new Random().nextInt(900) + 100));
String asd = "asch";
remoteViews = new RemoteViews(context.getPackageName(),
R.layout.simple_widget);
remoteViews.setTextViewText(R.id.textView, asd);
Intent intent = new Intent(context, SimpleWidgetProvider.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);
}

Related

How to update a widget using a service

Need to update TextView of a clock widget every second or every time the minute changes ..
I am calling the service from onReceive of my AppWidgetProvider :
private String action = "clock.beautiful.best.com.mmclock.TheService";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
//UseThis
Log.e("h","R");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main_widget);
// Create a fresh intent
Intent serviceIntent = new Intent(context, TheService.class);
serviceIntent.setAction(action);
context.startService(serviceIntent);
ComponentName componentName = new ComponentName(context, TheService.class);
AppWidgetManager.getInstance(context).updateAppWidget(componentName, remoteViews);
}
What should i do to check for update in time and if there is a then update the 'time' TextView..
Service :
public class TheService extends Service {
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public void onCreate() {
Log.e("Service","created");
}
#Override
public void onDestroy() {
Log.e("Service","Destroy");
}
public void changeYexy (){
RemoteViews remoteViews = new RemoteViews(TheService.this.getPackageName(), R.layout.main_widget);
remoteViews.setTextViewText(R.id.dateTextView,"T");
}
#Override
public void onStart(Intent intent, int startid) {
Log.e("Service","start");
}
}
I don't want users to open the activity again and again to update , is there any way i can check and update the time from service or widget..
Any kind of is really really really appreciated
Instead of Using service you can use AlarmManager to update widget periodically
public class Alarm
{
public static void setAlarm(Context context, int interval)
{
AlarmManager am =( AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, yourWidget.class);
intent.setAction("WIDGET_UPDATE");
int[] ids = AppWidgetManager.getInstance(context)
.getAppWidgetIds(new ComponentName(context, yourWidget.class));
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
PendingIntent pi = PendingIntent.getBroadcast(context, 0, intent, 0);
am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + interval * 1000, pi);
}
public void cancelAlarm(Context context)
{
Intent intent = new Intent(context, Alarm.class);
PendingIntent sender = PendingIntent.getBroadcast(context, 0, intent, 0);
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(sender);
}
}
in this way the alram send a broadCast to widget with "WIDGET_UPDATE" as action after interval seconds.
Enable the alarm in onEnable method of your widget:
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
Alarm.setAlarm(context, 1);
}
In the onReceive method of yourWidget update yourWidget and set the alarm for next time
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if ("WIDGET_UPDATE".equals(intent.getAction())) {
int[] appWidgetIds = AppWidgetManager.getInstance(context)
.getAppWidgetIds(new ComponentName(context, yourWidget.class));
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
//set alarm for the next time
Alarm.setAlarm(context, 1);
//update your widget here
onUpdate(context, appWidgetManager, appWidgetIds);
}
}
Note : although it is possile to use setRepeating instead of setExact but for me it does not work properly

Android widget with custom font

I am trying to create a simple android widget that shows and I want to use custom font in my application, can anyone help me?
this my code :
public class ExampleAppWidgetProvider extends AppWidgetProvider {
private static final String LOG_TAG = "ExampleWidget";
private static final DateFormat df = new SimpleDateFormat("hh:mm:ss");
/**
* Custom Intent name that is used by the AlarmManager to tell us to update
* the clock once per second.
*/
public static String CLOCK_WIDGET_UPDATE = "com.eightbitcloud.example.widget.8BITCLOCK_WIDGET_UPDATE";
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (CLOCK_WIDGET_UPDATE.equals(intent.getAction())) {
Log.d(LOG_TAG, "Clock update");
// Get the widget manager and ids for this widget provider, then
// call the shared
// clock update method.
ComponentName thisAppWidget = new ComponentName(
context.getPackageName(), getClass().getName());
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
int ids[] = appWidgetManager.getAppWidgetIds(thisAppWidget);
for (int appWidgetID : ids) {
updateAppWidget(context, appWidgetManager, appWidgetID);
}
}
}
private PendingIntent createClockTickIntent(Context context) {
Intent intent = new Intent(CLOCK_WIDGET_UPDATE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
#Override
public void onDisabled(Context context) {
super.onDisabled(context);
Log.d(LOG_TAG, "Widget Provider disabled. Turning off timer");
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(createClockTickIntent(context));
}
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
Log.d(LOG_TAG,
"Widget Provider enabled. Starting timer to update widget every second");
AlarmManager alarmManager = (AlarmManager) context
.getSystemService(Context.ALARM_SERVICE);
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.add(Calendar.SECOND, 1);
alarmManager.setRepeating(AlarmManager.RTC, calendar.getTimeInMillis(),
1000, createClockTickIntent(context));
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
final int N = appWidgetIds.length;
Log.d(LOG_TAG, "Updating Example Widgets.");
// 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, WidgetExampleActivity.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.widget1);
views.setOnClickPendingIntent(R.id.button, pendingIntent);
// Tell the AppWidgetManager to perform an update on the current app
// widget
appWidgetManager.updateAppWidget(appWidgetId, views);
// Update The clock label using a shared method
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
public static void updateAppWidget(Context context,
AppWidgetManager appWidgetManager, int appWidgetId) {
String currentTime = df.format(new Date());
RemoteViews updateViews = new RemoteViews(context.getPackageName(),
R.layout.widget1);
updateViews.setTextViewText(R.id.widget1label, currentTime);
appWidgetManager.updateAppWidget(appWidgetId, updateViews);
}
}

Widget onReceive doesnt increment int

I am currently learning about widgets in Android. I want to increment counter value, but when I click on widget it increment it from 0 to 1 and stops to increase it. My onRecieve method work fine.
Here is my code:
public static CheckDate CheckDate;
public static EventList EventList;
public static String EVENT_CLICK = "EventClick";
public String msg;
public RemoteViews rviews;
public AppWidgetManager manager;
public Context cntxt;
public Intent intnt;
public int[] ids;
public int counter = 0;
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds){
super.onUpdate(context, appWidgetManager, appWidgetIds);
CheckDate = new CheckDate();
EventList = new EventList();
manager = appWidgetManager;
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
ids = appWidgetIds;
Intent intent = new Intent(context, DayWidget.class);
intent.setAction(EVENT_CLICK);
intent.putExtra("msg", "change");
PendingIntent actionPendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);
views.setOnClickPendingIntent(R.id.Event, actionPendingIntent);
CheckDate.Check();
views.setTextViewText(R.id.Today, CheckDate.Today);
views.setTextViewText(R.id.Event, String.valueOf(counter));
manager.updateAppWidget(ids, views);
}
public void UpdateWidget(){
Bundle extras = intnt.getExtras();
if(extras!=null) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(cntxt);
ComponentName AppWidget = new ComponentName(cntxt.getPackageName(), DayWidget.class.getName());
int[] appWidgetIds = appWidgetManager.getAppWidgetIds(AppWidget);
rviews = new RemoteViews(AppWidget.getPackageName(), R.layout.widget_layout);
counter ++;
rviews.setTextViewText(R.id.Event, String.valueOf(counter));
appWidgetManager.updateAppWidget(appWidgetIds, rviews);
}
}
public void onReceive(Context context, Intent intent){
intnt = intent;
cntxt = context;
if(EVENT_CLICK.equals(intent.getAction())){
try{
msg = intent.getStringExtra("msg");
}catch(NullPointerException e){
e.printStackTrace();
}
UpdateWidget();
Toast toast = Toast.makeText(cntxt, "OnClick", Toast.LENGTH_LONG);
toast.show();
}
super.onReceive(context, intent);
}
make your public int counter = 0; static to be public static int counter = 0;
Or save it on shared preference

Android widgets update doesn't work

Code is written down to update the widget.
this code works always
Toast.makeText(context, ""+cd.getId(), Toast.LENGTH_LONG).show();
But nether code only works when it is Debug.
#Override
public void onUpdate(Context context, AppWidgetManager appwidgetmanager,
int[] appWidgetIds) {
for (int i : appWidgetIds) {
RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.widget4x4persian);
shaffle(context, appwidgetmanager, i, views);
}
}
#Override
public void onReceive(Context context, Intent intent) {
this.context = context;
super.onReceive(context, intent);
ComponentName thisWidget = new ComponentName(context, gift4x4.class);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.widget4x4persian);
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
appWidgetManager.updateAppWidget(thisWidget, remoteViews);
clickWidget(context, appWidgetManager, intent, remoteViews);
}
private void clickWidget(Context context,
AppWidgetManager appWidgetManager, Intent intent,
RemoteViews remoteViews) {
Cursor c = null;
try {
ComponentName thisWidget = new ComponentName(context, gift4x4.class);
Bundle b = intent.getExtras();
if (b != null) {
int key = b.getInt(WIDGET_KEY);
String id = null;
int[] allWidgetIds = appWidgetManager
.getAppWidgetIds(thisWidget);
for (int i : allWidgetIds) {
RemoteViews views = new RemoteViews(
context.getPackageName(),
R.layout.widget4x4persian);
shaffle(context, appWidgetManager, i, remoteViews);
}
}
} catch (NumberFormatException e) {
e.getMessage();
} finally {
if (c != null)
c.close();
}
}
public void shaffle(Context context, AppWidgetManager appwidgetmanager,
int appWidgetId, RemoteViews Rview) {
Cursor c = null;
try {
Card cd = null;
do {
PreferenceManager pm = new PreferenceManager(context);
Cards_Count = pm.get(PREFNAME_CARDS_COUNTS, CARDS_COUNTS);
int shaffle = (new Random()).nextInt(Cards_Count);
c = context.getContentResolver().query(CONTENT_URI_CARDS,
new String[] { ID, TEXT, ISREAD, ISBOOKMARK, NOTE },
"id=" + shaffle, null, null);
if (c.moveToFirst()) {
cd = new Card(c.getInt(c.getColumnIndex(ID)), c.getString(c
.getColumnIndex(TEXT)), c.getInt(c
.getColumnIndex(ISREAD)), c.getInt(c
.getColumnIndex(ISBOOKMARK)), c.getString(c
.getColumnIndex(NOTE)));
}
c.close();
} while (c == null);
Rview.setImageViewResource(R.id.imgIsBookmarkWidget, cd
.getIsBookmark() == 1 ? R.drawable.bookmark
: R.drawable.unbookmark);
Bitmap bmp = getPicture(context, cd.getId());
Toast.makeText(context, ""+cd.getId(), Toast.LENGTH_LONG).show();
Rview.setImageViewBitmap(R.id.imgWidget, bmp);
Intent intentTemp = new Intent(context, gift4x4.class);
intentTemp.putExtra(WIDGET_KEY, key);
PendingIntent pendingintentTemp = PendingIntent.getBroadcast(context, key,
intentTemp, PendingIntent.FLAG_UPDATE_CURRENT);
Rview.setOnClickPendingIntent(R.id.imgShaffleWidget,
getProperIntent(context, 3, cd));
appwidgetmanager.updateAppWidget(appWidgetId, Rview);
} catch (Exception e) {
e.getMessage();
} finally {
if (c != null)
c.close();
}
}
Maybe the Context you are using is not the right type.
Just use the context which is passed into function, don't use private contexts declared in class.
public void onReceive(Context context, Intent intent)

First widget updates second widget

If I have two widgets and I press on a button on the first one, the second widget updates itself. That is not the intention :) When debugging I noticed that the first widget the widgetid of te second used for updating
public class WidgetActivity extends AppWidgetProvider {
public static WidgetActivity Widget = null;
public static Context context;
public static AppWidgetManager appWidgetManager;
public static int appWidgetIds[];
public static String ACTION_OPEN_APP = "OpenApp";
private static int appWidgetId;
#Override
public void onUpdate( Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds ) {
if (null == context) context = WidgetActivity.context;
if (null == appWidgetManager) appWidgetManager = WidgetActivity.appWidgetManager;
if (null == appWidgetIds) appWidgetIds = WidgetActivity.appWidgetIds;
WidgetActivity.Widget = this;
WidgetActivity.context = context;
WidgetActivity.appWidgetManager = appWidgetManager;
WidgetActivity.appWidgetIds = appWidgetIds;
final int N = appWidgetIds.length;
for (int i=0; i<N; i++)
{
appWidgetId = appWidgetIds[i];
updateAppWidget(context,appWidgetManager, appWidgetId);
}
}
public void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
Intent intent = new Intent(context, UpdateService.class);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
Intent configIntent = new Intent(context, Main.class);
configIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent configPendingIntent = PendingIntent.getActivity(context, 0, configIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.headlinesBox, configPendingIntent);
remoteViews.setOnClickPendingIntent(R.id.WidgetRefresh_btn, pendingIntent);
setHeadlines(appWidgetId);
// Tell the widget manager
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
public static void setHeadlines(int appWidgetId)
{
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
ArrayList<String> newsItems = getRssItems("*****rss.php", appWidgetId);
if(newsItems.size() == 3)
{
remoteViews.setTextViewText(R.id.headline1, newsItems.get(0));
remoteViews.setTextViewText(R.id.headline2, newsItems.get(1));
remoteViews.setTextViewText(R.id.headline3, newsItems.get(2));
}
DateTime dateTime = new DateTime();
CharSequence text = dateTime.getTime();
remoteViews.setTextViewText(R.id.WidgetUpdateTime, text);
remoteViews.setViewVisibility(R.id.progressWidget, View.GONE);
remoteViews.setViewVisibility(R.id.WidgetRefresh_btn, View.VISIBLE);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
public static ArrayList<String> getRssItems(String feedUrl, int appWidgetId)
{
}
public static class UpdateService extends Service {
#Override
public void onStart(Intent intent, int startId) {
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.widget);
remoteViews.setViewVisibility(R.id.WidgetRefresh_btn, View.GONE);
remoteViews.setViewVisibility(R.id.progressWidget, View.VISIBLE);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
WidgetActivity.Widget.onUpdate(context, appWidgetManager, appWidgetIds);
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
}
It is difficult to understand what you mean by:
When debugging I noticed that the first widget the widgetid of te second used for updating
But, I think I understand your general problem: your AppWidgets are not being updated correctly? After glancing at your code, it looks like your problem could be that appWidgetId is declared as static. Perhaps try removing that keyword.
Also, I don't see anywhere in your code a button.
EDIT
It looks like your appWidgetId is being overwritten. Here is my suggestion, take advantage of the AppWidgetProvider being a broadcast receiver and instead send a broadcast as a result of your PendingIntent button click. You will also have to make sure to pass the appWidgetId as an extra to ensure that the correct widget gets updated. Here is an example, should be in your updateAppWidget method:
Intent refreshAction = new Intent();
refreshAction.setAction(MY_CUSTOM_REFRESH_ACTION);
refreshAction.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
PendingIntent refreshPendingIntent.........
And then in the onReceive override:
#Override
public void onReceive(Context context, Intent intent) {
.....
Bundle extras = intent.getExtras();
int appWidgetId = extras.getExtra(AppWidgetManager.EXTRA_APPWIDGET_ID);
.....
}
And then you should be ready to go, updating the correct widget. One more caveat, make sure to read the documentation on BroadcastReceivers if you have not already. You will have to register to accept MY_CUSTOM_REFRESH_ACTION within the WidgetActivity element in your AndroidManifest.

Categories

Resources