Google nearby - subscribe fails after publish - android

I am writing a sharing app using Google Nearby. I am using MESSAGES_API to publish a message and subscribe to others. The problem is that once a device publishes a message, it will no longer receive messages. I have several devices I am testing - any of which can initially publish a message and other devices receive it. However, if any of the other devices decide they want to publish, the original publisher fails to receive.
How can I continue to receive messages once I publish?
I init my google client here:
mGoogleApiClient = new GoogleApiClient.Builder(mContext)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.addApi(Nearby.MESSAGES_API)
.enableAutoManage(this, this)
.build();
after the google client is connected, I "subscribe' to it
Nearby.Messages.registerStatusCallback(mGoogleApiClient, new StatusCallback() {
#Override
public void onPermissionChanged(boolean b) {
super.onPermissionChanged(b);
Log.d(TAG, "Permission = " + b);
}
});
And, I have a listener to react to messages
Nearby.Messages.subscribe(mGoogleApiClient, mMessageListener).setResultCallback(new ErrorCheckingCallback("subscribe"));
MessageListener mMessageListener = new MessageListener() {
#Override
public void onFound(Message message) {
String messageAsString = new String(message.getContent());
Toast.makeText(mContext, "Incoming Image...", Toast.LENGTH_SHORT).show();
Log.d(TAG, "Found message: " + messageAsString);
}
#Override
public void onLost(Message message) {
String messageAsString = new String(message.getContent());
Log.d(TAG, "Lost sight of message: " + messageAsString);
}
};

Related

How can I get Google Fit Client state?

At some devices, I get data once in an hour! But at another, I get them every 4 minutes.
I make client:
client = new GoogleApiClient.Builder(context)
.addApi(Fitness.SENSORS_API)
.addScope(Fitness.SCOPE_ACTIVITY_READ)
.addScope(Fitness.SCOPE_BODY_READ_WRITE)
.addScope(Fitness.SCOPE_LOCATION_READ_WRITE)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ))
.addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE))
.addScope(new Scope(Scopes.FITNESS_LOCATION_READ_WRITE))
.addConnectionCallbacks(Client.this)
.addOnConnectionFailedListener(Client.this)
.build();
client.connect();
Then sensor:
Fitness.SensorsApi.add(
client,
new SensorRequest.Builder()
.setDataSource(dataSource)
.setDataType(dataType)
.setAccuracyMode(SensorRequest.ACCURACY_MODE_HIGH)
.setSamplingRate(5, TimeUnit.SECONDS)
.setFastestRate(1, TimeUnit.SECONDS)
.setMaxDeliveryLatency(20, TimeUnit.SECONDS)
.build(),
mListener)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
Log.d("stepsCount", "Listener registered!");
} else {
Log.d("stepsCount", "Listener not registered.");
}
}
});
And then I want to check client state, but I don't know how (
You can always check the state with the callback given in the document:
private void buildFitnessClient() {
if (mClient == null && checkPermissions()) {
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.SENSORS_API)
.addScope(new Scope(Scopes.FITNESS_LOCATION_READ))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected!!!");
// Now you can make calls to the Fitness APIs.
findFitnessDataSources();
}
#Override
public void onConnectionSuspended(int i) {
// If your connection to the sensor gets lost at some point,
// you'll be able to determine the reason and react to it here.
if (i == ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
} else if (i
== ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Log.i(TAG,
"Connection lost. Reason: Service Disconnected");
}
}
}
)
.enableAutoManage(this, 0, new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Google Play services connection failed. Cause: " +
result.toString());
Snackbar.make(
MainActivity.this.findViewById(R.id.main_activity_view),
"Exception while connecting to Google Play services: " +
result.getErrorMessage(),
Snackbar.LENGTH_INDEFINITE).show();
}
})
.build();
}
}
Now for some information on how to show the data in your app in real time, using the Sensors API together with the Recording API.
DevBytes: Google Fit APIs for Android - Setup and Sensors
DevBytes: Google Fit APIs for Android - Recording and History
Hope it helps!

watch face service data layer api

I got a problem with the Google android wear Data Layer Api...
I already used it to call handheld activities from a wearable activity and it worked just fine. But now I want call a handheld activity from a watchface service...
I created a Google API Client and added wearableApi:
public void onCreate(SurfaceHolder holder) {
super.onCreate(holder);
setWatchFaceStyle(new WatchFaceStyle.Builder(MyWatchFace.this)
.setCardPeekMode(WatchFaceStyle.PEEK_MODE_VARIABLE)
.setBackgroundVisibility(WatchFaceStyle.BACKGROUND_VISIBILITY_INTERRUPTIVE)
.setShowSystemUiTime(false)
.setAcceptsTapEvents(true)
.build());
mGoogleApiClient = new GoogleApiClient.Builder(MyWatchFace.this)
.addApi(Wearable.API)
.build();
mGoogleApiClient.connect();
Then I used these methods to send the data:
public void startActivity()
{
HashSet<String> results = new HashSet<String>();
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() {
#Override
public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult) {
String handheld = getConnectedNodesResult.getNodes().get(0).getId();
Toast.makeText(MyWatchFace.this, getConnectedNodesResult.getNodes().get(0).getDisplayName()+": "+ handheld, Toast.LENGTH_SHORT).show();
sendStartActivityMessage(handheld, giveValueXYZ());
}
});
private void sendStartActivityMessage(String nodeId, String data) {
byte[] dataArray = data.getBytes();
Toast.makeText(MyWatchFace.this, "ActivityPath: "+ START_ACTIVITY_PATH, Toast.LENGTH_SHORT).show();
Wearable.MessageApi.sendMessage(
mGoogleApiClient, nodeId, START_ACTIVITY_PATH, dataArray).setResultCallback(
new ResultCallback<MessageApi.SendMessageResult>() {
#Override
public void onResult(MessageApi.SendMessageResult sendMessageResult) {
if (!sendMessageResult.getStatus().isSuccess()) {
Log.e(TAG, "Failed to send message with status code: "
+ sendMessageResult.getStatus().getStatusCode());
}
}
});
}
On the mobile site I used this code to listen for the messages:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_host_main);
context = getApplicationContext();
...
//Google Api
final GoogleApiClient googleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API).build();
googleApiClient.connect();
Wearable.MessageApi.addListener(googleApiClient, this);
...
public void onMessageReceived(MessageEvent messageEvent) {
if (messageEvent.getPath().equals(START_ACTIVITY_PATH_WEARDATA)) {
Log.d(TAG, "getPath: " + messageEvent.getPath() + "|||getData: " + messageEvent.getData());
someActions();
}
All this works perfectly fine if I send the message from a wearable activity but does not even trigger the onMessageReceived(...) methode if I send a message from the watchface service...
Could there be a problem with my package names?
mobile :com.example.janik.xxx.xxx
watchface: de.WatchSmart.watch_smart_watch_face_service
How does the client know which Data Layer Api message is adressed to him?

Not able to send data from mobile app to wear app when both the apps implements the WearableListenerService

I have created a mobile app with an Activity which sends the data to wear. Mobile App Side the code is as below
Please note I have deleted some code to reduce the number of lines.
public class MainActivity extends AppCompatActivity implements
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
GoogleApiClient mGoogleClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Build a new GoogleApiClient for the the Wearable API
mGoogleClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
Button sendBtn = (Button) findViewById(R.id.send_btn);
sendBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mGoogleClient.isConnected()) {
Log.w("mobile-p", "connected.....sending data");
sendData();
}
}
});
}
// Connect to the data layer when the Activity starts
#Override
protected void onStart() {
super.onStart();
mGoogleClient.connect();
}
private void constructDataI temsForNotification() {
//I construct the dataItems here which needs to be passed to the wear
//and call the sendata.
sendData();
}
private void sendData() {
//Requires a new thread to avoid blocking the UI
if (mDataMapList != null && mDataMapList.size() > 0 ) {
new SendToDataLayerThread().start();
} else {
Log.w("mobile", "Nothing to notify");
}
}
#Override
public void onConnected(Bundle connectionHint) {
}
// Disconnect from the data layer when the Activity stops
#Override
protected void onStop() {
if (null != mGoogleClient && mGoogleClient.isConnected()) {
mGoogleClient.disconnect();
}
super.onStop();
}
// Placeholders for required connection callbacks
#Override
public void onConnectionSuspended(int cause) {
if (mGoogleClient != null) {
mGoogleClient.reconnect();
}
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) { }
//Use thread or asynctask.
class SendToDataLayerThread extends Thread {
public void run() {
// Construct a DataRequest and send over the data layer
PutDataMapRequest putDMR = PutDataMapRequest.create("/weardatapath");
putDMR.getDataMap().putDataMapArrayList("/weardatapath", mDataMapList);
PutDataRequest request = putDMR.asPutDataRequest();
DataApi.DataItemResult result = Wearable.DataApi.putDataItem(mGoogleClient, request).await();
if (result.getStatus().isSuccess()) {
for (DataMap mapItem : mDataMapList) {
Log.v("mobile-p", "DataMap: " + mapItem + " sent successfully to data layer ");
}
} else {
// Log an error
Log.v("mobile-p", "ERROR: failed to send DataMap to data layer");
}
}
}
}
On the Wear app side I have created a PhoneListenerService as below
public class PhoneListenerService extends WearableListenerService {
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
DataMap dataMap;
for (DataEvent event : dataEvents) {
Log.v("Wear-W", "DataMap received on watch: " + DataMapItem.fromDataItem(event.getDataItem()).getDataMap());
// Check the data type
if (event.getType() == DataEvent.TYPE_CHANGED) {
// Check the data path
String path = event.getDataItem().getUri().getPath();
if (path.equals("/weardatapath")) {
DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
ArrayList<DataMap> dataItems = dataMapItem.getDataMap().getDataMapArrayList
("dataMapItems");
// Broadcast DataMap contents to wearable show in notification..
if (dataItems != null && dataItems.size() > 0) {
for (DataMap item : dataItems) {
........
}
}
}
}
}
}
}
The above code works fine. Whenever I send a data from the MainActivity from mobileApp I do recieve it on the Wear app in PhoneListenerService.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
From the received data I build notifications on the wear app and for each action taken on the notification I want to notify to the mobile App. To do this I created PhoneSyncService on the wear app which will notify the mobile App on the actions taken..
public class PhoneSyncService extends IntentService implements
GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks{
private static final String "wearsrvc-w" = "PhoneSyncService-W";
public static final String ACTION_REPLY = "com.test.mobilewearsample.action.REPLY";
GoogleApiClient mGoogleClient;
public PhoneSyncService() {
super("PhoneSyncService");
}
#Override
public void onCreate() {
super.onCreate();
mGoogleClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
#Override
public void onDestroy() {
if (null != mGoogleClient && mGoogleClient.isConnected()) {
mGoogleClient.disconnect();
}
super.onDestroy();
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
Log.w("wearsrvc-w", "ACTION : "+action);
if (ACTION_REPLY.equals(action)) {
final String uId = intent.getStringExtra("dataId");
notifyHandheldDevice(uId);
}
}
}
private void notifyHandheldDevice(String uId) {
Log.v("wearsrvc-w", "in notify to handheld device :"+uId);
if (mGoogleClient.isConnected()) {
DataMap dataMap = new DataMap();
dataMap.putInt("uId", Integer.valueOf(uId));
PutDataMapRequest putDMR = PutDataMapRequest.create("/mobiledatapath");
putDMR.getDataMap().putAll(dataMap);
PutDataRequest request = putDMR.asPutDataRequest();
DataApi.DataItemResult result = Wearable.DataApi.putDataItem(mGoogleClient, request).await();
if (result.getStatus().isSuccess()) {
Log.v("wearsrvc-w" , "Wear DataMap: " + dataMap + " sent successfully to data layer ");
} else {
// Log an error
Log.v("wearsrvc-w" , "ERROR: failed to send DataMap to data layer");
}
}
Log.v("wearsrvc-w", "done notify to handheld device :"+uId);
}
#Override
public void onConnected(Bundle bundle) {
}
#Override
public void onConnectionSuspended(int i) {
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
}
To get the data sent from wear app to the mobile App I created a WearDataListenerService as well on the mobile app , below is the code.
public class WearDataListenerService extends WearableListenerService {
private static final String TAG = "WearDataLstrService-M";
#Override
public void onDataChanged(DataEventBuffer dataEvents) {
for (DataEvent event : dataEvents) {
Log.v(TAG, "DataMap received on mobile: " + DataMapItem.fromDataItem(event.getDataItem()).getDataMap());
// Check the data type
Log.v(TAG, "event type :"+event.getType());
if (event.getType() == DataEvent.TYPE_CHANGED) {
// Check the data path
String path = event.getDataItem().getUri().getPath();
if (path.equals("/mobiledatapath")) {
DataMap dataMap = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
int uId = dataMap.getInt("dataId");
Log.v(TAG, "action received for uId :"+uId);
}
}
}
}
}
When I did the above changes I started to see a strange issue. When I try to send the data from the mobile app to the wear app the data is received on the WearDataListenerService which is on the mobile app side only and is not being received at the wear app side.
Its like the data sent from mobile app is received on the mobile app WearableListenerService instead of the one on wear app.
Can someone please help me.
Your mobile listener service has the following line:
if (path.equals("/mobiledatapath")) {}
I think you are closing the block too early; did you mean to do:
if (path.equals("/mobiledatapath")) {
// rest of that code
}
Your mobile side is adding/changing data so ANY node can receive a callback, including the mobile device, so that is why your mobile device receives it (and because of your faulty if-clause, it is not filtered out). As for the other part, what is the payload that you are sending in the data (mDataMapList)? Is that the same thing across multiple tries or it changes each time? There are two possible causes:
Your payload is the same so there is no "change", hence onDataChanged is not called for a second time (adding a, say, timestamp to data can address that)
in Play Services 8.3+, some changes were made to batch the data sync across network and transfer them not immediately (can be delayed up to 20 minutes); if an app needs immediate sync, they need to set the urgent flag, see setUrgent(). On the mobile side, teh change can be seen immediately (it is not crossing wire) but on the wear side, it can take a while unless send as urgent.

Multiple instance of GoogleApiClient

Context
When my app is launched for the first time, it asks the user to connect to Google Fit and in the next step (another activity), he has the possibility to connect to Google Plus.
When I accepted to connect to both APIs, once in my app, I have the possibility to disconnect from Fit or Plus, but, I don't know why, it is impossible to disconnect from Fit when the Plus client is connected and if I disconnect from Plus, it works well, but the Fit client gets also disconnected.
When the app is launched, if I decide to connect only to Fit and not Plus, it works as expected, I mean I can disconnect correctly from Fit.
Question
I thought that it was possible to have multiple instances of GoogleApiClient, but I have the impression that both clients are "connected".
Is there a kind of hierarchy between the API clients?
Edit
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
/**
* Create the fitness client - this is mandatory to use the app
*/
buildFitnessClient();
/**
* Get the result of Google Plus connection
*/
// If skip button is clicked, the user does not want to connect to G+
Boolean isSkipClicked = getSharedPreferences("ISSKIPCLICKED", MODE_PRIVATE).getBoolean("isSkipClicked", false);
if(isSkipClicked){
// The user has the possibility to connect to G+ through the menu
}
// else, the user is connected to G+, rebuilt the client
else{
buildPlusClient();
mPlusClient.connect();
}
}
The buildFitnessClient() :
private void buildFitnessClient() {
// Create the Google API Client
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.HISTORY_API)
.addApi(Fitness.RECORDING_API)
.addApi(Fitness.CONFIG_API)
.addScope(new Scope(Scopes.FITNESS_LOCATION_READ_WRITE))
.addScope(new Scope((Scopes.FITNESS_NUTRITION_READ_WRITE)))
.addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE))
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected to Fitness API!!!");
// Now you can make calls to the Fitness APIs.
// Put application specific code here.
mClient.connect();
}
#Override
public void onConnectionSuspended(int i) {
// If your connection to the sensor gets lost at some point,
// you'll be able to determine the reason and react to it here.
if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
} else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Log.i(TAG, "Connection lost. Reason: Service Disconnected");
}
}
}
)
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
// Called whenever the API client fails to connect.
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed. Cause: " + result.toString());
if (!result.hasResolution()) {
// Show the localized error dialog
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(),
Main2Activity.this, 0).show();
return;
}
// The failure has a resolution. Resolve it.
// Called typically when the app is not yet authorized, and an
// authorization dialog is displayed to the user.
if (!authInProgress) {
try {
Log.i(TAG, "Attempting to resolve failed connection");
authInProgress = true;
result.startResolutionForResult(Main2Activity.this, REQUEST_OAUTH);
} catch (IntentSender.SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
}
}
)
.build();
}
The buildPlusClient method:
public void buildPlusClient(){
/**
* Handle the connection to Google Plus client
*/
// Configure sign-in to request the user's ID, email address, and basic
// profile. ID and basic profile are included in DEFAULT_SIGN_IN.
GoogleSignInOptions gso = new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
.requestEmail()
.requestProfile()
.build();
GoogleApiClient.OnConnectionFailedListener unresolvedConnectionFailedListener = new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Log.d(TAG, "onConnectionFailed:" + connectionResult);
}
};
// Build a GoogleApiClient with access to the Google Sign-In API and the
// options specified by gso.
mPlusClient = new GoogleApiClient.Builder(this)
.enableAutoManage(this /* FragmentActivity */, unresolvedConnectionFailedListener /* OnConnectionFailedListener */)
.addApi(Auth.GOOGLE_SIGN_IN_API, gso)
.build();
}
Below, methods to disconnect from Gplus and/or Gfit:
private void signOutFit(){
if(mClient.isConnected()){
Fitness.ConfigApi.disableFit(mClient)
.setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if (status.isSuccess()) {
//Log.d(TAG, "Disconnect success");
Toast.makeText(Main2Activity.this,"Disconnected from Google Fit",Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(Main2Activity.this,"Impossible to disconnect from Fit",Toast.LENGTH_SHORT).show();
}
}
});
}
}
private void signOutPlus(){
if(mPlusClient.isConnected()){
Auth.GoogleSignInApi.signOut(mPlusClient).setResultCallback(
new ResultCallback<Status>() {
#Override
public void onResult(Status status) {
if(status.isSuccess()){
Toast.makeText(Main2Activity.this, "Disconnect from Google Plus", Toast.LENGTH_SHORT).show();
}else{
Toast.makeText(Main2Activity.this, "Impossible to disconnect from Google Plus", Toast.LENGTH_SHORT).show();
}
}
});
}
}

Reading weight with Google Fit

I can connect to Google Fit and read weight data but not all the data that I can see in Google Fit Web. I believe that something is wrong with datasources but I'm not sure. The code for reading is:
Instant endTime = Instant.now();
Instant startTime = DateTime.now().minusYears(10).toInstant();
DataReadRequest readRequest = new DataReadRequest.Builder ()
.setTimeRange (startTime.getMillis(), endTime.getMillis(), TimeUnit.MILLISECONDS)
.read (DataType.TYPE_WEIGHT)
.build ();
DataReadResult dataReadResult = Fitness.HistoryApi.readData(MyApp.mClient, readRequest).await (1, TimeUnit.MINUTES);
https://developers.google.com/fit/rest/v1/authorization#OAuth2Authorizing
DataType.TYPE_WEIGHT must be authorized by an authenticated Scopes.FITNESS_BODY_READ
mClient = new GoogleApiClient.Builder(this)
.addApi(Fitness.HISTORY_API)
.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE))
.addScope(new Scope(Scopes.FITNESS_BODY_READ))
.addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE))
.addConnectionCallbacks(
new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
Log.i(TAG, "Connected!!!");
// Now you can make calls to the Fitness APIs. What to do?
// Look at some data!!
new InsertAndVerifyDataTask().execute();
}
#Override
public void onConnectionSuspended(int i) {
// If your connection to the sensor gets lost at some point,
// you'll be able to determine the reason and react to it here.
if (i == ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Log.i(TAG, "Connection lost. Cause: Network Lost.");
} else if (i == ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Log.i(TAG, "Connection lost. Reason: Service Disconnected");
}
}
}
)
.enableAutoManage(this, 0, new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Google Play services connection failed. Cause: " +
result.toString());
Snackbar.make(
MainActivity.this.findViewById(R.id.main_activity_view),
"Exception while connecting to Google Play services: " +
result.getErrorMessage(),
Snackbar.LENGTH_INDEFINITE).show();
}
})
.build();

Categories

Resources