Android Wearable Data Layer won't sync. - android

I am trying to use Data sync between watch and my phone but I am failing miserably on that.
Mobile side :
package com.off.testcomm;
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setOnClickListener((Button) findViewById(R.id.button));
initGoogleAPIClient();
}
private void setOnClickListener(Button button) {
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.i("OFF", "increase counter");
PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/count");
putDataMapReq.getDataMap().putInt("COUNT_COUNT", 7);
PutDataRequest putDataReq = putDataMapReq.asPutDataRequest();
Wearable.DataApi.putDataItem(mGoogleApiClient, putDataReq)
.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
#Override
public void onResult(DataApi.DataItemResult dataItemResult) {
Log.i("OFF", "SaveConfig: " + dataItemResult.getStatus() + ", " + dataItemResult.getDataItem().getUri());
}
});
}
});
}
private void initGoogleAPIClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle connectionHint) {
Log.d("OFF", "onConnected: " + connectionHint);
// Now you can use the Data Layer API
}
#Override
public void onConnectionSuspended(int cause) {
Log.d("OFF", "onConnectionSuspended: " + cause);
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.d("OFF", "onConnectionFailed: " + result);
}
})
// Request access only to the Wearable API
.addApi(Wearable.API)
.build();
}
#Override
protected void onStop() {
mGoogleApiClient.disconnect();
super.onStop();
}
#Override
protected void onStart() {
super.onStart();
mGoogleApiClient.connect();
}
When I click the button I get :
SaveConfig: Status{statusCode=SUCCESS, resolution=null}, wear://ad9cb4db-c697-4777-9088-0b29b8584043/count
So I assume it is sent.
On Wear :
package com.off.testcomm;
public class MyWatchFace extends CanvasWatchFaceService {
...
private class Engine extends CanvasWatchFaceService.Engine implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,DataApi.DataListener, MessageApi.MessageListener {
#Override
public void onCreate(SurfaceHolder holder) {
super.onCreate(holder);
mGoogleApiClient = new GoogleApiClient.Builder(getApplicationContext())
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
#Override
public void onVisibilityChanged(boolean visible) {
if (visible) {
Log.i("OFF","is visible");
registerReceiver();
mGoogleApiClient.connect();
} ...
#Override
public void onConnected(Bundle bundle) {
Log.i("OFF", "OnConnected ");
Wearable.DataApi.addListener(mGoogleApiClient, this);
}
#Override
public void onConnectionSuspended(int i) {
Log.i("OFF","onConnectionSuspended");
}
#Override
public void onDataChanged(DataEventBuffer dataEventBuffer) {
Log.i("OFF","OnDataChanged");
}
#Override
public void onMessageReceived(MessageEvent messageEvent) {
Log.i("OFF","onMessageReceived");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.i("OFF","onConnectionFailed");
}
...
On wear last log I am getting is : "OnConnected" . When I click button on mobile nothing seems to be synced on wear.
As you can see both classes are in the same packages.
As for manifests both have :
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
any ideas?
thanks
w.

Since you are adding the same data each time the button is clicked, there is no "change" in the exiting data, hence you don't receive an onDataChanged() callback; Android Wear framework looks at the content of your data and decided if it is a new one or not and if it doesn't see any change in the content (assuming that its path doesn't change either), it won't considers that a new one. Add a timestamp to your data and that should make it a new data each time, and should trigger the callback:
putDataMapReq.getDataMap().putLong("timestamp", System.currentTimeMillis());

Related

Google Play Games fails to sign-in at the first attemp, success at the second

I'm experiencing a really silly problem in the Google Play Games API, when a user joins, he needs to click the sign in again to be signed-in.
I have the auto-sign in at startup, so when the user opens the app, it shows the sign-in dialog, choose an email, then closes without any message, after that the user must click on the sign in again to be signed.
So, it's unknown why its happening, the popular problem that people are having is not signing in, but this is failing at the first attemp.
My code:
public class MainActivity extends FragmentActivity implements
View.OnClickListener,GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener{
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Games.API)
.addScope(Games.SCOPE_GAMES)
.build();
}
#Override
protected void onStart(){
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
#Override
public void onConnected(#Nullable Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
if (connectionResult.hasResolution()) {
try {
connectionResult.startResolutionForResult(this, 2);
} catch (IntentSender.SendIntentException e) {
mGoogleApiClient.connect();
} catch (Exception e) {
startActivityForResult(null, 3);
}
}
}
You have to call mGoogleApiClient.connect() in your onActivityResult() method:
#Override
protected void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
mGoogleApiClient.connect();
}
As otherwise the result from connectionResult.startResolutionForResult does not update the GoogleApiClient state.

Can a service be added as a listener in Android?

I am creating an android app, where I start a service in the background which should act as a listener for on Datachanged.BackgroundService is currently not doing anything, except to display log inside OnDatachanged.I would Like to do something like this.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent =new Intent(this,BackgroundService.class);
startService(intent);
Button button=(Button)findViewById(R.id.button);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle connectionHint) {
Log.d("Inside", "onConnected: " + connectionHint);
Toast.makeText(getApplicationContext(),"Inside On connected",Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionSuspended(int cause) {
Log.d("Inside", "onConnectionSuspended: " + cause);
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.d("Inside", "onConnectionFailed: " + result);
}
})
// Request access only to the Wearable API
.addApiIfAvailable(Wearable.API)
.build();
mGoogleApiClient.connect();
// This is what I want to achieve.Is there any way around for this?
Wearable.DataApi.addListener(mGoogleApiClient, BackgroundService.class);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
}
});
}
Background Service extends intentService and Implements Data.ApiDataListener.
If you subclass WearableListenerService it will be called by the system when matching data is changed in the API. You don't need to call addListener in an Activity like this unless that's explicitly what you want to do.
I suggest you start with one of the sample apps (https://developer.android.com/samples/DataLayer seems a good choice) and build from there. The APIs do work.

GoogleApiClient onConnected not called on Watch

I have read this thread but I still faced similar issue:
GoogleApiClient onConnected never called on Wearable device
I tried to follow exactly how this works:
https://developer.android.com/training/wearables/data-layer/events.html
Here are my codes:
public class Main extends Activity implements DataApi.DataListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static final String PATH = "/phonewatch";
private GoogleApiClient client;
#Override
protected void onCreate(Bundle savedInstanceState) {
Log.d("phone watch", "On Create!");
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
client = new GoogleApiClient.Builder(this).addApi(Wearable.API).build();
...
}
#Override
protected void onStart() {
Log.d("phone watch", "On Start!");
super.onStart();
client.connect();
}
#Override
protected void onStop() {
Log.d("phone watch", "On Stop!");
if (client != null && client.isConnected()) {
Wearable.DataApi.removeListener(client, this);
client.disconnect();
}
super.onStop();
}
#Override
public void onConnected(Bundle bundle) {
Log.d("phone watch", "On connected! Add listener.");
Wearable.DataApi.addListener(client, this);
}
#Override
public void onConnectionSuspended(int i) {
Log.d("phone watch", "connection suspended.");
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d("phone watch", "connection failed.");
}
#Override
public void onDataChanged(final DataEventBuffer dataEventBuffer) {
Log.d("phone watch", "Data changed!");
...
}
I only got this:
07-23 20:07:41.730 24874-24874/virtualgs.phonewatch D/phone watch﹕ On Create!
07-23 20:07:41.772 24874-24874/virtualgs.phonewatch D/phone watch﹕ On Start!
On connected and other log messages were not called. Do I miss anything?
Although your activity implements GoogleApiClient.ConnectionCallbacks and GoogleApiClient.OnConnectionFailedListener, you have never registered your activity as a listener to receive those callbacks. When building the api client, you need to call the following two: addConnectionCallbacks(this) and addOnConnectionFailedListener(this):
client = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();

GoogleApiClient.ConnectionCallbacks methods not being called after connecting to the GoogleApiClient

I've got some code which is connecting to the GoogleApiClient but onConnected is not being called.
public class MainActivity extends Activity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private GoogleApiClient mApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initGoogleApiClient();
}
private void initGoogleApiClient() {
mApiClient = new GoogleApiClient.Builder( this )
.addApi( Wearable.API )
.build();
mApiClient.connect(); // On completion onConnected() will be called
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
protected void onDestroy() {
super.onDestroy();
mApiClient.disconnect();
}
#Override
public void onConnectionFailed(com.google.android.gms.common.ConnectionResult connectionResult) {
}
None of the four #Override methods are being called, why is that?
You need to call addConnectionCallbacks() and addOnConnectionFailedListener() on your GoogleApiClient.Builder:
mApiClient = new GoogleApiClient.Builder( this )
.addApi( Wearable.API )
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();

Play Service wont submit score

Im running into a problem when trying to submit a score to my Play Services Leader board. From my MainActivity the user is logged in successfully then from my GameScreen activity I try to submit a score but it fails:(...My Question is does the connection persist or do I have to reconnect the user before I submit???
MAIN ACTIVITY.
public class MainActivity extends BaseGameActivity implements View.OnClickListener, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
Button siButton;
private GoogleApiClient mGoogleApiClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API).addScope(Plus.SCOPE_PLUS_LOGIN)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.build();
siButton = (Button) findViewById(R.id.sign_out_button);
siButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (view.getId() == R.id.sign_in_button) {
beginUserInitiatedSignIn();
} else if (view.getId() == R.id.sign_out_button) {
signOut();
findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
findViewById(R.id.sign_out_button).setVisibility(View.GONE);
}
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public void onSignInSucceeded() {
findViewById(R.id.sign_in_button).setVisibility(View.GONE);
findViewById(R.id.sign_out_button).setVisibility(View.VISIBLE);
}
#Override
public void onSignInFailed() {
findViewById(R.id.sign_in_button).setVisibility(View.VISIBLE);
findViewById(R.id.sign_out_button).setVisibility(View.GONE);
}
#Override
public void onClick(View v) {
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
GAMESCREEN
public class GameScreen extends BaseGameActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private int c;
private GoogleApiClient mGoogleApiClient;
TextView counter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.game_screen);
setRequestedClients(BaseGameActivity.CLIENT_GAMES | BaseGameActivity.CLIENT_APPSTATE);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API).addScope(Plus.SCOPE_PLUS_LOGIN)
.addApi(Games.API).addScope(Games.SCOPE_GAMES)
.build();
private void progressSetup() {
Thread timerThread = new
Thread() {
#Override
public void run() {
try {
while (mbActive && (waited < TIMER_RUNTIME)) {
sleep(THREAD_SLEEP);
if (mbActive) {
waited += 100;
updateProgress(waited);
if (waited > 9999) {
mbActive = false;
gameOver();
}
}
}
} catch (InterruptedException e) {
Log.d("fail", "failure" + e);
}
}
};
startTread = false;
timerThread.start();
}
private void updateProgress(final int timePassed) {
if (null != mProgressBar) {
progress = mProgressBar.getMax() * timePassed / TIMER_RUNTIME;
mProgressBar.setProgress(progress);
}
}
//game over
private void gameOver() {
runOnUiThread(new Runnable() {
#Override
public void run() {
upDateScore();
}
});
}
private void upDateScore(){
if (mGoogleApiClient.isConnected()) {
Games.Leaderboards.submitScore(mGoogleApiClient, getString(R.string.app_id), c);
Log.d("connectted.....................................................");
} else {
Log.d("not connectted.....................................................");
}
}
#Override
public void onBackPressed() {
Intent home = new Intent(GameScreen.this, MainActivity.class);
home.addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
startActivity(home);
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
#Override
public void onSignInFailed() {
}
#Override
public void onSignInSucceeded() {
}
}
Just replace getString(R.string.app_id) with your LEADERBOARD id in method Games.Leaderboards.submitScore(mGoogleApiClient, getString(R.string.app_id).
Leaderboard id looks like this: "CgkI0tXt-q0HEA****"
Ivan Syabro is right. You must use the LEADERBOARD_ID, see Leaderboards in Android - Updating the player's score.
In the developer console's game services section, you can easily export your leaderboard and achievements ids as xml files using the provided button.
In general, using the game services with more than one activity might cause additional waiting periods as each of them signs in individually at its start. Therefore, as far as I know, the implementation with fragments should be preferred, see this famous example playgameservices/android-basic-samples.

Categories

Resources