I have 2 Notifications: one for incoming messages, one for outgoing messages. On Notification click, it sends the PendingIntent to self. I put in an extra value to determine which of the Notifications was clicked:
private static final int INID = 2;
private static final int OUTID = 1;
private void update(boolean incoming, String title, String message, int number) {
notificationManager = (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
Intent intent = new Intent(this, Entry.class);
intent.putExtra((incoming ? "IN" : "OUT"), incoming);
PendingIntent pi = PendingIntent.getActivity(Entry.this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
Notification noti = new Notification(incoming ? R.drawable.next : R.drawable.prev, incoming ? "Incoming message" : "Outgoing message", System.currentTimeMillis());
noti.flags |= Notification.FLAG_NO_CLEAR;
noti.setLatestEventInfo(this, title, message, pi);
noti.number = number;
notificationManager.notify(incoming ? INID : OUTID, noti);
}
And capture the Intent in the onNewIntent method:
#Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
if (intent.getExtras() != null)
for (String id : new ArrayList<String>(intent.getExtras().keySet())) {
Object v = intent.getExtras().get(id);
System.out.println(id + ": " + v);
}
else
log("onNewIntent has no EXTRAS");
}
plus the manifest line that makes sure that there's only one task (in activity tag):
android:launchMode="singleTop"
I logged that it runs through the onNewIntent method, but always use the same intent (IE if I click either the IN or OUT notification, the intent extra always contains the same bundle(logs: OUT: false)). It's always the Intent that was created last, which I found out because the initialization of both intents happens in another sequence than when they are changed:
private void buttonClick(View v) {
update(true, "IN", "in", 1);
update(false, "OUT", "out", 3);
}
private void setNotificationSettings() {
update(false, "IN", "===out message===", 0);
update(true, "OUT", "===in message===", 0);
}
Why do I always receive the same (last created) Intent?
You are passing same requestcode for all intent that why you reciev last intent everytime, so you have to pass different requestcode in pending intent..
like as below code
Your code:
PendingIntent pi = PendingIntent.getActivity(Entry.this, 0, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
Need to change:
PendingIntent pi = PendingIntent.getActivity(Entry.this, your_request_code, intent, Intent.FLAG_ACTIVITY_NEW_TASK);
Related
I am using push notifications and they work fine when i am inside the app. But when app is in background . When notification arrives , i need it to go to onMessageRecieved because i am setting a condition like :
public class MyGcmListenerService extends GcmListenerService {
private static final String TAG = "MyGcmListenerService";
#Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
String type = data.getString("type");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
Log.d(TAG, "Type: " + type);
sendNotification(message, type);
}
private void sendNotification(String message, String type) {
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(this);
//Set all notifcation properties etc
if (type.equals(Constants.GROUP_NOTIFICATION)) {
Intent intent = new Intent(this, MainActivity.class);
mBuilder.setContentIntent(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
}else {
Intent intent = new Intent(this, MainActivity.class);
intent.putExtra(Keys.NOTIFICATION_TYPE, Constants.QUESTION_NOTIFICATION);
mBuilder.setContentIntent(PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT));
}
}
}
For question Push Notification when it comes to the mainactivity by checking intent data it shoud be redirected to the questionActivity but since intent data is never set , it stays in mainactivity.
So my question is , how do i get data from the notification?
Well since i didn't get answers on my post so i figured out the problem my self . Did some searching and found out that there are two types of payloads. Data and notification . And if u have the notification payload than if your app is in background . Android will create a notification itself and will not called onMEssageRecieved . So i went to my server code and simply removed the notification payload part :) and now onMessagerecieved gets called.
I'd like to make an notification which start to count time when user exited android application. If user do not executed application after 1hours, It notified me to execute and If user ignoring it, It executes saved SMS messages. I found some examples on timer, but I do not know how to find application exit time. Please give me some advice with full code. I am desperately need it...
TimerTask task = new TimerTask(){
public void run() {
try {
mainTime++;
int min = mainTime / 60;
int sec = mainTime % 60;
String strTime = String.format("%s : %s", min, sec);
} catch (Exception e) {
e.printStackTrace();
}
}
};
Timer mTimer = new Timer();
mTimer.schedule(task, 0, 60000);
Intent sendIntent = new Intent(Intent.ACTION_VIEW);
sendIntent.putExtra("Chack your app", smsBody);
sendIntent.putExtra("12345678", phonenumber);
sendIntent.setType("vnd.android-dir/mms-sms");
startActivity(sendIntent);
Okay so what you need to do is to store the system time locally (may be using SharedPreferences) when the application exits. You can register a BroadcastReceiver which will help you trigger some action when 1hr or a certain time has passed from the locally stored time when app exited.
If you want to know how to handle programmatically when and how to exit the app , please refer this answer.
You could also try to use the Android alarm system. Once the user exit your application, you could set up an Alarm. Something like:
YourActivityOrFragment.java
#Override
protected void onStop() {
Calendar c = Calendar.getInstance();
c.setTimeInMillis(System.currentTimeMillis());
c.add(Calendar.HOUR,1);
scheduleAlarm(c.getTimeInMillis());
}
private void scheduleAlarm(long time) {
Intent yourIntent = new Intent("Some_ID");
PendingIntent pi = PendingIntent.getBroadcast(YourClass.this, ALARM_ID, yourIntent, PendingIntent.FLAG_CANCEL_CURRENT);
// Put some extras here, if you need so. Like:
// yourIntent.putExtra("field","value");
AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP,time,pi);
}
Now, create a BroadcastReceiver to handle those alarms.
AlarmReceiver.java
public class AlarmReceiver extends BroadcastReceiver {
private static final String LOG_TAG = AlarmReceiver.class.getSimpleName();
#Override
public void onReceive(Context context, Intent intent) {
Log.d(LOG_TAG, "Alarm fired!");
Intent it = new Intent(context, YourNotificationHandler.class);
// Get your Extras here. And do whatever you want, if you need.
// For what you said, there's no need to start an Activity, so let's handle that alarm as a service.
context.startService(it);
// But if for some reason you want to start an Activity, just do it like:
// context.startActivity(it);
}
}
On your AndroidManifest.xml declare your BroadcastReceiver.
<receiver android:name=".AlarmReceiver" >
<intent-filter>
<action android:name="Some_ID" />
<category android:name="android.intent.category.default" />
</intent-filter>
</receiver>
And last of all, create your service to handle your notifications, you could try something like an IntentService. On that file, you'll have a onHandleIntent(Intent intent) method. Get your Intent there, and it's Extras, and do whatever you want to do. Later, just call your Notifications. I've used a utility class on my projects to handle those, but feel free to choose how you'll do that.
Example:
public static void createService(Context context, CharSequence tickerMessage, CharSequence title,
CharSequence message, int icon, int id, Intent intent, long[] pattern, Boolean autoCancel) {
PendingIntent p = PendingIntent.getService(context, 0, intent, 0);
Notification n;
int apiLevel = Build.VERSION.SDK_INT;
if (apiLevel >= 11) {
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setContentTitle(title)
.setTicker(tickerMessage)
.setContentText(message)
.setSmallIcon(icon)
.setContentIntent(p)
.setPriority(NotificationCompat.PRIORITY_DEFAULT);
if (pattern.length > 0) {
builder.setVibrate(pattern);
}
if (autoCancel != null) {
builder.setAutoCancel(autoCancel);
}
if (apiLevel >= 17) {
// Android 4.2+
n = builder.build();
}
else {
// Android 3.x
n = builder.getNotification();
}
}
else {
// Android 2.2+
n = new Notification(icon, tickerMessage, System.currentTimeMillis());
// Data
n.setLatestEventInfo(context, title, message, p);
}
NotificationManager nm = (NotificationManager)
context.getSystemService(Activity.NOTIFICATION_SERVICE);
nm.notify(id, n);
}
You can read more about alarms here.
More on Service here.
BroadcastReceiver here.
Notifications, here and here.
And this might be an interesting read about Notification as well.
I have created a big view style notification in a service
I intend to put a button that will pass some info back to the activity but it seems the activity just can't get the extras I set before.
Here's the code that I used to show the notification:
public class TestService extends Service {
...
#Override
public void onCreate() {
showNotification();
}
private void showNotification() {
PendingIntent contentIntent = PendingIntent.getActivity(this, 0,
new Intent(this, TestActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
Intent discardIntent = new Intent(this, TestActivity.class);
discardIntent.putExtra("piAction", "discard");
PendingIntent piDiscard = PendingIntent.getActivity(this, 0, discardIntent, PendingIntent.FLAG_CANCEL_CURRENT);
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
mBuilder.setSmallIcon(R.drawable.ic_launcher);
mBuilder.setContentTitle("Test Notification");
mBuilder.addAction(R.drawable.content_discard, "Discard", piDiscard);
mBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText("Test service is running"));
mBuilder.setContentIntent(contentIntent);
Notification notification = mBuilder.build();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
mNotificationManager.notify(0, notification);
}
...
}
And here's the activity that will catch the info sent by the button in notification
public class TestActivity extends Activity {
...
#Override
protected void onResume() {
super.onResume();
Log.i("Activity Resume", "onResume");
Bundle extras = getIntent().getExtras();
if (extras != null) {
Log.i(TAG, "extras not null");
if (extras.containsKey("piAction")) {
Log.i("Intent Received", "piAction");
}
}
}
...
}
Please note, when launching TestActivity, it will also start TestService. What I intend to do is when the discard button inside the notification is clicked, it will pass the previously put extra back to TestActivity. However, after a few tests, I found TestActivity can be launched successfully, but it can't get the extras I set before.
So where's the possible problems in my code?
If you require any other details, please state in the comment, I'll update my question with those details accordingly.
I had face same type of problem when I was passing string from my notification to my launching activity to solve that
1) take a one String e.g. public String temp field in your application extended class
now instead of this
discardIntent.putExtra("piAction", "discard");
use this
YourApplication app = (YourApplication)getApplicationContext();
app.temp = "discard";
in your activity
instead of this
Bundle extras = getIntent().getExtras();
if (extras != null) {
Log.i(TAG, "extras not null");
if (extras.containsKey("piAction")) {
Log.i("Intent Received", "piAction");
}
}
get your piAction status from YourApplication
YourApplication app = (YourApplication)getApplicationContext();
String stringFromNotification = app.temp;
I've just started with Android development. I've created an App Engine connected Android Project in Eclipse by following this guide: Creating an App Engine Connected Android Project.
The app works, but when the task goes to background and then is activated again by receiving a GCM message, intents invoked by the GCMIntentService class do not reach the corresponding activity. What might be the problem?
public class GCMIntentService extends GCMBaseIntentService {
[...]
#Override
public void onMessage(Context context, Intent intent) {
sendNotificationIntent(context, "Message received via Google Cloud Messaging:\n\n" + intent.getStringExtra("message"), true, false);
}
[...]
private void sendNotificationIntent(Context context, String message, boolean isError, boolean isRegistrationMessage) {
Intent notificationIntent = new Intent(context, RegisterActivity.class);
notificationIntent.putExtra("gcmIntentServiceMessage", true);
notificationIntent.putExtra("registrationMessage", isRegistrationMessage);
notificationIntent.putExtra("error", isError);
notificationIntent.putExtra("message", message);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(notificationIntent);
}
[...]
}
Thanks in advance!
// add permission <uses-permission android:name="android.permission.WAKE_LOCK" />
#Override
public void onMessage(Context context, Intent intent) {
sendNotificationIntent(context, "Message received via Google Cloud Messaging:\n\n" + intent.getStringExtra("message"), true, false);
context.sendBroadcast(intent) ;
}
private void sendNotificationIntent(Context context, String message, boolean isError, boolean isRegistrationMessage) {
Intent notificationIntent = new Intent(context, RegisterActivity.class);
notificationIntent.putExtra("gcmIntentServiceMessage", true);
notificationIntent.putExtra("registrationMessage", isRegistrationMessage);
notificationIntent.putExtra("error", isError);
notificationIntent.putExtra("message", message);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
NotificationManager notificationManager =
(NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = neNotification(R.drawable.ic_launcher,"Title",System.currentTimeMillis());
PendingIntent intents = PendingIntent.getActivity(context, 0, notificationIntent, Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
notification.setLatestEventInfo(context , context.getString(R.string.app_name), tickerText , intents );
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notificationManager.notify(100, notification);
}
public class AppBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if(intent.getAction() == "AppReceiver") {
// this intent is gcminit intent and you can get data from this Intent
}
}
}
// in menifest file
<receiver android:name="AppBroadcastReceiver" >
<intent-filter>
<action android:name="AppReceiver" >
</action>
</intent-filter>
</receiver>
If the activity is in background then the intent is receive in onNewIntent which will be called before onResume, thus you have to override onNewIntent
#Override
protected void onNewIntent(Intent intent)
{
super.onNewIntent(intent);
boolean b = intent.getBooleanExtra("gcmIntentServiceMessage", false);
........
}
Issue almost solved... had to add:
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
There is only one problem left: onNewIntent() is still not fired when activity is brought to front by a GCM message. I put the code in onCreate() instead.
I did not find an answer to this question.
I have a VOIP application. I'm able to add a log about missed calls in the native call-log but the notification is not shown.
Is there a way to ask the device native call log to show the notification?
I would not like to add my own notification because I want to be sure that the icon is always that one that the native call-log application would show for other calls.
I found this but there is no answer.
I'm using a code that is similar to that one shown in the previous post.
Just for clarity:
You can still add your own notification, but use the android system build-in icons - these are the same icons that the built-in phonecall app is using. For example:
Notification notification = new Notification();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.icon = android.R.drawable.stat_notify_missed_call;
This way you will always display the icon that's characteristic for the specific Android OS version.
For more information check out the Icon Guidelines, and especially in your case -the status bar icons.
If you are just adding an entry in the call log db the notificatin will not be shown.
You need to add your on notification.
If you do not add your own notification, a notification will be shown only at phone start up if the call log is still there.
This is my implementation (mainly copied from the android code):
private static void showMissedCallNotification(Context context, final Contact contact) {
notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// display the first line of the notification:
// 1 missed call: call name
// more than 1 missed call: <number of calls> + "missed calls"
int titleResId;
String expandedText;
numberMissedCalls++;
if (numberMissedCalls == 1) {
titleResId = R.string.notification_missedCallTitle;
expandedText = contact.getDisplayName();
} else {
titleResId = R.string.notification_missedCallsTitle;
expandedText = context.getString(R.string.notification_missedCallsMsg,
numberMissedCalls);
}
final PendingIntent callLogIntent = createCallLogIntent(context);
// make the notification
int id = android.R.drawable.stat_notify_missed_call;
String ticker = context.getString(R.string.notification_missedCallTicker, contact.getDisplayNumber());
long currentTime = Platform.timeProvider().getTime();
Notification note = new Notification(id, ticker, currentTime);
note.setLatestEventInfo(context, context.getText(titleResId), expandedText, callLogIntent);
note.flags |= Notification.FLAG_AUTO_CANCEL;
// This intent will be called when the notification is dismissed.
// It will take care of clearing the list of missed calls.
note.deleteIntent = createClearMissedCallsIntent(context);
//configureLedNotification(note);
notificationManager.notify(MISSED_CALL_NOTIFICATION, note);
}
/**
* Returns an intent to be invoked when the missed call notification is clicked.
* #param context
*/
private static PendingIntent createCallLogIntent(Context context) {
Intent intent = new Intent(context, ClearMissedCallsService.class);
intent.setAction(ClearMissedCallsService.ACTION_OPEN_CALL_LOGS);
return PendingIntent.getService(context, 0, intent, 0);
}
/**
* Returns an intent to be invoked when the missed call notification is cleared.
* #param context
*/
private static PendingIntent createClearMissedCallsIntent(Context context) {
Intent intent = new Intent(context, ClearMissedCallsService.class);
intent.setAction(ClearMissedCallsService.ACTION_CLEAR_MISSED_CALLS);
return PendingIntent.getService(context, 0, intent, 0);
}
/*package */ static void cancelMissedCallNotification() {
// reset the number of missed calls to 0.
numberMissedCalls = 0;
notificationManager.cancel(MISSED_CALL_NOTIFICATION);
}
and:
/**
* Handles the intent to clear the missed calls that is triggered when a notification is dismissed.
*/
public class ClearMissedCallsService extends IntentService {
/** This action is used to clear missed calls. */
public static final String ACTION_CLEAR_MISSED_CALLS = "com.android.phone.intent.CLEAR_MISSED_CALLS";
public static final String ACTION_OPEN_CALL_LOGS = "com.android.phone.intent.OPEN_CALL_LOGS";
public ClearMissedCallsService() {
super(ClearMissedCallsService.class.getSimpleName());
}
#Override
public void onCreate() {
super.onCreate();
}
#Override
protected void onHandleIntent(Intent intent) {
// Clear the list of new missed calls.
ContentValues values = new ContentValues();
values.put(Calls.NEW, 0);
StringBuilder where = new StringBuilder();
where.append(Calls.NEW);
where.append(" = 1 AND ");
where.append(Calls.TYPE);
where.append(" = ?");
getContentResolver().update(Calls.CONTENT_URI, values, where.toString(),
new String[]{ Integer.toString(Calls.MISSED_TYPE) });
NativeCallLog.cancelMissedCallNotification();
if (ACTION_OPEN_CALL_LOGS.equals(intent.getAction())) {
Intent intentOpenCallLogs = createOpenCallLogIntent();
startActivity(intentOpenCallLogs);
}
}
private static Intent createOpenCallLogIntent() {
Intent intent = new Intent(Intent.ACTION_VIEW, null);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setType("vnd.android.cursor.dir/calls");
return intent;
}
}
you also need to add this in the AndroidManifest
<service
android:exported="true"
android:name="yourpackage.ClearMissedCallsService" >
<intent-filter >
<action android:name="com.android.phone.intent.CLEAR_MISSED_CALLS" />
</intent-filter>
<intent-filter >
<action android:name="com.android.phone.intent.OPEN_CALL_LOGS" />
</intent-filter>
</service>