com.google.android.apps.muzei.api
Class MuzeiArtSource

java.lang.Object
  extended by android.content.Context
      extended by android.content.ContextWrapper
          extended by android.app.Service
              extended by android.app.IntentService
                  extended by com.google.android.apps.muzei.api.MuzeiArtSource
All Implemented Interfaces:
ComponentCallbacks, ComponentCallbacks2
Direct Known Subclasses:
RemoteMuzeiArtSource

public abstract class MuzeiArtSource
extends IntentService

Base class for a Muzei Live Wallpaper artwork source. Art sources are a way for other apps to feed wallpapers (called artworks) to the Muzei Live Wallpaper. Art sources are specialized IntentService classes.

Only one source can be selected at a time. When the user chooses a source, the Muzei app subscribes to the source for updates. When a different source is chosen, Muzei unsubscribes from the original source.

The API is designed such that other applications besides Muzei Live Wallpaper can also subscribe to updates from an artwork source.

Subclassing MuzeiArtSource

Subclasses must implement at least the onUpdate callback method, which may be called on a number of occasions, such as when an app subscribes to the source and the source hasn't yet published an artwork, or when a scheduled update occurs.

To publish an artwork, call publishArtwork(Artwork), either from the onUpdate callback method, or elsewhere in the source's code. Any and all subscribers will then immediately receive an update with the new artwork information. Under the hood, this is all done with service intents.

Registering your source

A source is simply a service that Muzei and other apps interact with via service intents. Subclasses of this base MuzeiArtSource class should thus be declared as <service> components in the application's AndroidManifest.xml file.

The Muzei app and other potential subscribers discover available sources using Android's Intent mechanism. Ensure that your service definition includes an <intent-filter> with an action of ACTION_MUZEI_ART_SOURCE.

Muzei uses the drawable indicated by the source's android:icon attribute in the <service> element to represent the source in the user interface. The icon should be completely flat and contain padding, as Muzei will apply some additional styling to present the icon.

Lastly, there are a few <meta-data> elements that you should add to your service definition:

Example

Below is an example source declaration in the manifest:
 <service android:name=".ExampleArtSource"
     android:icon="@drawable/ic_source_example"
     android:label="@string/source_title"
     android:description="@string/source_description">
     <intent-filter>
         <action android:name="com.google.android.apps.muzei.api.MuzeiArtSource" />
     </intent-filter>
     <meta-data android:name="color" android:value="#ace5cc" />
     <!-- A settings activity is optional -->
     <meta-data android:name="settingsActivity"
         android:value=".ExampleSettingsActivity" />
 </service>
If a settingsActivity meta-data element is present, an activity with the given component name should be defined and exported in the application's manifest as well. Muzei will set the EXTRA_FROM_MUZEI_SETTINGS extra to true in the launch intent for this activity. An example is shown below:
 <activity android:name=".ExampleSettingsActivity"
     android:label="@string/title_settings"
     android:exported="true" />
Finally, below is a simple example MuzeiArtSource subclass that publishes a single, static artwork:
 public class ExampleArtSource extends MuzeiArtSource {
     protected void onUpdate(int reason) {
         publishArtwork(new Artwork.Builder()
                 .imageUri(Uri.parse("http://example.com/image.jpg"))
                 .title("Example image")
                 .byline("Unknown person, c. 1980")
                 .viewIntent(new Intent(Intent.ACTION_VIEW,
                         Uri.parse("http://example.com/imagedetails.html")))
                 .build());
     }
 }

Additional lifecycle methods

There are a number of lifecycle methods that you can override for additional control. They occur in the following order:
  1. onEnabled(), called when the first subscriber is added.
  2. onSubscriberAdded(ComponentName), called when a new subscriber is added.
  3. onSubscriberRemoved(ComponentName), called when a subscriber is removed.
  4. onDisabled(), called when the last subscriber unsubscribes.
In most cases, if the only subscriber is the Muzei Live Wallpaper app, these four methods will be called as the user switches between your source and other available sources.

Additional notes

To schedule an update for a future time, call scheduleUpdate(long). Cancel any scheduled updates using unscheduleUpdate().

Sources can also expose additional user-facing commands (such as 'Next artwork' or 'Share artwork') using the setUserCommands(UserCommand...) method, and clear available actions using removeAllUserCommands(). To handle custom commands, override the onCustomCommand(int) callback method.

Sources can provide a dynamic description of the current configuration (e.g. 'Popular photos tagged "landscape"'), by using the setDescription(String). If no description is provided, the android:description element of the source's service element in the manifest will be used.

See Also:
RemoteMuzeiArtSource

Field Summary
static String ACTION_MUZEI_ART_SOURCE
          The Intent action representing a Muzei art source.
static int BUILTIN_COMMAND_ID_NEXT_ARTWORK
          The command ID for the built-in "next artwork" command.
static String EXTRA_FROM_MUZEI_SETTINGS
          Boolean extra that will be set to true when Muzei starts source settings activities.
protected static int MAX_CUSTOM_COMMAND_ID
          The largest command ID that can be used for custom commands.
static int UPDATE_REASON_INITIAL
          Indicates that onUpdate(int) was triggered because this source has not yet published an artwork and the first subscriber has subscribed (e.g.
static int UPDATE_REASON_OTHER
          Indicates that onUpdate(int) was triggered for some reason not represented by another known reason constant.
static int UPDATE_REASON_SCHEDULED
          Indicates that onUpdate(int) was triggered because a scheduled update has been triggered.
static int UPDATE_REASON_USER_NEXT
          Indicates that onUpdate(int) was triggered because the user manually requested the next artwork.
 
Fields inherited from class android.app.Service
START_CONTINUATION_MASK, START_FLAG_REDELIVERY, START_FLAG_RETRY, START_NOT_STICKY, START_REDELIVER_INTENT, START_STICKY, START_STICKY_COMPATIBILITY
 
Fields inherited from class android.content.Context
ACCESSIBILITY_SERVICE, ACCOUNT_SERVICE, ACTIVITY_SERVICE, ALARM_SERVICE, AUDIO_SERVICE, BIND_ABOVE_CLIENT, BIND_ADJUST_WITH_ACTIVITY, BIND_ALLOW_OOM_MANAGEMENT, BIND_AUTO_CREATE, BIND_DEBUG_UNBIND, BIND_IMPORTANT, BIND_NOT_FOREGROUND, BIND_WAIVE_PRIORITY, CLIPBOARD_SERVICE, CONNECTIVITY_SERVICE, CONTEXT_IGNORE_SECURITY, CONTEXT_INCLUDE_CODE, CONTEXT_RESTRICTED, DEVICE_POLICY_SERVICE, DISPLAY_SERVICE, DOWNLOAD_SERVICE, DROPBOX_SERVICE, INPUT_METHOD_SERVICE, INPUT_SERVICE, KEYGUARD_SERVICE, LAYOUT_INFLATER_SERVICE, LOCATION_SERVICE, MEDIA_ROUTER_SERVICE, MODE_APPEND, MODE_ENABLE_WRITE_AHEAD_LOGGING, MODE_MULTI_PROCESS, MODE_PRIVATE, MODE_WORLD_READABLE, MODE_WORLD_WRITEABLE, NFC_SERVICE, NOTIFICATION_SERVICE, NSD_SERVICE, POWER_SERVICE, SEARCH_SERVICE, SENSOR_SERVICE, STORAGE_SERVICE, TELEPHONY_SERVICE, TEXT_SERVICES_MANAGER_SERVICE, UI_MODE_SERVICE, USB_SERVICE, USER_SERVICE, VIBRATOR_SERVICE, WALLPAPER_SERVICE, WIFI_P2P_SERVICE, WIFI_SERVICE, WINDOW_SERVICE
 
Fields inherited from interface android.content.ComponentCallbacks2
TRIM_MEMORY_BACKGROUND, TRIM_MEMORY_COMPLETE, TRIM_MEMORY_MODERATE, TRIM_MEMORY_RUNNING_CRITICAL, TRIM_MEMORY_RUNNING_LOW, TRIM_MEMORY_RUNNING_MODERATE, TRIM_MEMORY_UI_HIDDEN
 
Constructor Summary
MuzeiArtSource(String name)
          Remember to call this constructor from an empty constructor!
 
Method Summary
protected  Artwork getCurrentArtwork()
          Returns the most recently published artwork, or null if none has been published.
protected  SharedPreferences getSharedPreferences()
          Convenience method for accessing preferences specific to the source.
protected static SharedPreferences getSharedPreferences(Context context, String sourceName)
          Convenience method for accessing preferences specific to the source (with the given name within this package.
protected  boolean isEnabled()
          Returns true if this source is enabled; that is, if there is at least one active subscriber.
protected  boolean onAllowSubscription(ComponentName subscriber)
          Method called before a new subscriber is added that determines whether the subscription is allowed or not.
 IBinder onBind(Intent intent)
           
 void onCreate()
           
protected  void onCustomCommand(int id)
          Callback method indicating that the user has selected a custom command.
protected  void onDisabled()
          Lifecycle method called when the last subscriber is removed.
protected  void onEnabled()
          Lifecycle method called when the first subscriber is added.
protected  void onHandleIntent(Intent intent)
           
protected  void onNetworkAvailable()
          Convenience callback method indicating that a network connection is now available.
protected  void onSubscriberAdded(ComponentName subscriber)
          Lifecycle method called when a new subscriber is added.
protected  void onSubscriberRemoved(ComponentName subscriber)
          Lifecycle method called when a subscriber is removed.
protected abstract  void onUpdate(int reason)
          Called on occasions where the source should probably publish an artwork update.
protected  void publishArtwork(Artwork artwork)
          Publishes the provided Artwork object.
protected  void removeAllUserCommands()
          Clears the list of available user commands.
protected  void scheduleUpdate(long scheduledUpdateTimeMillis)
          Schedules an update for some time in the future.
protected  void setDescription(String description)
          Sets the current source description of the current configuration (e.g.
protected  void setUserCommands(int... commands)
          Sets the list of available user-visible commands for the source.
protected  void setUserCommands(List<UserCommand> commands)
          Sets the list of available user-visible commands for the source.
protected  void setUserCommands(UserCommand... commands)
          Sets the list of available user-visible commands for the source.
protected  void setWantsNetworkAvailable(boolean wantsNetworkAvailable)
          Indicates that the source is interested (or no longer interested) in getting notified via onNetworkAvailable() when a network connection becomes available.
protected  void unscheduleUpdate()
          Cancels any previously scheduled updates.
 
Methods inherited from class android.app.IntentService
onDestroy, onStart, onStartCommand, setIntentRedelivery
 
Methods inherited from class android.app.Service
dump, getApplication, onConfigurationChanged, onLowMemory, onRebind, onTaskRemoved, onTrimMemory, onUnbind, startForeground, stopForeground, stopSelf, stopSelf, stopSelfResult
 
Methods inherited from class android.content.ContextWrapper
attachBaseContext, bindService, checkCallingOrSelfPermission, checkCallingOrSelfUriPermission, checkCallingPermission, checkCallingUriPermission, checkPermission, checkUriPermission, checkUriPermission, clearWallpaper, createConfigurationContext, createDisplayContext, createPackageContext, databaseList, deleteDatabase, deleteFile, enforceCallingOrSelfPermission, enforceCallingOrSelfUriPermission, enforceCallingPermission, enforceCallingUriPermission, enforcePermission, enforceUriPermission, enforceUriPermission, fileList, getApplicationContext, getApplicationInfo, getAssets, getBaseContext, getCacheDir, getClassLoader, getContentResolver, getDatabasePath, getDir, getExternalCacheDir, getExternalFilesDir, getFilesDir, getFileStreamPath, getMainLooper, getObbDir, getPackageCodePath, getPackageManager, getPackageName, getPackageResourcePath, getResources, getSharedPreferences, getSystemService, getTheme, getWallpaper, getWallpaperDesiredMinimumHeight, getWallpaperDesiredMinimumWidth, grantUriPermission, isRestricted, openFileInput, openFileOutput, openOrCreateDatabase, openOrCreateDatabase, peekWallpaper, registerReceiver, registerReceiver, removeStickyBroadcast, removeStickyBroadcastAsUser, revokeUriPermission, sendBroadcast, sendBroadcast, sendBroadcastAsUser, sendBroadcastAsUser, sendOrderedBroadcast, sendOrderedBroadcast, sendOrderedBroadcastAsUser, sendStickyBroadcast, sendStickyBroadcastAsUser, sendStickyOrderedBroadcast, sendStickyOrderedBroadcastAsUser, setTheme, setWallpaper, setWallpaper, startActivities, startActivities, startActivity, startActivity, startInstrumentation, startIntentSender, startIntentSender, startService, stopService, unbindService, unregisterReceiver
 
Methods inherited from class android.content.Context
getString, getString, getText, obtainStyledAttributes, obtainStyledAttributes, obtainStyledAttributes, obtainStyledAttributes, registerComponentCallbacks, unregisterComponentCallbacks
 
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
 

Field Detail

ACTION_MUZEI_ART_SOURCE

public static final String ACTION_MUZEI_ART_SOURCE
The Intent action representing a Muzei art source. This service should declare an <intent-filter> for this action in order to register with Muzei.

See Also:
Constant Field Values

BUILTIN_COMMAND_ID_NEXT_ARTWORK

public static final int BUILTIN_COMMAND_ID_NEXT_ARTWORK
The command ID for the built-in "next artwork" command. When this command is clicked, onUpdate(int) will be called with UPDATE_REASON_USER_NEXT

See Also:
setUserCommands(UserCommand...), Constant Field Values

EXTRA_FROM_MUZEI_SETTINGS

public static final String EXTRA_FROM_MUZEI_SETTINGS
Boolean extra that will be set to true when Muzei starts source settings activities. Check for this extra in your settings activity if you need to adjust your UI depending on whether or not the user came from Muzei's settings screen.

See Also:
Constant Field Values

MAX_CUSTOM_COMMAND_ID

protected static final int MAX_CUSTOM_COMMAND_ID
The largest command ID that can be used for custom commands.

See Also:
setUserCommands(UserCommand...), Constant Field Values

UPDATE_REASON_INITIAL

public static final int UPDATE_REASON_INITIAL
Indicates that onUpdate(int) was triggered because this source has not yet published an artwork and the first subscriber has subscribed (e.g. the user has chosen this source).

See Also:
Constant Field Values

UPDATE_REASON_OTHER

public static final int UPDATE_REASON_OTHER
Indicates that onUpdate(int) was triggered for some reason not represented by another known reason constant.

See Also:
Constant Field Values

UPDATE_REASON_SCHEDULED

public static final int UPDATE_REASON_SCHEDULED
Indicates that onUpdate(int) was triggered because a scheduled update has been triggered.

See Also:
Constant Field Values

UPDATE_REASON_USER_NEXT

public static final int UPDATE_REASON_USER_NEXT
Indicates that onUpdate(int) was triggered because the user manually requested the next artwork. This should only be sent when BUILTIN_COMMAND_ID_NEXT_ARTWORK is an available user command.

See Also:
Constant Field Values
Constructor Detail

MuzeiArtSource

public MuzeiArtSource(String name)
Remember to call this constructor from an empty constructor!

Parameters:
name - Should be an ID-style name for your source, usually just the class name. This is not user-visible and is only used for storing preferences and in system log output.
Method Detail

getCurrentArtwork

protected final Artwork getCurrentArtwork()
Returns the most recently published artwork, or null if none has been published.


getSharedPreferences

protected final SharedPreferences getSharedPreferences()
Convenience method for accessing preferences specific to the source.

See Also:
getSharedPreferences(android.content.Context, String)

getSharedPreferences

protected static SharedPreferences getSharedPreferences(Context context,
                                                        String sourceName)
Convenience method for accessing preferences specific to the source (with the given name within this package. The source name must be the one provided in the MuzeiArtSource(String) constructor. This static method is useful for exposing source preferences to other application components such as the source settings activity.

Parameters:
context - The context; can be an application context.
sourceName - The source name, provided in the MuzeiArtSource(String) constructor.

isEnabled

protected final boolean isEnabled()
Returns true if this source is enabled; that is, if there is at least one active subscriber.

See Also:
onEnabled(), onDisabled()

onAllowSubscription

protected boolean onAllowSubscription(ComponentName subscriber)
Method called before a new subscriber is added that determines whether the subscription is allowed or not. The default behavior is to allow all subscriptions.

Returns:
true if the subscription should be allowed, false if it should be denied.

onBind

public IBinder onBind(Intent intent)
Overrides:
onBind in class IntentService

onCreate

public void onCreate()
Overrides:
onCreate in class IntentService

onCustomCommand

protected void onCustomCommand(int id)
Callback method indicating that the user has selected a custom command.

Parameters:
id - The ID of the command the user has chosen.
See Also:
setUserCommands(UserCommand...)

onDisabled

protected void onDisabled()
Lifecycle method called when the last subscriber is removed. This will be called after onSubscriberRemoved(ComponentName). Sources generally don't need to override this. For more details on the source lifecycle, see the discussion in the MuzeiArtSource reference.


onEnabled

protected void onEnabled()
Lifecycle method called when the first subscriber is added. This will be called before onSubscriberAdded(ComponentName). Sources generally don't need to override this. For more details on the source lifecycle, see the discussion in the MuzeiArtSource reference.


onHandleIntent

protected void onHandleIntent(Intent intent)
Specified by:
onHandleIntent in class IntentService

onNetworkAvailable

protected void onNetworkAvailable()
Convenience callback method indicating that a network connection is now available. This will only be called if setWantsNetworkAvailable(boolean) was last called with true.


onSubscriberAdded

protected void onSubscriberAdded(ComponentName subscriber)
Lifecycle method called when a new subscriber is added. Sources generally don't need to override this. For more details on the source lifecycle, see the discussion in the MuzeiArtSource reference.


onSubscriberRemoved

protected void onSubscriberRemoved(ComponentName subscriber)
Lifecycle method called when a subscriber is removed. Sources generally don't need to override this. For more details on the source lifecycle, see the discussion in the MuzeiArtSource reference.


onUpdate

protected abstract void onUpdate(int reason)
Called on occasions where the source should probably publish an artwork update. Implementations can choose to do nothing, or more commonly, publish an artwork update using publishArtwork(Artwork). Sources can also choose to update metadata here such as setDescription(String) or setUserCommands(UserCommand...).

Note that publishArtwork(Artwork) can be called outside of this callback method. This is simply the most common point at which you'll want to publish an update.

Parameters:
reason - The reason for the update. See UPDATE_REASON_INITIAL and related constants for more details.

publishArtwork

protected final void publishArtwork(Artwork artwork)
Publishes the provided Artwork object. This will be sent to all current subscribers and to all future subscribers, until a new artwork is published.


removeAllUserCommands

protected final void removeAllUserCommands()
Clears the list of available user commands.

See Also:
setUserCommands(UserCommand...)

scheduleUpdate

protected final void scheduleUpdate(long scheduledUpdateTimeMillis)
Schedules an update for some time in the future. Any previously scheduled updates will be replaced. When the update time elapses, onUpdate(int) will be called with UPDATE_REASON_SCHEDULED.

Note that this is persisted across device reboots, but only triggers after a subscriber subscribes to the source after reboot. The Muzei Live Wallpaper will re-subscribe to sources after reboot if it's the active wallpaper.

Parameters:
scheduledUpdateTimeMillis - The absolute scheduled update time, based on System.currentTimeMillis(). This value must be after the current time.

setDescription

protected final void setDescription(String description)
Sets the current source description of the current configuration (e.g. 'Popular photos tagged "landscape"'). If no description is provided, the android:description element of the source's service element in the manifest will be used.


setUserCommands

protected final void setUserCommands(int... commands)
Sets the list of available user-visible commands for the source. Shorthand for setUserCommands(int...) using only the UserCommand.UserCommand(int) constructor.

See Also:
BUILTIN_COMMAND_ID_NEXT_ARTWORK, MAX_CUSTOM_COMMAND_ID

setUserCommands

protected final void setUserCommands(List<UserCommand> commands)
Sets the list of available user-visible commands for the source. Commands can be built-in, such as BUILTIN_COMMAND_ID_NEXT_ARTWORK, or custom-defined. Custom commands must have identifiers below MAX_CUSTOM_COMMAND_ID.

See Also:
BUILTIN_COMMAND_ID_NEXT_ARTWORK, MAX_CUSTOM_COMMAND_ID

setUserCommands

protected final void setUserCommands(UserCommand... commands)
Sets the list of available user-visible commands for the source. Commands can be built-in, such as BUILTIN_COMMAND_ID_NEXT_ARTWORK, or custom-defined. Custom commands must have identifiers below MAX_CUSTOM_COMMAND_ID.

If you're only using built-in commands, setUserCommands(int...) is preferred.

See Also:
BUILTIN_COMMAND_ID_NEXT_ARTWORK, MAX_CUSTOM_COMMAND_ID

setWantsNetworkAvailable

protected final void setWantsNetworkAvailable(boolean wantsNetworkAvailable)
Indicates that the source is interested (or no longer interested) in getting notified via onNetworkAvailable() when a network connection becomes available.

Parameters:
wantsNetworkAvailable - Whether or not the source wants to be notified about network availability.

unscheduleUpdate

protected final void unscheduleUpdate()
Cancels any previously scheduled updates.