I am building out a media player for Android Auto and struggling to make a simple Toast Message that appears on the Automotive Display Head Unit.
In my Custom Actions, I have an action that needs to display a toast message on the Car interface, but when I implement the toast it instead only shows on the handheld device/phone.
I have searched the internet high and low, and can not find anything about displaying toasts on the Car Head Unit, even though it is listed in the Android Auto Design guide:: https://designguidelines.withgoogle.com/android-auto/android-auto/app-ui.html#app-ui-drawer
could someone please point me to an example for giving visual feedback or toasts on the Android Auto Platform?
You cannot.
If you have a look at the following question: Develop an Android Auto custom app I have shared a jar which allows you to use some of the un-offical Android Auto SDK from there you can import this:
import com.google.android.apps.auto.sdk.CarToast;
import com.google.android.apps.auto.sdk.notification.CarNotificationExtender;
However even if you import the classes and use the CarToast like this:
CarToast.makeText(context,"SPEED CAMERA: " + text, Toast.LENGTH_LONG).show();
it will only display the toast on the phone screen not on the projected screen.
So to display a message correctly you will need to do something like this:
CarToast.makeText(context,"SPEED CAMERA: " + text, Toast.LENGTH_LONG).show();
CarNotificationExtender paramString2 = new CarNotificationExtender.Builder()
.setTitle(title)
.setSubtitle(text)
.setShouldShowAsHeadsUp(true)
.setActionIconResId(R.drawable.ic_danger_r)
.setBackgroundColor(Color.WHITE)
.setNightBackgroundColor(Color.DKGRAY)
.setThumbnail(bmp)
.build();
NotificationCompat.Builder mynot = new NotificationCompat.Builder(context)
.setContentTitle(title)
.setContentText(text)
.setLargeIcon(bmp)
.setSmallIcon(R.drawable.ic_danger_r)
.setColor(Color.GRAY)
.extend(paramString2);
mNotifyMgr.notify(1983,mynot.build());
This will show a toast which will only be visible on the phone screen and it will show a heads-up notification which will only be visible on the car's screen. Since there is no action attached to it, nothing will happen if the use interacts with it the notification.
If the phone is connected to the car the phone's screen will be turned off anyway so displaying Toast there will be ignored.
The problem with all this is that since it's an unofficial jar and the SDK is not available to the public you won't be able to publish the app on PlayStore :(, that being said I only tried to publish complete apps, but an app which just display notification might pass through the filter.
Related
I have made an android app (Android Studio / Java) that checks a website for content and stores it in an sqlite DB. If new content is fetched that is not stored in DB, it shows a notification with the new content for user to notice.
That's working fine, although if user does not read/open/dismiss that notification, the next notification will update current one and replace its content with new data. This is wanted behavior, because I don't want the user to receive many notifications for the same thing, so I'm using the same notification id.
This introduces a problem though, if user checks the notification now, he will see the second fetched data, but won't be aware of the existence of the first fetched data.
So, what I'm trying to do is to append to the notification's content, so that both first and second fetched data are shown.
I tried the "inboxStyle" notifications that allow for new lines to be added, but it seems to be working only for setting many lines at the time notification is created and not for appending lines to an existing notifications.
I know that I can do that by storing what user has seen and what not, whether a notification was opened, etc, but this seems too much hassle for a simple thing, there must be an easier way to achieve it.
The expected behavior would be to either be able to append the message of existing notifications, or be able to fetch the message of an existing notification (by id) and then manually append to it and push the updated notification.
If that's not clear enough, the expected outcome is:
Issue the first notification with message "Test message 1"
Issue second notification using the same notification-id with message "Test message 2" that would NOT overwrite "Test message 1" but rather keep that message and append to it, so that the notification's message would now be "Test message 1 {newline-here} Test message 2" (or even better reversed so that the last message is shown on top).
Thank you in advance!
I was looking for a solution myself. I managed to do something that works but I'm quite sure there are other elegant solutions : I'm checking whether or not similar notification has been displayed. If so, I get the previous content and append it to the new notification content before publishing.
First, make sure that the notifications you want to assemble have the same uniqueID
This way, when you receive your 2nd, 3rd notification, you can easily match the one you are creating with the ones already displayed.
Note : This code works only on API 23 and higher.
String message = null;
if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
StatusBarNotification[] notifications = mNotificationManager.getActiveNotifications();
for (StatusBarNotification notification: notifications) {
if (notification.getId() == uniqueID) {
// You have a match
Bundle extras = notification.getNotification().extras;
message = extras.getCharSequence(Notification.EXTRA_TEXT).toString();
break;
}
}
}
The easy part : Now that you have the previous notification text, you have to append it to the new notification text before publishing
String newMessage = message + remoteMessage.getData.get("text");
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getApplicationContext(),
channelID)
.setStyle(new NotificationCompat.BigTextStyle().bigText(newMessage))
.setContentTitle("Title")
.setContentText(notification.getMessage())
.setAutoCancel(true);
When I use WhatsApp or Telegram and receive N messages, the notification on Android will show "N new messages" (and it can be expanded).
Telegram shows notification with contentText "7 new messages" on Android. I have achieved this successfully.
However, on my Pebble Time, the last notification is the string of the last message, not "7 new messages".
On Pebble, it shows the 7th (last) message (the censored part is phone number). This is what I want.
I am trying to develop similar feature but have not succeeded. The notification on my Android displays correctly ("N new messages") but on Pebble Time, it's identical (also "N new messages", I want it to be the Nth message).
My app on Pebble. This is NOT what I want.
I have tried to call .notify twice (one contains "N new messages" and the other contains last message) and immediately .cancel the latter but Pebble Time only shows the first one.
If I don't call .cancel on the second notification, my Pebble will show what I want BUT there will be 2 notifications on both Android and Pebble (which I don't want).
How do I achieve similar feature like WhatsApp and Telegram?
Update:
This is the snippet I use (I have used different notification ID)
NotificationCompat.Builder nb = new NotificationCompat.Builder();
...
nb.setContentText("2 new messages");
notificationManager.notify(1, nb.build());
nb.setContentText("B");
notificationManager.notify(2, nb.build());
notificationManager.cancel(2);
Because you use same id for two notification item. you can try with different id for each show notification item.
From Android docs: https://developer.android.com/reference/android/app/NotificationManager.html#notify(int, android.app.Notification)
id: An identifier for this notification unique within your
application.
In Lollipop and below, you could easily send a sound only notification by omitting the icon, content title and content text when constructing, like so:
NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext());
builder.setSound(Uri.parse(ringtone));
notificationManager.notify(9998, builder.build());
In Marshmallow, I'm forced to include at least an icon, or I get a 'no valid small icon' exception. I want to use the Notification system, but don't always want to display a notification in the notification bar. Is this possible with Marshmallow, or should I change to playing my notification sound with media player, even though sometimes I, or the user, may want to display a notification?
I read somewhere that the docs said icon was required even thought it didn't throw an exception when omitted in Lollipop and below. After looking into using MediaPlayer, I finally decided to use RintoneManager to play it. I am using the notification sounds, so may as well save myself some typing and do a quick
try {
RingtoneManager.getRingtone(getApplicationContext(), Uri.parse(ringtone)).play();
} catch (Exception e) {
e.printStackTrace();
}
to trigger the sound, I'll save the notification for when I need an actual notification. I was already planing on using if, depending on whether or not the notification should appear in the notification bar.
On Android L, I would like show the user a notification on the lock screen only if the user settings is set to "show all notification content", otherwise the content will be pointless and I just prefer not to show the notification at all.
Any idea how to verify in code the user notification settings?
Thanks!
You need to read
Settings.Secure.LOCK_SCREEN_ALLOW_PRIVATE_NOTIFICATIONS = "lock_screen_allow_private_notifications"
Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS = "lock_screen_show_notifications"
only if both are 1 then you need to show your notifications.
But since these values are not part of public api, these might change in future, or might not work on all devices
int show_all = Settings.Secure.getInt(getContentResolver(),"lock_screen_allow_private_notifications", -1);
int noti_enabled = Settings.Secure.getInt(getContentResolver(),"lock_screen_show_notifications", -1);
if(show_all > 0 && noti_enabled > 0){
//post noti
}
You can't check that setting as far as I know, but your app can control the level of detail visible when its notifications are displayed over the secure lock screen. To control the visibility level, call setVisibility() (Notification.Builder.setVisibility) and specify one of these values:
VISIBILITY_PUBLIC: Shows the notification’s full content.
VISIBILITY_PRIVATE: Shows basic information, such as the notification’s icon, but hides the notification’s full content.
VISIBILITY_SECRET: Shows nothing, excluding even the notification’s icon.
When the visibility level is VISIBILITY_PRIVATE, you can also provide a redacted version of the notification content that hides personal details. For example, an SMS app might display a notification that shows "You have 3 new text messages" but hides the message content and senders. To provide this alternative notification, first create the replacement notification using Notification.Builder. When you create the private notification object, attach the replacement notification to it through the setPublicVersion() method.
Sources
I am making an extension for my android app. I can get the notification to android wear without a problem with all the data I want. I have lat and long for every POI for which im sending a notification, and i want to add a feature "Navigate to" inside android wear notification, that would take this coordinates and ran a google navigation on smart watch.
Is this possible? Can u provide some example or documentation.
Thanks
This is a sample code that i use in my app for running google maps on phone by clicking "Open on map" button on my android wear.
Intent mapIntent = new Intent(Intent.ACTION_VIEW);
Uri geoUri = Uri.parse("geo:0,0?q=" + chapter.getLatitude() + "," + chapter.getLongitude());
mapIntent.setData(geoUri);
PendingIntent mapPendingIntent =
PendingIntent.getActivity(context, 0, mapIntent, 0);
...
.addAction(R.drawable.ic_map_white_24dp, "Open on map", mapPendingIntent)
as far as I understand what you are trying to do, you already reached your goal. Once you are able to start navigation on your phone, it will be automatically displayed on your watch as a notification card which appears at the bottom of your watchface.
I'm currently developing an application where I'm doing the same thing except I'm using CardFragments for triggering the action instead of using Wearable Notifications and PendingIntents. When I press the action button of the CardFragment displayed on my watch, I'm sending a Wearable Message to my Phone App which runs the following code when it receives this particular message.
String uri = "google.navigation:q=" + String.valueOf(latitude) + "," + String.valueOf(longitude);
Intent mapsIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(uri));
mapsIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(mapsIntent);
I have to set the FLAG_ACTIVITY_NEW_TASK because the code is part of a method of a normal java class. Everything works fine when the screen of the phone is unlocked and screen is turned on. However, navigation should also start when the phone is locked. This is where I'm currently struggling with.