我的 onReceive 方法被多次调用并从我的 MainActivity (Wear) 触发 onCreate

My onReceive method get called multiple and trigger onCreate from my MainActivity (Wear)

我是 android 的新手。我正在尝试使用 Wea​​rableListenerService 将数据从我的平板电脑发送到我的 phone。这部分运行良好,我可以通过日志看到数据已发送。问题是我在 Listener class 中从平板电脑接收数据,我必须将其传输到 Mainactivity 以更新我的视图。为此,我使用 LocalBroadcaster 并在 MainActivity 中实现了 onReceive 方法。因此,当我下令从 phone 发送数据时,onReceive 在大多数情况下被多次调用 2 或 3 次,而且 activity 被重新创建,因为 onCreate 是由此方法触发的(我不知道这种行为是否是预期的)。

代码如下:

DataLayerListenerService.java(听众)

public class DataLayerListenerService extends WearableListenerService {

// Tag for Logcat
private static final String TAG = "DataLayerService";
private int notificationId = 001;
private String notif;

// Member for the Wear API handle
GoogleApiClient mGoogleApiClient;

@Override
public void onCreate() {
    super.onCreate();

    // Start the Wear API connection
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Wearable.API)
            .build();
    mGoogleApiClient.connect();
}

//@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    Log.v(TAG, "onDataChanged: " + dataEvents);
    for (DataEvent event : dataEvents) {
        if (event.getType() == DataEvent.TYPE_CHANGED) {

            Log.e(TAG, "DataItem Changed: " + event.getDataItem().toString() + "\n"
                    + DataMapItem.fromDataItem(event.getDataItem()).getDataMap());

            String path = event.getDataItem().getUri().getPath();

            switch (path) {
                case DataLayerCommons.NOTIFICATION_PATH:
                    Log.v(TAG, "Data Changed for NOTIF_PATH: " + event.getDataItem().toString());
                    DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
                    notif = dataMapItem.getDataMap().getString(DataLayerCommons.NOTIFICATION_KEY);
                    Intent intent = new Intent(NOTIFICATION_RECEIVED);
                    intent.putExtra(NOTIFICATION_RECEIVED, notif);
                    LocalBroadcastManager.getInstance(this).sendBroadcast(intent);

                    break;
                case DataLayerCommons.COUNT_PATH:
                    Log.v(TAG, "Data Changed for COUNT_PATH: " + event.getDataItem() + "\n"
                            + "Count data = " + DataMapItem.fromDataItem(event.getDataItem())
                            .getDataMap().getInt(DataLayerCommons.COUNT_KEY));
                    break;
                default:
                    Log.v(TAG, "Data Changed for unrecognized path: " + path);
                    break;
            }
        } else if (event.getType() == DataEvent.TYPE_DELETED) {
            Log.v(TAG, "DataItem Deleted: " + event.getDataItem().toString());
        }

        }
    }
}

主要Activity

public class MainActivity extends Activity {

private static final String TAG = "MainActivity";
public static final String NOTIFICATION_RECEIVED = "NOTIFICATION_RECEIVED";
private String notif="";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.e(TAG,"OnCreate");
    setContentView(R.layout.main_activity);
    getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
    LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver,
            new IntentFilter(NOTIFICATION_RECEIVED));

}

private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {

        Log.e(TAG, "Got message!");
        notif = intent.getStringExtra(NOTIFICATION_RECEIVED);
        TextView warnView = findViewById(R.id.warningView);
        warnView.setText(notif);

    }
};

}

AndroidManifest.xml

<uses-feature android:name="android.hardware.type.watch" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.VIBRATE"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/Theme.AppCompat">


    <meta-data
        android:name="com.google.android.wearable.standalone"
        android:value="false" />

    <meta-data
    android:name="com.google.android.gms.version"
    android:value="@integer/google_play_services_version" />

    <service android:name=".DataLayerListenerService">
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.DATA_CHANGED" />

            <data
                android:host="*"
                android:pathPrefix="/notification"
                android:scheme="wear" />
        </intent-filter>
        <intent-filter>
            <action android:name="com.google.android.gms.wearable.MESSAGE_RECEIVED" />
            <data
                android:host="*"
                android:pathPrefix="/start-activity"
                android:scheme="wear" />
        </intent-filter>
    </service>

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
        <intent-filter>
            <action android:name="com.example.android.wearable.datalayer.EXAMPLE" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

</application>

感谢帮助

我建议使用 Application class 来存储您的 Activity 而不是 BroadcastReceiver 注册。

我的意思是:

Application class 中创建一个变量来存储您的 activity:

class MyApp extends Application {
public static MyActivity activity;
}

到 link 在 onCreate 时将电流 activity 保存到此变量中,并在 onDestroy.

时释放

不知何故:

public MyActivity extends Activity {
void onCreate() {
MyApp.activity = this;
}

void onDestroy() {
MyApp.activity = null;
}

void redraw() {
//redraw
}

}

在服务内部做这样的事情:

class MyService extends WearableListenerService {

void onDataChanged() {
if (MyApp.activity != null) {
MyApp.activity.redraw()
}
}

}

不要忘记在清单中设置应用程序:

<application
    android:name=".MyApp"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/Theme.AppCompat">