Play sound on widget click - android

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

Related

Android: Intent's extra is missing (working with widget)

I want to make a widget with 2 Buttons(one is a Textview with a number). One button should increment the number and the other decrement it.
Here are my variables(2x action-names and an int for the number)
private static final String PLUS_ONE = "Plus1";
private static final String MINUS_ONE = "minus1";
static int counter = 0;
The onUpdate():
#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];
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.plus1counter_widget);
remoteViews.setOnClickPendingIntent(R.id.counter_widget, getPendingSelfIntent(context, PLUS_ONE, counter));
remoteViews.setOnClickPendingIntent(R.id.img_downWid, getPendingSelfIntent(context, MINUS_ONE, counter));
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}}
getPendingSelfIntent is my method to create an intent, putting an int value in it and returning an PendingIntent
Here in detail:
protected PendingIntent getPendingSelfIntent(Context context, String action, int i) {
Intent intent = new Intent(context, Plus1CounterAppWidgetProvider.class);
intent.setAction(action);
intent.putExtra("safeInt", i);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);}
and eventually my onReturn() in which I want to set the counter to the value I gave to the Intent and perform the action:
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
counter = intent.getIntExtra("safeInt", 0);
if (PLUS_ONE.equals(intent.getAction())) {
counter++;
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.plus1counter_widget);
remoteViews.setTextViewText(R.id.counter_widget, Integer.toString(counter));
AppWidgetManager.getInstance(context).updateAppWidget(new ComponentName(context, Plus1CounterAppWidgetProvider.class), remoteViews);
}
if (MINUS_ONE.equals(intent.getAction())) {
counter--;
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.plus1counter_widget);
remoteViews.setTextViewText(R.id.counter_widget, Integer.toString(counter));
AppWidgetManager.getInstance(context).updateAppWidget(new ComponentName(context, Plus1CounterAppWidgetProvider.class), remoteViews);
}}
By calling
counter = intent.getIntExtra("safeInt", 0);
the counter is always set to 0, which means that there is no extra value.
I just do not get why! Any Solutions? :)
I found an other solution.
I just used SharedPreferences instead of the Intent and it worked! :)
Here is the code:
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.widget.RemoteViews;
public class Plus1CounterAppWidgetProvider extends AppWidgetProvider{
private static final String PLUS_ONE = "Plus1";
private static final String MINUS_ONE = "Minus1";
private static final String REFRESH_COUNTER = "Refresh";
static int counter = 0;
#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];
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.plus1counter_widget);
remoteViews.setOnClickPendingIntent(R.id.counter_widget, getPendingSelfIntent(context, PLUS_ONE));
remoteViews.setOnClickPendingIntent(R.id.img_downWid, getPendingSelfIntent(context, MINUS_ONE));
remoteViews.setOnClickPendingIntent(R.id.img_refreshWid, getPendingSelfIntent(context, REFRESH_COUNTER));
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
SharedPreferences sharedPref = context.getSharedPreferences("com.plus1counter.safeFile", Context.MODE_PRIVATE);
counter = sharedPref.getInt("safeFile", 0);
if(counter == 100){
counter = 0;
}
if (PLUS_ONE.equals(intent.getAction())) {
counter++;
writeSharedPrefs(sharedPref);
}
if (MINUS_ONE.equals(intent.getAction())) {
counter--;
writeSharedPrefs(sharedPref);
}
if(REFRESH_COUNTER.equals(intent.getAction())){
counter = 0;
writeSharedPrefs(sharedPref);
}
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.plus1counter_widget);
remoteViews.setTextViewText(R.id.counter_widget, Integer.toString(counter));
AppWidgetManager.getInstance(context).updateAppWidget(new ComponentName(context, Plus1CounterAppWidgetProvider.class), remoteViews);
}
public void writeSharedPrefs(SharedPreferences sharedPref){
SharedPreferences.Editor editor = sharedPref.edit();
editor.putInt("safeFile", counter);
editor.commit();
}
protected PendingIntent getPendingSelfIntent(Context context, String action) {
Intent intent = new Intent(context, Plus1CounterAppWidgetProvider.class);
intent.setAction(action);
return PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
}

Automatically update widget in the home screen when i make modification in my application

How can we updating the View of a Home Screen Widget on the onReceive method of AppWidgetProvider?.I am trying to update the listview of my Home screen widget but it seems that I cant access the listview of my AppWidgetProvider on onReceive method.My problem is when i changes in my application and come back to the home screen that the widget has no modification.Here is a sample code of my onReceive
public class WidgetTaskSchedular extends AppWidgetProvider {
private final String TAG = "CalendarViewSample:"
+ this.getClass().getName();
static int ID;
int[] sameid=new int[1];
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if(intent.getAction().equals("update_widget"))
{
Log.i(TAG,"AppWidgetIds:"+ID);
for(int i=0;i<1;i++)
{
sameid[i]=ID;
Log.i(TAG,"SameId:"+sameid[i]);
onUpdate(context, AppWidgetManager.getInstance(context),sameid);
}
}
}
public static String EXTRA_WORD=
"com.capsone.testing.calendar.WORD";
#SuppressWarnings("deprecation")
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i=0; i<appWidgetIds.length; i++) {
ID=appWidgetIds[i];
Log.i(TAG,"LengthofWidget:"+appWidgetIds.length);
Log.i(TAG,"TestAppWidget:"+appWidgetIds[i]);
Intent intentWidgetService=new Intent(context, WidgetService.class);
intentWidgetService.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
intentWidgetService.setData(Uri.parse(intentWidgetService.toUri(Intent.URI_INTENT_SCHEME)));
RemoteViews remoteView=new RemoteViews(context.getPackageName(),
R.layout.widgetlayout);
remoteView.setRemoteAdapter(appWidgetIds[i], R.id.listWidget,
intentWidgetService);
Intent clickIntent=new Intent(context, ActionBarActivity.class);
PendingIntent clickPendingIntent=PendingIntent
.getActivity(context, 0,
clickIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
remoteView.setPendingIntentTemplate(R.id.listWidget, clickPendingIntent);
ComponentName component=new ComponentName(context,WidgetTaskSchedular.class);
appWidgetManager.updateAppWidget(component, remoteView);
}
}
}
MainActivity class:
In this main class i change some modification and broadcast this to widget class using on pause method:
#Override
public void onPause() {
super.onPause();
Intent updateWidget = new Intent(getActivity(), WidgetTaskSchedular.class);
updateWidget.setAction("update_widget");
PendingIntent pending = PendingIntent.getBroadcast(getActivity(), 0, updateWidget, PendingIntent.FLAG_CANCEL_CURRENT);
try {
pending.send();
} catch (CanceledException e) {
e.printStackTrace();
}
}

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: Clickable imageview widget

I want to make a very simple widget:
It must consist from just one image view
1) on incoming sms it should change the image
2) on click it also should change the image
I tried to make it using ImageButton but failed: there were problems with changing the image on sms received event: new image had wrong scale.
Anyway now I want to make an ImageView without anything else.
The problem is that I can't handle onClick event:
I've got a running service which should handle all events: sms received and click:
widget provider:
public class MyWidgetProvider extends AppWidgetProvider {
#Override
public void onDisabled(Context context) {
context.stopService(new Intent(context, UpdateService.class));
super.onDisabled(context);
}
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
Intent intent = new Intent(context, UpdateService.class);
context.startService(intent);
}
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i = 0; i < appWidgetIds.length; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
Intent widgetClickIntent = new Intent(context, UpdateService.class);
widgetClickIntent.setAction(UpdateService.ACTION_ON_CLICK);
PendingIntent pendingIntentViewClick = PendingIntent.getService(context, 0, widgetClickIntent, 0);
remoteViews.setOnClickPendingIntent(R.id.widget_imageview, pendingIntentViewClick);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}
}
service:
public class UpdateService extends Service {
static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
static final String ACTION_ON_CLICK = "android.MyWidget.ACTION_ON_CLICK";
private final static IntentFilter intentFilter;
static {
intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_SMS_RECEIVED);
intentFilter.addAction(ACTION_ON_CLICK);
}
public final BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (action.equals(ACTION_SMS_RECEIVED)) {
reactOnSms(context);
}
if (action.equals(ACTION_ON_CLICK)) {
onCLick(context);
}
}
};
#Override
public void onCreate() {
super.onCreate();
registerReceiver(broadcastReceiver, intentFilter);
}
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(broadcastReceiver);
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void reactOnSms(Context context) {
// doSomething
}
public void onCLick(Context context) {
// doSomething
}
Manifest:
<receiver a:name="..."...>
<intent-filter>
<action a:name="android.provider.Telephony.SMS_RECEIVED"/>
<action a:name="android.MyWidget.ACTION_ON_CLICK"/>
</intent-filter>
<meta-data a:name="android.appwidget.provider"
a:resource="#xml/my_widget_provider_info"/>
</receiver>
<service a:name=".UpdateService"
a:label="UpdateService">
<intent-filter>
<action a:name="android.provider.Telephony.SMS_RECEIVED"/>
<action a:name="android.MyWidget.ACTION_ON_CLICK"/>
</intent-filter>
</service>
I tried this Clickable widgets in android
I found the solution.
Sorry for those of you who read the question. Too much code inside, I understand.
The problem was that UpdateService was not the real handler of the broadcast intent. Anonymous implementation of BroadcastReceiver made all the work.
So the problem was in this code (widgetProvider):
#Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int i = 0; i < appWidgetIds.length; i++) {
int appWidgetId = appWidgetIds[i];
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
// wrong:
// Intent widgetClickIntent = new Intent(context, UpdateService.class);
// widgetClickIntent.setAction(UpdateService.ACTION_ON_CLICK);
// PendingIntent pendingIntentViewClick = PendingIntent.getService(context, 0, widgetClickIntent, 0);
// correct:
Intent widgetClickIntent = new Intent(UpdateService.ACTION_ON_CLICK);
PendingIntent pendingIntentViewClick = PendingIntent.getBroadcast(context, 0, widgetClickIntent, 0);
///////
remoteViews.setOnClickPendingIntent(R.id.widget_imageview, pendingIntentViewClick);
appWidgetManager.updateAppWidget(appWidgetId, remoteViews);
}
}

Categories

Resources