google nearby connection access to api - android

I have a problem with the last update of the google nearby connections API.
When I call start Discovery () or start Advertising () before the update I needed to pass a googleApiClient as a parameter.
After the update, I don't need to do this, but I still need to access the api with googleApiClient.
How can I run the sample without using googleApiClient?
private void startAdvertising() {
Nearby.getConnections(context).startAdvertising(
getUserNickname(),
SERVICE_ID,
mConnectionLifecycleCallback,
new AdvertisingOptions(STRATEGY))
.addOnSuccessListener(
new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unusedResult) {
// We're advertising!
}
})
.addOnFailureListener(
new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
// We were unable to start advertising.
}
});
}

Use Nearby.Connections instead of Nearby.getConnections.

Use Nearby.getConnectionsClient(Context), to use the API without making a GoogleApiClient.

Related

Why does PlacesClient.fetchPlace Task never hit a callback

I'm migrating from the old Android Places API to either the new one or the compatibility library, in both approaches the auto prediction search works, but getting more details from the ID of the selected location appears to never complete.
I started with the compatibility library, the initial autoPrediction lookup works as expected. Suggesting the API key and account are fine. But getPlaceByID failed to finish.
I've switched to the new API instead, again, the new FindAutocompletePredictions works, but the fetchPlaces task never finishes.
I've boiled the code down to manually putting an ID in, only asking for LatLong, and having all the available listeners with breakpoints. They are never hit.
List<Place.Field> placeFields = Arrays.asList(Place.Field.LAT_LNG);
FetchPlaceRequest request = FetchPlaceRequest.builder("EhtHbGFzZ293IFN0cmVldCwgR2xhc2dvdywgVUsiLiosChQKEgmvXKElzUWISBFN3LArF1aEERIUChIJqZHHQhE7WgIReiWIMkOg-MQ", placeFields)
.build();
placesClient.fetchPlace(request).addOnCompleteListener(new OnCompleteListener<FetchPlaceResponse>() {
#Override
public void onComplete(#NonNull Task<FetchPlaceResponse> task) {
System.out.println("");
}
}).addOnCanceledListener(new OnCanceledListener() {
#Override
public void onCanceled() {
System.out.println("");
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
System.out.println("");
}
}).addOnSuccessListener(new OnSuccessListener<FetchPlaceResponse>() {
#Override
public void onSuccess(FetchPlaceResponse fetchPlaceResponse) {
System.out.println("");
}
});
I would expect to hit one of the listeners and see a place, or some reason for it to fail. Or, at least something in the logcat to say what's going on.
Use
public Task<TResult> addOnCompleteListener(#NonNull OnCompleteListener<TResult> var1)

How to authenticate a Firebase user with ChatSDK?

I've integrated Firebase into my app. I can authenticate with Firebase via email/password. Then I initialize the ChatSDK and call InterfaceManager.shared().a.startLoginActivity(this,true); From there, the app is "taken over" by the default chat user interface and the functionality works great and ChatSDK.currentUser() returns the expected User object.
I would like to do the same thing with my own UI. To authenticate a user after ChatSDK initialization, I've tried:
ChatSDK.auth().authenticateWithCachedToken();
ChatSDK.auth().authenticate(AccountDetails.signUp(email,pwd));
ChatSDK.auth().authenticate(AccountDetails.username(email,pwd));
It is my understanding that I wouldn't be able to do ChatSDK.thread().createThread(...) until I have a valid User. However, after each authentication attempt, ChatSDK.currentUser() is null.
Looking at the ChatSDK source code and documentation, it appears this is the mechanism for authentication. Is there something I'm missing?
Subscribe is necessary, even if you aren't using it.
ChatSDK.auth()
.authenticateWithCachedToken()
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action() {
#Override
public void run() throws Exception {
Log.d("Success","We're in!");
}
}, new Consumer<Throwable>() {
#Override
public void accept(Throwable throwable) throws Exception {
Log.d("Err",throwable.toString());
}
});
Also, here's some code to start a new chat thread with a known user id.
UserWrapper userWrapper = UserWrapper.initWithEntityId(firebaseUser.uid);
userWrapper.metaOn();
userWrapper.onlineOn();
User otherUser = userWrapper.getModel();
ProgressDialog pd = new ProgressDialog(MainActivity.this);
pd.show();
ChatSDK.thread().createThread("", otherUser, ChatSDK.currentUser())
.observeOn(AndroidSchedulers.mainThread())
.doFinally(() -> {
pd.dismiss();
})
.subscribe(thread -> {
ChatSDK.ui().startChatActivityForID(getApplicationContext(), thread.getEntityID());
}, throwable -> {
ToastHelper.show(getApplicationContext(), throwable.getLocalizedMessage());
});

Using RxJava with Paho MQTT

In my Android app, I have a service which has an instance of a class(call it MQTTClient) which publishes or subscribes to an MQTT server. I want to use RxJava with Eclipse Paho Android to manage MQTT subscribe and publish operations.
I am using Single observable and SingleObserver for publishing, and Flowable observable and Observer for subscribing. But I am stuck at a point where I cannot figure out when and how to dispose of the Disposable.
Here is the Single Observable from the publish method in MQTTClient
Single<IMqttToken> pubTokenSingle = Single.create(new SingleOnSubscribe<IMqttToken>() {
#Override
public void subscribe(final SingleEmitter<IMqttToken> emitter) throws Exception {
final IMqttToken token = client.publish(topic, mqttMessage);
token.setActionCallback(new IMqttActionListener() {
#Override
public void onSuccess(IMqttToken asyncActionToken) {
emitter.onSuccess(token);
}
#Override
public void onFailure(IMqttToken asyncActionToken, Throwable exception) {
boolean hasNetwork = isOnline(context);
if (hasNetwork && Objects.equals(((MqttException) exception).getReasonCode(),
MqttException.REASON_CODE_CLIENT_NOT_CONNECTED)) {
//connect client and retry MQTT pub
try {
//connect() is a method in MQTTClient
//connect() method also utilizes RxJava2 Single.
//Same issue of disposing a `Disposable` exists in that method as well
connect();
//call the publish method again
} catch (MqttException e) {
e.printStackTrace();
emitter.onError(e);
}
} else if (!hasNetwork) {
emitter.onError(exception);
} else {
emitter.onError(exception);
}
}
});
}
});
Here is the SingleObserver
final Disposable[] disposable = new Disposable[1];
SingleObserver<IMqttToken> pubTokenSingleObserver = new SingleObserver<IMqttToken>() {
#Override
public void onSubscribe(Disposable d) {
disposable[0] = d;
}
#Override
public void onSuccess(IMqttToken iMqttToken) {
//disposable[0].dispose();
//Planning to use the above as last resort
//Also thought of moving this to doOnSuccess
}
#Override
public void onError(Throwable e) {
//Put topic name, and mqtt message in SQLite
//disposable[0].dispose();
//Planning to use the above as last resort
//Also thought of moving this to doOnError
}
};
Someone suggested that I have a cleanup method in the concerned class which gets called when onStop is invoked.
I am concerned what would happen in case I use disposable.dispose() and the network operation is still in progress.
How do I ensure that if the operation is incomplete then at least the details persist in the SQLite DB?
I am hoping that the solution would be easily extensible for subscribing as well. If not then tell me about the possible pitfalls.
This is a learning project where I am learning RxJava2 that is why I didn't opt for RxMQTT.

Stripe creates token on Android

We are trying to create a stripe token from a credit card on our android application, but when we call stripe.createToken it does nothing, it doesn't enter onSuccess nor onError methods in the listener. Our code is the following:
private void getStripeToken(Card card) {
Stripe stripe = null;
try {
stripe = new Stripe(getApplicationContext(), getString(R.string.stripe_public_key));
} catch (AuthenticationException e) {
e.printStackTrace();
return;
}
stripe.createToken(card, new TokenCallback() {
#Override
public void onError(Exception error) {
stripeError = error.getLocalizedMessage();
}
#Override
public void onSuccess(Token token) {
stripeToken = token;
}
});
}
When getStripeToken is finished, stripeError and stripeToken are null. Where are the mistake? Thanks
At the end of your getStripeToken method, the values are going to be unchanged because createToken is an asynchronous action -- that's why you have to give it a callback.
So, if you use createToken, you must be on the UI thread (because it uses a AsyncTask to make that call, and you should expect your values to be updated whenever the network call is done.
If you want the values to be updated at the end of your method call, use createTokenSynchronous, but be sure to only do so off the main thread.

Access google plus client from multiple activities

I'm developing an application in which i have integrated google plus. So far Its working fine, I am able to retrieve the user profile.
But now i want to do the following:
1)I have two activity signInActivity and shareActivity.
2)If user is already signin using signInActivity then it should not ask for signin again in
shareActivity and should directly share the content.
3)If user is not signedin in the signInActivity and try to share data using shareActivitythen app should signin the user and then only share the data. In this case if user goes back to the signInActivity then app should show that "you have already signedin"
In short i want user signin to be Central within application so that if it is alrady signedin it should be accessible from any activity.
I have heard about the access token but i dont know how to use it and document says that it expires in an hour which is not what i want.
How can i make central google plus signin? is it possible? or i need to authenticate user in each activity?
Managing a separate instance of GoogleApiClient in each activity will not result in the user being asked to sign in multiple times.
Google+ Sign-in (ie. GoogleApiClient) provides an interface to the Google accounts on the device and the Google Play services core service - it doesn't have state per GoogleApiClient instance. So once a device account has been authenticated for your app, new instances of GoogleApiClient will access the same state. GoogleApiClient is specifically designed to be a lightweight way to access the central state managed by Google Play services.
You're in luck regarding access tokens! Google Play services takes care of all token management for you. So although access tokens only last for one hour, as you say, if you try to use your PlusClient to access a Google API and your access token has expired, Google Play services will transparently request a new access token for you and complete the call.
Take a look at the first part of this Google I/O talk for more details:
http://www.youtube.com/watch?v=_KBHf1EODuk
0. TL;DR
For the impatient coder, a working version of the following implementation can be found on GitHub. This is the same answer written on another Stack Overflow post.
After rewriting the login activity code several times in many different apps, the easy (and not so elegant) solution was create the Google API client as a Application class object. But, since the connection state affect the UX flow, I never was happy about with this approach.
Reducing our problem only to the connection concept, we may consider that:
It hides the Google API client.
It has finite states.
It is a (rather) unique.
The current state affect the behavior of the app.
1. Proxy Pattern
Since the Connection encapsulates the GoogleApiClient, it will implement the ConnectionCallbacks and OnConnectionFailedListener:
#Override
public void onConnected(Bundle hint) {
changeState(State.OPENED);
}
#Override
public void onConnectionSuspended(int cause) {
changeState(State.CLOSED);
connect();
}
#Override
public void onConnectionFailed(ConnectionResult result) {
if (currentState.equals(State.CLOSED) && result.hasResolution()) {
changeState(State.CREATED);
connectionResult = result;
} else {
connect();
}
}
Activities can communicate to the Connection class through the methods connect, disconnect, and revoke, but their behaviors are decided by the current state. The following methods are required by the state machine:
protected void onSignIn() {
if (!googleApiClient.isConnected() && !googleApiClient.isConnecting()) {
googleApiClient.connect();
}
}
protected void onSignOut() {
if (googleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(googleApiClient);
googleApiClient.disconnect();
googleApiClient.connect();
changeState(State.CLOSED);
}
}
protected void onSignUp() {
Activity activity = activityWeakReference.get();
try {
changeState(State.OPENING);
connectionResult.startResolutionForResult(activity, REQUEST_CODE);
} catch (IntentSender.SendIntentException e) {
changeState(State.CREATED);
googleApiClient.connect();
}
}
protected void onRevoke() {
Plus.AccountApi.clearDefaultAccount(googleApiClient);
Plus.AccountApi.revokeAccessAndDisconnect(googleApiClient);
googleApiClient = googleApiClientBuilder.build();
googleApiClient.connect();
changeState(State.CLOSED);
}
2. State Pattern
This is a behavioral pattern the allow an object to alter its behavior when its internal state changes. The GoF Design Patterns book describes how a TCP connection can be represent by this pattern (which is also our case).
A state from a state machine should be a singleton, and the easiest away of doing it in Java was to create Enum named State as follows:
public enum State {
CREATED {
#Override
void connect(Connection connection) {
connection.onSignUp();
}
#Override
void disconnect(Connection connection) {
connection.onSignOut();
}
},
OPENING {},
OPENED {
#Override
void disconnect(Connection connection) {
connection.onSignOut();
}
#Override
void revoke(Connection connection) {
connection.onRevoke();
}
},
CLOSED {
#Override
void connect(Connection connection) {
connection.onSignIn();
}
};
void connect(Connection connection) {}
void disconnect(Connection connection) {}
void revoke(Connection connection) {}
The Connection class holds the context, i.e. the current state, which defines how the Connection methods connect, disconnect, and revoke will behave:
public void connect() {
currentState.connect(this);
}
public void disconnect() {
currentState.disconnect(this);
}
public void revoke() {
currentState.revoke(this);
}
private void changeState(State state) {
currentState = state;
setChanged();
notifyObservers(state);
}
3. Singleton Pattern
Since there is not need to recreate this class repeatedly, we provide it as a singleton:
public static Connection getInstance(Activity activity) {
if (null == sConnection) {
sConnection = new Connection(activity);
}
return sConnection;
}
public void onActivityResult(int result) {
if (result == Activity.RESULT_OK) {
changeState(State.CREATED);
} else {
changeState(State.CLOSED);
}
onSignIn();
}
private Connection(Activity activity) {
activityWeakReference = new WeakReference<>(activity);
googleApiClientBuilder = new GoogleApiClient
.Builder(activity)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(Plus.API, Plus.PlusOptions.builder().build())
.addScope(new Scope("email"));
googleApiClient = googleApiClientBuilder.build();
currentState = State.CLOSED;
}
4. Observable Pattern
The Connection class extends Java Observable, so 1 or more activities can observe the state changes:
#Override
protected void onCreate(Bundle bundle) {
connection = Connection.getInstance(this);
connection.addObserver(this);
}
#Override
protected void onStart() {
connection.connect();
}
#Override
protected void onDestroy() {
connection.deleteObserver(this);
connection.disconnect();
}
#Override
protected void onActivityResult(int request, int result, Intent data) {
if (Connection.REQUEST_CODE == request) {
connection.onActivityResult(result);
}
}
#Override
public void update(Observable observable, Object data) {
if (observable != connection) {
return;
}
// Your presentation logic goes here...
}
For anyone reading this question you can also check this answer by Ian Barber and also the one below, answered by Lee, that explains three broad ways of working with Google plus login and multiple activies which I found very useful actually.

Categories

Resources