1

我是 Android Wear 操作系统的新手。我想将数字数据 (0,1,2,3,...,9) 公开给 Android Smartwatch 的数据字段(手动触发而不点击数据字段)

如此处所述,

https://developer.android.com/codelabs/data-providers#0

我已经实现了 onReceive() / onComplicationUpdate() 方法:

public class ComplicationTapBroadcastReceiver extends BroadcastReceiver {

private static final String EXTRA_PROVIDER_COMPONENT =
        "com.example.android.wearable.watchface.provider.action.PROVIDER_COMPONENT";
private static final String EXTRA_COMPLICATION_ID =
        "com.example.android.wearable.watchface.provider.action.COMPLICATION_ID";

static final int MAX_NUMBER = 20;
static final String COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY =
        "com.example.android.wearable.watchface.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY";

@Override
public void onReceive(Context context, Intent intent) {
    Bundle extras = intent.getExtras();
    ComponentName provider = extras.getParcelable(EXTRA_PROVIDER_COMPONENT);
    int complicationId = extras.getInt(EXTRA_COMPLICATION_ID);

    // Retrieve data via SharedPreferences.
    String preferenceKey = getPreferenceKey(provider, complicationId);
    SharedPreferences sharedPreferences =
            context.getSharedPreferences(COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY, 0);

    int value = sharedPreferences.getInt(preferenceKey, 0);

    // Update data for complication.
    value = (value + 1) % MAX_NUMBER;

    SharedPreferences.Editor editor = sharedPreferences.edit();
    editor.putInt(preferenceKey, value);
    editor.apply();

    // Request an update for the complication that has just been tapped.
    ProviderUpdateRequester requester = new ProviderUpdateRequester(context, provider);
    requester.requestUpdate(complicationId);
}

/**
 * Returns a pending intent, suitable for use as a tap intent, that causes a complication to be
 * toggled and updated.
 */
static PendingIntent getToggleIntent(
        Context context, ComponentName provider, int complicationId) {
    Intent intent = new Intent(context, ComplicationTapBroadcastReceiver.class);
    intent.putExtra(EXTRA_PROVIDER_COMPONENT, provider);
    intent.putExtra(EXTRA_COMPLICATION_ID, complicationId);

    // Pass complicationId as the requestCode to ensure that different complications get
    // different intents.
    return PendingIntent.getBroadcast(
            context, complicationId, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

/**
 * Returns the key for the shared preference used to hold the current state of a given
 * complication.
 */
static String getPreferenceKey(ComponentName provider, int complicationId) {
    return provider.getClassName() + complicationId;
}
}

public class CustomComplicationProviderService extends ComplicationProviderService {

private static final String TAG = "ComplicationProvider";

/*
 * Called when a complication has been activated. The method is for any one-time
 * (per complication) set-up.
 *
 * You can continue sending data for the active complicationId until onComplicationDeactivated()
 * is called.
 */
@Override
public void onComplicationActivated(
        int complicationId, int dataType, ComplicationManager complicationManager) {
    Log.d(TAG, "onComplicationActivated(): " + complicationId);
}

/*
 * Called when the complication needs updated data from your provider. There are four scenarios
 * when this will happen:
 *
 *   1. An active watch face complication is changed to use this provider
 *   2. A complication using this provider becomes active
 *   3. The period of time you specified in the manifest has elapsed (UPDATE_PERIOD_SECONDS)
 *   4. You triggered an update from your own class via the
 *       ProviderUpdateRequester.requestUpdate() method.
 */
@Override
public void onComplicationUpdate(
        int complicationId, int dataType, ComplicationManager complicationManager) {
    Log.d(TAG, "onComplicationUpdate() id: " + complicationId);

    // Create Tap Action so that the user can trigger an update by tapping the complication.
    ComponentName thisProvider = new ComponentName(this, getClass());
    // We pass the complication id, so we can only update the specific complication tapped.
    PendingIntent complicationPendingIntent =
            ComplicationTapBroadcastReceiver.getToggleIntent(
                    this, thisProvider, complicationId);

    // Retrieves your data, in this case, we grab an incrementing number from SharedPrefs.
    SharedPreferences preferences =
            getSharedPreferences(
                    ComplicationTapBroadcastReceiver.COMPLICATION_PROVIDER_PREFERENCES_FILE_KEY,
                    0);
    int number =
            preferences.getInt(
                    ComplicationTapBroadcastReceiver.getPreferenceKey(
                            thisProvider, complicationId),
                    0);
    String numberText = String.format(Locale.getDefault(), "%d!", number);

    ComplicationData complicationData = null;

    switch (dataType) {
        case ComplicationData.TYPE_SHORT_TEXT:
            complicationData =
                    new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
                            .setShortText(ComplicationText.plainText(numberText))
                            .setTapAction(complicationPendingIntent)
                            .build();
            break;
        case ComplicationData.TYPE_LONG_TEXT:
            complicationData =
                    new ComplicationData.Builder(ComplicationData.TYPE_LONG_TEXT)
                            .setLongText(ComplicationText.plainText("Number: " + numberText))
                            .setTapAction(complicationPendingIntent)
                            .build();
            break;
        case ComplicationData.TYPE_RANGED_VALUE:
            complicationData =
                    new ComplicationData.Builder(ComplicationData.TYPE_RANGED_VALUE)
                            .setValue(number)
                            .setMinValue(0)
                            .setMaxValue(ComplicationTapBroadcastReceiver.MAX_NUMBER)
                            .setShortText(ComplicationText.plainText(numberText))
                            .setTapAction(complicationPendingIntent)
                            .build();
            break;
        default:
            if (Log.isLoggable(TAG, Log.WARN)) {
                Log.w(TAG, "Unexpected complication type " + dataType);
            }
    }

    if (complicationData != null) {
        complicationManager.updateComplicationData(complicationId, complicationData);

    } else {
        // If no data is sent, we still need to inform the ComplicationManager, so the update
        // job can finish and the wake lock isn't held any longer than necessary.
        complicationManager.noUpdateRequired(complicationId);
    }
}

/*
 * Called when the complication has been deactivated.
 */
@Override
public void onComplicationDeactivated(int complicationId) {
    Log.d(TAG, "onComplicationDeactivated(): " + complicationId);
}
}

代码正在运行,但是...

a) 如何在不点击智能手表的数据字段的情况下,用我的传感器信息更新智能手表数据字段的显示?甚至可能吗?

b) 我必须如何配置 AndroidManifest.xml,以及如何在我的 Java 应用程序中实现 ProviderUpdateRequester 方法 requestUpdateAll() 以手动触发显示更新?

new ProviderUpdateRequester(context, new ComponentName(context, "myComplicationClass"))
        .requestUpdateAll();

就我而言,什么是“上下文”,什么是“myComplicationClass”?

不幸的是,我还没有找到任何好的代码示例......

4

1 回答 1

0

要使用您的传感器值更新您的复杂性,您必须使用共享首选项存储它。在 SensorEventListener 的 onSensorChanged 中执行此操作。

    @Override
    public void onSensorChanged(SensorEvent event) {
        String heartrate = Integer.toString(Math.round(event.values[0]));

        getSharedPreferences("callItWhatEverYouWant", 0).edit().putString("heartrate", heartrate).apply();

        ComponentName providerComponentName = new ComponentName(this, CustomComplicationProviderService.class);
        ProviderUpdateRequester providerUpdateRequester = new ProviderUpdateRequester(this, providerComponentName);
        providerUpdateRequester.requestUpdateAll();
    }

目前,您正在从共享首选项中获取一个数字并将其转换为 numberText。将此替换为您之前定义的传感器值共享首选项。

@Override
public void onComplicationUpdate(
        int complicationId, int dataType, ComplicationManager complicationManager) {
    Log.d(TAG, "onComplicationUpdate() id: " + complicationId);

    // Create Tap Action so that the user can trigger an update by tapping the complication.
    ComponentName thisProvider = new ComponentName(this, getClass());
    // We pass the complication id, so we can only update the specific complication tapped.
    PendingIntent complicationPendingIntent =
            ComplicationTapBroadcastReceiver.getToggleIntent(
                    this, thisProvider, complicationId);

    // Retrieve your sensor value
    String heartrate = getSharedPreferences("callItWhatEverYouWant", 0).getString("heartrate", "--");

    ComplicationData complicationData = null;

    switch (dataType) {
        case ComplicationData.TYPE_SHORT_TEXT:
            complicationData =
                    new ComplicationData.Builder(ComplicationData.TYPE_SHORT_TEXT)
                            .setShortText(ComplicationText.plainText(heartrate))
                            .setTapAction(complicationPendingIntent)
                            .build();
            break;
        case ComplicationData.TYPE_LONG_TEXT:
            complicationData =
                    new ComplicationData.Builder(ComplicationData.TYPE_LONG_TEXT)
                            .setLongText(ComplicationText.plainText("Heart Rate: " + heartrate))
                            .setTapAction(complicationPendingIntent)
                            .build();
            break;
        case ComplicationData.TYPE_RANGED_VALUE:
            complicationData =
                    new ComplicationData.Builder(ComplicationData.TYPE_RANGED_VALUE)
                            .setValue(Integer.parseInt(heartrate))
                            .setMinValue(0)
                            .setMaxValue(ComplicationTapBroadcastReceiver.MAX_NUMBER)
                            .setShortText(ComplicationText.plainText(heartrate))
                            .setTapAction(complicationPendingIntent)
                            .build();
            break;
        default:
            if (Log.isLoggable(TAG, Log.WARN)) {
                Log.w(TAG, "Unexpected complication type " + dataType);
            }
    }

    if (complicationData != null) {
        complicationManager.updateComplicationData(complicationId, complicationData);

    } else {
        // If no data is sent, we still need to inform the ComplicationManager, so the update
        // job can finish and the wake lock isn't held any longer than necessary.
        complicationManager.noUpdateRequired(complicationId);
    }
}

显现...

        <service
            android:name=".CustomComplicationProviderService"
            android:exported="true"
            android:icon="@drawable/ic_heart"
            android:label="Current Heartrate"
            android:permission="com.google.android.wearable.permission.BIND_COMPLICATION_PROVIDER">
            <intent-filter>
                <action
                    android:name="android.support.wearable.complications.ACTION_COMPLICATION_UPDATE_REQUEST"/>
            </intent-filter>

            <meta-data
                android:name="android.support.wearable.complications.SUPPORTED_TYPES"
                android:value="RANGED_VALUE,SHORT_TEXT,LONG_TEXT"/>

            <meta-data
                android:name="android.support.wearable.complications.UPDATE_PERIOD_SECONDS"
                android:value="0" />
        </service>
于 2022-02-13T22:49:40.603 回答