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();
Related
Calling FusedLocationApi within jobscheduler doesn't work. I have tried in 2 ways but onConnected() are never called in both of them. How can I make it work? Thankyou
MainActivity.class
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnStartJob = (Button)findViewById(R.id.startjob);
jobScheduler = (JobScheduler)getSystemService(JOB_SCHEDULER_SERVICE);
btnStartJob.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v) {
ComponentName jobService =
new ComponentName(getPackageName(), MyJobService.class.getName());
PersistableBundle bundle = new PersistableBundle();
bundle.putString("lat", latitude+"");
bundle.putString("lon", longitude+"");
JobInfo jobInfo =
new JobInfo.Builder(MYJOBID, jobService).setPeriodic(10000).
setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY).
setRequiresCharging(false).
setRequiresDeviceIdle(false).
setPersisted(true).
setExtras(bundle).
build();
int jobId = jobScheduler.schedule(jobInfo);
if(jobScheduler.schedule(jobInfo)>0){
}else{
}
}
});
}
}
Try 1:
Here I have implemented ConnectionCallbacks, OnConnectionFailedListener in JobService but its onConnected() method is never called...
public class MyJobService extends JobService implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
protected JobParameters mJobParameters;
private GoogleApiClient mGoogleApiClient;
LocationRequest mLocationRequest;
public MyJobService() {
}
#Override
public boolean onStartJob(JobParameters jobParameters) {
Log.e("token", "Start Job Called");
setUpLocationClientIfNeeded();
mLocationRequest = LocationRequest.create();
// Use high accuracy
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
mLocationRequest.setInterval(5000);
return true;
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
Toast.makeText(this,
"MyJobService.onStopJob()",
Toast.LENGTH_SHORT).show();
return false;
}
#Override
public void onConnected(#Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(this.mGoogleApiClient,
mLocationRequest, this); // This is the changed line.
Log.e("onConnected", "onConnected");
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
private void setUpLocationClientIfNeeded()
{
if(mGoogleApiClient == null)
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
this.mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
this.mGoogleApiClient.connect();
}
#Override
public void onLocationChanged(Location location) {
Log.e("token",location.getLatitude()+""+location.getLongitude());
}
}
Try 2:
Called innerClass that implements ConnectionCallbacks, OnConnectionFailedListener in onStartJob of JobService but still onConnected method is never called
public class MyJobService extends JobService {
private Location mLastLocation;
String latitude = null;
String longitude = null;
protected JobParameters mJobParameters;
private class GetLocation extends AsyncTask<Integer, Void, Integer> implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
protected Integer doInBackground(Integer... jobID) {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(getBaseContext())
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
return jobID[0];
}
protected void onPostExecute(Integer jobID) {
//h2 = new Handler();
//Runnable run = new Runnable() {
// #Override
// public void run() {
// long millis = System.currentTimeMillis() - 0;
// int seconds = (int) (millis / 1000);
// int minutes = seconds / 60;
// seconds = seconds % 60;
// Log.i("JobSchedulerTest","Job Finished!");
// h2.postDelayed(this, 1500);
jobFinished(mJobParameters, true);
}
};
}
#Override
public void onConnected(#Nullable Bundle bundle) {
Log.e("onConnected " , "onConnected" );
createLocationRequest();
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
protected void createLocationRequest() {
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setFastestInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
if (ActivityCompat.checkSelfPermission(MyJobService.this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MyJobService.this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, new LocationCallback() {
#Override
public void onLocationResult(final LocationResult locationResult) {
latitude = locationResult.getLastLocation().getLatitude() + "";
longitude = locationResult.getLastLocation().getLongitude() + "";
Log.e("onLocationResult lat", latitude);
Log.e("onLocationResult Lon", longitude);
}
#Override
public void onLocationAvailability(LocationAvailability locationAvailability) {
}
}, null);
}
}
public MyJobService() {
}
#Override
public boolean onStartJob(JobParameters jobParameters) {
Log.d("onstart", "onStartJob() :: ");
mJobParameters=jobParameters;
Integer i=new Integer(jobParameters.getJobId());
new GetLocation().execute(i);
return false;
}
#Override
public boolean onStopJob(JobParameters jobParameters) {
Toast.makeText(this,
"MyJobService.onStopJob()",
Toast.LENGTH_SHORT).show();
return false;
}
}
My Activity is like this:
public class MainMap extends FragmentActivity implements OnMarkerClickListener, OnMapReadyCallback,
ConnectionCallbacks, OnConnectionFailedListener, LocationListener, ActivityCompat.OnRequestPermissionsResultCallback {
private static final int REQUEST_ACCESS_FINE_LOCATION = 0;
protected GoogleApiClient mGoogleApiClient;
protected Location mCurrentLocation;
protected LocationRequest mLocationRequest;
// ...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(NativeLib.get_location_update_interval_in_mil());
mLocationRequest.setFastestInterval(NativeLib.get_location_fastest_update_interval_in_mil());
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
#Override
protected void onStart() {
if (debug_mode) { Log.i(TAG, "onStart");}
super.onStart();
mGoogleApiClient.connect();
}
#Override
protected void onStop() {
if (debug_mode) { Log.i(TAG, "onStop");}
super.onStop();
mGoogleApiClient.disconnect();
}
#Override
public void onConnected(Bundle connectionHint) {
if (debug_mode) { Log.i(TAG, "onConnected");}
// permissions
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
request_fine_location_permission();
}
// location
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}
#Override
public void onLocationChanged(Location location) {
// CALL either do_background or do_foreground
}
private void do_background() {
// DO WORK
}
private void do_foreground() {
// DO WORK
}
}
The code works just fine in the foreground - what I want to do is to make sure that location is constantly tracked (even when the app is in the background or the phone is in sleep mode) and launch the appropriate function in my Activity.
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());
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();
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.