I have a music application in which I am trying to add some action button on the notification bar.
I tried something like this:
public void onPrepared(MediaPlayer mediaPlayer) {
mediaPlayer.start();
Intent onPreparedIntent=new Intent("MEDIA_PLAYER_PREPARED").putExtra("CURR_SONG",songposn);
LocalBroadcastManager.getInstance(this).sendBroadcast(onPreparedIntent);
Intent notintent = new Intent(this, MainActivity.class).addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Notification.Builder builder=new Notification.Builder(this);
PendingIntent pendingIntent=PendingIntent.getActivity(this,0,notintent,PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent prevPendingIntent=PendingIntent.getActivity
(this,1,new Intent().setAction("PREVIOUS"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pausePendingIntent=PendingIntent.getActivity
(this,2,new Intent().setAction("PAUSE"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent nextPendingIntent=PendingIntent.getActivity
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;
builder.setContentIntent(pendingIntent).setSmallIcon(R.drawable.playicon)
.addAction(R.drawable.back, "Previous", prevPendingIntent)
.addAction(R.drawable.playsmall, "Pause", pausePendingIntent)
.addAction(R.drawable.forw, "Next", nextPendingIntent)
.setTicker(songArtist)
.setOngoing(true).setContentTitle(songTitle).setContentText(songArtist);
Notification not=builder.build();
startForeground(MusicService.NOTIFY_ID,not);
}
I declared a NotificationReciever class inside this service
public class NotificationReciever extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.e("here","here");
String action=intent.getAction();
if(action!=null){
switch (action){
case "PREVIOUS":{
playPrev();
break;
}
case "PAUSE":{
pausePlayer();
LocalBroadcastManager.getInstance(MusicService.this).sendBroadcast(new Intent("STOP_THREAD"));
break;
}
case "NEXT":{
playNext();
break;
}
}
}
}
}
Structure looks something like this:
-MusicService extends Service
--NotificationReciever extends BroadcastReceiver
My manifest file contains reciever like this:
<receiver android:name=".MusicService$NotificationReciever">
<intent-filter>
<action android:name="PREVIOUS"/>
<action android:name="PAUSE"/>
<action android:name="NEXT"/>
</intent-filter>
</receiver>
When I run my music play, notification does come up with buttons but they don't seem to fire the onReceive function?
What am I missing here?
Update:
Followed hasif sayed answer and I seem to found an error
java.lang.RuntimeException: Unable to instantiate receiver com.example.tilak.imusicplay.MusicService$NotificationReciev‌​er: java.lang.InstantiationException:java.lang.Class has no zero argument constructor
Googling about it, I found that I have to use a static class or I have to register/unregister in the parent class.
So this is what I did:
public void onCreate() {
super.onCreate();
//
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PREVIOUS"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PAUSE"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("NEXT"));
}
PendingIntent prevPendingIntent=PendingIntent.getBroadcast
(this,1,new Intent().setAction("PREVIOUS"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pausePendingIntent=PendingIntent.getBroadcast
(this,2,new Intent().setAction("PAUSE"),PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent nextPendingIntent=PendingIntent.getBroadcast
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);
Now I don't get this above error but onReceive is not working again.
Actually the reason why your broadcast reciever is not called when you click on pause,previous and next button is because ,you have set the pending intent to fire an acitivity,instead you have to set the pending intent to fire a boradcast
instead of this code snippet
PendingIntent nextPendingIntent=PendingIntent.getActivity
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;
you have to correct it like this
PendingIntent nextPendingIntent=PendingIntent.getBroadcast
(this,3,new Intent().setAction("NEXT"),PendingIntent.FLAG_UPDATE_CURRENT);;
make corrections in all the three pending intent code which you have written
UPDATE
The reason why you still not receiving the broadcast in your Broadcast Receiver is because you are programitically registering your Receiver as LocalBroadCast
When using with PendingIntent, LocalBroadcast will not receive the Broadcast
so please remove this Line
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PREVIOUS"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("PAUSE"));
LocalBroadcastManager.getInstance(this).registerReceiver(
new NotificationReciever(),new IntentFilter("NEXT"));
Instead, you only have to register the receiver in the Manifest.xml file
or
programitically you can register in code as
NotificationReciever mReciever = new NotificationReciever();
this.registerReceiver(
mReciever,new IntentFilter("PREVIOUS"));
this.registerReceiver(
mReciever,new IntentFilter("PAUSE"));
this.registerReceiver(
mReciever,new IntentFilter("NEXT"));
but if you register this programitically, make sure you unregister it while service is getting destroyed. Otherwise you may LEAK the BroadcastReceiver Object
Related
I'm trying to schedule notifications with AlarmManager It works perfectly when I schedule one notification but when I schedule two notification, the first notification is okay but the second one not works.
I figured out opening the app after few minutes will notify the second notification. I think something is wrong with my BroadcastReceiver
MainActivity.java
Intent intent = new Intent(context,NotificationClass.class);
intent.putExtra("notification_id", id);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,id,intent,PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),pendingIntent);
Notification.java
public class NotificationClass extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
int id = intent.getIntExtra("notification_id",0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context,"1")
.setContentTitle("Notification")
.setContentText("Content")
.setSmallIcon(R.drawable.notif_ic);
Notification notification = builder.build();
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel channel = new NotificationChannel("1","test", NotificationManager.IMPORTANCE_HIGH);
notificationManager.createNotificationChannel(channel);
}
notificationManager.notify(id,notification);
}
AndroidManifest.xml
<receiver android:name=".NotificationClass" ></receiver>
I don't know what is wrong with my code. Can anybody help me with this?
Broadcast receiver to receive the data:
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String alertMessage = intent.getStringExtra("type");
doNotificationAlertWorkHere(alertMessage);
}
};
Register & Unregister your broadcast to avoid static leaks.
via the Android manifest file. (Statically)
<receiver android:name="YourBroadcastReceiverName"> </receiver>
via the Context.registerReceiver() and Context.unregisterReceiver() methods. (Dynamically)
#Override
protected void onPause() {
super.onPause();
// unregister broadcast
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceiver);
}
#Override
protected void onResume() {
super.onResume();
// register broadcast
IntentFilter filter = new IntentFilter(Constants.ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(mReceiver, filter);
}
Send Broadcast like:
// public static final String ACTION = "ALERT";
Intent intent = new Intent(Constants.ACTION);
intent.putExtra("type", "SUP BRO. Stay Inside");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
Knowledge Note :- Broadcast receiver is like a Cannon-fire to score a hit, you have to determine what to fire (eg. msg), where to fire (eg. activity). Load & unload the cannon to score another hit. (eg. Register & Unregister)
I have tried it and it is working. Add your notification code inside onReceive.
Broadcast Receiver
class AlarmReceiver : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
/*
Your implementation
*/
}
}
Mainfest
<receiver
android:name=".AlarmReceiver"
android:exported="true"
android:enabled="true" />
Creating pending intents
val alarmManager = activity.getSystemService(Activity.ALARM_SERVICE) as AlarmManager
val alarmIntent = Intent(activity.applicationContext, AlarmReceiver::class.java) // AlarmReceiver1 = broadcast receiver
val calendar = Calendar.getInstance()
calendar.timeInMillis = timeInMilliSeconds
val pendingIntent = PendingIntent.getBroadcast(activity, timeInMilliSeconds.toInt(), alarmIntent, PendingIntent.FLAG_CANCEL_CURRENT)
alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.timeInMillis, pendingIntent)
First, make sure your notification Id is difference every single time you create a notification
Second, you miss tag intent-filter inside tag receive in manifest. pls check this https://developer.android.com/guide/components/broadcasts.
Hope this help!
I have read lot about WakefulBroadcastReceiver... but didn't get anywhere about how to even call this from main activity. whenever I search how to call WakefulBroadcastReceiver the result always shows me how to call IntentService from WakefulBroadcastReceiver...
Well to call IntentService we write the code "startService()" in activity or in WakefulBroadcastReceiver...
to call BroadcastReceiver we write
AlarmManager am.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
PendingIntent.getBroadcast(this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT));
But I don't find anywhere how to call WakefulBroadcastReceiver...
please help..
android.support.v4.content.WakefulBroadcastReceiver is a helper class that receives a device wakeful event.
you shouldoverride onReceive() method where you can call a service or perform your task.
WakefulBroadcastReceiver uses wake lock, so you must provide WAKE_LOCK permission in AndroidManifest.xml. WakefulBroadcastReceiver is implemented as
public class AlarmReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(final Context context, Intent intent) {
MainActivity.getTextView2().setText("Enough Rest. Do Work Now!");
Uri uri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
Ringtone ringtone = RingtoneManager.getRingtone(context, uri);
ringtone.play();
}
}
in menifest add
<uses-permission android:name="android.permission.WAKE_LOCK"></uses-permission>
call AlarmReceiver like this:
Intent myIntent = new Intent(MainActivity.this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);
also add receiver tag in manifest:
<receiver android:name=".AlarmReceiver"/>
For full working sample see this link:http://www.concretepage.com/android/android-alarm-clock-tutorial-to-schedule-and-cancel-alarmmanager-pendingintent-and-wakefulbroadcastreceiver-example
I am using AlarmManager to create an alarm by playing a sound. To do this, I first create a PendingIntent, for which I have to create a class called AlarmReceiver, which extends BroadcastReceiver. In this new class, I override the onReceive method, in which I also start the sound. However, from what I've tested, the onReceive method is not even called from the MainActivity.
After some research, I found out that I should declare the receiver in the manifest file. Thus, I declare it, but it doesn't recognize the name of the class, AlarmReceiver, it shows it in red. I don't fully understand how to properly declare in the manifest file. I know there are other similar SO questions and I've checked them all, but I am still not able to get it work.
The code for the MainActivity is:
package com.example.alarmsound;
public class MainActivity extends AppCompatActivity {
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
final MediaPlayer mp = MediaPlayer.create(context, R.raw.music);
Log.d("Music", "It went here.");
mp.start();
Button stop = (Button) findViewById(R.id.stopAlarm);
stop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mp.stop();
}
});
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
Calendar t = Calendar.getInstance();
t.add(Calendar.SECOND, 5);
Context context = this;
AlarmManager alarmMgr;
alarmMgr = (AlarmManager)getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmMgr.set(AlarmManager.RTC_WAKEUP, t.getTimeInMillis(), pendingIntent);
}
}
And the declaration in Manifest is:
<receiver android:name="com.example.alarmsound.AlarmReceiver">
<intent-filter>
<action android:name="com.example.alarmsound.MainActivity" />
</intent-filter>
</receiver>
I could also be doing something wrong in the MainActivity, even though I think I'm doing everything right there.
Change the first line of the receiver declaration to:
<receiver android:name="com.example.alarmsound.MainActivity$AlarmReceiver">. That should let Android detect your class through the manifest.
The $ symbol is used to reference inner classes in the Android Manifest.
Okay. So as you mentioned the the AlarmReceiver class cannot be recognized in the AndroidManifest.xml. So I tried it out in Android Studio and it seems the format should be something like this:
<receiver android:name=".MainActivity$AlarmReceiver">
<intent-filter>
<action android:name="com.example.alarmsound.MainActivity" />
</intent-filter>
</receiver>
Tried running the code but it returns an error where the app crashes. Anyways, I think that's a different concern now.
I am able to read message of user when the application gets installed. But what I want is that even after the application is closed, I should be able to read user message after a fixed interval of time. For example, application like Walnut that reads specific message and gives alerts automatically if any new message has come. How can I do the same.
Use Alarm manager and Pending Intent
Initiate Alarm manager here.
AlarmManager alarmMgr = (AlarmManager) this
.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
new Intent(this, AlarmReceiver_update.class),
PendingIntent.FLAG_CANCEL_CURRENT);
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
0, yourTimeInterval, pendingIntent);
And in AlarmReceiver_update class:
public class AlarmReceiver_update extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
// Do whatever you want
}
}
And in Your AndroidManifest file register your receiver:
<receiver android:name="com.x.y.AlarmReceiver_update" >
<intent-filter>
<action android:name="android.test.BROADCAST" />
</intent-filter>
</receiver>
This is not complete just sample you have any doubt just comment.
You shuold use an alarm manager to set a repeating alarm.
Then you should setup a BroadcastReceiver Service that read the user messages onRecieve.
public class AlarmReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Run the task to read the user messages
}
}
This is a good tutorial
Have a look at the below links to learn how to notify the user if you found new message.
http://javatechig.com/android/repeat-alarm-example-in-android#3-defining-alarm-broadcastreceiver
http://developer.android.com/training/notify-user/build-notification.html
I have set up parse push notifications and I had my app crash when I tried to open it, now I found a work around my making a new java class and overriding onPushOpen like this:
public class Receiver extends ParsePushBroadcastReceiver {
#Override
public void onPushOpen(Context context, Intent intent) {
Intent i = new Intent(context, MainActivity.class);
i.putExtras(intent.getExtras());
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
}
But in order to still receive push notifications I still need this depreciated method in my MyApplication.java class PushService.setDefaultPushCallback(this, MainActivity.class);
How could I get rid of this depreciated method I have looked at this question where I got some help but it did not answer this part about the depreciated method. Exception when opening Parse push notification.
I was thinking that maybe this method could be over ridden but Im not sure if it acutely handles recvieving the push or more handles the push after it has been received?
#Override
public void onPushReceive(final Context c, Intent i) {
// Handle the received push
}
Thanks for the help in advance.
You are subclassing ParsePushBroadcastReceiver.
Then in manifest
<receiver
android:name=".Receiver " // your broadcastreceiver
android:exported="false" >
<intent-filter>
// youtr actions
</intent-filter>
</receiver>
In BroadCastReceiver
public class Receiver extends ParseBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
extras = intent.getExtras();
if(intent.hasExtra("com.parse.Data"))
{
try
{
json = new JSONObject(intent.getExtras().getString("com.parse.Data"));
int notificationtype = json.getInt("notificationtype"); // this is send on the sender side
switch(notificationtype)
{
case 1:
// show your custom notification. Refer android notification guide
break;
case 2:
//rest of the code
Note : If either "alert" or "title" are specified in the push, then a Notification is constructed using getNotification. So no alert and title on the sender side.
Read Managing Push Lifecycle #
https://www.parse.com/docs/push_guide#receiving/Android
Reference
https://www.parse.com/questions/how-suppress-push-notification-from-being-displayed