[AA] Working GridView for Android Auto
With this commit we have the first functional version of the AndroidAuto integration.
This commit is contained in:
@@ -15,6 +15,12 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
|
||||
<uses-sdk android:minSdkVersion="32"
|
||||
android:targetSdkVersion="34" />
|
||||
|
||||
<uses-feature
|
||||
android:name="android.software.car.templates_host"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:dataExtractionRules="@xml/data_extraction_rules"
|
||||
@@ -31,6 +37,9 @@
|
||||
android:value="AIzaSyB7C4QCJEBvS7mFa_DeIZdzqe2hddtl-vk" />
|
||||
<meta-data android:name="com.google.android.gms.car.application"
|
||||
android:resource="@xml/automotive_app_desc"/>
|
||||
<meta-data
|
||||
android:name="androidx.car.app.minCarApiLevel"
|
||||
android:value="1" />
|
||||
|
||||
<activity
|
||||
android:name=".FlashlightActivity"
|
||||
@@ -51,7 +60,6 @@
|
||||
tools:ignore="LockedOrientationActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
@@ -71,9 +79,8 @@
|
||||
<service android:name=".auto.ShareLocationCarAppService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="androidx.car.app.action.SERVICE" />
|
||||
<action android:name="androidx.car.app.CarAppService"/>
|
||||
<category android:name="androidx.car.app.category.MESSAGING"/>
|
||||
<category android:name="androidx.intent.category.IOT" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
|
||||
|
||||
@@ -476,6 +476,10 @@ public class ShareLocationActivity extends AppCompatActivity implements OnMapRea
|
||||
|
||||
@Override
|
||||
public void onMapReady(@NonNull final GoogleMap googleMap) {
|
||||
if (googleMap == null) {
|
||||
Log.w(TAG, "onMapReady: Map null, cannot continue");
|
||||
return;
|
||||
}
|
||||
mGmap = googleMap;
|
||||
if (mIsNightMode) {
|
||||
mGmap.setMapStyle(MapStyleOptions.loadRawResourceStyle(this, R.raw.map_style_night));
|
||||
|
||||
@@ -7,8 +7,16 @@ import androidx.car.app.CarAppService;
|
||||
import androidx.car.app.Session;
|
||||
import androidx.car.app.validation.HostValidator;
|
||||
|
||||
/**
|
||||
* The {@link CarAppService} extension to be called upon connection.
|
||||
*/
|
||||
public class ShareLocationCarAppService extends CarAppService {
|
||||
|
||||
/**
|
||||
* Tag for debugging purposes.
|
||||
*/
|
||||
private static final String TAG = "ShareLocationCarAppServ";
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public HostValidator createHostValidator() {
|
||||
@@ -19,7 +27,13 @@ public class ShareLocationCarAppService extends CarAppService {
|
||||
@NonNull
|
||||
@Override
|
||||
public Session onCreateSession() {
|
||||
Log.d(TAG, "onCreateSession: ");
|
||||
return new ShareLocationSession();
|
||||
try {
|
||||
Log.d(TAG, "onCreateSession: ");
|
||||
return new ShareLocationSession();
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "onCreateSession: ", e);
|
||||
return new ShareLocationSession();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,10 +1,5 @@
|
||||
package com.aldo.apps.familyhelpers.auto;
|
||||
|
||||
import static androidx.core.app.NotificationManagerCompat.IMPORTANCE_DEFAULT;
|
||||
|
||||
import static com.aldo.apps.familyhelpers.utils.GlobalConstants.SHARE_LOCATION_CANCEL_ACTION;
|
||||
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.util.Log;
|
||||
|
||||
@@ -17,136 +12,127 @@ import androidx.car.app.Screen;
|
||||
import androidx.car.app.annotations.ExperimentalCarApi;
|
||||
import androidx.car.app.model.CarIcon;
|
||||
import androidx.car.app.model.GridItem;
|
||||
import androidx.car.app.model.GridTemplate;
|
||||
import androidx.car.app.model.ItemList;
|
||||
import androidx.car.app.model.ListTemplate;
|
||||
import androidx.car.app.model.Template;
|
||||
import androidx.car.app.notification.CarAppExtender;
|
||||
import androidx.car.app.notification.CarNotificationManager;
|
||||
import androidx.core.app.NotificationChannelCompat;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
|
||||
import com.aldo.apps.familyhelpers.R;
|
||||
import com.aldo.apps.familyhelpers.workers.LocationHelper;
|
||||
import com.aldo.apps.familyhelpers.workers.ShareLocationBackgroundWorker;
|
||||
|
||||
/**
|
||||
* {@link Screen} implementation to be shown in the Android Auto environment.
|
||||
*/
|
||||
public class ShareLocationScreen extends Screen {
|
||||
|
||||
private static final String AA_NOTIFICATION_CHANNEL = "ShareLocation_AA";
|
||||
|
||||
private static final int AA_NOTIFICATION_ID = 1;
|
||||
|
||||
/**
|
||||
* Tag for debugging purpose.
|
||||
*/
|
||||
private static final String TAG = "ShareLocationScreen";
|
||||
|
||||
/**
|
||||
* {@link LocationHelper} instance to observe the current sharing state.
|
||||
*/
|
||||
private LocationHelper mLocationHelper;
|
||||
|
||||
// Constructor for ShareLocationScreen
|
||||
/**
|
||||
* C'Tor.
|
||||
*
|
||||
* @param carContext The {@link CarContext} this was instantiated in.
|
||||
*/
|
||||
protected ShareLocationScreen(@NonNull CarContext carContext) {
|
||||
super(carContext);
|
||||
Log.d(TAG, "ShareLocationScreen() called with: carContext = [" + carContext + "]");
|
||||
mLocationHelper = LocationHelper.getInstance(getCarContext());
|
||||
}
|
||||
|
||||
|
||||
@ExperimentalCarApi
|
||||
@NonNull
|
||||
@Override
|
||||
public Template onGetTemplate() {
|
||||
Log.d(TAG, "onGetTemplate() called");
|
||||
mLocationHelper = LocationHelper.getInstance(getCarContext());
|
||||
|
||||
final GridItem startItem = new GridItem.Builder()
|
||||
.setTitle(getString(R.string.android_auto_share_location_start))
|
||||
.setText(getString(R.string.android_auto_share_location_start_desc))
|
||||
.setImage(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_start_sharing))
|
||||
.build(), GridItem.IMAGE_TYPE_LARGE)
|
||||
.setImage(getIconForResource(R.drawable.ic_start_sharing), GridItem.IMAGE_TYPE_ICON)
|
||||
.setOnClickListener(this::startLocationShareService)
|
||||
.build();
|
||||
|
||||
final GridItem stopItem = new GridItem.Builder()
|
||||
.setTitle(getString(R.string.android_auto_share_location_stop))
|
||||
.setText(getString(R.string.android_auto_share_location_stop_desc))
|
||||
.setImage(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_stop_sharing))
|
||||
.build(), GridItem.IMAGE_TYPE_LARGE)
|
||||
.setImage(getIconForResource(R.drawable.ic_stop_sharing), GridItem.IMAGE_TYPE_ICON)
|
||||
.setOnClickListener(this::stopLocationSharingService)
|
||||
.build();
|
||||
|
||||
final ItemList itemList = new ItemList.Builder()
|
||||
.setNoItemsMessage("No Items yet, something went wrong I guess")
|
||||
.setNoItemsMessage(getString(R.string.android_auto_share_location_no_items_yet))
|
||||
.addItem(startItem)
|
||||
.addItem(stopItem)
|
||||
.build();
|
||||
|
||||
mLocationHelper.getSharingStateSubject().subscribe(this::createNotification, this::handleError);
|
||||
|
||||
return new ListTemplate.Builder()
|
||||
return new GridTemplate.Builder()
|
||||
.setLoading(false)
|
||||
.setTitle("Share Location")
|
||||
.setTitle(getString(R.string.android_auto_share_location_start_desc))
|
||||
.setSingleList(itemList)
|
||||
.build();
|
||||
}
|
||||
|
||||
private void createNotification(final Boolean isSharing) {
|
||||
Log.d(TAG, "createNotification() called with: isSharing = [" + isSharing + "]");
|
||||
CarNotificationManager notificationManager = CarNotificationManager.from(getCarContext());
|
||||
notificationManager.createNotificationChannel(
|
||||
new NotificationChannelCompat.Builder(AA_NOTIFICATION_CHANNEL, IMPORTANCE_DEFAULT)
|
||||
.build());
|
||||
final PendingIntent serviceIntent;
|
||||
@DrawableRes final int iconId;
|
||||
final String title;
|
||||
if (isSharing) {
|
||||
// Create an intent to start the ShareLocationBackgroundWorker service
|
||||
final Intent stopService = new Intent(getCarContext(), ShareLocationBackgroundWorker.class);
|
||||
stopService.setAction(SHARE_LOCATION_CANCEL_ACTION);
|
||||
serviceIntent = PendingIntent.getService(getCarContext(), 0, stopService, PendingIntent.FLAG_IMMUTABLE);
|
||||
title = getString(R.string.android_auto_share_location_stop);
|
||||
iconId = R.drawable.ic_stop_sharing;
|
||||
} else {
|
||||
// Create an intent to start the ShareLocationBackgroundWorker service
|
||||
final Intent startServiceIntent = new Intent(getCarContext(), ShareLocationBackgroundWorker.class);
|
||||
serviceIntent = PendingIntent.getService(getCarContext(), 0, startServiceIntent, PendingIntent.FLAG_IMMUTABLE);
|
||||
title = getString(R.string.android_auto_share_location_start);
|
||||
iconId = R.drawable.ic_start_sharing;
|
||||
}
|
||||
|
||||
final NotificationCompat.Builder carNotification = new NotificationCompat.Builder(getCarContext(), AA_NOTIFICATION_CHANNEL)
|
||||
.setContentTitle("Share Location")
|
||||
.addAction(iconId, title, serviceIntent)
|
||||
.extend(new CarAppExtender.Builder()
|
||||
.build());
|
||||
|
||||
notificationManager.notify(AA_NOTIFICATION_ID, carNotification);
|
||||
|
||||
/**
|
||||
* Helper method to get an Icon from Resources and tint it into the proper color.
|
||||
*
|
||||
* @param iconId The DrawableId of the icon.
|
||||
*
|
||||
* @return The CarIcon.
|
||||
*/
|
||||
private CarIcon getIconForResource(@DrawableRes final int iconId) {
|
||||
final IconCompat iconCompat = IconCompat.createWithResource(getCarContext(), iconId);
|
||||
iconCompat.setTint(getCarContext().getColor(R.color.md_theme_primary));
|
||||
return new CarIcon.Builder(iconCompat).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to start the location sharing by starting the {@link ShareLocationBackgroundWorker}.
|
||||
*/
|
||||
private void startLocationShareService() {
|
||||
Log.d(TAG, "startLocationShareService: ");
|
||||
if (mLocationHelper != null && mLocationHelper.isCurrentlySharing()) {
|
||||
CarToast.makeText(getCarContext(), "You already are sharing", CarToast.LENGTH_SHORT).show();
|
||||
CarToast.makeText(getCarContext(), R.string.android_auto_share_location_already_sharing,
|
||||
CarToast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
// Create an intent to start the ShareLocationBackgroundWorker service
|
||||
final Intent startServiceIntent = new Intent(getCarContext(), ShareLocationBackgroundWorker.class);
|
||||
final Intent serviceIntent = new Intent(getCarContext(), ShareLocationBackgroundWorker.class);
|
||||
// Start the service using the car context
|
||||
getCarContext().startForegroundService(startServiceIntent);
|
||||
getCarContext().startForegroundService(serviceIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to stop the location sharing by stopping the {@link ShareLocationBackgroundWorker}.
|
||||
*/
|
||||
private void stopLocationSharingService() {
|
||||
Log.d(TAG, "stopLocationSharingService: ");
|
||||
if (mLocationHelper != null && !mLocationHelper.isCurrentlySharing()) {
|
||||
CarToast.makeText(getCarContext(), "You are not sharing", CarToast.LENGTH_SHORT).show();
|
||||
CarToast.makeText(getCarContext(), R.string.android_auto_share_location_not_yet_sharing,
|
||||
CarToast.LENGTH_SHORT).show();
|
||||
return;
|
||||
}
|
||||
// Create an intent to start the ShareLocationBackgroundWorker service
|
||||
final Intent startServiceIntent = new Intent(getCarContext(), ShareLocationBackgroundWorker.class);
|
||||
final Intent serviceIntent = new Intent(getCarContext(), ShareLocationBackgroundWorker.class);
|
||||
// Start the service using the car context
|
||||
getCarContext().stopService(startServiceIntent);
|
||||
getCarContext().stopService(serviceIntent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Helper method to extract a string resource.
|
||||
*
|
||||
* @param stringId The String resource ID.
|
||||
*
|
||||
* @return The unwrapped string.
|
||||
*/
|
||||
private String getString(@StringRes final int stringId) {
|
||||
return getCarContext().getString(stringId);
|
||||
}
|
||||
|
||||
private void handleError(final Throwable error) {
|
||||
Log.e(TAG, "handleErrot: ", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,14 @@ import androidx.annotation.NonNull;
|
||||
import androidx.car.app.Screen;
|
||||
import androidx.car.app.Session;
|
||||
|
||||
/**
|
||||
* The {@link Session} to be started by the CarAppService to show the {@link ShareLocationScreen}.
|
||||
*/
|
||||
public class ShareLocationSession extends Session {
|
||||
|
||||
/**
|
||||
* Tag for debugging purposes.
|
||||
*/
|
||||
private static final String TAG = "ShareLocationSession";
|
||||
|
||||
@NonNull
|
||||
|
||||
@@ -63,9 +63,13 @@
|
||||
<string name="android_auto_actions_start_sharing">Ja, fang an zu teilen</string>
|
||||
<string name="android_auto_actions_stop_sharing">Ja, hör auf zu teilen</string>
|
||||
<string name="android_auto_share_location_start">Start</string>
|
||||
<string name="android_auto_share_location_start_desc">Anfangen den Standort zu teilen</string>
|
||||
<string name="android_auto_share_location_start_desc">Standrot teilen</string>
|
||||
<string name="android_auto_share_location_stop">Stop</string>
|
||||
<string name="android_auto_share_location_stop_desc">Aufhören den Standort zu teilen</string>
|
||||
<string name="android_auto_share_location_stop_desc">Nicht mehr teilen</string>
|
||||
<string name="pref_on_screen_flashlight_custom_color_summary">Wähle eine eigene Farbe für deine Bildschirm-Taschenlampe</string>
|
||||
<string name="flashlight_on_screen_custom_color">Eigene Farbe</string>
|
||||
<string name="android_auto_share_location_no_items_yet">Noch keine Einträge, seltsam...</string>
|
||||
<string name="android_auto_share_location_already_sharing">Du teilst deinen Standort schon</string>
|
||||
<string name="android_auto_share_location_not_yet_sharing">Du teilst deinen Standort noch nicht</string>
|
||||
|
||||
</resources>
|
||||
@@ -62,10 +62,15 @@
|
||||
<string name="android_auto_message_not_sharing">Android Auto start has been detected, do you wanna share your location?</string>
|
||||
<string name="android_auto_actions_start_sharing">Yes, start to share</string>
|
||||
<string name="android_auto_actions_stop_sharing">Yes, stop sharing</string>
|
||||
<string name="android_auto_share_location_start">Start</string>
|
||||
<string name="android_auto_share_location_start_desc">Start to share location</string>
|
||||
<string name="android_auto_share_location_start_desc">Share Location</string>
|
||||
<string name="android_auto_share_location_stop">Stop</string>
|
||||
<string name="android_auto_share_location_stop_desc">Stop to share the location</string>
|
||||
<string name="android_auto_share_location_stop_desc">Stop Sharing</string>
|
||||
<string name="android_auto_share_location_start">Start</string>
|
||||
<string name="pref_on_screen_flashlight_custom_color_summary">Choose an own color to be displayed in the on-screen flashlight.</string>
|
||||
<string name="flashlight_on_screen_custom_color">Custom Color</string>
|
||||
<string name="android_auto_share_location_no_items_yet">No Items yet, something went wrong</string>
|
||||
<string name="android_auto_share_location_already_sharing">You already share your location</string>
|
||||
<string name="android_auto_share_location_not_yet_sharing">You are not yet sharing your location</string>
|
||||
|
||||
|
||||
</resources>
|
||||
@@ -94,8 +94,11 @@
|
||||
<string name="android_auto_actions_start_sharing">Yes, start to share</string>
|
||||
<string name="android_auto_actions_stop_sharing">Yes, stop sharing</string>
|
||||
<string name="android_auto_share_location_start">Start</string>
|
||||
<string name="android_auto_share_location_start_desc">Start to share location</string>
|
||||
<string name="android_auto_share_location_start_desc">Share Location</string>
|
||||
<string name="android_auto_share_location_stop">Stop</string>
|
||||
<string name="android_auto_share_location_stop_desc">Stop to share the location</string>
|
||||
<string name="android_auto_share_location_stop_desc">Stop Sharing</string>
|
||||
<string name="android_auto_share_location_no_items_yet">No Items yet, something went wrong</string>
|
||||
<string name="android_auto_share_location_already_sharing">You already share your location</string>
|
||||
<string name="android_auto_share_location_not_yet_sharing">You are not yet sharing your location</string>
|
||||
|
||||
</resources>
|
||||
@@ -1,4 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<automotiveApp>
|
||||
<uses name="notification" />
|
||||
<uses name="template"/>
|
||||
</automotiveApp>
|
||||
|
||||
Reference in New Issue
Block a user