How to stop audio playback when a phone call arrives in Android - android

hello im new to android and im doing a simple online radio app for my church the poblem is that i need the playback service to stop and restart when the phone gets a call and end it
so far i can stop the service just fine but when it gets started again just crashes so i dont know what im doing wrong
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.content.res.Resources;
import android.os.IBinder;
import android.os.PowerManager.WakeLock;
import android.support.v4.app.NotificationCompat;
import com.spoledge.aacdecoder.MultiPlayer;
public class RadioService extends Service{
WakeLock wakelock;
//TelephonyManager teleManager= null;
//PhoneStateListener listener;
NotificationManager mNotificationManager;
public static MultiPlayer aacPlayer;
public static String radio;
private static Boolean isTuning;
// private TeleListener myListener = null;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
super.onCreate();
setTuning(false);
setRadio(getString(R.string.rhema));
aacPlayer = new MultiPlayer();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId){
setTuning(true);
setTuning(true);
aacPlayer.playAsync(radio);
//CallReceiver.setTuning(true);
Resources r= getResources();
String[] Notify = r.getStringArray(R.array.PlayNotify);
// prepare intent which is triggered if the
// notification is selected
Intent inten = new Intent(this, PlayerActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, inten, 0);
// build notification
// the addAction re-use the same intent to keep the example short
NotificationCompat.Builder n = new NotificationCompat.Builder(this)
.setContentTitle(Notify[0])
.setContentText(Notify[1])
.setSmallIcon(R.drawable.noti_icon)
.setContentIntent(pIntent)
.setAutoCancel(true)
.setOngoing(true)
.setContentIntent(pIntent);
Notification hola = n.build();
startForeground(100, hola);
//startForeground(startId, notification);
return START_STICKY;
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
pause();
//CallReceiver.setTuning(false);
super.onDestroy();
}
public static boolean getTuning() {
return isTuning;
}
public void setTuning(boolean Tuning) {
isTuning = Tuning;
}
public void setRadio(String r){
radio = r;
}
public void PlayNotify(){
Resources r= getResources();
String[] Notify = r.getStringArray(R.array.PlayNotify);
// prepare intent which is triggered if the
// notification is selected
Intent intent = new Intent(this, RadioService.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, 0);
// build notification
// the addAction re-use the same intent to keep the example short
NotificationCompat.Builder n = new NotificationCompat.Builder(this)
.setContentTitle(Notify[0])
.setContentText(Notify[1])
.setSmallIcon(R.drawable.noti_icon)
.setContentIntent(pIntent)
.setAutoCancel(true);
n.setOngoing(true);
n.setContentIntent(pIntent);
//NotificationManager mNotificationManager =(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
mNotificationManager.notify(100, n.build());
}
public static void play(){
aacPlayer.playAsync(radio);
}
public static void pause(){
aacPlayer.stop();
}
}
and this is the broadcast
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
public class CallReceiver extends BroadcastReceiver{
TelephonyManager telManager;
Context context;
public static boolean Tuning = false;
PlayerActivity mainActivity;
NotificationManager mNotificationManager;
#Override
public void onReceive(Context context, Intent intent) {
mainActivity=new PlayerActivity();
this.context=context;
telManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
telManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
private final PhoneStateListener phoneListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
try {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING: {
//PAUSE
if(Tuning){
context.stopService(new Intent(context,RadioService.class));
}
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {
if(Tuning){
context.stopService(new Intent(context,RadioService.class));
}
break;
}
case TelephonyManager.CALL_STATE_IDLE: {
//PLAY
if(Tuning){
showNotification(context);
context.stopService(new Intent(context,RadioService.class));}
break;
}
default: { }
}
} catch (Exception ex) {
}
}
};
public static void setTuning(boolean r){
Tuning = r;
}
private void showNotification(Context context) {
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, PlayerActivity.class), 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.noti_icon)
.setContentTitle("Rhema Stereo")
.setContentText("Vuelve a Sintonizarnos.");
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(1, mBuilder.build());}
}
the weir thing is that from the activities i can start and stop the service just fine but here i can only stop it. So for now im using a notification to get back to an activity and restart the service

If I may, I would suggest another approach for this problem. You state that:
i need the playback service to stop and restart when the phone gets a
call
However, the issue is more complex. You should also stop playback, for example, when a notification arrives, or if another music player is started by the user. Instead of having to monitor all these posibilities independently, Android provides built-in support for this concept -- it's called the audio focus. In broad terms, it means that only one app can have audio focus at one point in time, and that you should relinquish if it asked to.
This behavior can be obtained by using an OnAudioFocusChangeListener.
Basically, you must:
Request audio focus before starting playback.
Only start playback if you effectively obtain it.
Abandon focus when you stop playback.
Handle audio focus loss (either by lowering volume or stopping playback altogether).
Please check the Managing Audio Focus article in the Android documentation.

you need to add this snippet in your current activity
IntentFilter receiverFilter = new IntentFilter(
Intent.ACTION_HEADSET_PLUG);
BootBroadcast receiver = new BootBroadcast();
registerReceiver(receiver, receiverFilter);
then the same need to register in the receiver manifest.xml
eg:
<receiver
android:name="YOUR_ACTION_STRING.BootCompletedReceiver"
android:enabled="true"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
Also add this flag inside BootBroadcast class
newIntent .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

Related

Why is deleteIntent(PendingIntent) not called when notification is canceled?

Why is deleteIntent(PendingIntent) not called when notification is canceled?
I am doing this android tutorial on Notifications and in the 'extra challenge', am using deleteIntent.
However it is not invoked at all. Running in the emulator on API 27.
When I swipe the notification to cancel, the cancelNotification() method is not called.
In the docs, I see the watermark 'deprecated' on the page but it's not in the text.
Not sure if it's actually deprecated or if I am using deleteIntent() wrongly.
https://codelabs.developers.google.com/codelabs/android-training-notifications/#6
In the NotifyMe app, there is one use case in which the state of your
buttons does not match the state of the app: when a user dismisses a
notification by swiping it away or clearing the whole notification
drawer. In this case, your app has no way of knowing that the
notification was canceled and that the button state must be changed.
Create another pending intent to let the app know that the user has
dismissed the notification, and toggle the button states accordingly.
Hint: Check out the NotificationCompat.Builder class for a method that
delivers an Intent if the user dismisses the notification.
package com.notifyme;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private static final String PRIMARY_CHANNEL_ID = "primary_notification_channel";
private NotificationManager mNotifyManager;
private static final int NOTIFICATION_ID = 0;
private static final String ACTION_UPDATE_NOTIFICATION =
"com.example.android.notifyme.ACTION_UPDATE_NOTIFICATION";
private static final String ACTION_CANCEL_NOTIFICATION =
"com.example.android.notifyme.ACTION_CANCEL_NOTIFICATION";
private NotificationReceiver mReceiver = new NotificationReceiver();
public class NotificationReceiver extends BroadcastReceiver {
public NotificationReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case ACTION_UPDATE_NOTIFICATION:
updateNotification();;
break;
case ACTION_CANCEL_NOTIFICATION:
cancelNotification();
break;
}
}
}
public void createNotificationChannel() {
mNotifyManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.O) {
// Create a NotificationChannel
NotificationChannel notificationChannel = new NotificationChannel(PRIMARY_CHANNEL_ID,
"Mascot Notification", NotificationManager
.IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setDescription("Notification from Mascot");
mNotifyManager.createNotificationChannel(notificationChannel);
}
}
private Button button_notify;
private Button button_cancel;
private Button button_update;
public void sendNotification() {
Intent updateIntent = new Intent(ACTION_UPDATE_NOTIFICATION);
PendingIntent updatePendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, updateIntent, PendingIntent.FLAG_ONE_SHOT);
Intent cancelIntent = new Intent(ACTION_CANCEL_NOTIFICATION);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, cancelIntent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
notifyBuilder.addAction(R.drawable.ic_update, "Update Notification", updatePendingIntent);
notifyBuilder.setDeleteIntent(cancelPendingIntent);
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
setNotificationButtonState(false, true, true);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_notify = findViewById(R.id.notify);
button_notify.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendNotification();
}
});
createNotificationChannel();
button_update = findViewById(R.id.update);
button_update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Update the notification
updateNotification();
}
});
button_cancel = findViewById(R.id.cancel);
button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Cancel the notification
cancelNotification();
}
});
registerReceiver(mReceiver,new IntentFilter(ACTION_UPDATE_NOTIFICATION));
setNotificationButtonState(true, false, false);
}
#Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
public void updateNotification() {
Bitmap androidImage = BitmapFactory
.decodeResource(getResources(),R.drawable.mascot_1);
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
notifyBuilder.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(androidImage)
.setBigContentTitle("Notification Updated!"));
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
setNotificationButtonState(false, false, true);
}
public void cancelNotification() {
mNotifyManager.cancel(NOTIFICATION_ID);
setNotificationButtonState(true, false, false);
}
private NotificationCompat.Builder getNotificationBuilder(){
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent notificationPendingIntent = PendingIntent.getActivity(this,
NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this, PRIMARY_CHANNEL_ID)
.setContentTitle("You've been notified!")
.setContentText("This is your notification text.")
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(notificationPendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setAutoCancel(true);
return notifyBuilder;
}
void setNotificationButtonState(Boolean isNotifyEnabled,
Boolean isUpdateEnabled,
Boolean isCancelEnabled) {
button_notify.setEnabled(isNotifyEnabled);
button_update.setEnabled(isUpdateEnabled);
button_cancel.setEnabled(isCancelEnabled);
}
}
Update: From CommonsWare's helpful answer below, I corrected the registration of the receiver to use multiple Actions for the same IntentFilter. However it still failed even though I tried all the different flags for the PendingIntent.
When you press the Update button in the notification and then swipe right, the buttons in the Activity do not reset their states because the PendingIntent is not firing.
Here is my updated code.
package com.onedropaflame.notifyme;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
private static final String PRIMARY_CHANNEL_ID = "primary_notification_channel";
private NotificationManager mNotifyManager;
private static final int NOTIFICATION_ID = 0;
private static final String ACTION_UPDATE_NOTIFICATION =
"com.example.android.notifyme.ACTION_UPDATE_NOTIFICATION";
private static final String ACTION_CANCEL_NOTIFICATION =
"com.example.android.notifyme.ACTION_CANCEL_NOTIFICATION";
private NotificationReceiver mReceiver = new NotificationReceiver();
public class NotificationReceiver extends BroadcastReceiver {
public NotificationReceiver() {
}
#Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case ACTION_UPDATE_NOTIFICATION:
updateNotification();;
break;
case ACTION_CANCEL_NOTIFICATION:
cancelNotification();
break;
}
}
}
public void createNotificationChannel() {
mNotifyManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
if (android.os.Build.VERSION.SDK_INT >=
android.os.Build.VERSION_CODES.O) {
// Create a NotificationChannel
NotificationChannel notificationChannel = new NotificationChannel(PRIMARY_CHANNEL_ID,
"Mascot Notification", NotificationManager
.IMPORTANCE_HIGH);
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.enableVibration(true);
notificationChannel.setDescription("Notification from Mascot");
mNotifyManager.createNotificationChannel(notificationChannel);
}
}
private Button button_notify;
private Button button_cancel;
private Button button_update;
public void sendNotification() {
Intent updateIntent = new Intent(ACTION_UPDATE_NOTIFICATION);
PendingIntent updatePendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, updateIntent, PendingIntent.FLAG_ONE_SHOT);
Intent cancelIntent = new Intent(ACTION_CANCEL_NOTIFICATION);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, cancelIntent, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
notifyBuilder.addAction(R.drawable.ic_update, "Update Notification", updatePendingIntent);
notifyBuilder.setDeleteIntent(cancelPendingIntent);
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
setNotificationButtonState(false, true, true);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button_notify = findViewById(R.id.notify);
button_notify.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
sendNotification();
}
});
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(ACTION_CANCEL_NOTIFICATION);
intentFilter.addAction(ACTION_UPDATE_NOTIFICATION);
createNotificationChannel();
registerReceiver(mReceiver,intentFilter);
button_update = findViewById(R.id.update);
button_update.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Update the notification
updateNotification();
}
});
button_cancel = findViewById(R.id.cancel);
button_cancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
//Cancel the notification
cancelNotification();
}
});
setNotificationButtonState(true, false, false);
}
#Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
public void updateNotification() {
Bitmap androidImage = BitmapFactory
.decodeResource(getResources(),R.drawable.mascot_1);
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
notifyBuilder.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(androidImage)
.setBigContentTitle("Notification Updated!"));
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
setNotificationButtonState(false, false, true);
}
public void cancelNotification() {
mNotifyManager.cancel(NOTIFICATION_ID);
setNotificationButtonState(true, false, false);
}
private NotificationCompat.Builder getNotificationBuilder(){
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent notificationPendingIntent = PendingIntent.getActivity(this,
NOTIFICATION_ID, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notifyBuilder = new NotificationCompat.Builder(this, PRIMARY_CHANNEL_ID)
.setContentTitle("You've been notified!")
.setContentText("This is your notification text.")
.setSmallIcon(R.drawable.ic_android)
.setContentIntent(notificationPendingIntent)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setDefaults(NotificationCompat.DEFAULT_ALL)
.setAutoCancel(true);
return notifyBuilder;
}
void setNotificationButtonState(Boolean isNotifyEnabled,
Boolean isUpdateEnabled,
Boolean isCancelEnabled) {
button_notify.setEnabled(isNotifyEnabled);
button_update.setEnabled(isUpdateEnabled);
button_cancel.setEnabled(isCancelEnabled);
}
}
It appears as though you are not registering a receiver for ACTION_CANCEL_NOTIFICATION, just ACTION_UPDATE_NOTIFICATION.
Commonsware posted the correct answer about both actions needing to be registered.
However that was not sufficient. I corrected the registration of the receiver to use multiple Actions for the same IntentFilter. However it still failed even though I tried all the different flags for the PendingIntent. When you press the Update button in the notification and then swipe right, the buttons in the Activity do not reset their states because the PendingIntent is not firing.
Solution: I found that I had to set the cancelPendingIntent again during the updateNotification(). I do not know the reason why it is lost.
public void updateNotification() {
Bitmap androidImage = BitmapFactory
.decodeResource(getResources(),R.drawable.mascot_1);
NotificationCompat.Builder notifyBuilder = getNotificationBuilder();
notifyBuilder.setStyle(new NotificationCompat.BigPictureStyle()
.bigPicture(androidImage)
.setBigContentTitle("Notification Updated!"));
// >>>>> SET AGAIN! >>>>>>>>>
Intent cancelIntent = new Intent(ACTION_CANCEL_NOTIFICATION);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast
(this, NOTIFICATION_ID, cancelIntent, PendingIntent.FLAG_ONE_SHOT);
notifyBuilder.setDeleteIntent(cancelPendingIntent);
// >>>>>>>>>>>>>>
mNotifyManager.notify(NOTIFICATION_ID, notifyBuilder.build());
setNotificationButtonState(false, false, true);
}

How to keep an app running when screen goes off(latest android)

I have an app (activity). I want it to stay running even if screen goes off, but older solution don't work. As i understand the only solution is to make a service. But is it easy to transform an activity to service?The method with wake lock can't be used any more, as it is deprecated.
Create Foreground Service as below.
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Build;
import android.os.IBinder;
import android.support.annotation.Nullable;
import android.support.v4.app.NotificationCompat;
public class ForegroundService extends Service {
public static final String CHANNEL_ID = "ForegroundServiceChannel";
#Override
public void onCreate() {
super.onCreate();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
String input = intent.getStringExtra("inputExtra");
createNotificationChannel();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("Foreground Service")
.setContentText(input)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentIntent(pendingIntent)
.build();
startForeground(1001, notification);
return START_NOT_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Foreground Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
}
Dont forget to declarer the service in manifest.

Android Studio AlarmManager Background Repeat Run

I am attempting to create a background Service so when the application is closed a service is running in the background that will show a notification every 5 seconds to the phone using an AlarmManager.
I currently have my java service file setup as:
package com.racecoursedatatechnologies.rdtstockmanagement;
import android.app.Service;
import android.app.AlarmManager;
import android.content.Intent;
import android.util.Log;
import android.os.Binder;
import android.os.IBinder;
import android.app.PendingIntent;
import android.app.PendingIntent;
public class BackIntentService extends Service {
private PendingIntent pendingIntent;
private AlarmManager manager;
public class LocalBinder extends Binder {
BackIntentService getService() {
return BackIntentService.this;
}
}
#Override
public void onCreate() {
startAlarm();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("LocalService", "Received start id " + startId + ": " + intent);
return START_NOT_STICKY;
}
public void startAlarm()
{
manager = (AlarmManager)getSystemService(this.ALARM_SERVICE);
Intent intent = new Intent(this, BackNotifyAlarm.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
int interval = 1000 * 5;
manager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), interval, pendingIntent);
Toast.makeText(this, "Alarm Started", Toast.LENGTH_SHORT).show();
}
#Override
public void onDestroy() {
// Tell the user we stopped.
Log.d("LocalService", "Stopped");
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients. See
// RemoteService for a more complete example.
private final IBinder mBinder = new LocalBinder();
/**
* Show a notification while this service is running.
*/
private void showNotification() {
//Create a notification and set it's content and display it.
NotificationManager notif=(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
Notification notify=new Notification.Builder
(getApplicationContext()).setContentTitle("RDT Stock").setContentText("HELLOOO").
setContentTitle("Low Stock Items").setSmallIcon(R.drawable.noticon).build();
notify.flags |= Notification.FLAG_AUTO_CANCEL;
notif.notify(11, notify);
}
}
BackNotifyAlarm Broadcast java file:
public class BackNotifyAlarm extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
//PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
//PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "");
//wl.acquire();
Toast.makeText(context, "Notification sent!", Toast.LENGTH_LONG).show();
//wl.release();
}
I am starting the service in the MainActivity file. The service starts and the service then runs an Alarm, however the alarm only seems to run once and not repeat, any idea why?

Android Notification showing only once

I have the following code in which I have one date picker and time picker
When I select that date and time I want to show notification...
It is perfectly working but when I again put notification means if I pu6 multiple notification it will show me only last one...
Means only last notification is showing not all...
NotifyService.java
package com.blundell.tut.service;
import android.R;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.Toast;
import com.blundell.tut.ui.phone.SecondActivity;
public class NotifyService extends Service {
/**
* Class for clients to access
*/
public class ServiceBinder extends Binder {
NotifyService getService() {
return NotifyService.this;
}
}
// Unique id to identify the notification.
public static int NOTIFICATION = 123;
// Name of an intent extra we can use to identify if this service was started to create a notification
public static final String INTENT_NOTIFY = "com.blundell.tut.service.INTENT_NOTIFY";
// The system notification manager
private NotificationManager mNM;
#Override
public void onCreate() {
Log.i("NotifyService", "onCreate()");
mNM = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("LocalService", "Received start id " + startId + ": " + intent);
// If this service was started by out AlarmTask intent then we want to show our notification
if(intent.getBooleanExtra(INTENT_NOTIFY, false))
showNotification();
// We don't care if this service is stopped as we have already delivered our notification
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients
private final IBinder mBinder = new ServiceBinder();
/**
* Creates a notification and shows it in the OS drag-down status bar
*/
private void showNotification() {
// This is the 'title' of the notification
CharSequence title = "Alarm!!";
// This is the icon to use on the notification
int icon = R.drawable.ic_dialog_alert;
// This is the scrolling text of the notification
CharSequence text = "Your notification time is upon us.";
// What time to show on the notification
long time = System.currentTimeMillis();
Notification notification = new Notification(icon, text, time);
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, SecondActivity.class), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, title, text, contentIntent);
// Clear the notification when it is pressed
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
NOTIFICATION++;
Toast.makeText(NotifyService.this, Integer.toString(NOTIFICATION), Toast.LENGTH_SHORT).show();
mNM.notify(NOTIFICATION, notification);
// Stop the service when we are finished
stopSelf();
}
}
ScheduleClient.java
package com.blundell.tut.service;
import java.util.Calendar;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.IBinder;
/**
* This is our service client, it is the 'middle-man' between the
* service and any activity that wants to connect to the service
*
* #author paul.blundell
*/
public class ScheduleClient {
// The hook into our service
private ScheduleService mBoundService;
// The context to start the service in
private Context mContext;
// A flag if we are connected to the service or not
private boolean mIsBound;
public ScheduleClient(Context context) {
mContext = context;
}
/**
* Call this to connect your activity to your service
*/
public void doBindService() {
// Establish a connection with our service
mContext.bindService(new Intent(mContext, ScheduleService.class), mConnection, Context.BIND_AUTO_CREATE);
mIsBound = true;
}
/**
* When you attempt to connect to the service, this connection will be called with the result.
* If we have successfully connected we instantiate our service object so that we can call methods on it.
*/
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
// This is called when the connection with our service has been established,
// giving us the service object we can use to interact with our service.
mBoundService = ((ScheduleService.ServiceBinder) service).getService();
}
public void onServiceDisconnected(ComponentName className) {
mBoundService = null;
}
};
/**
* Tell our service to set an alarm for the given date
* #param c a date to set the notification for
*/
public void setAlarmForNotification(Calendar c){
mBoundService.setAlarm(c);
}
/**
* When you have finished with the service call this method to stop it
* releasing your connection and resources
*/
public void doUnbindService() {
if (mIsBound) {
// Detach our existing connection.
mContext.unbindService(mConnection);
mIsBound = false;
}
}
}
ScheduleService.java
package com.blundell.tut.service;
import java.util.Calendar;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import com.blundell.tut.service.task.AlarmTask;
public class ScheduleService extends Service {
/**
* Class for clients to access
*/
NotifyService ns=new NotifyService();
public class ServiceBinder extends Binder {
ScheduleService getService() {
return ScheduleService.this;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i("ScheduleService", "Received start id " + ns.NOTIFICATION + ": " + intent);
// We want this service to continue running until it is explicitly stopped, so return sticky.
return START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
// This is the object that receives interactions from clients. See
private final IBinder mBinder = new ServiceBinder();
/**
* Show an alarm for a certain date when the alarm is called it will pop up a notification
*/
public void setAlarm(Calendar c) {
// This starts a new thread to set the alarm
// You want to push off your tasks onto a new thread to free up the UI to carry on responding
new AlarmTask(this, c).run();
}
}
AlarmTask.java
package com.blundell.tut.service.task;
import java.util.Calendar;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import com.blundell.tut.service.NotifyService;
public class AlarmTask implements Runnable{
// The date selected for the alarm
private final Calendar date;
// The android system alarm manager
private final AlarmManager am;
// Your context to retrieve the alarm manager from
private final Context context;
public AlarmTask(Context context, Calendar date) {
this.context = context;
this.am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
this.date = date;
}
#Override
public void run() {
// Request to start are service when the alarm date is upon us
// We don't start an activity as we just want to pop up a notification into the system bar not a full activity
Intent intent = new Intent(context, NotifyService.class);
intent.putExtra(NotifyService.INTENT_NOTIFY, true);
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
// Sets an alarm - note this alarm will be lost if the phone is turned off and on again
am.set(AlarmManager.RTC_WAKEUP, date.getTimeInMillis(), pendingIntent);
long firstTime = date.getTimeInMillis();
am.setRepeating(AlarmManager.RTC_WAKEUP, firstTime, am.INTERVAL_DAY * 7, pendingIntent);
}
}
MainActivity.java
package com.blundell.tut.ui.phone;
import java.util.Calendar;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.DatePicker;
import android.widget.TimePicker;
import android.widget.Toast;
import com.blundell.tut.R;
import com.blundell.tut.service.NotifyService;
import com.blundell.tut.service.ScheduleClient;
public class MainActivity extends Activity
{
// This is a handle so that we can call methods on our service
private ScheduleClient scheduleClient;
private DatePicker picker;
NotifyService ns;
private TimePicker tp;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
scheduleClient = new ScheduleClient(this);
scheduleClient.doBindService();
ns=new NotifyService();
picker = (DatePicker) findViewById(R.id.scheduleTimePicker);
tp=(TimePicker)findViewById(R.id.TimePicker);
tp.setIs24HourView(true);
}
public void onDateSelectedButtonClick(View v){
int day = picker.getDayOfMonth();
int month = picker.getMonth();
int year = picker.getYear();
int hour=tp.getCurrentHour();
int min=tp.getCurrentMinute();
// Create a new calendar set to the date chosen
// we set the time to midnight (i.e. the first minute of that day)
Calendar c = Calendar.getInstance();
c.set(year, month, day,hour,min,0);
scheduleClient.setAlarmForNotification(c);
// Notify the user what they just did
//Toast.makeText(this, Integer.toString(ns.NOTIFICATION), Toast.LENGTH_SHORT).show();
//Toast.makeText(this, "Notification set for: "+ day +"/"+ (month+1) +"/"+ year, Toast.LENGTH_SHORT).show();
}
#Override
protected void onStop()
{
// When our activity is stopped ensure we also stop the connection to the service
// this stops us leaking our activity into the system *bad*
if(scheduleClient != null)
scheduleClient.doUnbindService();
super.onStop();
}
}
SecondActivity.java
package com.blundell.tut.ui.phone;
import android.app.Activity;
import android.os.Bundle;
import com.blundell.tut.R;
/**
* This is the activity that is started when the user presses the notification in the status bar
* #author paul.blundell
*/
public class SecondActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
}
}
Please suggest me at which place i have to change code...????
In this line,
mNM.notify(NOTIFICATION, notification);
Just make sure that each time the different value of NOTIFICATION is being passed.
at AlarmTask.java, you are hard coded always 0 in PendingIntent.
requestCode must be
UNIQUE INTEGER NUMBER
so change your code,
from
PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
to
int random = (int)System.currentTimeMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, random, intent, 0);
Just write code like this.
int random = (int)System.currentTimeMillis();
manager.notify(random , activeNotification);

Notifications and AlarmManager - cancelling the alarm I set

I am making a sample app just for educational purposes, where I create a notification every minute. I also have a button to cancel the alarm.
What I do is that when the notification comes, I click it and click the unset button I have set to run unsetAlarm(). But it continues to bother me every minute.
How do I stop the notifications? Could it be that the activity is somehow duplicated? If this is the case, how do I ensure there is only one instance of the MainActivity?
MainActivity class
package no.perandersen.notifyontimeexample;
import java.util.Calendar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
public class MainActivity extends Activity {
private AlarmManager alarmManager;
private PendingIntent notifyIntent;
private static final String TAG = "MainActivity";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
}
public void setAlarm(View v) {
Intent myIntent = new Intent(MainActivity.this,
NotificationService.class);
notifyIntent = PendingIntent.getService(MainActivity.this, 0,
myIntent, 0);
Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 1);
Log.v(TAG, "time for alarm trigger:" + calendar.getTime().toString());
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,
calendar.getTimeInMillis(), 1 * 60 * 1000, notifyIntent);
}
public void unsetAlarm(View v) {
alarmManager.cancel(notifyIntent);
Log.v(TAG, "cancelling notification");
}
}
NotificationService class
package no.perandersen.notifyontimeexample;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.util.Log;
public class NotificationService extends Service {
private NotificationManager nm;
private static final String TAG = "NotificationService";
#Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
Log.v(TAG, "on onCreate");
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Log.v(TAG, "on onStartCommand");
Intent mainActivityIntent = new Intent(this, MainActivity.class);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, mainActivityIntent, 0);
Notification notification = new NotificationCompat.Builder(this)
.setContentTitle("bothering you")
.setContentText("Just bothering you from example code")
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pIntent)
.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.flags |= Notification.FLAG_SHOW_LIGHTS;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
notification.defaults|= Notification.DEFAULT_LIGHTS;
nm.notify(0, notification);
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
The problem is that to cancel an Alarm you need to recreate the PendingIntent exactly how you created it when you set the alarm. So change your unsetAlarm() to
public void unsetAlarm(View v) {
Intent myIntent = new Intent(MainActivity.this,
NotificationService.class);
notifyIntent = PendingIntent.getService(MainActivity.this, 0,
myIntent, 0); // recreate it here before calling cancel
alarmManager.cancel(notifyIntent);
Log.v(TAG, "cancelling notification");
}

Categories

Resources