I'm trying to send data from my wearable to my phone via the DataLayer. The code for mobile is not completed yet, do I have to finish writing it before I send things to the DataLayer from the wearable?
Right now, when I try to do mDataClient.putDataItem(putDataReq)
, I get this error: java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.android.gms.tasks.Task com.google.android.gms.wearable.DataClient.putDataItem(com.google.android.gms.wearable.PutDataRequest)' on a null object reference
sendData(data)
is being called by another class, and there should be no problem with that because I had debug logs confirm that it was working.
I tried using GoogleApiClient.Builder(this).addApi(Wearable.API)
and sending things through Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq)
instead, but even mGoogleApiClient returns null when I do that.
This my build.gradle file:
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.example.watchsleep"
minSdkVersion 23
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.google.android.support:wearable:2.4.0'
implementation 'com.google.android.gms:play-services-wearable:16.0.1'
implementation 'com.android.support:percent:28.0.0'
implementation 'com.android.support:support-v4:28.0.0'
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.android.support:wear:28.0.0'
compileOnly 'com.google.android.wearable:wearable:2.4.0'
}
This is my code:
public class WearActivity extends WearableActivity implements DataClient.OnDataChangedListener {
private static final String COUNT_KEY = "com.example.count";
private DataClient mDataClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_wear);
// Enables Always-on
setAmbientEnabled();
// initialise API client for sending data to phone here
mDataClient = Wearable.getDataClient(this);
}
@Override
protected void onStart(){
super.onStart();
Log.d(TAG, "onStart");
mDataClient = Wearable.getDataClient(this);
}
@Override
protected void onResume() {
super.onResume();
Log.d(TAG, "onResume");
mDataClient = Wearable.getDataClient(this);
Wearable.getDataClient(this).addListener(this);
}
@Override
protected void onPause() {
super.onPause();
Log.d(TAG, "onPause");
Wearable.getDataClient(this).removeListener(this);
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
for (DataEvent event : dataEvents) {
if (event.getType() == DataEvent.TYPE_DELETED) {
Log.d(TAG, "DataItem deleted: " + event.getDataItem().getUri());
} else if (event.getType() == DataEvent.TYPE_CHANGED) {
Log.d(TAG, "DataItem changed: " + event.getDataItem().getUri());
}
}
}
// Create a data map and put data in it
public void sendData(ArrayList<String> data) {
Log.d(TAG, "sending data");
PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count"); // create data map
putDataMapReq.getDataMap().putStringArrayList(COUNT_KEY, data); // put data in map
PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
Task<DataItem> putDataTask = mDataClient.putDataItem(putDataReq); // ERROR COMES FROM THIS LINE
putDataTask.addOnSuccessListener(
new OnSuccessListener<DataItem>() {
@Override
public void onSuccess(DataItem dataItem) {
Log.d(TAG, "Sending text was successful: " + dataItem);
}
});
}
}
It feels like I'm missing something really simple from the code, but I don't know what it is. Any help will be greatly appreciated.
The problem was calling sendData()
in my class by doing this:
WearActivity mAct = new WearActivity();
mAct.sendData();
Following the answer given here, I've since changed it to send the activity as an argument by adding it to the class constructor like so:
// in WearActivity
MyClass instanceClass = new MyClass(this);
// in MyClass
public class MyClass{
private WearActivity mAct;
public MyClass (WearActivity activity) {
mAct = activity;
}
// code
mAct.sendData();