diff --git a/art/ic_complication.svg b/art/ic_complication.svg new file mode 100644 index 000000000..6e038fded --- /dev/null +++ b/art/ic_complication.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/wearable/src/main/AndroidManifest.xml b/wearable/src/main/AndroidManifest.xml index ab04b06f9..bbeb901a1 100644 --- a/wearable/src/main/AndroidManifest.xml +++ b/wearable/src/main/AndroidManifest.xml @@ -65,6 +65,7 @@ @@ -74,7 +75,7 @@ + android:value="LONG_TEXT,SMALL_IMAGE,LARGE_IMAGE" /> @@ -84,7 +85,8 @@ android:exported="true" android:permission="android.permission.BIND_JOB_SERVICE" /> + android:name="com.google.android.apps.muzei.complications.ArtworkComplicationBootReceiver" + android:enabled="false"> diff --git a/wearable/src/main/java/com/google/android/apps/muzei/complications/ArtworkComplicationJobService.java b/wearable/src/main/java/com/google/android/apps/muzei/complications/ArtworkComplicationJobService.java index e07301f73..e6ddf6fe9 100644 --- a/wearable/src/main/java/com/google/android/apps/muzei/complications/ArtworkComplicationJobService.java +++ b/wearable/src/main/java/com/google/android/apps/muzei/complications/ArtworkComplicationJobService.java @@ -24,6 +24,7 @@ import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.os.Build; import android.preference.PreferenceManager; import android.support.wearable.complications.ProviderUpdateRequester; @@ -48,11 +49,21 @@ static void scheduleComplicationUpdateJob(Context context) { MuzeiContract.Artwork.CONTENT_URI, JobInfo.TriggerContentUri.FLAG_NOTIFY_FOR_DESCENDANTS)) .build()); + // Enable the BOOT_COMPLETED receiver to reschedule the job on reboot + ComponentName bootReceivedComponentName = new ComponentName(context, + ArtworkComplicationBootReceiver.class); + context.getPackageManager().setComponentEnabledSetting(bootReceivedComponentName, + PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP); } static void cancelComplicationUpdateJob(Context context) { JobScheduler jobScheduler = context.getSystemService(JobScheduler.class); jobScheduler.cancel(ARTWORK_COMPLICATION_JOB_ID); + // Disable the BOOT_COMPLETED receiver to reduce memory pressure on boot + ComponentName bootReceivedComponentName = new ComponentName(context, + ArtworkComplicationBootReceiver.class); + context.getPackageManager().setComponentEnabledSetting(bootReceivedComponentName, + PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP); } @Override diff --git a/wearable/src/main/java/com/google/android/apps/muzei/complications/ArtworkComplicationProviderService.java b/wearable/src/main/java/com/google/android/apps/muzei/complications/ArtworkComplicationProviderService.java index c0f7e8531..e94b48928 100644 --- a/wearable/src/main/java/com/google/android/apps/muzei/complications/ArtworkComplicationProviderService.java +++ b/wearable/src/main/java/com/google/android/apps/muzei/complications/ArtworkComplicationProviderService.java @@ -17,14 +17,21 @@ package com.google.android.apps.muzei.complications; import android.annotation.TargetApi; +import android.app.PendingIntent; +import android.content.Intent; import android.content.SharedPreferences; import android.graphics.drawable.Icon; import android.os.Build; +import android.os.Bundle; import android.preference.PreferenceManager; import android.support.wearable.complications.ComplicationData; import android.support.wearable.complications.ComplicationManager; import android.support.wearable.complications.ComplicationProviderService; +import android.support.wearable.complications.ComplicationText; +import android.text.TextUtils; +import com.google.android.apps.muzei.FullScreenActivity; +import com.google.android.apps.muzei.api.Artwork; import com.google.android.apps.muzei.api.MuzeiContract; import com.google.firebase.analytics.FirebaseAnalytics; @@ -49,7 +56,9 @@ public void onCreate() { @Override public void onComplicationActivated(int complicationId, int type, ComplicationManager manager) { addComplication(complicationId); - FirebaseAnalytics.getInstance(this).logEvent("complication_artwork_activated", null); + Bundle bundle = new Bundle(); + bundle.putString(FirebaseAnalytics.Param.CONTENT_TYPE, Integer.toString(type)); + FirebaseAnalytics.getInstance(this).logEvent("complication_artwork_activated", bundle); } private void addComplication(int complicationId) { @@ -84,8 +93,44 @@ public void onComplicationUpdate(int complicationId, int type, ComplicationManag if (!complications.contains(Integer.toString(complicationId))) { addComplication(complicationId); } - ComplicationData.Builder builder = new ComplicationData.Builder(type) - .setLargeImage(Icon.createWithContentUri(MuzeiContract.Artwork.CONTENT_URI)); + Artwork artwork = MuzeiContract.Artwork.getCurrentArtwork(this); + if (artwork == null) { + complicationManager.updateComplicationData(complicationId, + new ComplicationData.Builder(ComplicationData.TYPE_NO_DATA).build()); + return; + } + ComplicationData.Builder builder = new ComplicationData.Builder(type); + Intent intent = new Intent(this, FullScreenActivity.class); + PendingIntent tapAction = PendingIntent.getActivity(this, 0, intent, 0); + switch (type) { + case ComplicationData.TYPE_LONG_TEXT: + String title = artwork.getTitle(); + String byline = artwork.getByline(); + if (TextUtils.isEmpty(title) && TextUtils.isEmpty(byline)) { + // Both are empty so we don't have any data to show + complicationManager.updateComplicationData(complicationId, + new ComplicationData.Builder(ComplicationData.TYPE_NO_DATA).build()); + return; + } else if (TextUtils.isEmpty(title)) { + // We only have the byline, so use that as the long text + builder.setLongText(ComplicationText.plainText(byline)); + } else { + if (!TextUtils.isEmpty(byline)) { + builder.setLongTitle(ComplicationText.plainText(byline)); + } + builder.setLongText(ComplicationText.plainText(title)); + } + builder.setTapAction(tapAction); + break; + case ComplicationData.TYPE_SMALL_IMAGE: + builder.setImageStyle(ComplicationData.IMAGE_STYLE_PHOTO) + .setSmallImage(Icon.createWithContentUri(MuzeiContract.Artwork.CONTENT_URI)); + builder.setTapAction(tapAction); + break; + case ComplicationData.TYPE_LARGE_IMAGE: + builder.setLargeImage(Icon.createWithContentUri(MuzeiContract.Artwork.CONTENT_URI)); + break; + } complicationManager.updateComplicationData(complicationId, builder.build()); } } diff --git a/wearable/src/main/res/drawable/ic_complication.xml b/wearable/src/main/res/drawable/ic_complication.xml new file mode 100644 index 000000000..f99ff7183 --- /dev/null +++ b/wearable/src/main/res/drawable/ic_complication.xml @@ -0,0 +1,25 @@ + + + + +