Android Auto notification not showing - android

I'm attempting to show a notification through Android Auto. The notification does show on my phone. However, it is not showing on Android Auto emulator. This is a media application.
automotvie_app_desc.xml:
<automotiveApp>
<uses name="media"/>
</automotiveApp>
This code is in my MediaBrowserService class:
private Notification postNotification(AutoNotificationHelper.Type type) {
Log.d(TAG, "Post Notification");
Notification notification = AutoNotificationHelper.createMenuErrorNotification(
getApplicationContext(), type, mSession);
if (notification != null) {
mNotificationManager.notify(TAG, NOTIFICATION_ID, notification);
}
return notification;
}
Here is where the notification is created:
static Notification createMenuErrorNotification(Context context, Type type,
MediaSessionCompat mediaSession) {
MediaControllerCompat controller = mediaSession.getController();
MediaMetadataCompat mMetadata = controller.getMetadata();
PlaybackStateCompat mPlaybackState = controller.getPlaybackState();
if (mMetadata == null) {
Log.e(TAG, "MetaData is null");
}
if (mPlaybackState == null) {
Log.e(TAG, "Playback state is null");
}
if (type.equals(Type.MENU_ERROR)) {
Bitmap icon = BitmapFactory.decodeResource(context.getResources(), R.drawable.error);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(context.getApplicationContext());
notificationBuilder.extend(new android.support.v4.app.NotificationCompat.CarExtender())
.setStyle(new NotificationCompat.MediaStyle()
.setMediaSession(mediaSession.getSessionToken()))
.setSmallIcon(R.drawable.error)
.setShowWhen(false)
.setContentTitle(context.getString(R.string.title))
.setContentText(context.getString(R.string.message))
.setLargeIcon(icon)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
return notificationBuilder.build();
}
return null;
}
What am I missing to get this to show on the auto display and not on the phone?

NotificationCompat.CarExtender seems to be an option only for app declare as "notification" (message read and response feature for a messaging app for example).
<automotiveApp>
<uses name="notification"/>
</automotiveApp>
Display notification on home in "Auto" context with a "media" automotiveApp seems not allowed in actual api version.
For an error message associated to a media playing app (like it seems to be in your case) you can use error state which will be interpreted and displayed directly by Auto system.
private void showErrorMessage(final int errorCode, final String errorMessage) {
final PlaybackStateCompat.Builder playbackStateBuilder = new PlaybackStateCompat.Builder();
playbackStateBuilder.setState(PlaybackStateCompat.STATE_ERROR, -1L, 1.0F);
playbackStateBuilder.setErrorMessage(errorCode, errorMessage);
mSession.setPlaybackState(playbackStateBuilder.build());
}

Try this code to show the notification,
private void showPushNotification(String title, String message, Intent tapIntent, int notificationID) {
android.support.v7.app.NotificationCompat.Builder builder = new android.support.v7.app.NotificationCompat.Builder(this);
builder.setSmallIcon(R.drawable.swiftee_white_logo_notification);
//Intent tapIntent = new Intent(this, HomeScreenActivity.class);
//tapIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
//tapIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
//tapIntent.putExtra(AppConstants.PUSH_MESSAGE, true);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, tapIntent, PendingIntent.FLAG_ONE_SHOT);
builder.setContentIntent(pendingIntent);
builder.setAutoCancel(true);
builder.setContentTitle(title);
builder.setContentText(message);
NotificationManager notificationManager = (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(notificationID, builder.build());
}

Please follow step by step from here
This sample demonstrate full demo
EDIT
For Media Notification you can use this . Here step by step explained about media app and notification for auto

Related

Custom notification is not shown when using `startForeground` on Android O

I want to run background location service. It works more or less, however - instead of my custom notification with text and content intent, generic notification is shown. Why is that?
I am using Nexus API 28 emulator.
Service starting method:
private void moveToRunningState() {
Intent serviceStartIntent = new Intent(getApplicationContext(), this.getClass());
int requestId = 1;
Intent goToMainScreenIntent = new Intent(getApplicationContext(), MainActivity.class);
serviceStartIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent onTapIntent = PendingIntent.getActivity(getApplicationContext(), requestId, goToMainScreenIntent, 0);
Notification.Builder builder = NotificationUtils.notificationBuilderO(this);
builder.setContentTitle("Location tracking is running");
builder.setContentText("Your location is beeing sent to the server so it can be shown on map");
builder.setFullScreenIntent(onTapIntent, true);
builder.setProgress(0,100,true);
if (NotificationUtils.isPreAndroidO()) {
Log.d(TAG, "moveToStartedState: Running on Android N or lower - startService(intent)");
startService(serviceStartIntent);
} else {
Log.d(TAG, "moveToStartedState: Running on Android O - startForegroundService(intent)");
startForegroundService(serviceStartIntent);
}
startForeground(1, builder.build());
Log.i(TAG, "Service moved to start state");
isRunning = true;
}
Just in case, builder creation
public static Notification.Builder notificationBuilderO(Context ctx) {
NotificationManager notificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
NotificationChannel notificationChannel = new NotificationChannel(UUID.randomUUID().toString(), "Geoloc channel", NotificationManager.IMPORTANCE_DEFAULT);
notificationManager.createNotificationChannel(notificationChannel);
Notification.Builder builder = new Notification.Builder(ctx, notificationChannel.getId());
return builder;
and actual result:
As usual, I had to post question on SO only to find answer myself seconds afterwards.
The problem is, that I am not setting notification icon. I have tried to show the same notification using NotificationManager and it failed with explainatory exception saying that this icon is not set. This exception is not shown in logs in my case when using startForeground
All in all, setting icon fixes the issue.

permanent notification does not show

I submitted my app at the end of 2017 in the play store and it worked.
Then it was built in Eclipse.
Now I run it in Android Studio and the same code doesn't show any notification.
It is a permanent notification which is present after I call the app's finish() method. (why I do this: see at the bottom if you want to know).
So I looked at all the examples and NONE of the work. No single notification is shown.
So I start an activity and in the activity I show the notification. Then I call finish().
This is my code:
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
intent, 0);
CharSequence connectedPart = getResources().getString(R.string.app_name);
String melding = "";
melding = getResources().getString(R.string.screentimeoutsetto) + " " + newTimeString + ".";
NotificationManager notificationManager = (NotificationManager) this
.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = new Notification.Builder(this)
.setContentTitle(connectedPart)
.setTicker(connectedPart)
.setContentText(melding)
.setSmallIcon(R.drawable.ic_stat_name)
.setContentIntent(pendingIntent)
.setOngoing(true)
.build();
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.flags |= Notification.FLAG_NO_CLEAR;
notificationManager.notify(2, notification);
dependencies:
dependencies{
implementation "com.android.support:support-compat:26.1.0"
}
Why I do this:
My app does 1 thing: toggle the screentimeout. So when you start it it sets the screentimeout to 30 minutes (starts, sets a notification, then finish()). Start again, it removes the notification and restore the original value for the screen timeout.
Starting with Android Oreo, all notifications require a notification channel, otherwise the notification wont post and an error will appear in your logcat. Here's an example of how you can do it, lifted from one of my apps:
private static void createNotificationChannel(Context ctx) {
if(SDK_INT < O) return;
final NotificationManager mgr = ctx.getSystemService(NotificationManager.class);
if(mgr == null) return;
final String name = ctx.getString(R.string.channel_name);
if(mgr.getNotificationChannel(name) == null) {
final NotificationChannel channel =
new NotificationChannel(CHANNEL_ID, name, IMPORTANCE_DEFAULT);
mgr.createNotificationChannel(channel);
}
}
//Usage...
createNotificationChannel(context);
NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID);
builder.setSmallIcon(R.drawable.ic_alarm_white_24dp);
//etc...
manager.notify(id, builder.build());
Now from Android 8.0 and onward you need to create notification channel before showing notifications. Here is the Docs link
https://developer.android.com/training/notify-user/channels

I want to show notification even if my Android app is running

I am using AWS SNS to send push notification to both SNS topics and Device Endpoints. It shows notification if the app is not running but does not show notification while the app is running.
I will like to show notification even if the app is running because the notification will inform the app user of changes happening in another section of the app so they can go check it out when they are ready. Something like getting notification of a new Whatsapp message from another group chat while you are typing message to another person.
Below is the notification builder code. Any hint will be really appreciated. Thanks.
private void displayNotification(final String message) {
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
int requestID = (int) System.currentTimeMillis();
PendingIntent contentIntent = PendingIntent.getActivity(this, requestID, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap large_icon = BitmapFactory.decodeResource(this.getResources(),
R.mipmap.myImage);
// Display a notification with an icon, message as content, and default sound. It also
// opens the app when the notification is clicked.
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setLargeIcon(large_icon)
.setContentTitle("My Subject Title")
.setContentText(message)
.setDefaults(Notification.DEFAULT_SOUND)
.setAutoCancel(true)
.setContentIntent(contentIntent);
NotificationManager notificationManager = (NotificationManager) getSystemService(
Context.NOTIFICATION_SERVICE);
notificationManager.notify(0, builder.build());
}
I found the problem.
#Override
public void onMessageReceived(final String from, final Bundle data) {
String message = getMessage(data);
Log.d(LOG_TAG, "From: " + from);
Log.d(LOG_TAG, "Message: " + message);
// Display a notification in the notification center if the app is in the background.
// Otherwise, send a local broadcast to the app and let the app handle it.
displayNotification(message);
/* if (isForeground(this)) {
// broadcast notification
broadcast(from, data);
} else {
displayNotification(message);
} */
}
my displayNotification() function was not called because of the "if" conditional statement that will only display notification if the application is not in foreground. So now when onMessageReceived() gets the message it passes it directly to displayNotification() even if my application is currently running, which is what I want.
Use this below code to show notification message.
private static void generateNotification(Context context, final String message)
{
try {
NotificationManager mNotificationManager = (NotificationManager)
context.getSystemService(Context.NOTIFICATION_SERVICE);
//Define sound URI
Uri soundUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
Intent notificationIntent = new Intent(context, DemoActivity.class);
notificationIntent.putExtra("message", message);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
PendingIntent contentIntent = PendingIntent.getActivity(context, RandomNumberGenerator.getRandom(),notificationIntent
/*new Intent(context, LuncherActivity.class)*/, 0);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context);
mBuilder.setSmallIcon(R.drawable.icon_small);
mBuilder.setContentTitle("YOUR-APP-NAME");
// mBuilder.setStyle(new NotificationCompat.BigTextStyle()
// mBuilder.bigText(msg);
mBuilder.setContentText(message);
mBuilder.setAutoCancel(true);
mBuilder.setContentIntent(contentIntent);
mBuilder.setSound(soundUri);
mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
}
Create a random number genetor class like below
public class RandomNumberGenerator {
public static int getRandom()
{
int random_number=0;
Random random = new Random();
random_number= random.nextInt(9999 - 1000) + 1000;
return random_number;
}
}
Try it and let me know.its working in my case.

Do not show notification if it is already shown

In my application I want show a notification in some cases.
When notification is active I do not want to create notification again.
I have activity recognition in my app and when it's detected that I am in car it starts to sound notification every second.
How could I prevent a new build notification if there is at least one active notification there?
Here is my code what I tried:
Intent closeIntent;
Intent showIntent;
if (isStart){
closeIntent = new Intent(this, SwitchButtonListener1.class);
} else {
closeIntent = new Intent(this, SwitchButtonListener2.class);
}
closeIntent.setAction("No");
PendingIntent pendingIntentClose = PendingIntent.getBroadcast(this, 0,
closeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action closeAction = new NotificationCompat.Action(R.drawable.btn_close_gray, "No", pendingIntentClose);
if (isStart){
showIntent = new Intent(this, SwitchButtonListener1.class);
} else {
showIntent = new Intent(this, SwitchButtonListener2.class);
}
showIntent.setAction("Yes");
PendingIntent pendingIntentShow = PendingIntent.getBroadcast(this, 0,
showIntent, PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Action showAction = new NotificationCompat.Action(R.drawable.ic_tick, "Yes", pendingIntentShow);
Uri alarmSound = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
.setWhen(System.currentTimeMillis())
.setAutoCancel(true)
.setSmallIcon(R.drawable.ic_stat_milebox)
.setContentTitle(title)
.setContentText(message)
.addAction(showAction)
.addAction(closeAction);
builder.setSound(alarmSound);
NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.notify(100, builder.build());
Though it is an old question, but I think this answer might help others in the future:
In a case like this, when the user needs to be notified only once and the event is ongoing then using .setOnlyAlertOnce(true) and setOngoing(true) with the builder will solve the problem.
Documentation:
setOnlyAlertOnce(true): Set this flag if you would only like the sound, vibrate and ticker to be played if the notification is not already showing.
setOngoing(true): Set whether this is an ongoing notification. Ongoing notifications cannot be dismissed by the user, so your application or service must take care of canceling them. They are typically used to indicate a background task that the user is actively engaged with (e.g., playing music) or is pending in some way and therefore occupying the device (e.g., a file download, sync operation, active network connection).
Notification notification = new NotificationCompat.Builder(this, notificationChannel.getId())
.....
.....
.setOngoing(true)
.setOnlyAlertOnce(true)
.....
.....
.build();
Objects.requireNonNull(notificationManager).notify(notificationId, notification);
You can try the following as a sketch:
public class MediaNotificationManager extends BroadcastReceiver {
private final NotificationManager mNotificationManager;
private Context ctx;
private boolean mStarted = false;
public MediaNotificationManager(Context ctx) {
mCtx = ctx;
mNotificationManager = (NotificationManager) ctx.getSystemService(Context.NOTIFICATION_SERVICE);
// Cancel all notifications to handle the case where the Service was killed and
// restarted by the system.
mNotificationManager.cancelAll();
}
/**
* Posts the notification and starts tracking the session to keep it
* updated. The notification will automatically be removed if the session is
* destroyed before {#link #stopNotification} is called.
*/
public void startNotification() {
if (!mStarted) {
// The notification must be updated after setting started to true
Notification notification = createNotification();
if (notification != null) {
mStarted = true;
}
}
}
/**
* Removes the notification and stops tracking the session. If the session
* was destroyed this has no effect.
*/
public void stopNotification() {
if (mStarted) {
mStarted = false;
try {
mNotificationManager.cancel(NOTIFICATION_ID);
} catch (IllegalArgumentException ex) {
// ignore if the receiver is not registered.
}
}
}
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
LogHelper.d(TAG, "Received intent with action " + action);
switch (action) {
//do something with this.
}
}
private Notification createNotification() {
//create and return the notification
}
}
For a bit more read this:
I also used this notification in my code:
https://github.com/googlesamples/android-UniversalMusicPlayer/blob/master/mobile/src/main/java/com/example/android/uamp/MediaNotificationManager.java

Using Phonegap PushPlugin does not open App when in background and Push Notification arrives

I'm using the Phonegap plugin "PushPlugin" (https://github.com/phonegap-build/PushPlugin) together with Phonegap 2.9.0 for iOS and Android. For iOS everything works as expected: A notification arrives, I click on the notification and the app is started.
On Android, we distinguish between two cases: The app is in foreground (active) or in background (closed or just not actively used). When I receive a notification while in foreground, the plugin works. When I receive a notification while in background, the plugin creates a notification in the notification bar, but tapping on the notification does not open my app.
The relevant code that should open my app is:
// Gets called when the notification arrives
protected void onMessage(Context context, Intent intent) {
Log.d(TAG, "onMessage - context: " + context);
// Extract the payload from the message
final Bundle extras = intent.getExtras();
if (extras != null)
{
final boolean foreground = this.isInForeground();
extras.putBoolean("foreground", foreground);
if (foreground)
PushPlugin.sendExtras(extras);
else
createNotification(context, extras);
}
}
// This creates the notification in the notification bar, but a click on the notification does not open my app
public void createNotification(Context context, Bundle extras)
{
final NotificationManager mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
final String appName = getAppName(this);
final Intent notificationIntent = new Intent(this, PushHandlerActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP);
notificationIntent.putExtra("pushBundle", extras);
final PendingIntent contentIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_UPDATE_CURRENT);
final NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(context)
.setSmallIcon(context.getApplicationInfo().icon)
.setWhen(System.currentTimeMillis())
.setContentTitle(appName)
.setTicker(appName)
.setContentIntent(contentIntent);
final String message = extras.getString("message");
if (message != null) {
mBuilder.setContentText(message);
} else {
mBuilder.setContentText("<missing message content>");
}
final String msgcnt = extras.getString("msgcnt");
if (msgcnt != null) {
mBuilder.setNumber(Integer.parseInt(msgcnt));
}
mNotificationManager.notify(appName, NOTIFICATION_ID, mBuilder.build());
tryPlayRingtone();
}
I thought it was a problem similar to https://github.com/phonegap-build/PushPlugin/issues/35#issuecomment-24722796, but it was simply an issue with the Android Manifest: The PushPlugin activity was entered with a wrong package.

Categories

Resources