Search in sources :

Example 1 with Artwork

use of com.google.android.apps.muzei.api.Artwork in project muzei by romannurik.

the class FeaturedArtSource method onTryUpdate.

@Override
protected void onTryUpdate(int reason) throws RetryException {
    Artwork currentArtwork = getCurrentArtwork();
    Artwork artwork;
    JSONObject jsonObject;
    try {
        jsonObject = fetchJsonObject(QUERY_URL);
        artwork = Artwork.fromJson(jsonObject);
    } catch (JSONException | IOException e) {
        Log.e(TAG, "Error reading JSON", e);
        throw new RetryException(e);
    }
    if (artwork != null && currentArtwork != null && artwork.getImageUri() != null && artwork.getImageUri().equals(currentArtwork.getImageUri())) {
        if (BuildConfig.DEBUG) {
            Log.d(TAG, "Skipping update of same artwork.");
        }
    } else {
        if (BuildConfig.DEBUG) {
            Log.d(TAG, "Publishing artwork update: " + artwork);
        }
        if (artwork != null && jsonObject != null) {
            artwork.setMetaFont(MuzeiContract.Artwork.META_FONT_TYPE_ELEGANT);
            publishArtwork(artwork);
        }
    }
    Date nextTime = null;
    String nextTimeStr = jsonObject.optString("nextTime");
    if (!TextUtils.isEmpty(nextTimeStr)) {
        int len = nextTimeStr.length();
        if (len > 4 && nextTimeStr.charAt(len - 3) == ':') {
            nextTimeStr = nextTimeStr.substring(0, len - 3) + nextTimeStr.substring(len - 2);
        }
        try {
            nextTime = sDateFormatTZ.parse(nextTimeStr);
        } catch (ParseException e) {
            try {
                sDateFormatLocal.setTimeZone(TimeZone.getDefault());
                nextTime = sDateFormatLocal.parse(nextTimeStr);
            } catch (ParseException e2) {
                Log.e(TAG, "Can't schedule update; " + "invalid date format '" + nextTimeStr + "'", e2);
            }
        }
    }
    boolean scheduleFallback = true;
    if (nextTime != null) {
        // jitter by up to N milliseconds
        scheduleUpdate(nextTime.getTime() + sRandom.nextInt(MAX_JITTER_MILLIS));
        scheduleFallback = false;
    }
    if (scheduleFallback) {
        // No next time, default to checking in 12 hours
        scheduleUpdate(System.currentTimeMillis() + 12 * 60 * 60 * 1000);
    }
}
Also used : Artwork(com.google.android.apps.muzei.api.Artwork) JSONObject(org.json.JSONObject) JSONException(org.json.JSONException) IOException(java.io.IOException) ParseException(java.text.ParseException) Date(java.util.Date)

Example 2 with Artwork

use of com.google.android.apps.muzei.api.Artwork in project muzei by romannurik.

the class GalleryArtSource method onCreate.

@Override
public void onCreate() {
    super.onCreate();
    mGeocoder = new Geocoder(this);
    mContentObserver = new ContentObserver(new Handler()) {

        @Override
        public void onChange(boolean selfChange, Uri uri) {
            // Update the metadata
            updateMeta();
            // See if we've just added the very first image
            Artwork currentArtwork = getCurrentArtwork();
            if (currentArtwork == null) {
                publishNextArtwork(null);
                return;
            }
            // See if the current artwork was removed
            Uri currentArtworkUri = currentArtwork.getToken() != null ? Uri.parse(currentArtwork.getToken()) : null;
            if (uri.equals(currentArtworkUri)) {
                // We're showing a removed URI
                publishNextArtwork(null);
            }
        }
    };
    // Make any changes since the last time the GalleryArtSource was created
    mContentObserver.onChange(false, GalleryContract.ChosenPhotos.CONTENT_URI);
    getContentResolver().registerContentObserver(GalleryContract.ChosenPhotos.CONTENT_URI, true, mContentObserver);
}
Also used : Artwork(com.google.android.apps.muzei.api.Artwork) Handler(android.os.Handler) Geocoder(android.location.Geocoder) Uri(android.net.Uri) ContentObserver(android.database.ContentObserver)

Example 3 with Artwork

use of com.google.android.apps.muzei.api.Artwork in project muzei by romannurik.

the class ArtworkComplicationProviderService method onComplicationUpdate.

@Override
public void onComplicationUpdate(int complicationId, int type, ComplicationManager complicationManager) {
    // Make sure that the complicationId is really in our set of added complications
    // This fixes corner cases like Muzei being uninstalled and reinstalled
    // (which wipes out our SharedPreferences but keeps any complications activated)
    SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this);
    Set<String> complications = preferences.getStringSet(KEY_COMPLICATION_IDS, new TreeSet<String>());
    if (!complications.contains(Integer.toString(complicationId))) {
        if (BuildConfig.DEBUG) {
            Log.d(TAG, "Update missing id " + complicationId);
        }
        addComplication(complicationId);
    }
    Artwork artwork = MuzeiContract.Artwork.getCurrentArtwork(this);
    if (artwork == null) {
        if (BuildConfig.DEBUG) {
            Log.d(TAG, "Update no artwork for " + complicationId);
        }
        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;
    }
    if (BuildConfig.DEBUG) {
        Log.d(TAG, "Updated " + complicationId);
    }
    complicationManager.updateComplicationData(complicationId, builder.build());
}
Also used : Artwork(com.google.android.apps.muzei.api.Artwork) SharedPreferences(android.content.SharedPreferences) Intent(android.content.Intent) PendingIntent(android.app.PendingIntent) PendingIntent(android.app.PendingIntent) ComplicationData(android.support.wearable.complications.ComplicationData)

Example 4 with Artwork

use of com.google.android.apps.muzei.api.Artwork in project muzei by romannurik.

the class ArtworkCacheIntentService method processDataItem.

private boolean processDataItem(GoogleApiClient googleApiClient, DataItem dataItem) {
    if (!dataItem.getUri().getPath().equals("/artwork")) {
        Log.w(TAG, "Ignoring data item " + dataItem.getUri().getPath());
        return false;
    }
    DataMapItem dataMapItem = DataMapItem.fromDataItem(dataItem);
    DataMap artworkDataMap = dataMapItem.getDataMap().getDataMap("artwork");
    if (artworkDataMap == null) {
        Log.w(TAG, "No artwork in datamap.");
        return false;
    }
    final Asset asset = dataMapItem.getDataMap().getAsset("image");
    if (asset == null) {
        Log.w(TAG, "No image asset in datamap.");
        return false;
    }
    final Artwork artwork = Artwork.fromBundle(artworkDataMap.toBundle());
    // Change it so that all Artwork from the phone is attributed to the DataLayerArtSource
    artwork.setComponentName(this, DataLayerArtSource.class);
    // Check if the source info row exists at all.
    ComponentName componentName = artwork.getComponentName();
    Cursor sourceQuery = getContentResolver().query(MuzeiContract.Sources.CONTENT_URI, null, MuzeiContract.Sources.COLUMN_NAME_COMPONENT_NAME + "=?", new String[] { componentName.flattenToShortString() }, null);
    if (sourceQuery == null || !sourceQuery.moveToFirst()) {
        // If the row does not exist, insert a dummy row
        ContentValues values = new ContentValues();
        values.put(MuzeiContract.Sources.COLUMN_NAME_COMPONENT_NAME, componentName.flattenToShortString());
        values.put(MuzeiContract.Sources.COLUMN_NAME_IS_SELECTED, true);
        getContentResolver().insert(MuzeiContract.Sources.CONTENT_URI, values);
    }
    if (sourceQuery != null) {
        sourceQuery.close();
    }
    Uri artworkUri = getContentResolver().insert(MuzeiContract.Artwork.CONTENT_URI, artwork.toContentValues());
    if (artworkUri == null) {
        Log.w(TAG, "Unable to write artwork information to MuzeiProvider");
        return false;
    }
    DataApi.GetFdForAssetResult result = null;
    InputStream in = null;
    try (OutputStream out = getContentResolver().openOutputStream(artworkUri)) {
        if (out == null) {
            // We've already cached the artwork previously, so call this a success
            return true;
        }
        // Convert asset into a file descriptor and block until it's ready
        result = Wearable.DataApi.getFdForAsset(googleApiClient, asset).await();
        in = result.getInputStream();
        if (in == null) {
            Log.w(TAG, "Unable to open asset input stream");
            return false;
        }
        byte[] buffer = new byte[1024];
        int bytesRead;
        while ((bytesRead = in.read(buffer)) > 0) {
            out.write(buffer, 0, bytesRead);
        }
        out.flush();
    } catch (IOException e) {
        Log.e(TAG, "Error writing artwork", e);
    } finally {
        try {
            if (in != null) {
                in.close();
            }
        } catch (IOException e) {
            Log.e(TAG, "Error closing artwork input stream", e);
        }
        if (result != null) {
            result.release();
        }
    }
    return true;
}
Also used : ContentValues(android.content.ContentValues) Artwork(com.google.android.apps.muzei.api.Artwork) InputStream(java.io.InputStream) OutputStream(java.io.OutputStream) IOException(java.io.IOException) Cursor(android.database.Cursor) Uri(android.net.Uri) DataApi(com.google.android.gms.wearable.DataApi) DataMap(com.google.android.gms.wearable.DataMap) Asset(com.google.android.gms.wearable.Asset) ComponentName(android.content.ComponentName) DataMapItem(com.google.android.gms.wearable.DataMapItem)

Example 5 with Artwork

use of com.google.android.apps.muzei.api.Artwork in project muzei by romannurik.

the class WearableController method updateArtwork.

public static synchronized void updateArtwork(Context context) {
    if (ConnectionResult.SUCCESS != GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(context)) {
        return;
    }
    GoogleApiClient googleApiClient = new GoogleApiClient.Builder(context).addApi(Wearable.API).build();
    ConnectionResult connectionResult = googleApiClient.blockingConnect(5, TimeUnit.SECONDS);
    if (!connectionResult.isSuccess()) {
        if (connectionResult.getErrorCode() != ConnectionResult.API_UNAVAILABLE) {
            Log.w(TAG, "onConnectionFailed: " + connectionResult);
        }
        return;
    }
    ContentResolver contentResolver = context.getContentResolver();
    Bitmap image = null;
    try {
        BitmapFactory.Options options = new BitmapFactory.Options();
        options.inJustDecodeBounds = true;
        BitmapFactory.decodeStream(contentResolver.openInputStream(MuzeiContract.Artwork.CONTENT_URI), null, options);
        options.inJustDecodeBounds = false;
        if (options.outWidth > options.outHeight) {
            options.inSampleSize = ImageUtil.calculateSampleSize(options.outHeight, 320);
        } else {
            options.inSampleSize = ImageUtil.calculateSampleSize(options.outWidth, 320);
        }
        image = BitmapFactory.decodeStream(contentResolver.openInputStream(MuzeiContract.Artwork.CONTENT_URI), null, options);
    } catch (FileNotFoundException e) {
        Log.e(TAG, "Unable to read artwork to update Android Wear", e);
    }
    if (image != null) {
        int rotation = getRotation(context);
        if (rotation != 0) {
            // Rotate the image so that Wear always gets a right side up image
            Matrix matrix = new Matrix();
            matrix.postRotate(rotation);
            image = Bitmap.createBitmap(image, 0, 0, image.getWidth(), image.getHeight(), matrix, true);
        }
        final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        image.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
        Asset asset = Asset.createFromBytes(byteStream.toByteArray());
        PutDataMapRequest dataMapRequest = PutDataMapRequest.create("/artwork");
        Artwork artwork = MuzeiContract.Artwork.getCurrentArtwork(context);
        dataMapRequest.getDataMap().putDataMap("artwork", DataMap.fromBundle(artwork.toBundle()));
        dataMapRequest.getDataMap().putAsset("image", asset);
        Wearable.DataApi.putDataItem(googleApiClient, dataMapRequest.asPutDataRequest().setUrgent()).await();
    }
    googleApiClient.disconnect();
}
Also used : GoogleApiClient(com.google.android.gms.common.api.GoogleApiClient) Artwork(com.google.android.apps.muzei.api.Artwork) FileNotFoundException(java.io.FileNotFoundException) ByteArrayOutputStream(java.io.ByteArrayOutputStream) ContentResolver(android.content.ContentResolver) Bitmap(android.graphics.Bitmap) Matrix(android.graphics.Matrix) ConnectionResult(com.google.android.gms.common.ConnectionResult) Asset(com.google.android.gms.wearable.Asset) BitmapFactory(android.graphics.BitmapFactory) PutDataMapRequest(com.google.android.gms.wearable.PutDataMapRequest)

Aggregations

Artwork (com.google.android.apps.muzei.api.Artwork)9 Intent (android.content.Intent)4 Uri (android.net.Uri)4 Cursor (android.database.Cursor)3 Handler (android.os.Handler)3 ComponentName (android.content.ComponentName)2 ContentResolver (android.content.ContentResolver)2 ContentValues (android.content.ContentValues)2 Asset (com.google.android.gms.wearable.Asset)2 IOException (java.io.IOException)2 Date (java.util.Date)2 SuppressLint (android.annotation.SuppressLint)1 PendingIntent (android.app.PendingIntent)1 SharedPreferences (android.content.SharedPreferences)1 ContentObserver (android.database.ContentObserver)1 Bitmap (android.graphics.Bitmap)1 BitmapFactory (android.graphics.BitmapFactory)1 Matrix (android.graphics.Matrix)1 Geocoder (android.location.Geocoder)1 Bundle (android.os.Bundle)1