Android - Set timeout to Loader - android

I'm using loaders to handle internet connections and it's working fine. Now I want to control the duration of the connection attempt, in other words to set a timeout.
I'm using the following code:
in onCreate method:
Uri SearchUri =
Uri.parse(urlString);
Bundle args = new Bundle();
args.putParcelable(ARGS_URI, SearchUri);
// Initialize the Loader.
getLoaderManager().initLoader(LOADER_SEARCH,
args, this);
The other methods:
#Override
public Loader<RESTLoader.RESTResponse> onCreateLoader(int i, Bundle args) {
a = args;
Log.v("TESTING","in OnCreateLoader");
if (args != null && args.containsKey(ARGS_URI)){
Log.v("TESTING","in OnCreateLoader, getting communication key");
Uri action = args.getParcelable(ARGS_URI);
return new RESTLoader(this, RESTLoader.HTTPVerb.GET,action);
}
return null;
}
#Override
public void onLoadFinished(Loader<RESTLoader.RESTResponse> loader, RESTLoader.RESTResponse data) {
int code = data.getCode();
String json = data.getData();
if (code == 200){
Log.v("TESTING","Inside onLoadFinished, code = 200");
}
else {
Log.v("TESTING","Inside onLoadFinished, code != 200");
Toast.makeText(getApplicationContext(), "Connection Problem", Toast.LENGTH_SHORT).show();
}
// Check to see if we got an HTTP 200 code and have some data.
if (code == 200 && !json.equals("")) {
...
}
}
So how can I set a timeout on the loader? For instance give a 10 sec duration, if there's no response yet, stop the attempt.

Related

how to get CallId in CSipSimple in Android

I am using CSipSimple for adding a new feature which is transfer call . For this feature I need the callID of call .
I am seeing that when I call ,the following function is called .
public void placeCallWithOption(Bundle b) {
if (service == null) {
return;
}
String toCall = "";
Long accountToUse = SipProfile.INVALID_ID;
// Find account to use
SipProfile acc = accountChooserButton.getSelectedAccount();
if(acc == null) {
return;
}
accountToUse = acc.id;
// Find number to dial
toCall = digits.getText().toString();
if(isDigit) {
toCall = PhoneNumberUtils.stripSeparators(toCall);
}
if(accountChooserFilterItem != null && accountChooserFilterItem.isChecked()) {
toCall = rewriteNumber(toCall);
}
if (TextUtils.isEmpty(toCall)) {
return;
}
// Well we have now the fields, clear theses fields
digits.getText().clear();
// -- MAKE THE CALL --//
if (accountToUse >= 0) {
// It is a SIP account, try to call service for that
try {
service.makeCallWithOptions(toCall, accountToUse.intValue(), b);
// service.xfer(callId,"01628105601");
} catch (RemoteException e) {
Log.e(THIS_FILE, "Service can't be called to make the call");
}
} else if (accountToUse != SipProfile.INVALID_ID) {
// It's an external account, find correct external account
CallHandlerPlugin ch = new CallHandlerPlugin(getActivity());
ch.loadFrom(accountToUse, toCall, new OnLoadListener() {
#Override
public void onLoad(CallHandlerPlugin ch) {
placePluginCall(ch);
}
});
}
}
But from this , I can't get callId of the call. How can I get callId of each call ? Any advice is of great help .
Using SipCallSession to fetch a call id
SipCallSession callInfo = new SipCallSession();
callinfo.getCallid();

Android Google Play Services returns invalid token for blogger api

I've been given access to the blogger API, I've confirmed that on my developer console.
I've also written some code to perform oAuth2 with Google Play Services using some of the code below.
String SCOPE ="oauth2:https://www.googleapis.com/auth/blogger";
GoogleAuthUtil.getToken(context, "myEmail#gmail.com", mScope);
It returns a token. As it should.
However, once I try to access the api using the token i get a error.
Unexpected response code 403 for https://www.googleapis.com/blogger/v3/users/self/blogs
Here is my request:
And here is my response:
Here is my BaseActivity.java code that gets the token:
public class BaseActivity extends Activity {
static final int REQUEST_CODE_PICK_ACCOUNT = 1000;
static final int REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR = 1001;
static final int REQUEST_CODE_RECOVER_FROM_AUTH_ERROR = 1002;
private static final String SCOPE ="oauth2:https://www.googleapis.com/auth/blogger";
private String mEmail; // Received from newChooseAccountIntent(); passed to getToken()
public ProgressDialog mDialog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mDialog = new ProgressDialog(this);
login();
}
public void login() {
pickUserAccount();
}
private void pickUserAccount() {
String[] accountTypes = new String[]{"com.google"};
Intent intent = AccountPicker.newChooseAccountIntent(null, null, accountTypes, false, null, null, null, null);
startActivityForResult(intent, REQUEST_CODE_PICK_ACCOUNT);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_CODE_PICK_ACCOUNT) {
// Receiving a result from the AccountPicker
if (resultCode == RESULT_OK) {
mEmail = data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
// With the account name acquired, go get the auth token
getToken();
} else if (resultCode == RESULT_CANCELED) {
// The account picker dialog closed without selecting an account.
// Notify users that they must pick an account to proceed.
Toast.makeText(this, "Pick Account", Toast.LENGTH_SHORT).show();
}
} else if ((requestCode == REQUEST_CODE_RECOVER_FROM_AUTH_ERROR ||
requestCode == REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR)
&& resultCode == RESULT_OK) {
// Receiving a result that follows a GoogleAuthException, try auth again
getToken();
}
}
private void getToken() {
if (mEmail == null) {
pickUserAccount();
} else {
if (isDeviceOnline()) {
new getTokenTask(BaseActivity.this, mEmail, SCOPE).execute();
} else {
Toast.makeText(this, "Not online", Toast.LENGTH_LONG).show();
}
}
}
/**
* This method is a hook for background threads and async tasks that need to
* provide the user a response UI when an exception occurs.
*/
public void handleException(final Exception e) {
// Because this call comes from the AsyncTask, we must ensure that the following
// code instead executes on the UI thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
if (e instanceof GooglePlayServicesAvailabilityException) {
// The Google Play services APK is old, disabled, or not present.
// Show a dialog created by Google Play services that allows
// the user to update the APK
int statusCode = ((GooglePlayServicesAvailabilityException)e).getConnectionStatusCode();
Dialog dialog = GooglePlayServicesUtil.getErrorDialog(statusCode, BaseActivity.this, REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR);
dialog.show();
} else if (e instanceof UserRecoverableAuthException) {
// Unable to authenticate, such as when the user has not yet granted
// the app access to the account, but the user can fix this.
// Forward the user to an activity in Google Play services.
Intent intent = ((UserRecoverableAuthException)e).getIntent();
startActivityForResult(intent, REQUEST_CODE_RECOVER_FROM_PLAY_SERVICES_ERROR);
}
}
});
}
public boolean isDeviceOnline() {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
return true;
} else {
return false;
}
}
public class getTokenTask extends AsyncTask{
Activity mActivity;
String mScope;
String mEmail;
getTokenTask(Activity activity, String name, String scope) {
this.mActivity = activity;
this.mScope = scope;
this.mEmail = name;
}
#Override
protected Object doInBackground(Object[] params) {
try {
String token = fetchToken();
Preferences.saveString(Constants.KEY_BLOGGER_TOKEN, token);
} catch (IOException e) {
// The fetchToken() method handles Google-specific exceptions,
// so this indicates something went wrong at a higher level.
// TIP: Check for network connectivity before starting the AsyncTask.
}
return null;
}
/**
* Gets an authentication token from Google and handles any
* GoogleAuthException that may occur.
*/
protected String fetchToken() throws IOException {
try {
return GoogleAuthUtil.getToken(mActivity, mEmail, mScope);
} catch (UserRecoverableAuthException userRecoverableException) {
// GooglePlayServices.apk is either old, disabled, or not present
// so we need to show the user some UI in the activity to recover.
((BaseActivity)mActivity).handleException(userRecoverableException);
} catch (GoogleAuthException fatalException) {
// Some other type of unrecoverable exception has occurred.
// Report and log the error as appropriate for your app.
}
return null;
}
}
}
I've been banging my head against the wall on this one. Anyone have any ideas?
Finally figured it out.
My build.gradle file somehow ended up having a different Application ID than my manifest. I changed it so they both match the manifest, and boom! it worked.

Stuck in Connection Failed loop with GoogleApiClient

I am trying to implement the com.google.android.gms.common.api.GoogleApiClient in my project.
The problem is that every time I try to connect, I get the call back to the onConnectionFailed listener with a pending intent that I execute. On a clean install, the very first pending intent will launch an account select screen. This is expected. Every subsequent restart of the app will bypass the account selection, unless the app's data is cleared in the Application Manager.
After the account-select screen, the signing-in screen will appear breifly. It never signs in though. The onActivityResult will be called after the signing-in screen flashes, which tries to connect the client. It doesn't connect, and calls the onConnectionFailed listener again.
If I keep trying to execute the intents, I get stuck in loop with the signing in screen breifly appearing, then disappearing, but never connecting or getting signed in. The ConnectionResult.toString indicates "Sign_In_Required", and returns an error code of 4 (the same as the Sign_In_Required constant.
On the API console, I've implemented an Ouath 2.0 client ID, and a public API access key for android applications. Notably, my app works using the older com.google.api.services.drive.Drive client.
As for my code:
I've tried using two different implementations here and here. I tried to implement the second example making as few changes as possible. It is reproduced below:
public class MainActivity extends Activity implements ConnectionCallbacks,
OnConnectionFailedListener {
private static final String TAG = "android-drive-quickstart";
private static final int REQUEST_CODE_CAPTURE_IMAGE = 1;
private static final int REQUEST_CODE_CREATOR = 2;
private static final int REQUEST_CODE_RESOLUTION = 3;
private GoogleApiClient mGoogleApiClient;
private Bitmap mBitmapToSave;
/**
* Create a new file and save it to Drive.
*/
private void saveFileToDrive() {
// Start by creating a new contents, and setting a callback.
Log.i(TAG, "Creating new contents.");
final Bitmap image = mBitmapToSave;
Drive.DriveApi.newContents(mGoogleApiClient).setResultCallback(new ResultCallback<DriveApi.ContentsResult>() {
#Override
public void onResult(DriveApi.ContentsResult result) {
// If the operation was not successful, we cannot do anything
// and must
// fail.
if (!result.getStatus().isSuccess()) {
Log.i(TAG, "Failed to create new contents.");
return;
}
// Otherwise, we can write our data to the new contents.
Log.i(TAG, "New contents created.");
// Get an output stream for the contents.
OutputStream outputStream = result.getContents().getOutputStream();
// Write the bitmap data from it.
ByteArrayOutputStream bitmapStream = new ByteArrayOutputStream();
image.compress(Bitmap.CompressFormat.PNG, 100, bitmapStream);
try {
outputStream.write(bitmapStream.toByteArray());
} catch (IOException e1) {
Log.i(TAG, "Unable to write file contents.");
}
// Create the initial metadata - MIME type and title.
// Note that the user will be able to change the title later.
MetadataChangeSet metadataChangeSet = new MetadataChangeSet.Builder()
.setMimeType("image/jpeg").setTitle("Android Photo.png").build();
// Create an intent for the file chooser, and start it.
IntentSender intentSender = Drive.DriveApi
.newCreateFileActivityBuilder()
.setInitialMetadata(metadataChangeSet)
.setInitialContents(result.getContents())
.build(mGoogleApiClient);
try {
startIntentSenderForResult(
intentSender, REQUEST_CODE_CREATOR, null, 0, 0, 0);
} catch (SendIntentException e) {
Log.i(TAG, "Failed to launch file chooser.");
}
}
});
}
#Override
protected void onResume() {
super.onResume();
if (mGoogleApiClient == null) {
// Create the API client and bind it to an instance variable.
// We use this instance as the callback for connection and connection
// failures.
// Since no account name is passed, the user is prompted to choose.
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
// Connect the client. Once connected, the camera is launched.
mGoogleApiClient.connect();
}
#Override
protected void onPause() {
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
super.onPause();
}
#Override
protected void onActivityResult(final int requestCode, final int resultCode, final Intent data) {
switch (requestCode) {
case REQUEST_CODE_CAPTURE_IMAGE:
// Called after a photo has been taken.
if (resultCode == Activity.RESULT_OK) {
// Store the image data as a bitmap for writing later.
mBitmapToSave = (Bitmap) data.getExtras().get("data");
}
break;
case REQUEST_CODE_CREATOR:
// Called after a file is saved to Drive.
if (resultCode == RESULT_OK) {
Log.i(TAG, "Image successfully saved.");
mBitmapToSave = null;
// Just start the camera again for another photo.
startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
REQUEST_CODE_CAPTURE_IMAGE);
}
break;
}
}
#Override
public void onConnectionFailed(ConnectionResult result) {
// Called whenever the API client fails to connect.
Log.i(TAG, "GoogleApiClient connection failed: " + result.toString());
if (!result.hasResolution()) {
// show the localized error dialog.
GooglePlayServicesUtil.getErrorDialog(result.getErrorCode(), 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.
try {
result.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (SendIntentException e) {
Log.e(TAG, "Exception while starting resolution activity", e);
}
}
#Override
public void onConnected(Bundle connectionHint) {
Log.i(TAG, "API client connected.");
if (mBitmapToSave == null) {
// This activity has no UI of its own. Just start the camera.
startActivityForResult(new Intent(MediaStore.ACTION_IMAGE_CAPTURE),
REQUEST_CODE_CAPTURE_IMAGE);
return;
}
saveFileToDrive();
}
#Override
public void onConnectionSuspended(int cause) {
Log.i(TAG, "GoogleApiClient connection suspended");
}
}
This happens because after the first login/authorization android keeps using the same default account parameters. If you want to avoid the loop and make sure the picker shows again you must clear completely the default account by calling Plus.AccountApi.clearDefaultAccount(mGoogleApiClient) before reconnecting again.
To achieve this, you must add the Plus.API scope to the GoogleApiClient builder:
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addApi(Plus.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
And then you can clear the default account before rebuilding the api client and connecting to a different account (rebuilding the api client when changing accounts avoids problems):
// if the api client existed, we terminate it
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
Plus.AccountApi.clearDefaultAccount(mGoogleApiClient);
mGoogleApiClient.disconnect();
}
// build new api client to avoid problems reusing it
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addApi(Plus.API)
.addScope(Drive.SCOPE_FILE)
.setAccountName(account)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
No additional permissions or api activations are needed for using the Plus.API scope this way. I hope this helps with your problem.
It is a tough one, since I don't have time to completely re-run and analyze your code. And without running it, I don't see anything obvious.
But, since I have this stuff up and running in my app, I'd like to help. Unfortunately the Google Play services connection and authorization code is scattered all over my app's fragments and activities. So, I made an attempt to create a dummy activity and pull all the stuff in it. By 'all the stuff' I mean the account manager wrapper (GA) and associated account picker code.
The result is some 300 lines of gibberish that may work, but I don't make any claims it will. Take a look and good luck.
package com.......;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.Dialog;
import android.app.DialogFragment;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.common.AccountPicker;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
public class GooApiClient extends Activity implements
GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {
private static final String DIALOG_ERROR = "dialog_error";
private static final String REQUEST_CODE = "request_code";
private static final int REQ_ACCPICK = 1;
private static final int REQ_AUTH = 2;
private static final int REQ_RECOVER = 3;
private GoogleApiClient mGooApiClient;
private boolean mIsInAuth; //block re-entrancy
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (checkPlayServices() && checkUserAccount()) {
gooInit();
gooConnect(true);
}
}
#Override
public void onConnected(Bundle bundle) {
Log.d("_", "connected");
}
#Override
public void onConnectionSuspended(int i) { }
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.d("_", "failed " + result.hasResolution());
if (!mIsInAuth) {
if (result.hasResolution()) {
try {
mIsInAuth = true;
result.startResolutionForResult(this, REQ_AUTH);
} catch (IntentSender.SendIntentException e) {
suicide("authorization fail");
}
} else {
suicide("authorization fail");
}
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent it) {
Log.d("_", "activity result " + requestCode + " " + resultCode);
switch (requestCode) {
case REQ_AUTH: case REQ_RECOVER: {
mIsInAuth = false;
if (resultCode == Activity.RESULT_OK) {
gooConnect(true);
} else if (resultCode == RESULT_CANCELED) {
suicide("authorization fail");
}
return;
}
case REQ_ACCPICK: { // return from account picker
if (resultCode == Activity.RESULT_OK && it != null) {
String emil = it.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (GA.setEmil(this, emil) == GA.CHANGED) {
gooInit();
gooConnect(true);
}
} else if (GA.getActiveEmil(this) == null) {
suicide("selection failed");
}
return;
}
}
super.onActivityResult(requestCode, resultCode, it); // DO NOT REMOVE
}
private boolean checkPlayServices() {
Log.d("_", "check PS");
int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (status != ConnectionResult.SUCCESS) {
if (GooglePlayServicesUtil.isUserRecoverableError(status)) {
mIsInAuth = true;
errorDialog(status, LstActivity.REQ_RECOVER);
} else {
suicide("play services failed");
}
return false;
}
return true;
}
private boolean checkUserAccount() {
String emil = GA.getActiveEmil(this);
Account accnt = GA.getPrimaryAccnt(this, true);
Log.d("_", "check user account " + emil + " " + accnt);
if (emil == null) { // no emil (after install)
if (accnt == null) { // multiple or no accounts available, go pick one
accnt = GA.getPrimaryAccnt(this, false);
Intent it = AccountPicker.newChooseAccountIntent(accnt, null,
new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, true, null, null, null, null
);
this.startActivityForResult(it, LstActivity.REQ_ACCPICK);
return false; //--------------------->>>
} else { // there's only one goo account registered with the device, skip the picker
GA.setEmil(this, accnt.name);
}
// UNLIKELY BUT POSSIBLE, emil's OK, but the account have been removed since (through settings)
} else {
accnt = GA.getActiveAccnt(this);
if (accnt == null) {
accnt = GA.getPrimaryAccnt(this, false);
Intent it = AccountPicker.newChooseAccountIntent(accnt, null,
new String[]{GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE}, true, null, null, null, null
);
this.startActivityForResult(it, LstActivity.REQ_ACCPICK);
return false; //------------------>>>
}
}
return true;
}
private void gooInit(){
String emil = GA.getActiveEmil(this);
Log.d("_", "goo init " + emil);
if (emil != null){
mGooApiClient = new GoogleApiClient.Builder(this)
.setAccountName(emil).addApi(com.google.android.gms.drive.Drive.API)
.addScope(com.google.android.gms.drive.Drive.SCOPE_FILE)
.addConnectionCallbacks(this).addOnConnectionFailedListener(this)
.build();
}
}
private void gooConnect(boolean bConnect) {
Log.d("_", "goo connect " + bConnect);
if (mGooApiClient != null) {
if (!bConnect) {
mGooApiClient.disconnect();
} else if (! (mGooApiClient.isConnecting() || mGooApiClient.isConnected())){
mGooApiClient.connect();
}
}
}
private void suicide(String msg) {
GA.removeActiveAccnt(this);
Toast.makeText(this, msg, Toast.LENGTH_LONG).show();
finish();
}
private void errorDialog(int errorCode, int requestCode) {
Bundle args = new Bundle();
args.putInt(DIALOG_ERROR, errorCode);
args.putInt(REQUEST_CODE, requestCode);
ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
dialogFragment.setArguments(args);
dialogFragment.show(getFragmentManager(), "errordialog");
}
public static class ErrorDialogFragment extends DialogFragment {
public ErrorDialogFragment() { }
#Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
int errorCode = getArguments().getInt(DIALOG_ERROR);
int requestCode = getArguments().getInt(DIALOG_ERROR);
return GooglePlayServicesUtil.getErrorDialog(errorCode, getActivity(), requestCode);
}
#Override
public void onDismiss(DialogInterface dialog) {
getActivity().finish();
}
}
private static class GA {
private static final String ACC_NAME = "account_name";
public static final int FAIL = -1;
public static final int UNCHANGED = 0;
public static final int CHANGED = +1;
private static String mCurrEmil = null; // cache locally
private static String mPrevEmil = null; // cache locally
public static Account[] getAllAccnts(Context ctx) {
return AccountManager.get(acx(ctx)).getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
}
public static Account getPrimaryAccnt(Context ctx, boolean bOneOnly) {
Account[] accts = getAllAccnts(ctx);
if (bOneOnly)
return accts == null || accts.length != 1 ? null : accts[0];
return accts == null || accts.length == 0 ? null : accts[0];
}
public static Account getActiveAccnt(Context ctx) {
return emil2Accnt(ctx, getActiveEmil(ctx));
}
public static String getActiveEmil(Context ctx) {
if (mCurrEmil != null) {
return mCurrEmil;
}
mCurrEmil = ctx == null ? null : pfs(ctx).getString(ACC_NAME, null);
return mCurrEmil;
}
public static Account getPrevEmil(Context ctx) {
return emil2Accnt(ctx, mPrevEmil);
}
public static Account emil2Accnt(Context ctx, String emil) {
if (emil != null) {
Account[] accounts =
AccountManager.get(acx(ctx)).getAccountsByType(GoogleAuthUtil.GOOGLE_ACCOUNT_TYPE);
for (Account account : accounts) {
if (emil.equalsIgnoreCase(account.name)) {
return account;
}
}
}
return null;
}
/**
* Stores a new email in persistent app storage, reporting result
* #param newEmil new email, optionally null
* #param ctx activity context
* #return FAIL, CHANGED or UNCHANGED (based on the following table)
* OLD NEW SAVED RESULT
* ERROR FAIL
* null null null FAIL
* null new new CHANGED
* old null old UNCHANGED
* old != new new CHANGED
* old == new new UNCHANGED
*/
public static int setEmil(Context ctx, String newEmil) {
int result = FAIL; // 0 0
mPrevEmil = getActiveEmil(ctx);
if ((mPrevEmil == null) && (newEmil != null)) {
result = CHANGED;
} else if ((mPrevEmil != null) && (newEmil == null)) {
result = UNCHANGED;
} else if ((mPrevEmil != null) && (newEmil != null)) {
result = mPrevEmil.equalsIgnoreCase(newEmil) ? UNCHANGED : CHANGED;
}
if (result == CHANGED) {
mCurrEmil = newEmil;
pfs(ctx).edit().putString(ACC_NAME, newEmil).apply();
}
return result;
}
public static void removeActiveAccnt(Context ctx) {
mCurrEmil = null;
pfs(ctx).edit().remove(ACC_NAME).apply();
}
private static Context acx(Context ctx) {
return ctx == null ? null : ctx.getApplicationContext();
}
private static SharedPreferences pfs(Context ctx) {
return ctx == null ? null : PreferenceManager.getDefaultSharedPreferences(acx(ctx));
}
}
}
BTW, I know how to spell 'email', 'Emil' just happened to be my uncle's name and I couldn't resist :-)
UPDATE (2015-Apr-11):
I've recently re-visited the code that handles Google Drive Authorization and Account switching. The result can be found here and it supports both REST and GDAA apis.

Android Google Play Services for turn based game , Not able to receive invitation with default UI

I am new to turn based game development and trying to develop a turn based game. I am using default UI for selecting players
Intent intent = Games.TurnBasedMultiplayer.getSelectOpponentsIntent(getApiClient(), 1, 1, true);
startActivityForResult(intent, RC_SELECT_PLAYERS);
When I select player sand say Play, other player is supposed to get notification. But that player is not receiving invitation / notification.
#Override
public void onSignInSucceeded() {
updateLayouts();
Games.Invitations.registerInvitationListener(getApiClient(), this);
// developer document says that above line is not required
// include or exclude for me it is not making any difference
}
#Override
public void onInvitationReceived(Invitation invitation) {
Toast.makeText(
this,
"An invitation has arrived from "
+ invitation.getInviter().getDisplayName(), Toast.LENGTH_LONG)
.show();
Log.d(TAG, "Invitation arrived from " + invitation.getInviter().getDisplayName());
}
Here is my onActivtityResult
#Override
public void onActivityResult(int request, int response, Intent data) {
super.onActivityResult(request, response, data);
if (request == RC_LOOK_AT_MATCHES) {
// Returning from the 'Select Match' dialog
if (response != Activity.RESULT_OK) {
// user canceled
return;
}
TurnBasedMatch match = data
.getParcelableExtra(com.google.android.gms.games.multiplayer.Multiplayer.EXTRA_TURN_BASED_MATCH);
if (match != null) {
updateMatch(match);
}
Log.d(TAG, "Match = " + match);
}
else if (request == RC_SELECT_PLAYERS) {
if (response != Activity.RESULT_OK) {
// user canceled
return;
}
// get the invitee list
final ArrayList<String> invitees =
data.getStringArrayListExtra(Games.EXTRA_PLAYER_IDS);
Log.d(TAG, "Invitees count = " + invitees.size());
for(int i=0; i<invitees.size(); i++){
Log.d(TAG, invitees.get(i));
}
// get auto-match criteria
Bundle autoMatchCriteria = null;
int minAutoMatchPlayers = data.getIntExtra(
Multiplayer.EXTRA_MIN_AUTOMATCH_PLAYERS, 0);
int maxAutoMatchPlayers
= data.getIntExtra(
Multiplayer.EXTRA_MAX_AUTOMATCH_PLAYERS, 0);
if (minAutoMatchPlayers > 0) {
autoMatchCriteria
= RoomConfig.createAutoMatchCriteria(
minAutoMatchPlayers, maxAutoMatchPlayers, 0);
Log.d(TAG, "minAutoMatchPlayers > 0");
} else {
autoMatchCriteria = null;
Log.d(TAG, "minAutoMatchPlayers <= 0");
}
TurnBasedMatchConfig tbmc = TurnBasedMatchConfig.builder()
.addInvitedPlayers(invitees)
.setAutoMatchCriteria(autoMatchCriteria).build();
// kick the match off
Games.TurnBasedMultiplayer
.createMatch(getApiClient(), tbmc)
.setResultCallback(new ResultCallback<TurnBasedMultiplayer.InitiateMatchResult>() {
#Override
public void onResult(TurnBasedMultiplayer.InitiateMatchResult result) {
processResult(result);
}
});
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
showSpinner();
}
}
Can Anyone tell me where I am going wrong?
The notification happens after the first player (who created the match) takes his turn by calling Games.TurnBasedMultiplayer.takeTurn() and not right away after the match is created.
Can also try this. If there is no invitations (even when your app is closed), the account-lvl restrictions can block them.

How to get string value from string array in Android

I am trying to create an application that reads an NFC tag and checks the tag against strings in a string array and then sets the text on another activity. I have got it working so that it checks if the string exists and sets the text in the new activity, but I want to be able to specify which string I want it to check against within the array, because there will be multiple strings in the NFC tag that I want to then display in the new activity. I have tried this for it:
result == getResources().getString(R.string.test_dd)
Here is the relevant code:
String[] dd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dd = getResources().getStringArray(R.array.device_description);
}
#Override
protected void onPostExecute(String result) {
if (result != null) {
if(doesArrayContain(dd, result)) {
Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
v.vibrate(800);
Intent newIntent = new Intent(getApplicationContext(), TabsTest.class);
Bundle bundle1 = new Bundle();
bundle1.putString("key", result);
newIntent.putExtras(bundle1);
startActivity(newIntent);
Toast.makeText(getApplicationContext(), "NFC tag written successfully!", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(getApplicationContext(), result + " is not in the device description!", Toast.LENGTH_SHORT).show();
}
}
}
EDIT:
Here is the method used and please can anyone help me with this problem:
public static boolean doesArrayContain(String[] array, String text) {
for (String element : array) {
if(element != null && element.equalsIgnoreCase(text)) {
return true;
}
}
return false;
}
For comparing equality of strings (and other objects) use the equals() method. == compares identity of objects (same string object).
Here is the solution that I found:
Create a new method:
public static boolean stringCaseInsensitive(String string, String result) {
if(string != null && string.equalsIgnoreCase(result)) {
return true;
}
return false;
}
And call it in like this:
if(stringCaseInsensitive(getResources().getString(R.string.test_dd), result))
{
Intent newIntent = new Intent(getApplicationContext(), TabsTest.class);
Bundle bundle1 = new Bundle();
bundle1.putString("key", result);
newIntent.putExtras(bundle1);
startActivity(newIntent);
Toast.makeText(getApplicationContext(), "NFC tag written successfully!", Toast.LENGTH_SHORT).show();
}
else{
}

Categories

Resources