Android adding more widgets with different content - android

I am trying to create an application with a widget. When the user places the widget on the desktop a listview should come up with a list of items. The user selects an item then the widget is created with the respective text related to that item. For simplicity I am using now an alertdialog. The input text should appear only in the widget I create. It should not appear in the other widgets. How am I supposed to do that? I have not found anyhing about this.
The AppWidgetProvider:
public class MyWidgetProvider extends AppWidgetProvider {
private static final String ACTION_CLICK = "ACTION_CLICK";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.i("INFO", "AppWidgetProvider");
ComponentName thisWidget = new ComponentName(context, MyWidgetProvider.class);
int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);
//Intent intent = new Intent(context.getApplicationContext(), UpdateWidgetService.class);
//intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, allWidgetIds);
//context.startService(intent);
Intent intentA = new Intent(context.getApplicationContext(), NoteListToWidget.class);
intentA.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intentA);
}
}
The service:
public class UpdateWidgetService extends Service {
public static String ACTION_WIDGET_CONFIGURE = "ConfigureWidget";
public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
String value;
Dialog dialog_newitem;
#Override
public void onStart(Intent intent, int startId) {
Log.i("INFO", "UpdateWidgetService");
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
ComponentName thisWidget = new ComponentName(getApplicationContext(), MyWidgetProvider.class);
int[] allWidgetIds2 = appWidgetManager.getAppWidgetIds(thisWidget);
for (int widgetId : allWidgetIds) {
int number = (new Random().nextInt(100));
String v = GlobalVars.getValue();
RemoteViews remoteViews = new RemoteViews(this.getApplicationContext().getPackageName(), R.layout.widget_layout);
//remoteViews.setTextViewText(R.id.update, "Random: " + String.valueOf(number));
remoteViews.setTextViewText(R.id.update, v);
Intent configIntent = new Intent(this, Notepad.class);
configIntent.setAction(ACTION_WIDGET_CONFIGURE);
PendingIntent configPendingIntent = PendingIntent.getActivity(this, REQUEST_CODE_ONE, configIntent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.widgetlayout, configPendingIntent);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
stopSelf();
super.onStart(intent, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
This is the Activity with the AlertDialog (the latter listview):
public class NoteListToWidget extends Activity {
Dialog dialog_newitem;
EditText et_newitem;
String value;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
dialog_newitem = new Dialog(NoteListToWidget.this);
dialog_newitem.setContentView(R.layout.dialog_productlists_grp_capitalized);
dialog_newitem.setTitle("Select");
dialog_newitem.setCancelable(true);
et_newitem = (EditText) dialog_newitem.findViewById(R.id.et_item_name);
Button btn_Save = (Button) dialog_newitem.findViewById(R.id.btn_save_pr);
btn_Save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
value = et_newitem.getText().toString();
GlobalVars.setValue(value);
dialog_newitem.dismiss();
/*
Intent serviceIntent = new Intent();
serviceIntent.setAction("com.myapp.app.UpdateWidgetService");
startService(serviceIntent);
*/
Intent intent = new Intent(NoteListToWidget.this, com.myapp.app.UpdateWidgetService.class);
startService(intent);
}
});
Button btn_Cancel = (Button) dialog_newitem.findViewById(R.id.btn_cancel_pr);
btn_Cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog_newitem.dismiss();
}
});
dialog_newitem.show();
}
}
I don't how and from where should I call the NoteListToWidget activity and how to make this whole thing work.

First of all it is impossible to answer your question in full. This is because it seems you are missing a lot of things about how app-widgets are working, so you must read more about them. However I will give you a place to start.
The onUpdate method of the AppWidgetProvider is called each time an app-widget that it is already placed on the desktop needs an update. That is, even if you manage to display your list from there and the user cancels the operation there is NO way to remove your app-widget from the onUpdate method.
Furthermore when the onUpdate method finishes the AppWidgetProvider is destroyed, so even if you manage to display your list from there there is NO way to get the items that user selected. Long story short, you canNOT do it from onUpdate method and you canNOT do it by this approach.
However, you CAN do it by using a configuration activity in a specified point of the app-widget's creation process but this cannot be answered in the context of your question because you must first understand how the app-widget system works in Android. The best place to start is this link. I had the same problems with my first app-widget application (and almost the same concerns with you) but then I started to read and read, finally after 1.5 months I 've managed to make something like the thing you want to do. So don't say
How am I supposed to do that? I have not found anyhing about this
and start reading, this is the life with Android. It's all in the above link, there are also very good open-source projects in google code like this weather widget which allows the user to configure it BEFORE it is placed on the desktop.
Hope this helps...

Related

Widget refresh from inside application

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);

How To change the imageview of an appwidget (remoteview) multiple times with a short break between?

I am new to Android Development and im stuck with a Problem.
I hope you guys can help me ;)
Im am working on an Appwidget, a remoteview with a linearlayout
that is containing multiple imageviews.
I worked myself through some tutorials and examples and
i was able to build up a first app , that detects a clicked imageview to open a specific installed app, or to change the imageresource of some Imageviews.
Now my Problem is that i want to animate the images when the button is clicked.
I made a drawableAnimation, but then i read that remoteviews dont support these.
So my Idea was to change the pictures manually with a little break between
For Example:
change imageview
0.1 seconds wait
change imageview
0.1 seconds wait
change imageview
0.1 seconds wait
change imageview
So now i read some about Sleep(), handlers, and adapterviewflipper (none of it i was able to implement) and i really dont know which way to go.
Here is the code of my Appwidgetprovider
public class MyWidgetProvider extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_demo);
// Button To Change Imageview
remoteViews.setOnClickPendingIntent(R.id.B1, buildButtonPendingIntent(context));
//Buttons to open some installed apps
remoteViews.setOnClickPendingIntent(R.id.T1, getPendingIntent(context, 1));
remoteViews.setOnClickPendingIntent(R.id.T2, getPendingIntent(context, 2));
pushWidgetUpdate(context, remoteViews);
}
public static PendingIntent buildButtonPendingIntent(Context context) {
Intent intent = new Intent();
intent.setAction("com.appwidgettest.intent.action.UPDATEUI");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static PendingIntent getPendingIntent(Context context, int btnId) {
// starts a htc radio app as standart and if button 2 is clicked it starts
// chrome browser just did this for testing the packagemanager
PackageManager pm = context.getPackageManager();
String gg = "com.htc.fm";
if (btnId==2){gg = "com.android.chrome";
}
Intent intentt= pm.getLaunchIntentForPackage(gg);
PendingIntent pi = PendingIntent.getActivity(context, 0, intentt, 0);
return pi;
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
ComponentName myWidget = new ComponentName(context, MyWidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
}
}
and the Broadcastreciever which is working so far.
public class MyWidgetIntentReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("com.appwidgettest.intent.action.UPDATEUI")){
updateWidgetPictureAndButtonListener(context);
}
}
private void updateWidgetPictureAndButtonListener(Context context) {
final RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_demo);
// Here i Change The Imageviews!
remoteViews.setImageViewResource(R.id.M3, R.drawable.image1);
//here i need a short time sleep of 0.2 seconds for example
remoteViews.setImageViewResource(R.id.M2, R.drawable.image2);
//here too
remoteViews.setImageViewResource(R.id.M1, R.drawable.image3);
// Here to set the Button Listeners
remoteViews.setOnClickPendingIntent(R.id.B1, MyWidgetProvider.buildButtonPendingIntent(context));
remoteViews.setOnClickPendingIntent(R.id.T2, MyWidgetProvider.getPendingIntent(context,2));
remoteViews.setOnClickPendingIntent(R.id.T1, MyWidgetProvider.getPendingIntent(context,1));
MyWidgetProvider.pushWidgetUpdate(context.getApplicationContext(), remoteViews);
}
}
I am really sorry for my bad english^^and i hope you could understand most of it :P
And if you have a better idea for the Title Please tell me
Help me Please!!
Regards T.R.Salvatore
If you are looking for sprite animation when a button is clicked, see this example https://code.google.com/p/mario-coin-block/. It causes a series of images to be displayed like a sprite animation.
If you simply want something like a slideshow, use the AdapterViewFlipper. I've created a similar app widget: https://github.com/mridang/appwidget-ilmaana

Change src image of ImageButton of Android widget programatically

I am developing an Android app with a homescreen widget, which is an imageButton, and i want the image of the button to change after its been pressed. I have tried selector in an xml file, to change the image of the button, but it changes it only when it is pressed, but it goes back when its released.
I want it to change image after it was pressed and when the code inside the WidgetProvider is executed, it changes the image back to the default one.
I tried to do it programatically(in onRecieve() method), I guess it should be something with RemoteViews but whatever i try, it doesnt work.
Could someone help my with this? I saw many people asking about it, but most of the posts were either pretty old or the solutions were not working for me.
Thank you :)
Normally you'd set the image on the surface of the ImageButton using the setImageResource method (ImageButton inherits it from ImageView), but that method isn't available for RemoteViews.
RemoteViews offers a corresponding setImageViewResource method that does what you want (as well as setImageViewBitmap and setImageViewUri depending on how you'd like to provide the image data).
The code to set the image (say, within your BroadcastReceiver's onReceive method) would look something like this:
#Override
public void onReceive(Context context, Intent intent) {
int appWidgetId = intent.getIntExtra("appWidgetId", -1);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
views.setImageViewResource(R.id.imageButton1, R.drawable.awesome_image);
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
Note that the code above assumes you've added the id of the widget to be manipulated as an extra to the broadcast intent (wrapped in a PendingIntent that is sent when the user clicks the ImageButton) using the key "appWidgetId". You'll most likely want to do that in the onUpdate method of your AppWidgetProvider, like so:
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int i = 0; i < appWidgetIds.length; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent ("YourActionHere");
intent.putExtra("appWidgetId", appWidgetId);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, i, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.main);
views.setImageViewResource(R.id.imageButton1, R.drawable.initial_image);
views.setOnClickPendingIntent(R.id.imageButton1, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
A simple but not elegant way is:
boolean isButtonSelected = false;
..
button.setOnClickListener(buttonListener);
..
OnClickListener buttonListener = new OnClickListener() {
#Override
public void onClick(View arg0) {
if(isButtonSelected ){
isButtonSelected = false;
button.setBackgroundResource(R.drawable.buttonOff); // or setImageResource(..);
} else{
isButtonSelected = true;
button.setBackgroundResource(R.drawable.buttonOn);
}
}
};

Updating text in a widget on an event

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) {
...
}

ViewFlipper in app widgets

I'm playing around building a new widget and was looking at the Android app widget documentation, in particular the section on which widget classes were supported. I noticed that ViewFlipper is supported, but I'm struggling to find any examples on how to use one in a home screen widget. In particular, I'm wondering if its possible to manually trigger swapping views. In an activity this looks relatively straightforward, one example being hooking up the onclick listener of a button to call the showNext() of the flipper.
The RemoteViews object has showNext and showPrevious methods but I'm not sure I understand how to hook them up to an event fired from the user interacting with the widget. Can anyone provide examples of when these methods might be called?
It looks like buttons in widgets can only be wired up to intents rather than code to exercise the flipper. If this restriction is true, then is the only use of a view flipper in an app widget for auto flipping of views?
Say you have 2 buttons: LEFT and RIGHT. First you would attach pending intent to each (here it's triggered from Service#onStart:
#Override
public void onStart(Intent intent, int startId) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
int[] allWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
// add listeners for every widget registered
for (int widgetId : allWidgetIds) {
addClickListeners(appWidgetManager, widgetId, root);
}
stopSelf();
}
protected void addClickListeners(AppWidgetManager appWidgetManager, int widgetId, RemoteViews root) {
root.setOnClickPendingIntent(R.id.left, getNavigationIntent(widgetId, R.id.left));
root.setOnClickPendingIntent(R.id.right, getNavigationIntent(widgetId, R.id.right));
}
protected PendingIntent getNavigationIntent(int widgetId, final int id) {
Intent clickIntent = new Intent(this, WidgetProvider.class);
clickIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
clickIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
clickIntent.putExtra(TRIGGER, id);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 0, clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
return pendingIntent;
}
Then, in AppWidgetProvider do
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Bundle extras = intent.getExtras();
Integer id = (Integer) (extras == null ? null : extras.get(TRIGGER));
if (AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action) && id != null) {
int widgetId = extras.getInt(AppWidgetManager.EXTRA_APPWIDGET_ID, 0);
onNavigate(context, widgetId, id);
} else {
super.onReceive(context, intent);
}
}
protected void onNavigate(Context context, Integer widgetId, Integer id) {
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
RemoteViews root = new RemoteViews(context.getPackageName(), R.layout.app_widget);
if (id == R.id.left) {
root.showPrevious(R.id.scroll);
} else {
root.showNext(R.id.scroll);
}
appWidgetManager.updateAppWidget(widgetId, root);
}
This should do it. Now the problem is - this will only work in API 11+ and I just found the hard way that root.setInt(R.id.scroll, "setDisplayedChild", pos) will not work in API 7.

Categories

Resources