On notification button click intent starting new activity instead of resuming - android

I am trying to implement a custom notification for my mediaplayer with notification bar that has just one button that will act as stop and play control.
So far have implemented the notification successfully and the button is making the function call, but the problem is that onReceive when I create an intent and call the activity, the activity gets recreated on top of the old one and I get bad double echoing media player playing in the background.
Have tried to make the launchMode= Single, but when I make it single the button click makes no difference, it means that the function call is not getting made if I turn the launch mode to SINGLE instead of STANDARD.
MAIN_ACTIVITY CODE SNIPPET
//NOTIFICATION RELATED CLASSES
private NotificationCompat.Builder builder;
private NotificationManager notificationManager;
//private int notification_id;
private RemoteViews remoteViews;
Context context;
Intent notification_intent;
final int notification_id =545816666;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
boolean attachMedia = getIntent().getBooleanExtra("attachMedia",false);
if (attachMedia) {
attachMediaActivity();
}
//CODE DE NOTIFICATION
context =this;
notification_intent=new Intent(context,MainActivity.class);
notificationManager=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
remoteViews=new RemoteViews(getPackageName(),R.layout.custom_notification);
remoteViews.setImageViewResource(R.id.notif_icon,R.mipmap.ic_launcher);
remoteViews.setTextViewText(R.id.notif_title,"BOOM");
remoteViews.setTextViewText(R.id.button,"Button");
Intent button_intent= new Intent("player_control_clicked");
button_intent.putExtra("id",notification_id);
PendingIntent p_button_intent=PendingIntent.getBroadcast(context,123,button_intent,0);
remoteViews.setOnClickPendingIntent(R.id.button,p_button_intent);
tview=(TextView) findViewById(R.id.playerText);
btn=(Button) findViewById(R.id.playerButton);
if(!mediaPlayer.isPlaying())
{
tview.setText("Press play");
btn.setText("Play");
}
else
{
tview.setText("Playing");
btn.setText("Stop");
}
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//Intent notification_intent=new Intent(context,MainActivity.class);
//THIS CODE UPDATES OLD NOTIFICATION
PendingIntent pendingIntent=PendingIntent.getActivity(context,0,notification_intent,PendingIntent.FLAG_UPDATE_CURRENT);
builder =new NotificationCompat.Builder(context);
builder.setSmallIcon(R.mipmap.ic_launcher)
.setCustomBigContentView(remoteViews)
.setContentIntent(pendingIntent)
.setOngoing(true);
notificationManager.notify(notification_id,builder.build());
if(!mediaPlayer.isPlaying())
{
//tview.setText("Playing");
btn.setText("Stop");
playStream();
}
else
{
tview.setText("Stopped");
btn.setText("Play");
mediaPlayer.stop();
mediaPlayer.reset();
}
}
});
}
public void attachMediaActivity()
{
//CODE DE NOTIFICATION
context =this;
notification_intent=new Intent(context,MainActivity.class);
notificationManager=(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
remoteViews=new RemoteViews(getPackageName(),R.layout.custom_notification);
remoteViews.setImageViewResource(R.id.notif_icon,R.drawable.stream_icon);
remoteViews.setTextViewText(R.id.notif_title,"Stopped");
remoteViews.setTextViewText(R.id.button,"STOPA");
Intent button_intent= new Intent("player_control_clicked");
button_intent.putExtra("id",notification_id);
/*PendingIntent p_button_intent=PendingIntent.getBroadcast(context,123,button_intent,0);
remoteViews.setOnClickPendingIntent(R.id.button,p_button_intent);*/
PendingIntent pendingIntent=PendingIntent.getActivity(context,0,notification_intent,PendingIntent.FLAG_UPDATE_CURRENT);
builder =new NotificationCompat.Builder(context);
builder.setSmallIcon(R.mipmap.ic_launcher)
.setCustomBigContentView(remoteViews)
.setContentIntent(pendingIntent)
.setOngoing(true);
notificationManager.notify(notification_id,builder.build());
if (mediaPlayer.isPlaying())
{
mediaPlayer.stop();
}
else
{
playStream();
}
}
THE BROADCAST LISTENER FOR THE NOTIFICATION BUTTON CLICK THAT CALLS THE ACTIVTY VIA INTENT
public class Button_listener extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
NotificationManager manager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
manager.cancel(intent.getExtras().getInt("id"));
Toast.makeText(context, "GENERATED BY NOTIFICATION", Toast.LENGTH_SHORT).show();
intent= new Intent(context, MainActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
//intents.addExtra("attachMedia",true); // Extra info
intent.putExtra("attachMedia",true);
context.startActivity(intent);
}
}
MY MANIFEST
<activity android:name=".MainActivity"
android:screenOrientation="portrait"
android:launchMode="singleTop"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="Button_listener">
<intent-filter>
<action android:name="player_control_clicked"/>
</intent-filter>
</receiver>
Thanks in advance
PS: TRIED EVERY POSSIBLE ANSWER ON STACK

The problem lies within your intent Flag
you have added the flag intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);,
change that to intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
For more reference read this https://developer.android.com/reference/android/content/Intent.html

Related

Android remote view pending Intent not working

I have a service that I need to stop using a pending intent from the remoteview that is showing a custom notification. I have set the pending intent and registered the broadcast receiver in the manifest. However when I am clicking the button nothing happens. The broadcast receiver is an inner class of the service class.
The inner class broadcast receiver:
public class CancelDownload extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive: cancel intent");
if(Objects.equals(intent.getAction(), VIDEODOWNLOADACTIONS.STOP)){
stopSelf();
CustomModel model = CustomModel.getInstance();
if (model != null) {
model.changeState();
}
notificationManager.cancel(notificationId);
database.setDownloadFileAsFailed(fileID);
File emptyfile = new File(destinationPath);
if (emptyfile.exists()) {
emptyfile.delete();
}
}
}
}
Manifest:
<receiver android:name=".data.VideoDownloadService$CancelDownload"
android:exported="true"
android:enabled="true">
<intent-filter>
<action android:name="my.action.stopdownload"/>
</intent-filter>
</receiver>
Notification code:
RemoteViews downloadViews = new RemoteViews(context.getPackageName(), R.layout.notificaition_layout);
Intent cancelIntent = new Intent(context, VideoDownloadService.CancelDownload.class);
cancelIntent.setAction(VIDEODOWNLOADACTIONS.STOP);
PendingIntent cancelPendingIntent = PendingIntent.getBroadcast(context, 0, cancelIntent, PendingIntent.FLAG_ONE_SHOT);
//trying both here
downloadViews.setPendingIntentTemplate(R.id.cancel,cancelPendingIntent);
downloadViews.setOnClickPendingIntent(R.id.cancel,cancelPendingIntent);
//setting the view to the notification
builder.setContent(downloadViews)
.setCustomBigContentView(downloadViews);
When I click the button nothing happens the button id is correct. The broadcast receiver has to be an inner class because I have plenty of operations that I want to do if the user clicks cancel.
How do I make it work. Please help.

Yet another onNewIntent() issue | still not called

Using FirebaseMessagingService to generate notification.
After tapping on it, activity is shown, but onNewIntent() is not called.
Running on 7.1.
GOAL:
receive FCM notifications - works
after tapping on notification, bring up activity and display notification message in a dialog box - doesn't work
activity shows up,
extras.getString() returns null.
After studying many posts so far i got this, what else am i missing ?
Thanks.
EDIT: added onResume() method, extras variable is not null, strings are null
Notification.Builder mBuilder =
new Notification.Builder(this)
.setSmallIcon(R.drawable.ic_icon)
.setContentTitle(title)
.setContentText(message)
.setOnlyAlertOnce(false)
.setAutoCancel(true)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION))
.setVibrate(new long[] {0,400,150,400});
mBuilder.setNumber(++count);
Intent pushIntent = new Intent(this, PushMeMessageDialogActivity.class);
pushIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
pushIntent.putExtra(Constants.INTENT_TOPIC, title);
pushIntent.putExtra(Constants.INTENT_MESSAGE, message);
pushIntent.setAction(Intent.ACTION_MAIN);
pushIntent.addCategory(Intent.CATEGORY_LAUNCHER);
PendingIntent pushPendingIntent = PendingIntent.getActivity(this, count, pushIntent, PendingIntent.FLAG_UPDATE_CURRENT);
mBuilder.setContentIntent(pushPendingIntent);
NotificationManager notifyMgr = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notifyMgr.notify(count, mBuilder.build());
Activity:
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_message_dialog);
}
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
}
#Override
protected void onResume() {
super.onResume();
Intent intent = getIntent();
Bundle extras = intent.getExtras();
if(extras == null)
return;
String strTopic = extras.getString(Constants.INTENT_TOPIC);
String strMessage = extras.getString(Constants.INTENT_MESSAGE);
}
<activity
android:name=".PushMeMessageDialogActivity"
android:launchMode="singleTop"
android:theme="#android:style/Theme.Dialog"
android:excludeFromRecents="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
minSdkVersion 22
targetSdkVersion 28
onNewIntent will not be called every time the activity is shown, as described in the documentation. Only if the Activity already existed it will be brought to the top of the stack and onNewIntent will be called. If the Activity didn't already exist the onCreate will be called.
For most use cases this means that for singleTop Activities you call setIntent in the onNewIntent method and call getIntent in the onResume. That way you always process the Intent that brought the Activity to the top of the stack.

how opening the targeted activity on click of notification when app is in background

I have sent notification through firebase console using key vale pair and handled the notification in launcher activity. below is the tried code:
#Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent.hasExtra("click_action")) {
ClickActionHelper ck=new ClickActionHelper();
ck.startActivity(intent.getStringExtra("click_action"), intent.getExtras(), this);
}
}
public class ClickActionHelper {
public void startActivity(String className, Bundle extras, Context context){
Class cls=null;
try {
cls = Class.forName(className);
}catch(ClassNotFoundException e){
}
Intent i = new Intent(context, cls);
i.putExtras(extras);
context.startActivity(i);
}
}
but this way i am not able to open the targeted activity on click of notification. Any ideas?
If you need to navigate any Activity then there should be bind with Notification class(NotificationCompat.Builder) which is missing in implementation.
Below line is very important to redirect any Activity:
NotificationCompat.Builder builder = new **NotificationCompat.Builder(this); builder.setContentIntent(resultPendingIntent);**
Here resultPendingIntent is used for to containing the backstack for the Activity with the notifications as below:
// Gets a PendingIntent containing the entire back stack PendingIntent
resultPendingIntent = stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
The complete code snippet is available here.
int id = 1;
Intent resultIntent = new Intent(this, ResultActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
// Adds the back stack
stackBuilder.addParentStack(ResultActivity.class);
// Adds the Intent to the top of the stack
stackBuilder.addNextIntent(resultIntent);
// Gets a PendingIntent containing the entire back stack
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
builder.setContentIntent(resultPendingIntent);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(id, builder.build());
Edit:
Let me explain how it will works
Suppose you are set response from server as below
{
"registration_ids": ["XXX", ...],
"data": {
"id_offer": "41"
},
"notification": {
"title": "This is the Title",
"text": "Hello I'm a notification",
"icon": "ic_push",
"click_action": "ACTIVITY_XPTO"
}
}
And In your Manifest File
<activity android:name=".ActivityXPTO" android:screenOrientation="sensor" android:windowSoftInputMode="stateHidden"> <intent-filter> <action android:name="ACTIVITY_XPTO" />
<category android:name="android.intent.category.DEFAULT" /> </intent-filter> </activity>
When the app is closed or in background and the user clicks on the notification it opens my ActivityXPTO, to retrieve the id_offer I only need to do:
public class ActivityXPTO extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState);
String idOffer = "";
Intent startingIntent = getIntent();
if (startingIntent != null) {
idOffer = startingIntent.getStringExtra("id_offer");
// Retrieve the id
}
getOfferDetails(id_offer);
}
}
}
And In Second Way
Send key through data payload like below and get key in MainActivity via getIntent() and call specific activity or fragments.
json1.put("title","Your Title");
json1.put("body","body content");
json1.put("message","Your Message");
json1.put("screen","2"); //secondFragment is 2nd position in nav drawer
json.put("data", json1);
Sample project on GitHub.
Nothing works for me. The thing work for me is simple. Make sure you add this in the activity that you want to open directly.
<intent-filter>
<action android:name="MainActivity" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
And from the push notification you must add a new payload: click_action
it will looks like this -
"notification": {
"title": "hello",
"body": "test message",
"click_action": "MAIN_ACTIVITY"
},
Note: You can name it as you want MAIN_ACTIVITY but must be same in both place.

Not getting extra from ACTION_VIEW intent

I am using firebase notifications and dynamic links in my application
I am sending deeplinks as a payload in notifications and when the user clicks on the notification i am opening the deeplink like this
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(pushAction.getActionDeeplink())); // contains the deeplink
if (pushNotification.getExtraData() != null) { // not extra Data from push
intent.putExtra(IntentKeys.PUSH_DATA_EXTRA, pushNotification.getExtraData());
}
PendingIntent actionPendingIntent =
PendingIntent.getActivity(context, pushNotification.getNotificationId(), intent,
PendingIntent.FLAG_UPDATE_CURRENT);
final NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher)
.setLargeIcon(largeIcon)
.setTicker(pushNotification.getTicker())
.setContentTitle(pushNotification.getTitle())
.setContentText(pushNotification.getMessage())
.setAutoCancel(true)
.setContentIntent(actionPendingIntent);
notificationManager.notify(uniqueId, mBuilder.build());
I have declared an activity in my application
<activity
android:name=".ui.activities.SaveActivity"
android:label="#string/title_activity_save"
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden|adjustPan">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="example.com"
android:pathPattern="/save"
android:scheme="http" />
</intent-filter>
</activity>
and the deeplink url, that is sent through notification is http://example.com/save
And in the activity I have setup to receive deeplinks like this
public class SaveActivity extends BaseActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_save);
setupGoogleApiClient();
}
private void setupGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this, this)
.addApi(AppInvite.API)
.build();
boolean autoLaunchDeepLink = false;
AppInvite.AppInviteApi.getInvitation(mGoogleApiClient, this, autoLaunchDeepLink)
.setResultCallback(
new ResultCallback<AppInviteInvitationResult>() {
#Override
public void onResult(#NonNull AppInviteInvitationResult result) {
if (result.getStatus().isSuccess()) {
Intent intent = result.getInvitationIntent();
String deepLink = AppInviteReferral.getDeepLink(intent);
Log.d("save getInvitation: found deeplink." + deepLink);
/**************************** ISSUE ***********************/
if(intent.hasExtra(IntentKeys.PUSH_DATA_EXTRA)) {
// there is no extra data :(
}
/**************************** ISSUE ***********************/
} else {
Log.d("save getInvitation: no deep link found.");
}
}
});
}
}
Everything is working as expected. The SaveActivity is getting called and it is opening the SaveActivity. But, NO extra data is received in the activity.
I am setting the string extra using IntentKeys.PUSH_DATA_EXTRA as the key in the intent.

How to bring an Activity to foreground? Nothing work from inside a BroadcastReceiver

I have an activity that receives SMS and I would like it to be brought to the foreground when that happens. It doesn't matter if it is the same instance or a new one. I've tried everything I found in this site, even other flags like FLAG_ACTIVITY_NEW_TASK works fine, but [so far] NOTHING brings the Activity to the foreground.
public class SMSMessenger extends Activity {
private static final String ACTION = "android.provider.Telephony.SMS_RECEIVED";
private BroadcastReceiver yourReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
final IntentFilter theFilter = new IntentFilter();
theFilter.addAction(ACTION);
this.yourReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// Bring activity to the foreground - doesn't work
Intent I = new Intent(context, SMSMessenger.class);
I.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
context.startActivity(I);
//------------------------------------------------
}
};
this.registerReceiver(this.yourReceiver, theFilter);
}
}
I believe what you are looking for is this. Create your receiver as a seperate file (MyBroadcastReceiver.java) and have it launch the activity or popup a notification or whatever. In your AndroidManifest try putting this:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name=
"android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
Also make sure you include the SMS permission in your AndroidManifest:
<uses-permission android:name="android.permission.RECEIVE_SMS" />
Try this one..
myManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
myNotification = new Notification(R.drawable.alert1, "ALERT...!!", System.currentTimeMillis());
myIntent = new Intent(context, SmsMessanger.class);
myPendingIntent = PendingIntent.getActivity(context, 0, myIntent, 0);
myNotification.setLatestEventInfo(context, "NEW SMS ALERT...!!", "You have a new SMS alert..!! Click here to stop the alert tone...!!", myPendingIntent);
myManager.notify(0, myNotification);
It worked for me..!
when we click on the notification, the activity is brought to front.

Categories

Resources