Check and observe the availability of the Play Store.

Useful for checking if a watch face is running on a watch that is being used with an iPhone.

Usage

In your onResume:

mChecker = new PlayStoreAvailabilityChecker(getActivity(), listener)
	.registerObserver();

In the onPause:

mChecker.unregisterObserver();

Then you’ll get callbacks like this:

@Override
protected void onPlayStoreAvailabilityChanged(@Availability int availability) {
    if (availability == PlayStoreAvailabilityChecker.PLAY_STORE_UNAVAILABLE) {
        // The paired phone does not have a Play Store (is probably an iPhone).
    }
}

PlayStoreAvailabilityChecker.java

The helper class for checking if there is a Play Store installed, and for observing the status of Play Store availability.

package com.pixplicity.example.utils;

import android.content.ContentResolver;
import android.content.Context;
import android.database.ContentObserver;
import android.database.Cursor;
import android.net.Uri;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.annotation.IntDef;

/**
 * Helper class for checking if there is a Play Store installed, and for observing the status of
 * Play Store availability.
 * <p>
 * Usage:
 * <p>
 * <strong>In your onResume:</strong>
 * <code>
 * pac = new PlayStoreAvailabilityChecker(getActivity(), listener).registerObserver();
 * </code>
 * <p>
 * <strong>In your onPause:</strong>
 * <code>
 * pac.unregisterObserver();
 * </code>
 */
public class PlayStoreAvailabilityChecker {

    private static final String PLAY_STORE_AVAILABILITY_PATH = "play_store_availability";
    private static final Uri PLAY_STORE_AVAILABILITY_URI = new Uri.Builder()
            .scheme("content")
            .authority("com.google.android.wearable.settings")
            .path(PLAY_STORE_AVAILABILITY_PATH)
            .build();

    // The name of the row which stores the play store availability
    private static final String KEY_PLAY_STORE_AVAILABILITY = "play_store_availability";

    public static final int PLAY_STORE_AVAILABILITY_UNKNOWN = 0;
    public static final int PLAY_STORE_AVAILABLE = 1;
    public static final int PLAY_STORE_UNAVAILABLE = 2;
    private final Context mContext;
    private final IPlayStoreAvailabilityChanged mListener;

    private HandlerThread mHandlerThread;
    private ContentObserver mObserver;

    @IntDef({PLAY_STORE_AVAILABLE, PLAY_STORE_AVAILABILITY_UNKNOWN, PLAY_STORE_UNAVAILABLE})
    public @interface Availability {}

    public interface IPlayStoreAvailabilityChanged {

        void onPlayStoreAvailabilityChanged(@Availability int availability);
    }

    @SuppressWarnings("WeakerAccess")
    @Availability
    public static int getPlayStoreAvailability(Context context) {
        Cursor cursor = context.getContentResolver()
                .query(PLAY_STORE_AVAILABILITY_URI,
                        null,
                        null,
                        null,
                        null);
        if (cursor != null) {
            try {
                while (cursor.moveToNext()) {
                    if (KEY_PLAY_STORE_AVAILABILITY.equals(cursor.getString(0))) {
                        //noinspection WrongConstant
                        return cursor.getInt(1);
                    }
                }
            } finally {
                cursor.close();
            }
        }
        return PLAY_STORE_AVAILABILITY_UNKNOWN;
    }

    public PlayStoreAvailabilityChecker(Context context, IPlayStoreAvailabilityChanged listener) {
        mContext = context;
        mListener = listener;
    }

    public void registerContentObserver() {
        mHandlerThread = new HandlerThread("PlayStoreAvailabilityThread");
        mHandlerThread.start();
        final Handler handler = new Handler(mHandlerThread.getLooper());
        final ContentResolver contentResolver = mContext.getContentResolver();
        watchPlayStoreAvailability(handler, contentResolver);
    }

    public void unregisterContentObserver() {
        final ContentResolver contentResolver = mContext.getContentResolver();
        contentResolver.unregisterContentObserver(mObserver);
        mHandlerThread.quitSafely();
    }

    private void watchPlayStoreAvailability(Handler handler, final ContentResolver contentResolver) {
        mObserver = new ContentObserver(handler) {
            @Override
            public void onChange(boolean selfChange) {
                int availability = getPlayStoreAvailability(mContext);
                mListener.onPlayStoreAvailabilityChanged(availability);
            }

            @Override
            public void onChange(boolean selfChange, Uri uri) {
                onChange(selfChange)
            }
        };

        contentResolver.registerContentObserver(PLAY_STORE_AVAILABILITY_URI, true, mObserver);
        mObserver.dispatchChange(true, PLAY_STORE_AVAILABILITY_URI);
    }

}