I'm developing an online radio application. The application works in the background. When I click the NotificationManager, radioclass starts working again. I want to call the radioclass that are running. How can I do?
player = MediaPlayer.create(this, Uri.parse("http://...../playlist.m3u8"));
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
#Override
public void onPrepared(MediaPlayer player) {
}
});
player.start();
final int notificationID = 1234;
String msg = "mesajjj";
Log.d(TAG, "Preparing to update notification...: " + msg);
NotificationManager mNotificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, RadioClass.class);
//Here RadioClass running again. But RadioClass already running. I should call RadioClass that is running.
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(
this).setSmallIcon(R.drawable.logotam)
.setContentTitle("Test FM")
.setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg);
mBuilder.setContentIntent(pendingIntent);
mNotificationManager.notify(notificationID, mBuilder.build());
If you want to go back to the same activity you are currently running, you can do it like this:
Add the following tag on your AndroidManifest.xml:
<activity
........
android:launchMode="singleTop" >
........
</activity>
Modify your PendingIntent like this:
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent,Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
With this modifications, you ensure that your activity will only have one instance at any given time. On your activity class, you can also override the onNewIntent method:
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
}
This method will handle all of the additional calls to your activity.
Related
Inside the onCreate method of my Service I create a notification by doing the following:
String channelId = "001";
String channelName = "myChannel";
NotificationChannel channel = new NotificationChannel(channelId, channelName, NotificationManager.IMPORTANCE_NONE);
channel.setLightColor(Color.BLUE);
channel.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) {
manager.createNotificationChannel(channel);
Notification notification;
Intent myIntent = new Intent("alarmReceiver");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, myIntent, 0);
Notification.Action action = new Notification.Action.Builder(
Icon.createWithResource(this, R.drawable.ic_stop_black_24dp),
"action string",
pendingIntent).build();
//Modify notification badge
notification = new Notification.Builder(getApplicationContext(), channelId).setOngoing(true)
.setSmallIcon(R.mipmap.ic_launcher)
.setCategory(Notification.CATEGORY_SERVICE)
.addAction(action)
.build();
startForeground(101, notification);
}
The alarmReceiver in the Intent above is registered in my manifest as shown below (I did the following after seeing this question):
<receiver android:name=".AlarmReceiver">
<intent-filter>
<action android:name="alarmReceiver" />
</intent-filter>
</receiver>
and here is my AlarmReceiver class:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("onReceive - ","was called");
}
}
The notification is shown, as well as the button, but when I press the button nothing happens.
I'm not sure what I'm doing wrong. Any help would greatly be appreciated.
Set PendingIntent to foreground service, And potentially add a flag:
FLAG_UPDATE_CURRENT
PendingIntent pendingIntent = PendingIntent.getForegroundService(this, 0, myIntent, FLAG_UPDATE_CURRENT);
Your broadcast is Implicit, so if you want to use getBroadcast() it may be best to Explicitly declare the receiver by providing the intent with the componentName of the receiver.
eg:
intent.setComponent(new ComponentName("packagename","fully qualified class name"));
Have you declared the service in your manifest?
I want a method to be executed when I press a button on my notification. For that purpose I am adding an action with a PendingIntent to my notification:
Intent intent = new Intent(context, AlertActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
Notification notification = new Notification.Builder(MainActivity.this)
.setContentTitle("New Notification")
.setContentText("Click Here")
.setSmallIcon(R.mipmap.ic_launcher)
.setContentIntent(pendingIntent)
.addAction(R.mipmap.ic_launcher, "Test2", pendingIntent)
.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
NotificationManager manager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
manager.notify(0, notification);
That works, however I don't want to start an Activity when the user invokes the action. I just need to do some work.
For that purpose I implemented a Service which should be targeted by the PendingIntent instead:
public class MyServices extends IntentService {
public MyServices() {
super("MyServices");
}
#Override
protected void onHandleIntent(Intent intent) {
clearNotification();
}
public void clearNotification() {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.cancel(0);
Intent intent = new Intent(MyServices.this, MainActivity.class);
//Starting new activity just to check
startActivity(intent);
}
}
I create the PendingIntent like this:
final Intent intent = new Intent(context, MyServices.class);
final PendingIntent pendingIntent = PendingIntent.getService(context, 0, intent, 0);
However when I invoke the action on my notification nothing happens. What am I doing wrong?
A Notification is not part of your application. It is managed by the OS. It just so happens that there are APIs you can use to show/cancel/etc notifications.
A pending intent allows for external code (Notifications for example) to launch your app/activity/service/broadcastreceiver. This cannot be done without a pending intent.
What my task is to execute some piece of code when a specific action button is clicked, and clear notification; without starting any activity
You don't have to start an activity. You can do it in a broadcastreceiver that has no UI. Or, as CommonsWare suggested, use an IntentService, depending on what what you are doing in your "piece of code". IntentServices handle work in a separate thread.
I have a problem with receiving notification. I am sure it is sent as I see log for sending. But I never receive it as I never see log or notification. I am not quiet sure what I am doing wrong.
And I don't want repeating alarm.
Using Nexus 7 on Marshmallow.
PracticeWordsActivity.java
public void setAlarm(int day){
alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
alarmIntent = new Intent(PracticeWordsActivity.this,AlarmReceiver.class);
pendingIntent = PendingIntent.getBroadcast(this, 0, alarmIntent, 0);
//alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, System.currentTimeMillis()+15000, pendingIntent);
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+15000, pendingIntent);
Log.e(TAG,"Lift off");
}
AlarmService
public class AlarmService extends IntentService
{
private static final int NOTIFICATION_ID = 1;
private static final String TAG = "AlarmService";
private NotificationManager notificationManager;
private PendingIntent pendingIntent;
public AlarmService() {
super("AlarmService");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent,flags,startId);
}
#Override
protected void onHandleIntent(Intent intent) {
Log.e(TAG,"Alarm Service has started.");
Context context = this.getApplicationContext();
notificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this,MainActivity.class);
Bundle bundle = new Bundle();
bundle.putString("test", "test");
mIntent.putExtras(bundle);
pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Resources res = this.getResources();
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_launcher)
.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
.setTicker("TITLE")
.setAutoCancel(true)
.setContentTitle("TITLE2")
.setContentText("SUBJECT");
notificationManager =(NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(NOTIFICATION_ID, builder.build());
Log.e(TAG,"Notifications sent.");
}
AlarmReceiver.java
public class AlarmReceiver extends WakefulBroadcastReceiver {
private static final String TAG = "AlarmReceiver";
Intent intent;
PendingIntent pendingIntent;
NotificationManager notificationManager;
#Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "BroadcastReceiver has received alarm intent.");
Intent service1 = new Intent(context, AlarmService.class);
context.startService(service1);
}
}
AndroidManifest.xml
I have set receiver and service after declaring last activity in AndroidManifest.
...
</activity>
<receiver android:name=".AlarmReceiver"
android:enabled="true"/>
<service android:name=".AlarmService" />
</application>
You're using AlarmManager.ELAPSED_REALTIME_WAKEUP to set the alarm. ELAPSED_REALTIME_WAKEUP means time elapsed since the device booted up.
If you want the alarm to be triggered 15 seconds after you set it, use:
alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime()+15000, pendingIntent);
or
alarmManager.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+15000, pendingIntent);
Also, I see you're triggering the alarm in WAKEUP mode and in your broadcast receiver you're starting a service. There is a chance that the device will go back to sleep before the service gets started. You can use WakefulBroadcastReceiver to prevent that.
You don't need to worry about repeating alarms, if you use the same intent to set a new alarm, the previous alarm that is using the same intent will be canceled.
I want to cancel/delete the notification after I click the addAction.
However it's not working. The notification is still there after the click.
I'm pretty sure this worked in an other project.
Can anyone see a stupid error I made, why its not working?
Actual code:
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
showNotification(context);
}
private void showNotification(Context context){
String onderwerp = ("Medicatietijd");
String name = ("Het is tijd om je medicitie in te nemen.");
// Geluid notificatie
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
// Notificatie trigger
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
new Intent(context, Test.class), 0);
// De notificatie
Notification mNotification = new Notification.Builder(context)
.setContentTitle(onderwerp)
.setContentText(name)
.setSmallIcon(R.drawable.ninja)
.setSound(soundUri)
.addAction(R.drawable.ja, "Ja, ik heb ze ingenomen.", contentIntent)
.setAutoCancel(true)
.build();
NotificationManager notificationManager
= (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotification.vibrate = new long[]{100, 200, 100, 500};
mNotification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(0, mNotification);
}
Solution:
In test activity OnCreate added this:
NotificationManager notificationManager
= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.cancel(0);
If you decided to use Test activity to receive the intent of your addAction call, then you must cancel notification when you receive the intent in the activity.
I also recommend that you add requestCode for the intent.
Here is the code :
to set the requestCode modify this :
static final int REQ_CODE = 101; // some number
// Notificatie trigger
PendingIntent contentIntent = PendingIntent.getActivity(context, REQ_CODE,
new Intent(context, Test.class), 0);
to Handle intent in activity and dismiss the notification, in Test activity class :
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
if (requestCode == REQ_CODE) {
// dismiss notification
notificationManager.cancel(0);
// handle your action
// ...
}
}
Hope that helps
I have the following code in an android app. What it currently does is, at the specified time passed with the Calendar when variable, it opens up the RunningActivity (which is blank), vibrates, and sends a notification. Even if I've pressed the home button and it's running in the background, it starts a new blank RunningActivity and vibrates and sends a notification. I'm trying to figure out how to do all the stuff in the RunningActivity (Vibrate and send a notification) without opening up the blank RunningActivity, allowing the application to stay in the background.
I do NOT need help with actually calling the notification or vibration. I just need to know how to run the actions in the RunningActivity onCreate at a specific time witout opening/showing the RunningActivity. As seen below, I setup a PendingIntent with an AlarmManagager, the issue is that it is launching an Activity and showing it when all I want it to do is vibrate/send a notification.
public void startAlarm(Activity activity, Calendar when){
currentTimerHour = when.get(Calendar.HOUR);
currentTimerMin = when.get(Calendar.MINUTE);
Intent intent = new Intent(activity, RunningActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(activity, 12345, intent, PendingIntent.FLAG_CANCEL_CURRENT);
AlarmManager am = (AlarmManager)activity.getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, when.getTimeInMillis(), pendingIntent);
}
RunningActivity Class:
public class RunningActivity extends Activity {
#Override
public void onCreate(Bundle bundle){
super.onCreate(bundle);
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(500);
NotificationCompat.Builder mBuilder;
mBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("My notification")
.setContentText("Hello World!");
Intent resultIntent = new Intent(this, MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(
0,
PendingIntent.FLAG_UPDATE_CURRENT
);
mBuilder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
}
}
To send Notification From Background:
public void createNotification(Context context) {
// Prepare intent which is triggered if the
// notification is selected
Intent intent = new Intent(context,Myexample.class);
PendingIntent pIntent = PendingIntent.getActivity(context, 0, intent, 0);
Notification noti = new Notification.Builder(context)
.setContentTitle("My Title")
.setContentText("My message.")
.setSmallIcon(R.drawable.app_icon)
.setContentIntent(pIntent).build();
#SuppressWarnings("static-access")
NotificationManager notificationManager =
(NotificationManager)context.getSystemService(context.NOTIFICATION_SERVICE);
// Hide the notification after its selected
noti.flags |= Notification.FLAG_AUTO_CANCEL;
noti.flags |= Notification.FLAG_SHOW_LIGHTS;
notificationManager.notify(0, noti);
}
You can use service. Add your vibrator class on Service and call it when you need need it. You can also create a method on your class and call it when you need it.
Vibrator v = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(500);