getIntent.remove extra not working - java

public void showNotification(Context context,String pnrNumber){
Intent intent=new Intent(context,HomeActivity.class);
intent.putExtra("PNR", pnrNumber);
//To Clear the Activity Stack
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent contentIntent = PendingIntent.getActivity(context, uniqueNumber,intent, Intent.FLAG_ACTIVITY_CLEAR_TASK);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(context).setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("TravelKhana")
.setContentText("Get food in train for the PNR:" +pnrNumber);
mBuilder.setContentIntent(contentIntent);
mBuilder.setDefaults(Notification.DEFAULT_SOUND);
mBuilder.setAutoCancel(true);
NotificationManager mNotificationManager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(uniqueNumber, mBuilder.build());
uniqueNumber++;
}
and in oncreate of the HomeActivity i am getting this string extra
if(getIntent().hasExtra("PNR")){
mPnrSearch.setTag(getIntent().getStringExtra("PNR"));
onClick(mPnrSearch);
}
And then in onClick(mPnrSearch);
public void onClick(View v) {
switch (v.getId()) {
case R.id.pnrSearch:
if(NetworkChecker.isConnected(getApplicationContext())) {
easyTracker.send(MapBuilder.createEvent("Home Activity","click", "PNR", null).build());
}
Intent pnrIntent = new Intent(HomeActivity.this, PnrSearch.class);
//If the user came from notification
if(v.getTag() != null){
pnrIntent.putExtra("PNR", v.getTag().toString());
v.setTag(null);
getIntent().removeExtra("PNR");
}
startActivity(pnrIntent);
break;
}
I removed the extra and then I pressed the back button to destroy the app and reopened it by long pressing the home button in my phone and then after the extra is still there and onClick(mPnrSearch) is called again, but i have removed the extra why is it so?? and what do i need to do to resolve this out.

This is either an Android bug or a feature, depending on whether you want it to happen or not ;-) This case isn't clearly documented, but it is clear that it behaves the way you describe.
I recently answered a similar question and made some suggestions about how to deal with this problem. See my answer for more information.

i think after removing you should update new intent, just implement this function in your activity
protected void onNewIntent(Intent intent) {
// TODO Auto-generated method stub
super.onNewIntent(intent);
setIntent(intent);
}

in my case i passed the value from notification to my MainActivity from onMessageReceived. why because i wanted to count the opening app by notification click for specific notification id which is the value i passed by exteras( notification opens the app mainactivity ) for analytics reasons. what ever, to find out if main activity is opened by notification or not i checked both exteras value and intent flag. i observed that when ever app is opened by notification click the intent flag is 0 so i added the below to my mainactivity.
if(getIntent().getFlags() == 0 && getIntent().getExtras() != null){
Log.i("opened by notification only",getIntent().getStringExtra("myID"));
//rest of process...............
}

Related

Android startActivityForResult returning result code on BackPressed event

I wrote a standard SettingsActivity. I need to check for a given settings after the Activity is closed. The typical event triggered on standard SettingsActivity closing is the onBackPressed event.
This my code:
#Override
public void onBackPressed() {
super.onBackPressed();
Intent intent = new Intent();
setResult(RESULT_CODE, intent);
finish();
}
The SettingsActivity is opened in this way:
Intent intent = new Intent(this, SettingsActivity.class);
startActivityForResult(intent, SettingsActivity.RESULT_CODE);
And this's the code that checks for the activity to return:
if((requestCode == SettingsActivity.RESULT_CODE) && (resultCode == SettingsActivity.RESULT_CODE))
{
if(settings.control_mode == ControlMode.GCS)
{
settings.getSettings(this);
selectController(getString(R.string.gcs_controller_id));
settings.storeSettings(this);
}
}
requestCode is correctly set but resultCode is always zero I think because I'm setting it trough onBackPressed event handler but I don't know how to make it in a different way.
How can I fix this?
Remove super.onBackPressed(); . That already finishes the current activity

update recycler view while receive fcm notification

I want to refresh my recycler view in fragment while receive FCM notification(if specific fragment is open) else receive notification.
I have tried multiple solutions, but that didn't work.
MyFirebaseMessagingService.java
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
Map<String, String> data = remoteMessage.getData();
if (remoteMessage.getNotification() != null) {
String noti_body = remoteMessage.getNotification().getBody();
String noti_title = remoteMessage.getNotification().getTitle();
String noti_activity = data.get("activity");
mBuilder = new NotificationCompat.Builder(this, "M_CH_ID")
.setSmallIcon(R.mipmap.logo)
.setContentTitle(noti_title)
.setContentText(noti_body)
.setLargeIcon(BitmapFactory.decodeResource(getResources(), R.mipmap.logo))
.setColor(getResources().getColor(R.color.colorAccent))
.setDefaults(Notification.DEFAULT_ALL)
.setPriority(NotificationManager.IMPORTANCE_HIGH)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setAutoCancel(true); // clear notification after click
if (remoteMessage.getData().size() > 0) {
fragmentNewJobs c = new fragmentNewJobs();
if (c.getUserVisibleHint()) {//fragmentNewJobs.is_open
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("activity", noti_activity);
getApplicationContext().startActivity(intent);
}else {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.putExtra("activity", noti_activity);
#SuppressLint("WrongConstant")
PendingIntent pi = PendingIntent.getActivity(this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
mBuilder.setContentIntent(pi);
NotificationManager mNotificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(0, mBuilder.build());
}
}
}
}
fragmentNewJobs c = new fragmentNewJobs();
if (c.getUserVisibleHint())
I have tried this, but it load fragmentNewJobs.java even I have opened any screen.
I want to refresh recyclerView in fragmentNewJobs.java only if fragmentNewJobs is open else receive notification.
I want to add only new item to recyclerView(not load all data if possible)
You can use Event Bus to publish message from receiver to particular fragment or activity.
And to findout if activity is visible or not have a look at this
Or if you are using fragment you can use static variable in Application class to track fragment(Most basic use)
i want to add only new item to recycler view(not load all data if
possible)
You can use BroadcastManager to send notification event to your existing Activity. Running Activity will add new item in List when it receive new broadcast.
Another option to notify Activity can be EventBus, that is fast growing, easy implementation library for notifying between Services, Activities and Fragments.
How to use BroadcastManager?
How to use EventBus?
i want to refresh recyclerview in fragmentNewJobs.java only if
fragmentNewJobs is open else receive notification.
For this you can take a static boolean in Application class, and make it true on Fragment's onResume() and make it false on onPause().
Then you can check Fragment's visibility by ApplicationClass.isFragmentVisible()
Edit
You can change fragmentVisible boolean inside setUserVisibleHint() of Fragment, that will work perfectly. You will need to make initially UserVisibleHint false because it is true default. Check this answer for better understanding.

Pop up window after the alarm signal - Android

I would like to know - how to show pop up window when AlarmManager will call? I've already created AlarmManager now I need to create something what will show popup window to cancel this Alarm.
My code:
public void setAlarm(long timeInMillis){
if(Build.VERSION.SDK_INT >= 23){
mCalendar.set(
mCalendar.get(Calendar.MONTH),
mCalendar.get(Calendar.YEAR),
mCalendar.get(Calendar.DAY_OF_YEAR),
mCalendar.get(Calendar.HOUR_OF_DAY),
mCalendar.get(Calendar.MINUTE)
);
}
final AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(this, MyAlarm.class);
intent.setData(currentUri);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, 0);
alarmManager.setExact(AlarmManager.RTC, timeInMillis, pendingIntent);
}
and
public class MyAlarm extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
MediaPlayer mediaPlayer = MediaPlayer.create(context, Settings.System.DEFAULT_RINGTONE_URI);
mediaPlayer.start();
}
}
onReceive(context, intent) {
/*show the dialog in this method. set the onclick so it can dismiss the alarm,
get the value for the alarm from the bundle. I may be wrong about this
but i think alarmManager has a cancel(PendingIntent operation) method that u can
just send in the intent and your done.
Call a stopMedia(context) method after the cancel in order to stop the media
that is playing
*/
showDialog(context, intent)
//Extract the play media code to a method for readability
playMedia(context)
}
That should solve your problem
Before the code was posted:
We can either use the pending intent and have an activity that handles the pending intent. or use the handler to execute the code.
In either case, create a dialog fragment and then use the appropriate context to show it. setOnClickListener { alarmManager.cancel } for the dialog fragment button.
A little more explanation may be required depending on how the alarm manager is setup

Local Notifications in an Android Library

I'm writing here because I'm facing a probleme that I could not resolve even after many researches and tries.
I'm currently developing an Android Library which consists only of java classes and fragment. The problem is I need to send Local Notifications to the user, and clicking on the notifications should send the user back to the activity where he was. At this point, my library sends the notifications just fine. But the click on the notification doesn't have any action.
In my notification reciver class (which extends the BroadcastReceiver class), when the notification appears, I create a Pending Intent but I don't know what I can give as parameters to send the user to the activity. I tried using intent filters but it give me no results
So how can I have the notification sending back the user to the application ? The best would be if I was able to have the notification sending back the user to the activity where the notification is created (but it's a fragment so...)
In an usual app, I would've an intent sending back the user to an activity class but my library needs to have only fragments.
Maybe there is no problem and the solution is easy since I'm new to notifications
If someone here have an idea thanks for helping me ! :D
And if my problem isn't clear (Because of my bad english as an example) don't hesitate to ask me to add informations ^^
**Edit from 29 April : **
I managed to achieve it by giving to my broadcast pending intent the canonical name of my class using :
mContext.getClass().getCanonicalName();
Once in my broadcast receiver class I just get the class from the name of the sending class :
Class<?> activityClass = null;
try {
activityClass = Class.forName(stringSourceClass);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
Check out below code...
public BroadcastReceiver batteryReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
try {
String title = context.getString(R.string.app_name);
Intent intent1 = new Intent(context, YourActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(),1,intent1,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(title)
.setContentText("Hello")
.setAutoCancel(false)
.setContentIntent(pendingIntent);
NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, notificationBuilder.build());
} catch (Exception e) {
}
}
};
check the Building a notification page:
Intent resultIntent = new Intent(this, ResultActivity.class);
...
// Because clicking the notification opens a new ("special") activity, there's
// no need to create an artificial back stack.
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
just put your activity in resultIntent
how can I have the notification sending back the user to the
application ?
That's pretty simple:
1. While creating intent for pending intent call addAction ("action_name") method;
2. In activity you want to call (in manifest file) inside intent-filter tag add <action android:name="action_name>.
Now when your notification try to launch activity it would send intent message to system, which would search activity with proper action and launch it.
P.S. action name must be unique for every application

MediaPlayer and returning to current activity via Intent

I'm using MediPlayer to stream internet radio, and have a notification display in the notification center when the stream is playing.
If I leave the app (i.e. via home button) and then return to the app with the notification (radio playing in background), I get a new activity where I am unable to then stop the music due to a new instance of MediaPlayer being created.
Is there any way to either stop all MediaPlayer instances or return to the current (active) activity?
#Override
protected void onPause() {
super.onPause();
}
#Override
protected void onResume() {
if (player.isPlaying()) {
buttonPlay.setEnabled(false);
buttonStopPlay.setEnabled(true);
}
super.onResume();
}
//Display notification in notification center
public void showStatus () {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle("RADIO")
.setContentText("You're listening to RADIO");
Intent resultIntent= new Intent(this, MainActivity.class);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
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(123, mBuilder.build());
}
Where are you creating the instance of the MediaPlayer?
If you are doing so within the Activity then consider changing your strategy.
The right way to go about is to:
Create a Service that is in charge of instantiating and calling the methods on the MediaPlayer.
According to your application logic (i.e. wen a button is tapped) the Activity should post an Intent that will instruct the Service to do some operation over the MediaPlayer.
When you go out and back again to the app the 'Activity' wether it's a new instance or an old one - will post the Intents to the same instance of Service and thus to the same instance of a MediaPlayer.
For more details, you should check out Google's documentation on Using a Service with MediaPlayer.

Categories

Resources