Good Morning,
I've made an application that implements GpS Location. I have a service that save my location on LocationChanged event. To avoid that Android close my app I start a notification and all works well. But now, I want that when I click on notification from Action Bar the app come back in foreground.I use fragment and the map fragment is called MappaFragment. I read a lot of messages but It seems not resolve my issue. Below my code, any suggestion is appreciated !
Alex
This is my monitoring Service:
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent.getAction().equals(Constants.STARTFOREGROUND_ACTION)) {
Log.i(TAG, "Received Start Foreground Intent ");
Intent notificationIntent = new Intent(getApplicationContext(), LocationMonitoringService.class);
Bundle extras = intent.getExtras();
numeroTraccia = extras.getInt("numeroTraccia");
itinerario = extras.getString("itinerarioRiferimento");
notificationIntent.setAction(Constants.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
Intent.FLAG_ACTIVITY_CLEAR_TASK);
setGiornoRiferimento(gg.checkDayLong(this));
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
0, new Intent(getBaseContext(),MappaFragment.class), 0);
Bitmap icon = BitmapFactory.decodeResource(getResources(), com.example.alex.myApp.R.drawable.smallicon );
Notification.BigTextStyle bigText = new Notification.BigTextStyle();
Notification notification = new Notification.Builder(getApplicationContext())
.setContentTitle("MyApp")
.setTicker(getString(R.string.track))
.setStyle(bigText.bigText(getString(R.string.track)))
.setSmallIcon(R.drawable.smallicon)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification);
}
This is my Manifest:
<activity android:name="com.example.alex.myApp.MainActivity"
android:screenOrientation="portrait"
android:configChanges="orientation|screenSize|keyboardHidden" />
<activity
android:name="com.example.alex.myApp.SplashScreen"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="com.example.alex.myApp.services.MonitoringService"
android:enabled="true"/>
<receiver
android:name="com.example.alex.myApp.RestarterBroadcastReceiver"
android:enabled="true"
android:exported="true"
android:label="RestartWhenStopped">
<intent-filter>
<action android:name="com.example.alex.myApp.ActivityRecognition.RestartSensor"/>
</intent-filter>
</receiver>
Thanks in advance !
Alex
First of all,
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0, new Intent(getBaseContext(),MappaFragment.class), 0);
this is incorrect. Fragment can't be opened using intent. You need to launch an activity, then redirect to required fragment.
Next thing is, if app is in background and you click on the notification, it will open launcher activity. So in launcher activity you need to check for bundle object and there you can redirect to particular activity or fragment.
Check this post: Push notification works incorrectly when app is on background or not running and Open specific Activity when notification clicked in FCM it will help you to better understand how FCM works when app is in background and foreground.
Create a BroadCast Receiver like below:
public static class ActionReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (action.equals("open_activity")) {
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
intent.setClass(AppContext.getContext(), MappaFragment.class);
intent.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
}
}
}
And then, Use this notificationIntent.setAction("open_activity");
And Change your PendingIntent to:
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),
0, new Intent(AppContext.getContext(), ActionReceiver.class), 0);
NOTE: For USing This you need to Remove These Lines:
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startForeground(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE, notification)
What I'm suggesting is to use a BroadcastReceiver to receive whatever you want to do in Your Notification.
Also, If this isn't working try Adding .setAction(Intent.ACTION_MAIN) to Your Notification like Below:
Notification notification = new Notification.Builder(getApplicationContext())
.setContentTitle("MyApp")
.setTicker(getString(R.string.track))
.setStyle(bigText.bigText(getString(R.string.track)))
.setSmallIcon(R.drawable.smallicon)
.setLargeIcon(Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setOngoing(true)
.setAction("open_activity")
.build();
Related
Creating notification:
PendingIntent pIntent = PendingIntent.getActivity(context, (int) taskId, intent, 0);
intent.setAction(Utils.MARK_AS_DONE);
PendingIntent pIntentMarkAsDone = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setTicker(ticker)
.setContentTitle(title)
.setContentText(description)
.setSmallIcon(getAlarmIcon(type))
.setLargeIcon(BitmapFactory.decodeResource(context.getResources(),R.mipmap.ic_launcher))
.setContentIntent(pIntent)
.addAction(0, context.getString(R.string.mark_as_done), pIntentMarkAsDone);
Notification notification = builder.build();
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify((int) taskId, notification);
I added the adding using a pending intent with getBroadcast.
Receiver:
public class NotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Log to check
}
}
This class should "receive" the action. I also add on Manifest
Manifest:
<receiver android:name=".NotificationReceiver">
<intent-filter>
<action android:name="<package_name>.MARK_AS_DONE"/>
</intent-filter>
</receiver>
Well, onReceive is not receiving. What am I doing wrong?
TL;DR: Create a fresh Intent, rather than reusing the one in intent, and get rid of the <intent-filter> from the <receiver>.
Your first line is:
PendingIntent pIntent = PendingIntent.getActivity(context, (int) taskId, intent, 0);
This implies that intent identifies some activity. If you created this via new Intent(context, YourActivityClass.class), then it has a ComponentName set inside of it, identifying your activity.
Then, you call setAction() on intent and use it with getBroadcast(). However, other than setting (or replacing) the action, everything else in intent is the same as it was. In particular, the ComponentName identifying the activity is still there. So, when the broadcast is sent, Android cannot deliver it, as the component is invalid (an activity cannot directly receive a broadcast), and the action string is ignored (as once a ComponentName is set on an Intent, things like actions and categories no longer count for routing).
So, I recommend that you create two Intent objects, one for the activity, one for the receiver.
Note that you do not need an action string for the receiver. You can use the explicit Intent constructor (new Intent(context, NotificationReceiver.class)). In fact, having the action string on the receiver is bad for security, as now any app can send you that broadcast. So, I recommend removing the <intent-filter> and using an explicit Intent to create your broadcast PendingIntent.
I'm trying to dismiss a notification from an .addAction() without having to open the app. The problem is when the button is pressed nothing happens, the onReceive() method doesn't trigger.
Here is the code on the MainActivity:
Intent notificationIntent = new Intent(mContext, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra("id", SOMENUMBER);
PendingIntent pIntent = PendingIntent.getBroadcast(mContext, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notification = new NotificationCompat.Builder(mContext);
notification.setContentTitle("");
notification.setContentText(t);
notification.setSmallIcon(R.mipmap.ic_launcher);
notification.setOngoing(true);
notification.addAction(R.mipmap.ic_launcher, "Dismiss", pIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(SOMENUMBER, notification.build());
And on other class I have the reciever:
public class Notification extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent){
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(intent.getIntExtra("id", 0));
}
}
And the reciever on the AndroidManifest.xml file:
<receiver android:name=".MainActivity">
<intent-filter>
<action android:name="io.github.seik.Notification" />
</intent-filter>
</receiver>
Your naming conventions are confusing. Android already has a class called Notification, so you probably shouldn't call your receiver Notification :-(
If MainActivity extends Activity then you need to have a manifest entry for it that looks like this:
<activity android:name=".MainActivity"/>
For your BroadcastReceiver, you need a manifest entry like this:
<receiver android:name=".Notification"
android:exported="true"/>
Since you are using an explicit Intent to launch your BroadcastReceiver, you don't need to provide an <intent-filter> for it. Since the BroadcastReceiver will be started by the NotificationManager, you need to make sure that it is exported.
You then need to create the PendingIntent so that it actually launches your BroadcastReceiver, so change this:
Intent notificationIntent = new Intent(mContext, MainActivity.class);
to this:
Intent notificationIntent = new Intent(mContext, Notification.class);
I want to make a notification from BroadcastReceiver. I'm using this code in my activity and it works fine but I can't make a notification from BroadcastReceiver . Could you help me to solve this problem :
Random rd;rd= new Random ();
NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
Intent notificationIntent = new Intent(Intent.ACTION_VIEW);
notificationIntent.setData(Uri.parse(link));
PendingIntent pending=null;
pending = PendingIntent.getActivity(ctx, 0, notificationIntent, pending.FLAG_UPDATE_CURRENT);
Notification myNotification = new NotificationCompat.Builder(ctx)
.setSmallIcon(R.drawable.ic_launcher).setAutoCancel(false).setLargeIcon(remote_picture)
.setContentTitle(onvan).setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
.setContentText(msg).setContentIntent(pending).build();
notificationManager.notify(rd.nextInt(75), myNotification);
The problem is , this code does not make a notification and no notification is showing in the tray .as I say , I run this code in Activity and it works find but in BroadcastReceiver it does not make any notifications
To execute the code inside BroadcastReceiver you have to call sendBroadcast() method or set some action in your Manifest file like
<receiver android:name="Your package name.ReceiverName">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
//set your action here
</intent-filter>
</receiver>
I want to trigger a Broadcast receiver from the notification. When I click on a button which is on the notification it shows this error:
"Unable to instantiate receiver com.example.testservice.myBroad:
java.lang.ClassCastException: com.example.testservice.myBroad cannot
be cast to android.content.BroadcastReceiver"
**updated/ edited and its working now **
Can you please help to handle 2 buttons from notification to broadcast receiver?
How can I pass extra value from notification broadcast trigger to a receiver that whether its play button pressed or pause?
Now my button working but when I click on notification text it does not take me into my activity. Any help?
I write this code for 2 buttons with extra on intent.
RemoteViews layout = new RemoteViews(getPackageName(), R.layout.notification);
layout.setTextViewText(R.id.notification_title, getString(R.string.app_name));
Intent clickIntent = new Intent();
clickIntent.putExtra("button","pause");
clickIntent.setAction(ACTION_DIALOG);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), pendingRequestCode, clickIntent, pendingFlag);
layout.setOnClickPendingIntent(R.id.notification_button,pendingIntent);
builder.setContent(layout);
layout = new RemoteViews(getPackageName(), R.layout.notification);
layout.setTextViewText(R.id.notification_title, getString(R.string.app_name));
Intent click = new Intent();
clickIntent.putExtra("Button","play");
clickIntent.setAction(ACTION_DIALOG);
PendingIntent pi1 = PendingIntent.getBroadcast(getApplicationContext(), pendingRequestCode, click, pendingFlag);
layout.setOnClickPendingIntent(R.id.notification_button1,pi1);
builder.setContent(layout);
myBroad receiver file
Bundle extrasBundle = intent.getExtras();
String str = (String) extrasBundle.get("button");
Toast.makeText(context, str, Toast.LENGTH_SHORT).show();
context.stopService(new Intent(context, myPlayService.class));
Here is my code:
void showNotification() {
int pendingRequestCode = 0;
int pendingFlag = 0;
final Resources res = getResources();
final NotificationManager notificationManager = (NotificationManager) getSystemService(
NOTIFICATION_SERVICE);
Intent intent = new Intent(MainActivity.this,myBroad.class);
PendingIntent pi= PendingIntent.getActivity(this, 0, intent, 0);
Notification.Builder builder = new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_action_search)
.setAutoCancel(true)
.setTicker("this is notification")
.setContentIntent(getDialogPendingIntent("Tapped the notification entry."));
// Sets a custom content view for the notification, including an image button.
RemoteViews layout = new RemoteViews(getPackageName(), R.layout.notification);
layout.setTextViewText(R.id.notification_title, getString(R.string.app_name));
Intent clickIntent = new Intent();
clickIntent.setAction(ACTION_DIALOG);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), pendingRequestCode, clickIntent, pendingFlag);
layout.setOnClickPendingIntent(R.id.notification_button,pendingIntent);
builder.setContent(layout);
// Notifications in Android 3.0 now have a standard mechanism for displaying large
// bitmaps such as contact avatars. Here, we load an example image and resize it to the
// appropriate size for large bitmaps in notifications.
Bitmap largeIconTemp = BitmapFactory.decodeResource(res,
R.drawable.notification_default_largeicon);
Bitmap largeIcon = Bitmap.createScaledBitmap(
largeIconTemp,
res.getDimensionPixelSize(android.R.dimen.notification_large_icon_width),
res.getDimensionPixelSize(android.R.dimen.notification_large_icon_height),
false);
largeIconTemp.recycle();
builder.setLargeIcon(largeIcon);
notificationManager.notify(NOTIFICATION_DEFAULT, builder.getNotification());
}
PendingIntent getDialogPendingIntent(String dialogText) {
return PendingIntent.getActivity(
this,
dialogText.hashCode(), // Otherwise previous PendingIntents with the same
// requestCode may be overwritten.
new Intent(ACTION_DIALOG)
.putExtra(Intent.EXTRA_TEXT, dialogText)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK),
0);
}
myBroad.class
public class myBroad extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "received", Toast.LENGTH_SHORT).show();
context.stopService(new Intent(context, myPlayService.class));
}
}
Manifest file is:
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".myBroad">
<intent-filter >
<action android:name="android.intent.action.MEDIA_BUTTON"/>
</intent-filter>
</receiver>
<service android:name="com.example.testservice.myPlayService" android:icon="#drawable/ic_action_search" android:label="#string/app_name" android:enabled="true"/>
</application>
Because myBroad is an activity object, and not a broadcast object...
Instead of extending (inheritance) from activity, and then making an internal class which extends broadcastreceiver, then just inherit directly from broadcastreceiver.
In your method getDialogPendingIntent you should use PendingIntent.getBroadcast instead of PendingIntent.getActivity. This will cause your PendingIntent to push a broadcast.
And fix this:
public class myBroad extends BroadcastReceiver
Exception says it clearly - your myBroad have to extend BroadcastReceiver, not Activity as it does now.
PS: you should consider switching to proper naming convenction. So it should be MyBroad (class) but myBroad (object of that class). i.e.:
MyBroad myBroad = new MyBroad();
I have code, and it just does not work, so I ask anyone to help me out. There is very little info on this specific matter.
MainActivity
public class MainActivity extends Activity {
public final int PENDING_INTENT_ID = 8;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Button clickity = (Button)findViewById(R.id.alarm_button);
clickity.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Calendar now = Calendar.getInstance();
now.add(Calendar.SECOND, 20);
//Create a new PendingIntent used by the Alarm when it activates
Intent intent = new Intent(v.getContext(), AlarmReciever.class);
intent.setAction("SOME_AWESOME_TRIGGER_WORD");
intent.putExtra("info", "This String shows that the info is actually sent correctly");
PendingIntent pendingIntent = PendingIntent.getBroadcast(v.getContext(), PENDING_INTENT_ID, intent, PendingIntent.FLAG_UPDATE_CURRENT|Intent.FILL_IN_DATA);
//Then Create the alarm manager to send this pending intent and set the date to go off
AlarmManager am = (AlarmManager)getSystemService(Activity.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, now.getTimeInMillis(), pendingIntent);
}
});
}
AlarmReciever (Aware I spelled it wrong but since thats how it is, im going with it)
public class AlarmReciever extends BroadcastReceiver{
#Override
public void onReceive(Context c, Intent arg1) {
//get a reference to NotificationManager
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) c.getSystemService(ns);
//Instantiate the notification
CharSequence tickerText = "Hello";
long when = System.currentTimeMillis();
Notification.Builder builder = new Notification.Builder(c)
.setTicker(tickerText)
.setWhen(when)
.setContentTitle(arg1.getStringExtra("info"))
.setContentText("Success!!")
.setAutoCancel(true);
Notification notification = builder.getNotification();
mNotificationManager.notify(0, notification);//note the first argument, the ID should be unique
}
}
Manifest
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="15" />
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name="com.testproject.AlarmReciever"
android:enabled="true"
android:exported="false" >
<intent-filter>
</receiver>
</application>
That should be everything. I am trying to run it as is and its not showing me anything. I am running it on an emulator is that actually matters.
EDIT: When I say it doesn't work, I mean nothing pops up. It runs fine, but the Notification never pops up.
The issue:
So the issue is narrowed down to Android just ignoring my Notification. Problem is it doesn't tell me why -_- so I can't fix it. Any experts on the matter see something wrong with my code to call a notification? Does it matter that its on an emulator?
I ran into the same issue. If you don't specify an icon when creating a "new Notification()", the notification will not appear.
Well, lesson learned on Notifications. The reason I was getting the error was because an img MUST be added, if not, it will not show! Everything else I had was basically right with the exception of what Vladimir was graciously able to point out. Posting this here incase others are getting a similar issue just testing out the notifications.
Intent intent = new Intent(v.getContext(), AlarmReciever.class);
// intent.setAction("SOME_AWESOME_TRIGGER_WORD"); replace to:
intent.setAction("com.testproject.SOME_AWESOME_TRIGGER_WORD");
It's at least for first look
UPD:
long firstTime = SystemClock.elapsedRealtime();
AlarmManager alarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
alarmManager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, /* INTERVAL IN MS */ 20 * 1000, /* PendingIntent */ intent);
This is because, you are not setting the notification icon. If you set notificaiton icon it should work. Log itself says that you can't send a notification without an image.
Seems like you forgot to set Icon.. You need to atleast set a default icon..
Try this..
Notification.Builder builder = new Notification.Builder(c)
.setTicker(tickerText)
.setWhen(when)
.setContentTitle(arg1.getStringExtra("info"))
.setContentText("Success!!")
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher); //<--- this one