Buttons in AppWidget - android

Hello I'm trying to add buttons to my Appwidget, but even after reading many codes, my buttons aren't working.
This is my AppWidgetProvider:
public class MyWidget extends AppWidgetProvider {
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Intent intent = new Intent(context, MyService.class);
intent.setAction("0");
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.widgetlayout);
views.setOnClickPendingIntent(R.id.button_widget, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, views);
}
}
And here is MyService:
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String command = intent.getAction();
int[] appWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
RemoteViews remoteView = new RemoteViews(getApplicationContext()
.getPackageName(), R.layout.widgetlayout);
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(getApplicationContext());
if (command.equals("0")) {
remoteViews.setTextViewText(R.id.button_widget, "TextChanged");
}
RemoteViews remoteViews = new RemoteViews(getPackageName(),
R.layout.widgetlayout);
appWidgetManager.updateAppWidget(appWidgetIds, remoteView);
super.onStart(intent, startId);
return 0;
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}
This is just a dummy code that is supposed to changed a button's text when you click it. It doesn't.
Any ideas about what I'm doing wrong?
Thanks.

i just take a look in your source code, it seem problem belong logic,
your re-create new RemoteView object after your change text content:
Solution: Comment out following line of code:
/* 22/07/2011 DELETE START */
//RemoteViews remoteViews = new RemoteViews(getPackageName(),
// R.layout.widgetlayout);
/* 22/07/2011 DELETE END */
In class MyService:
public class MyService extends Service {
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String command = intent.getAction();
int[] appWidgetIds = intent
.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
RemoteViews remoteView = new RemoteViews(getApplicationContext()
.getPackageName(), R.layout.widgetlayout);
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(getApplicationContext());
if (command.equals("0")) {
remoteViews.setTextViewText(R.id.button_widget, "TextChanged");
}
/* 22/07/2011 DELETE START */
//RemoteViews remoteViews = new RemoteViews(getPackageName(),
// R.layout.widgetlayout);
/* 22/07/2011 DELETE END */
appWidgetManager.updateAppWidget(appWidgetIds, remoteView);
super.onStart(intent, startId);
return 0;
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
}

Try to put your code from onStartCommand into
public void onStart(Intent intent, int startId)
as you might run your code on older Android platforms that only use onStart.

Related

Play sound on widget click

Here's my code, it opens the main activity, but I can't seem to find a way to just make the widget play a sound.
I tried to:
add a button to the widget (didn't work)
add an OnClickListener to the main activity (which works but it opens the main activity and I just want the sound not the activity)
write a new method to play the sound with the MediaPlayer sound.start() method in it and calling it (didn't work)
I've looked in the android dev page and all I was able to find was how to use the MediaPlayer, but it says nothing about playing audio from a widget.
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
public class ClockWidget extends AppWidgetProvider {
public static String ACTION_WIDGET_RECEIVER = "ActionReceiverWidget";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
final int N = appWidgetIds.length;
for (int i=0; i<N; i++) {
int appWidgetId = appWidgetIds[i];
Intent intent = new Intent(context, MainActivity.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.clock_widget_layout);
views.setOnClickPendingIntent(R.id.AnalogClock0, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
To do it you need to use a service which you call like this
Intent svc=new Intent(this, BackgroundSoundService.class);
startService(svc);
public class BackgroundSoundService extends Service {
private static final String TAG = null;
MediaPlayer player;
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
player = MediaPlayer.create(this, R.raw.trck);
//configure other settings
}
public int onStartCommand(Intent intent, int flags, int startId) {
player.start();
return 1;
}
public void onStart(Intent intent, int startId) {
// TO DO
}
public IBinder onUnBind(Intent arg0) {
// TO DO Auto-generated method
return null;
}
public void onStop() {
}
public void onPause() {
}
#Override
public void onDestroy() {
player.stop();
player.release();
}
}
Please register this service in Manifest.
<service android:enabled="true" android:name=".BackgroundSoundService" />
and you could do smth like this in widget
public class ClockWidget extends AppWidgetProvider {
private final String ACTION_WIDGET_PLAY = "PlaySong";
private final String ACTION_WIDGET_PAUSE = "PauseSong";
private final String ACTION_WIDGET_STOP = "StopSong";
private final int INTENT_FLAGS = 0;
private final int REQUEST_CODE = 0;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews controlButtons = new RemoteViews(context.getPackageName(),
R.layout.main);
Intent playIntent = new Intent(this, BackgroundSoundService.class);
Intent pauseIntent = new Intent(this, BackgroundSoundService.class);
Intent stopIntent = new Intent(this, BackgroundSoundService.class);
PendingIntent playPendingIntent = PendingIntent.getService(
this, REQUEST_CODE, playIntent, INTENT_FLAGS);
PendingIntent pausePendingIntent = PendingIntent.getService(
this, REQUEST_CODE, pauseIntent, INTENT_FLAGS);
PendingIntent stopPendingIntent = PendingIntent.getService(
this, REQUEST_CODE, stopIntent, INTENT_FLAGS);
controlButtons.setOnClickPendingIntent(
R.id.btnPlay, playPendingIntent);
controlButtons.setOnClickPendingIntent(
R.id.btnPause, pausePendingIntent);
controlButtons.setOnClickPendingIntent(
R.id.btnStop, stopPendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, controlButtons);
}
}

Widget calls Broadcast only one time

I have an app widget that sends a broadcast, then a broadcast receiver will start a service, the problem is when clicking the widget it would only work at the first time, then I have to open the app to stop the service.
this the widget code:
public class Widget extends AppWidgetProvider {
int appWidgetId;
RemoteViews views;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i = 0; i < appWidgetIds.length; i++) {
appWidgetId = appWidgetIds[i];
views = new RemoteViews(context.getPackageName(), R.layout.widget);
Intent bIntent = new Intent(context,BroadCast.class);
PendingIntent pIntent = PendingIntent.getBroadcast(context, 0, bIntent,0);
views.setOnClickPendingIntent(R.id.widgetbtn, pIntent);
appWidgetManager.updateAppWidget(appWidgetId, views);
}
}
}
The broadcast:
public class BroadCast extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent serviceIntent=new Intent(context,Service.class);
if (!isServiceOn) {
context.startService(serviceIntent);
} else {
context.stopService(serviceIntent);
}
}
}
But it works fine when I send the broadcast from the main activity.

Start my application by clicking on widget

I'm trying How do I run an Activity from a button on a widget in Android? in order to launch my application on click on an image button. When i un-comment the code it switches the images but when i try to use this code it does nothing. I'd like to kick off my application instead.
public class MyWidgetIntentReceiver extends BroadcastReceiver {
private static int clickCount = 0;
#Override
public void onReceive(Context context, Intent intent) {
if(intent.getAction().equals("pl.looksok.intent.action.CHANGE_PICTURE")){
updateWidgetPictureAndButtonListener(context);
}
}
private void updateWidgetPictureAndButtonListener(Context context) {
Log.i("PROJECTCARUSO", "updateWidgetPictureAndButtonListener");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
// remoteViews.setImageViewResource(R.id.widget_button, getImageToSet());
//
// //REMEMBER TO ALWAYS REFRESH YOUR BUTTON CLICK LISTENERS!!!
// remoteViews.setOnClickPendingIntent(R.id.widget_button, MyWidgetProvider.buildButtonPendingIntent(context));
//
// MyWidgetProvider.pushWidgetUpdate(context.getApplicationContext(), remoteViews);
Intent intentClick = new Intent(context, FragmentChange.class);
PendingIntent pendingIntent = PendingIntent.getActivity (context, 0,
intentClick, 0);
remoteViews.setOnClickPendingIntent (R.id.widget_button, pendingIntent);
}
private int getImageToSet() {
clickCount++;
return clickCount % 2 == 0 ? R.drawable.app_icon : R.drawable.energy;
}
}
Here's what i finally got to work:
public class WidgetProvider extends AppWidgetProvider {
public static String SWITCH_WIDGET_UPDATE = "MainActivity.Switch";
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
Log.i("PROJECTCARUSO","onUpdate");
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget);
remoteViews.setOnClickPendingIntent(R.id.widget_button, buildButtonPendingIntent(context));
Intent intentClick = new Intent(context, FragmentChange.class);
PendingIntent pendingIntent = PendingIntent.getActivity (context, 0, intentClick, 0);
remoteViews.setOnClickPendingIntent (R.id.widget_button, pendingIntent);
pushWidgetUpdate(context, remoteViews);
}
public static PendingIntent buildButtonPendingIntent(Context context) {
Intent intent = new Intent();
intent.setAction("CHANGE_PICTURE");
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public static void pushWidgetUpdate(Context context, RemoteViews remoteViews) {
ComponentName myWidget = new ComponentName(context, WidgetProvider.class);
AppWidgetManager manager = AppWidgetManager.getInstance(context);
manager.updateAppWidget(myWidget, remoteViews);
}
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
}
}

Why is AlarmManager not updating my widget?

I have a widget that is simply a textview, that I am attempting to update every second using an AlarmManager. The Log.d("test", "hello1") shows up in my LogCat when I run the app, but the Log.d("test", "service") does not show up, so it appears the program is not even reaching my MyService class.
I would greatly appreciate any help.
Thank you.
Here is my AppWidgetProvider class:
public class NetworkSpeedWidget extends AppWidgetProvider {
private PendingIntent service = null;
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
Log.d("test", "hello");
super.onUpdate(context, appWidgetManager, appWidgetIds);
final AlarmManager m = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
final Intent i = new Intent(context, MyService.class);
if (service == null)
{
service = PendingIntent.getService(context, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
}
Log.d("test", "hello1");
m.setRepeating(AlarmManager.RTC, System.currentTimeMillis(),1000,service);
}
}
Here is my MyService class:
public class MyService extends Service{
#Override
public void onCreate()
{
Log.d("test", "service");
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
buildUpdate();
return super.onStartCommand(intent, flags, startId);
}
private void buildUpdate()
{
MainActivity object = new MainActivity();
String objectString = object.getMegaBitsPerSecondString();
AppWidgetManager manager = AppWidgetManager.getInstance(this);
ComponentName thisWidget = new ComponentName(this, NetworkSpeedWidget.class);
int[]ids = manager.getAppWidgetIds(thisWidget);
final int N = ids.length;
for (int i = 0; i < N; i++){
int awID = ids[i];
RemoteViews v = new RemoteViews(getPackageName(), R.layout.widget);
v.setTextViewText(R.id.widgetTextView,objectString);
manager.updateAppWidget(awID, v);
}
}
#Override
public IBinder onBind(Intent intent)
{
return null;
}
}
All my code is correct, I just needed to declare it in my Manifest.
I simply added the following line:
<service android:enabled="true" android:name=".MyService" />
Thank you jul for your help.

Android OnClickPendingIntent ( widget -> service ) firing by itself

I've ran into a pretty interesting problem - I have a widget that when pressed, would fire a OnClickPendingIntent to invoke a service that would play a sound. But from time to time, about one an hour, it would fire by itself.
widget:
public class WidgetActivity extends AppWidgetProvider {
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
Intent intent = new Intent(context.getApplicationContext(), SilentService.class);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
PendingIntent pendingIntent = PendingIntent.getService(
context.getApplicationContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
remoteViews.setOnClickPendingIntent(R.id.layout, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
context.startService(intent);
}
}
service:
public class SilentService extends Service {
#Override
public void onStart(Intent intent, int startId) {
Log.e("UpdateWidgetService", "Called");
final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(this.getApplicationContext());
int[] appWidgetIds = intent.getIntArrayExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS);
if (appWidgetIds.length > 0) {
for (final int widgetId : appWidgetIds) {
final RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.widget_layout);
remoteViews.setImageViewResource(R.id.ivc, R.drawable.pic1);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
MediaPlayer mpl = MediaPlayer.create(this, R.raw.music1);
int intRand = random.nextInt(5)+1;
Log.e("r",String.valueOf(intRand));
mpl.start();
mpl.setOnCompletionListener(new OnCompletionListener() {
public void onCompletion(MediaPlayer mp) {
remoteViews.setImageViewResource(R.id.ivc, R.drawable.pic2);
appWidgetManager.updateAppWidget(widgetId, remoteViews);
}
});
}
stopSelf();
}
super.onStart(intent, startId);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Thanks!
I have a feeling Android is killing your service and then your code is trying to start it again. I have seen similar issues. Give this a read: http://developer.android.com/guide/topics/fundamentals.html#proclife
When your service restarts after Android tries to get memory back, it is trying to start the service, which creates a new media player, and starts it back up. This is my assumption without knowing exactly how the code is setup, but based on what I see it's most likely the issue.

Categories

Resources