When I click on Notification I should be navigated to Main2Activity and when I click on back button of Main2Activity I should be navigated back to MainActivitybut I am getting navigated back to Home screen.
Is there any mistake in my code?
NotificationCompat.Builder noti = new NotificationCompat.Builder(MainActivity.this);
noti.setContentTitle("Message for you!");
noti.setContentText("Hi!!This is message for you");
noti.setSmallIcon(R.drawable.ic_launcher_background);
noti.setTicker("app name:message app");
noti.setAutoCancel(true);
Intent intent = new Intent(MainActivity.this,Main2Activity.class);
TaskStackBuilder taskStackBuilder=TaskStackBuilder.create(MainActivity.this);
taskStackBuilder.addParentStack(MainActivity.class);
taskStackBuilder.addNextIntent(intent);
PendingIntent pendingIntent=
taskStackBuilder.getPendingIntent(1234,PendingIntent.FLAG_UPDATE_CURRENT);
noti.setContentIntent(pendingIntent);
Notification notification=noti.build();
NotificationManager notificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(1234,notification);
Mainifest.XML file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.sainathpawar.notifications">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Main2Activity"
android:parentActivityName=".MainActivity">
<intent-filter>
<action android:name="second_filter" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
</application>
Please try this
<activity
android:name=".Main2Activity"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
It is because you are not within a stack. You only launched one activity. Your default MainActivity has not been created or launched.
You can handle the back button press with android.R.id.home in the OnMenuItemSelected callback and redirect them wherever you would like. You can try the "parent activity" route as well, but I'm not certain how that works when launched from notification without context of the parent to launch it to begin with.
If you go that route, update to let us know if it worked for you.
Otherwise you can easily use my answer as well.
EDITED FOR CLARITY
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
startActivity(Main2Activity.this, MainActivity.class);
return true;
finish();
}
return super.onOptionsItemSelected(item);
}
taskStackBuilder.getPendingIntent(1234,PendingIntent.FLAG_UPDATE_CURRENT);
noti.setContentIntent(pendingIntent);
There was error in coding at above line.If we see here the requestcode is 1234 which is same as ID of notify method
notificationManager.notify(1234,notification);
so it was navigating back to Home screen because Android OS was thinking as if its on MainActivity because of 1234 request code in getPendingIntent.
****Solution is:****change requestCode of getPendingIntent() method from 1234 to any random number I changed it to 0 and it worked for me.
You can achieve this by PendingIntent without TaskStackBuilder as:
Intent parentIntent = new Intent(this, MainActivity.class);
parentIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
Intent resultIntent = new Intent(this, Main2Activity.class);
final PendingIntent pendingIntent = PendingIntent.getActivities(context, 0,
new Intent[] {parentIntent, resultIntent}, PendingIntent.FLAG_UPDATE_CURRENT);
noti.setContentIntent(pendingIntent);
Related
I'm new on android development and I still don't understand Intent very well. Here i'm using Firebase to create notifications, I add an Intent to my notification, but when my app is in foreground and I click on the notification nothing happens (when the app is killed or in background it work well).
The strange thing is at a moment it was working, when I clicked on the notification the function "onNewIntent" of my "MainActivity" class was called, but now nothing happen anymore, and I think I changed nothing on the code.
Here is how I create my intent :
Notifications notifs = new Notifications(this);
String title = remoteMessage.getData().get("title");
String body = remoteMessage.getData().get("body");
String url = remoteMessage.getData().get("url");
Intent intentNotif = new Intent(this, MainActivity.class);
intentNotif.setAction(Intent.ACTION_MAIN);
intentNotif.addCategory(Intent.CATEGORY_LAUNCHER);
intentNotif.putExtra("url", url);
intentNotif.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_SINGLE_TOP);
//intentNotif.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
notifs.showNotif(title, body, true, intentNotif);
Here is how I add the intent to the notification :
this.builderGeneric.setContentIntent(PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT));
I also tried to create an intent with a custom action but it's not working, I tryed different intent flags, but I feel like i'm trying random things without knowing what I do, so that's why I'm asking for your help.
EDIT :
Here is how I create the notification if it's usefull :
Notifications(Context context) {
this.context = context;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
this.notifManager = context.getSystemService(NotificationManager.class);
NotificationChannel channel = new NotificationChannel(CHANNEL_ID, CHANNEL_NAME, NotificationManager.IMPORTANCE_LOW);
channel.setDescription(CHANNEL_DESCRIPTION);
channel.enableLights(false);
channel.enableVibration(false);
channel.setSound(null, null);
if (this.notifManager != null) {
this.notifManager.createNotificationChannel(channel);
}
} else {
this.notifManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
}
this.builderGeneric = new Notification.Builder(context)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setWhen(System.currentTimeMillis())
.setSmallIcon(R.mipmap.ic_launcher_round);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
this.builderGeneric.setChannelId(this.CHANNEL_ID);
}
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP) {
this.builderGeneric.setSmallIcon(R.mipmap.ic_launcher_foreground);
}
}
public void showNotif(String title, String text, boolean cancelable, Intent intent) {
this.builderGeneric.setContentTitle(title)
.setContentText(text)
.setOngoing(!cancelable)
.setContentIntent(PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT));
Notification notifGeneric = this.builderGeneric.build();
this.notifManager.notify(1, notifGeneric);
}
EDIT 2 : Here is my manifest :
<application
android:allowBackup="true"
android:fullBackupContent="#xml/backup_descriptor"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:launchMode="standard"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:configChanges="orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
<receiver
android:name=".NetworkChangeReceiver"
android:label="NetworkChangeReceiver">
<intent-filter
android:name=".NetworkIntentFilter"
android:label="NetworkIntentFilter">
<action
android:name="android.net.conn.CONNECTIVITY_CHANGE"
tools:ignore="BatteryLife" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
<service android:name=".MyFirebaseService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT" />
</intent-filter>
</service>
</application>
OK, First try to remove
intentNotif.setAction(Intent.ACTION_MAIN);
intentNotif.addCategory(Intent.CATEGORY_LAUNCHER);
Next, adding android:launchMode="singleTask" (also removing android:launchMode="standard") inside your activity tag in AndroidManifest.xml.
Then try again, please aware that with the launchMode is singleTask and if you click on your notification while your MainActivity is opened -> onNewIntent will be triggered (because Android will not create one more instance of this Activity) otherwise onCreate will be called.
And if it works, I would like to recommend you to read more about LaundMode here
What I'm trying to do is create a notification in Android that will open an Activity whenever it is tapped. This activity is called "NotificationsActivity" and its parent is "MainActivity". Whenever the user is presented with NotificationsActivity I want them to be able to press the back button to get to the MainActivity. I've been using the instructions here (http://developer.android.com/guide/topics/ui/notifiers/notifications.html#DirectEntry) to try and get this to work. However, no matter what I try, whenever I press back from the NotificationsActivity the app exits completely. The only issue that I can think of is that my app has a login screen and I have also identified it as a MAIN and LAUNCHER. I don't think this would cause a problem, but that's all I can think of.
To summarize. What I want is:
Tap notification
Open NotificationsActivity
Press Back
Open MainActivity
But what I'm getting is:
Tap notification
Open NotificationsActivity
Press Back
Exit App
Pertinent code is displayed below.
From AndroidManifest.xml:
<activity
android:name=".LoginActivity"
android:label="#string/app_name"
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>
<activity
android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
<activity
android:name=".NotificationsActivity"
android:parentActivityName=".MainActivity" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
And here is my Java code:
private void notifyRecordChanges(){
String notificationText = "test notification";
Context context = this;
NotificationCompat.Builder builder =
new NotificationCompat.Builder(context)
.setSmallIcon(R.drawable.ic_notify)
.setAutoCancel(true)
.setContentText(notificationText);
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(context, NotificationsActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
stackBuilder.addParentStack(NotificationsActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
stackBuilder.addNextIntent(resultIntent);
PendingIntent resultPendingIntent =
stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(resultPendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(1, builder.build());
}
EDIT: I removed the LoginActivity class from the project and it made no difference. So, now I have no idea what I'm doing wrong.
SECOND EDIT:
To add to Skizo's answer, I had to support the back button on the action bar. Here is the code to handle that. I call "goBack" from both the method override provided by Skizo and the code below.
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch(item.getItemId()){
case android.R.id.home:
goBack();
break;
}
return super.onOptionsItemSelected(item);
}
private void goBack(){
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
finish();
}
Just Override the onBackPressed() on your NotificationsActivity.
Copy&Paste this method :
#Override
public void onBackPressed() {
// super.onBackPressed();
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
finish();
}
In TabHost we can do getActionBar().setTitle("ACTITIVTY TITLE").
But what about in the intent?
Is there possible way to set title in intent?
code
Intent i = new Intent(MenuActivity.this, DrawerListActivity.class);
startActivity(i);
Toast.makeText(getBaseContext(), "RF number: " +
KEY_RFnumber, Toast.LENGTH_SHORT).show();
MainActivity.class
public void send(View view) {
Intent intent = new Intent(this, DrawerListActivity.class);
String message = "Drawer Title";
intent.putExtra("key", message);
startActivity(intent);
}
DrawerListActivity.class, in onCreate()
String message = getIntent().getStringExtra("key").toString(); // Now, message has Drawer title
setTitle(message);
Now, set this message as Title.
You can't set the title directly with the intent. You could pass along the title in the intent, and have your target activity extract the title from the intent and set it. This would only be a few lines of extra code in the target activity.
I got it! I just declare from my MainActivity a public static String that holds a string which I set in my Intent, then it call to my DrawerListActivity. It works perfectly! Thanks.
i just paste another person answer regarding this question may be it will help you
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name_full" >
//This is my custom title name on activity. <- The question is about this one.
<intent-filter android:label="#string/app_launcher_name" > //This is my custom Icon title name (launcher name that you see in android apps/homescreen)
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
I'm new in this world. I have a problem when I use startActivity(intent).
This is the Manifest:
<activity
android:name="com.example.counter.Splash"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.counter.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
And this is the code:
public class Splash extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
Thread timer = new Thread(){
public void run()
{
try
{
sleep(5000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
finally
{
Intent i=new Intent ("com.example.counter.MainActivity");
startActivity(i);
}
}
};
timer.start();
}
I'd want to show Splash activity for 5 seconds and then show MainActivity.
LogErrors: !https://www.dropbox.com/s/kg7xyp6h4b95itq/Screenshot%202014-02-08%2016.57.36.png
There are two ways of doing what you are trying to do.
Using an implicit Intent
Using an explicit Intent
Refer Intent Types
Implicit Intent
Declare Intent Filters for your Activity in your AndroidManifest.xml. By doing that the Android system understands what kind of Intents your component(in this case your MainActivity) can handle.
<activity
android:name="com.example.counter.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="com.example.counter.MainAction" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<activity>
Now you will be able to launch your Activity with the same Intent
Intent i=new Intent ("com.example.counter.MainAction");
startActivity(i);
Such implicit Intents are used when you don't explicitly know which Activity has to be started and you want the Android system to decide which component to start. If the system finds multiple components which can handle your Intent, it will allow the user to choose.
Note: it is possible that there are no applications that can handle your intent. In this case, your application will crash when you invoke startActivity(). To avoid this, before calling startActivity() you should first verify that there is at least one application registered in the system that can handle the intent. To do this use resolveActivity() on your intent object.
Explicit Intent
In your case, you should use an explicit Intent as you already know which Activity you want to start. So create an Intent by passing the context and the component(Activity) class you want to start.
Intent i=new Intent (this,MainActivity.class);
startActivity(i);
You have to reference the class you want to start. So you'd need something like:
Intent newAct = new Intent(this, Splash.class);
startActivity(newAct);
What you're passing is an Action that is not understood as a class name.
I guess, Splash is your Launcher Activity, make following changes in your manifest file:
<activity
android:name="com.example.counter.Splash"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.example.counter.MainActivity"
android:label="#string/app_name" >
</activity>
Make your activity this way:
public class Splash extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.splash);
/*Splach screen that display for 5 seconds when app start*/
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent i = new Intent(Splash.this, MainActivity.class);
startActivity(i);
finish();
}
}, 5000);
}
}
I hope this should solve your problem now.
I think you should be able to use (implicit Intent):
Intent i=new Intent ("com.example.counter.MainActivity");
There is no reason to change it to (explicit intent):
startActivity(new Intent(mContext, MainActivity.class));
but then you need to change the action in intent filterof MainActivity from:
<action android:name="android.intent.action.MAIN" />
to:
<action android:name="com.example.counter.MainActivity"/>
You need to declare an activity in manifest file.
Like this:
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".FirstActivity"
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>
<activty
android:name="com.example.counter.MainActivity"/>
</application>
Hope it helps.
i think it is better if you use Handler put this code at the splash Activity at the onCreate
new Handler().postDelayed(new Runnable() {
#Override
public void run() {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
finish();
}
}, 1500);
and if you want to open it one time it is good to use SharedPreferences
I'm using Notifications in Android. When the user clicks them, I have to open the application and redirect him to one specific Activity, it works fine if the user who gets the notifications didn't have the application opened. (I mean, opened in background), if he has the application opened, when he clicks the notification he is redirected to the "Main" activity when I want to redirect him to the same activity.
I guess that it could be some mistake in my AndroidManifest.xml,, but, I'm not sure, could you someone help me??
My manifest:
<application
android:screenOrientation="portrait"
android:debuggable="true"
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar.Fullscreen">
<!-- android:theme="#style/AppTheme" android:theme="#android:style/Theme.NoTitleBar.Fullscreen" -->
<activity
android:name="com.trivialword.activities.MainDisplayActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.trivialword.activities.ResultActivity"
android:label="#string/title_activity_result"
android:theme="#android:style/Theme.Light.NoTitleBar.Fullscreen" >
</activity>
And here is where I configure the notification
Context contexto = context.getApplicationContext();
CharSequence title = "Trivial Invitación";
CharSequence description = "Invitacion a una partida del usuario " + msg;
Intent notIntent = new Intent(contexto,
GameOnePlayerPrivateOnlineActivity.class);
notIntent.putExtra("opponent", true);
notIntent.putExtra("who-create-game", msg);
PendingIntent contIntent = PendingIntent.getActivity(
contexto, 0, notIntent, 0);
notif.setLatestEventInfo(
contexto, title, description, contIntent);
Thank you!.
In intent declaration, try to write this.
http://developer.android.com/guide/topics/ui/notifiers/notifications.html
Creating a simple notification:
// Creates an explicit intent for an Activity in your app
Intent resultIntent = new Intent(this, ResultActivity.class);
I think, that is the problem.