Android Notification tap cause crashes the app due to Activity intent - android

I have MainActivity and UserAcitivity, I have passed some values to UserActivity through intent.
from the UserActivity, I call Notification then notification appeared, I made notification tap to
start the UserActivity by Pending Intent. When the Notification tap the App crashes because the values passed from MainAcitvity become null.
I can't Use SharedPreferences because the Value conflict for another UserAcitivity(the passed value was unique for every user)
example code is here:-
This is MainAcitvity
public void buttonClick(View view){
Intent intent = new Intent(this,SecondActivity.class);
intent.putExtra("myname","ashiqueHira");
startActivity(intent);
}
This is SecondAcivity Oncreate method;
String heading= "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Intent intent = getIntent();
heading = intent.getStringExtra("myname");
Toast.makeText(this, heading, Toast.LENGTH_SHORT).show();
}
This is my Notification method
public void notificationPops(){
Intent intent = new Intent(this, SecondActivity.class);
createNotificationChannel();
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addNextIntentWithParentStack(intent);
Vibrator vibrator = (Vibrator) getApplicationContext().getSystemService(Context.VIBRATOR_SERVICE);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, 0);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_vibration_black_24dp)
.setContentTitle("Token Reminder")
.setContentText("Dismiss the Alarm by Clicking this")
.setPriority(NotificationCompat.PRIORITY_MAX)
.setVibrate(new long[] { 100, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000, 1000 })
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
// Set the intent that will fire when the user taps the notification
.setContentIntent(pendingIntent)
.setAutoCancel(true);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(0, builder.build());
}
private void createNotificationChannel() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"myChannel",
NotificationManager.IMPORTANCE_HIGH
);
serviceChannel.enableVibration(true);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}
}
This is a similar condition that I have. The difference is I have many usages for the getIntent value
and that value is unique for every Activity.
Thanks in Advance

So, basically you get NullPointerException. For reducing this problem change youe SecondActivity code like this:
String heading= "";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_second);
Intent intent = getIntent();
if(intent.getStringExtra("myname")!= null){
heading = intent.getStringExtra("myname");
Toast.makeText(this, heading, Toast.LENGTH_SHORT).show();
}
}
This will reduce your nullException error and your app cannot crash.
Another thing If you always need heading value pass through intent. Then pass the value also from notification pendingIntent and get it from SecondActivity

I found a way to solve this problem by adding and replacing the following code
in the notificationPops() method
Intent intent = new Intent(this, SecondActivity.class);
intent.putExtra("yourName",heading);
PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 0,
intent, PendingIntent.FLAG_UPDATE_CURRENT);
this will get you the value to the activity when the activity stats by notification taps.
Please post if other best practices to solve the problem above

Related

Notification OnClick Event

I want to call the Activity NotificationReceiver, when I click onto an android notification.
The notification is already shown correctly, but when I click onto the notification nothing happens.
Here is the code for the notification:
private void notification_anzeigen2(){
Log.d("Test2", "Test2 ");
Intent intent = new Intent(this, NotificationReceiver.class);
intent.putExtra("NotiClick",true);
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, Intent.FILL_IN_ACTION);
Notification n = new Notification.Builder(this).setContentTitle("GestureAnyWhere Hintergrundservice")
.setContentText("Bitte klicken, um den Hintergrundservice zu beenden")
.setContentIntent(pIntent)
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_launcher)
.build();
NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(1, n);
Log.d("Test3", "Test3 ");
}
And here is the activity:
public class NotificationReceiver extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
if (savedInstanceState == null) {
Bundle extras = getIntent().getExtras();
if(extras == null)
{
Log.d("Test4", "Test4");
}
else if (extras.getBoolean("NotiClick"))
{
Log.d("Test5", "Test5");
stopService(new Intent(getApplicationContext(), HintergrundService.class));
}
}
super.onCreate(savedInstanceState);
setContentView(R.layout.result);
}
Thanks a lot.
Try:
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
You pass as a flag a constant that has nothing to do here, so its value can match to an undesired flag, see PendingIntent doc.
It says: "May be FLAG_ONE_SHOT, FLAG_NO_CREATE, FLAG_CANCEL_CURRENT, FLAG_UPDATE_CURRENT, or any of the flags as supported by Intent.fillIn() to control which unspecified parts of the intent that can be supplied when the actual send happens."

Pending Intent not receiving the putExtraBudle for different notificationId

I am using the code of PingService.java https://github.com/android/platform_development/blob/master/samples/training/notify-user/src/com/example/android/pingme/PingService.java
PingService.Java
/**
* PingService creates a notification that includes 2 buttons: one to snooze the
* notification, and one to dismiss it.
*/
public class PingService extends IntentService {
private NotificationManager mNotificationManager;
private String mMessage;
private int mMillis;
NotificationCompat.Builder builder;
public PingService() {
// The super call is required. The background thread that IntentService
// starts is labeled with the string argument you pass.
super("com.example.android.pingme");
}
#Override
protected void onHandleIntent(Intent intent) {
// The reminder message the user set.
mMessage = intent.getStringExtra(CommonConstants.EXTRA_MESSAGE);
// The timer duration the user set. The default is 10 seconds.
mMillis = intent.getIntExtra(CommonConstants.EXTRA_TIMER,
CommonConstants.DEFAULT_TIMER_DURATION);
NotificationManager nm = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
String action = intent.getAction();
// This section handles the 3 possible actions:
// ping, snooze, and dismiss.
if(action.equals(CommonConstants.ACTION_PING)) {
issueNotification(intent, mMessage);
} else if (action.equals(CommonConstants.ACTION_SNOOZE)) {
nm.cancel(CommonConstants.NOTIFICATION_ID);
Log.d(CommonConstants.DEBUG_TAG, getString(R.string.snoozing));
// Sets a snooze-specific "done snoozing" message.
issueNotification(intent, getString(R.string.done_snoozing));
} else if (action.equals(CommonConstants.ACTION_DISMISS)) {
nm.cancel(CommonConstants.NOTIFICATION_ID);
}
}
private void issueNotification(Intent intent, String msg) {
mNotificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
// Sets up the Snooze and Dismiss action buttons that will appear in the
// expanded view of the notification.
Intent dismissIntent = new Intent(this, PingService.class);
dismissIntent.setAction(CommonConstants.ACTION_DISMISS);
PendingIntent piDismiss = PendingIntent.getService(this, 0, dismissIntent, 0);
Intent snoozeIntent = new Intent(this, PingService.class);
snoozeIntent.setAction(CommonConstants.ACTION_SNOOZE);
PendingIntent piSnooze = PendingIntent.getService(this, 0, snoozeIntent, 0);
// Constructs the Builder object.
builder =
new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_stat_notification)
.setContentTitle(getString(R.string.notification))
.setContentText(getString(R.string.ping))
.setDefaults(Notification.DEFAULT_ALL) // requires VIBRATE permission
/*
* Sets the big view "big text" style and supplies the
* text (the user's reminder message) that will be displayed
* in the detail area of the expanded notification.
* These calls are ignored by the support library for
* pre-4.1 devices.
*/
.setStyle(new NotificationCompat.BigTextStyle()
.bigText(msg))
.addAction (R.drawable.ic_stat_dismiss,
getString(R.string.dismiss), piDismiss)
.addAction (R.drawable.ic_stat_snooze,
getString(R.string.snooze), piSnooze);
/*
* Clicking the notification itself displays ResultActivity, which provides
* UI for snoozing or dismissing the notification.
* This is available through either the normal view or big view.
*/
Intent resultIntent = new Intent(this, ResultActivity.class);
resultIntent.putExtra(CommonConstants.EXTRA_MESSAGE, msg);
resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
// 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
);
builder.setContentIntent(resultPendingIntent);
startTimer(mMillis);
}
private void issueNotification(NotificationCompat.Builder builder) {
mNotificationManager = (NotificationManager)
getSystemService(NOTIFICATION_SERVICE);
// Including the notification ID allows you to update the notification later on.
mNotificationManager.notify(CommonConstants.NOTIFICATION_ID, builder.build());
}
private void startTimer(int millis) {
Log.d(CommonConstants.DEBUG_TAG, getString(R.string.timer_start));
try {
Thread.sleep(millis);
} catch (InterruptedException e) {
Log.d(CommonConstants.DEBUG_TAG, getString(R.string.sleep_error));
}
Log.d(CommonConstants.DEBUG_TAG, getString(R.string.timer_finished));
issueNotification(builder);
}
}
Intent mServiceIntent = new Intent(context.getApplicationContext(), PingService.class);
mServiceIntent.putExtra(Const.EXTRA_MESSAGE, "" + msg);
mServiceIntent.putExtra(Const.ID, reminder_id);
startService(mServiceIntent);
And passing the data to issueNotification method for Action Button intent like
Intent dismissIntent = new Intent(this, PingService.class);
dismissIntent.setAction(CommonConstants.ACTION_DISMISS);
dismissIntent.putExtra(CommonConstants.ID, reminder_id);
PendingIntent piDismiss = PendingIntent.getService(this, 0, dismissIntent, 0);
Intent snoozeIntent = new Intent(this, PingService.class);
snoozeIntent.setAction(CommonConstants.ACTION_SNOOZE);
snoozeIntent.putExtra(CommonConstants.ID, reminder_id);
PendingIntent piSnooze = PendingIntent.getService(this, 0, snoozeIntent, 0);
But i am not getting the ID at the time of Click event of the Action button from issueNotification and passing the intent in onHandleIntent method
It is automatically set to 1 after Notification generation and i am not able to cancel that notification due to wrong notification id set into putExtra of PendingIntent
I am trying with passing different flag like
PendingIntent piDismiss = PendingIntent.getService(this, 0, taken_intent, PendingIntent.FLAG_UPDATE_CURRENT);
Please help me out i am trying it since long time but not getting the correct id.
My putExtra is override with 1 somehow....
Thank you in advnace
After so much reasearching finally got a solution that i need to pass different code in pending intent like
PendingIntent piDismiss = PendingIntent.getBroadcast(this, CommonConstants.NOTIFICATION_ID, dismissIntent, 0);
which is dynamic one and unique one in each Action Button case.
Use Broadcast receiver to achieve this instead of Service ( getBroadcast ).
Thank you.

Android - create notifications

I have question about notifications. I want to build an app with one buttons called (add notification) when I press add notification a notification is created Then, if I press the notification it takes me back to the activity.
I managed to create a notification but when i press on it, it makes nothing. What do I have to add so the notification sends me back to the activity?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
NotificationManager nmanger;
static int id=1;
public void buclick(View view) {
NotificationCompat.Builder nbuild= (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setContentTitle("Danger")
.setContentText("the raining is comming soon")
.setSmallIcon(R.drawable.amule);
nmanger =(NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
nmanger.notify(id,nbuild.build());
id++;
}
Create PendingIntent, then set it to builder:
Intent intent = new Intent(this, YourActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder nbuild = (NotificationCompat.Builder) new NotificationCompat.Builder(this)
.setContentTitle("Danger")
.setContentText("the raining is comming soon")
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.amule);
Try this code
Intent intent = new Intent(this, NameOfClassYouWantToOpen.class);
// Create pending intent and wrap our intent
PendingIntent pendingIntent = PendingIntent.getActivity(this, 1, intent, PendingIntent.FLAG_CANCEL_CURRENT);
try {
// Perform the operation associated with our pendingIntent
pendingIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
http://codetheory.in/android-pending-intents/
What is an Android PendingIntent?

how to make pressing on the notificaton text close the app not open other activity

I am developing a flashLight app and I faced a problem in notification which is : When I press the notification text I want to turn of flash and close the whole app , How can I modified the notification method to do that ??
I tried to make anthor activity and put turn of and close app methods in it, but it does not work .
please help and thanks in advance .
this is my notification method
public void getNotification()
{
Intent intent = new Intent();
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent , PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentIntent(pIntent)
.setContentTitle(res.getString(R.string.notification_title))
.setContentText(res.getString(R.string.notification_text))
.setSmallIcon(R.drawable.icon)
.setAutoCancel(true)
.setTicker(getString(R.string.notification_ticker_msg));
// Build the notification:
Notification notification = builder.build();
// Get the notification manager:
NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// Publish the notification:
final int notificationId = 0;
notificationManager.notify(notificationId, notification);
}
If you use the same Activity, then the onCreate method will be called again. You can send one extra with your Intent that indicates it is an Intent generated from the click of notification. In your Activity onCreate, check for this extra and call finish() if it is present.
public void getNotification() {
Intent intent = new Intent(this, FlashActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intent.putExtra("origin", "notification");
PendingIntent pIntent = PendingIntent.getActivity(this, 0, intent , PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setContentIntent(pIntent)
.setContentTitle(res.getString(R.string.notification_title))
.setContentText(res.getString(R.string.notification_text))
.setSmallIcon(R.drawable.icon)
.setAutoCancel(true)
.setTicker(getString(R.string.notification_ticker_msg));
// Build the notification:
Notification notification = builder.build();
// Get the notification manager:
NotificationManager notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// Publish the notification:
final int notificationId = 0;
notificationManager.notify(notificationId, notification);
}
And in your onCreate method in FlashActivity check the extra.
#Override
public void onCreate(Bundle savedInstanceState) {
...
if("notification".equals(getIntent().getStringExtra("origin"))) {
finish();
}
}
I believe you can use finish() on your Activity when the notification ils pressed.
EDIT: How to close any activity of my application by clicking on a notification?
You want to use PendingIntent.
Intent resultIntent = new Intent(this, MainActivity.class);
resultIntent.putExtra("FINISH",true);
PendingIntent resultPendingIntent =
PendingIntent.getActivity(
this,
0,
resultIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
builder.setContentIntent(resultPendingIntent);
// Build the notification:
Notification notification = builder.build();
//rest of your methods to show notification
In your MainActivity update depending on your code
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
onNewIntent(getIntent());
}
#Override
public void onNewIntent(Intent intent){
setContentView(R.layout.activity_main);
Bundle extras = intent.getExtras();
if(extras != null){
if(extras.containsKey("FINISH"))
{
finish();
}
}
}

How to check if Activity start from notification

I have problem my MainActivity can be created by 3 ways:
1) standart launch App
2) from Service
3) from notification click.
How I can check when it starts from notification click?
Notification code:
private void createNotification()
{
Log.d("service createNotification",MainActivity.TAG);
Context context = getApplicationContext();
Intent notificationIntent = new Intent(this,MainActivity.class);
intent.putExtra(AppNames.IS_NOTIFICATION_INTENT,true);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
notificationIntent, Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentTitle(this.getString(R.string.notification_title))
.setContentText(this.getString(R.string.notification_text))
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_launcher);
getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(AppNames.APP_NOTIFICATION, builder.getNotification());
}
add
intent.putExtra("started_from","notification");
to the code that starts the intent from the notifications, and the same thing to the other startActivity calls just change the value, then inside your activity
String startedFrom = getIntent().getStringExtra("started_from");
for more refer to this question: How do I get extra data from intent on Android?

Categories

Resources