Google Play Developer AP Iconnection issues - android

Hi we are trying to get Google Play subscriptions information connected to one of our Android apps. The first step is authorize and get subscriptions json
Has anyone succeed to work with Google Play Developer API? Authorization? Subscriptions list?
Below is our experience
When I use authScope = "https://www.googleapis.com/auth/androidpublisher";
(took it from Google Example)
private static final String authScope = "https://www.googleapis.com/auth/androidpublisher";
am.getAuthToken(
myAccount, // Account retrieved using getAccountsByType()
authScope, // Auth scope
options, // Authenticator-specific options
this, // Your activity
new OnTokenAcquired(), // Callback called when a token is successfully acquired
new Handler(new OnError())); // Callback called if an error occurs
private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
#Override
public void run(AccountManagerFuture<Bundle> accountManagerFuture) {
addProcessMessage("OnTokenAcquired");
// Get the result of the operation from the AccountManagerFuture.
try {
Bundle bundle = accountManagerFuture.getResult();
// The token is a named value in the bundle. The name of the value
// is stored in the constant AccountManager.KEY_AUTHTOKEN.
String token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
addProcessMessage("OnTokenAcquired token=" + token);
processAcessSubscriptions(token);
} catch ( Exception ae ) {
Log.e(TAG, "OnTokenAcquired Exception=" + ae.getMessage(), ae);
setProcessFailed(ae.getMessage());
}
}
}
I can’t get token, because I get exception below
OnTokenAcquired Exception=Unknown
android.accounts.AuthenticatorException: Unknown
at android.accounts.AccountManager.convertErrorToException(AccountManager.java:2213)
at android.accounts.AccountManager.-wrap0(AccountManager.java)
at android.accounts.AccountManager$AmsTask$Response.onError(AccountManager.java:2056)
at android.accounts.IAccountManagerResponse$Stub.onTransact(IAccountManagerResponse.java:69)
at android.os.Binder.execTransact(Binder.java:565)
When I use authScope = "Manage your tasks";
(took it from another Google Example)
private static final String authScope = "Manage your tasks";
I'm receiving token, but on ProductPurchase product = purchases.products().get(PACKAGE_NAME, TEST_SKU, token).execute();
I am getting getProducts Exception=400 Bad Request
See below
HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();
AssetManager assetManager = getAssets();
InputStream is = assetManager.open(CLIENT_SECRET_JSON);
GoogleCredential credential = GoogleCredential.fromStream(is).createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER));
AndroidPublisher publisher = new AndroidPublisher.Builder(httpTransport, jsonFactory, credential).setApplicationName(APP_NAME).build();
AndroidPublisher.Purchases purchases = publisher.purchases();
ProductPurchase product = purchases.products().get(PACKAGE_NAME, TEST_SKU, token).execute();
getProducts Exception=400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid Value",
"reason" : "invalid"
} ],
"message" : "Invalid Value"
}
com.google.api.client.googleapis.json.GoogleJsonResponseException: 400 Bad Request
{
"code" : 400,
"errors" : [ {
"domain" : "global",
"message" : "Invalid Value",
"reason" : "invalid"
} ],
"message" : "Invalid Value"
}
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:113)
at com.google.api.client.googleapis.services.json.AbstractGoogleJsonClientRequest.newExceptionOnError(AbstractGoogleJsonClientRequest.java:40)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest$1.interceptResponse(AbstractGoogleClientRequest.java:321)
at com.google.api.client.http.HttpRequest.execute(HttpRequest.java:1065)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:419)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.executeUnparsed(AbstractGoogleClientRequest.java:352)
at com.google.api.client.googleapis.services.AbstractGoogleClientRequest.execute(AbstractGoogleClientRequest.java:469)
Main Activity
package com.lemi.affilatemanager;
import android.Manifest;
import android.accounts.Account;
import android.accounts.AccountManager;
import android.accounts.AccountManagerCallback;
import android.accounts.AccountManagerFuture;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.os.Handler;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.services.androidpublisher.AndroidPublisher;
import com.google.api.services.androidpublisher.AndroidPublisherScopes;
import com.google.api.services.androidpublisher.model.ProductPurchase;
import java.io.InputStream;
import java.util.Collections;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private static final int DIALOG_ACCOUNTS = 11;
public static final String CLIENT_SECRET_JSON = "service_account.json";//"client_secret.json";
public static final String APP_NAME = "AffilateManager";
public static final String PACKAGE_NAME = "com.lemi.keywordmarketingautoresponder";
private AccountManager accountManager;
private Account myAccount;
protected static final int PERMISSION_REQUEST = 10;
private TextView resultText;
private StringBuilder testMessage = new StringBuilder();
private ProgressBar progressBar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
accountManager = AccountManager.get(this);
setContentView(R.layout.activity_main);
resultText = (TextView) findViewById(R.id.test_result);
progressBar = (ProgressBar) findViewById(R.id.progress_bar);
Button startProcessButton = (Button) findViewById(R.id.start_process_btn);
startProcessButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
test();
}
});
}
#Override
protected Dialog onCreateDialog(int id) {
switch (id) {
case DIALOG_ACCOUNTS:
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Select a Google account");
final Account[] accounts = accountManager.getAccountsByType("com.google");
final int size = accounts.length;
String[] names = new String[size];
for (int i = 0; i < size; i++) {
names[i] = accounts[i].name;
}
builder.setItems(names, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Stuff to do when the account is selected by the user
myAccount = accounts[which];
processGetAuthToken();
}
});
return builder.create();
}
return null;
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
Log.i(TAG, "onRequestPermissionsResult requestCode=" + requestCode);
switch (requestCode) {
case PERMISSION_REQUEST:
test();
break;
default:
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
private void test () {
boolean canReadContacts = ContextCompat.checkSelfPermission(this, Manifest.permission.GET_ACCOUNTS) == PackageManager.PERMISSION_GRANTED;
Log.i(TAG, "test canReadContacts=" + canReadContacts);
if ( !canReadContacts ) {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.GET_ACCOUNTS}, PERMISSION_REQUEST);
return;
}
startProcess();
if ( getAccount() ) {
processGetAuthToken();
}
}
private void startProcess () {
progressBar.setVisibility(View.VISIBLE);
testMessage.delete(0, testMessage.length());
resultText.setText(testMessage);
}
private void setProcessFailed ( final String message ) {
runOnUiThread(new Runnable() {
#Override
public void run() {
progressBar.setVisibility(View.INVISIBLE);
addProcessMessage(message);
}});
}
private void addProcessMessage ( String message ) {
Log.i(TAG, message);
testMessage.append("\n").append(message);
resultText.setText(testMessage);
}
private boolean getAccount () {
Account[] accounts = accountManager.getAccountsByType("com.google");
if ( accounts == null || accounts.length < 1 || accounts.length > 1) {
showDialog(DIALOG_ACCOUNTS);
return false;
}
myAccount = accounts[0];
return true;
}
private static final String authScope = "https://www.googleapis.com/auth/androidpublisher";
//private static final String authScope = "Manage your tasks";//https://www.googleapis.com/auth/androidpublisher";
//private static final String authScope = "Financial Access Enabled Account";
private void processGetAuthToken() {
addProcessMessage("Start processGetAuthToken process...");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
AccountManager am = AccountManager.get(this);
Bundle options = new Bundle();
//am.invalidateAuthToken(accountType, authTocken);
am.getAuthToken(
myAccount, // Account retrieved using getAccountsByType()
authScope, // Auth scope
options, // Authenticator-specific options
this, // Your activity
new OnTokenAcquired(), // Callback called when a token is successfully acquired
new Handler(new OnError())); // Callback called if an error occurs
}
private static final String TEST_SKU = "subs:com.lemi.keywordmarketingautoresponder:keywordmarketingautoresponder.1month.1keyword";
private void processAcessSubscriptions( String token ) {
addProcessMessage("processAcessSubscriptions token=" + token);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
//AndroidPublisher.Purchases ap = null;
try {
//NetHttpTransport httpTransport = GoogleNetHttpTransport.newTrustedTransport();
HttpTransport httpTransport = AndroidHttp.newCompatibleTransport();
JacksonFactory jsonFactory = JacksonFactory.getDefaultInstance();
AssetManager assetManager = getAssets();
InputStream is = assetManager.open(CLIENT_SECRET_JSON);
GoogleCredential credential = GoogleCredential.fromStream(is).createScoped(Collections.singleton(AndroidPublisherScopes.ANDROIDPUBLISHER));
AndroidPublisher publisher = new AndroidPublisher.Builder(httpTransport, jsonFactory, credential).setApplicationName(APP_NAME).build();
addProcessMessage("processAcessSubscriptions publisher=" + publisher);
getProducts(token, publisher);
} catch (Exception e) {
Log.e(TAG, "processAcessSubscriptions Exception:" + e.getMessage(), e);
setProcessFailed(e.getMessage());
}
}
private void getProducts(final String token, final AndroidPublisher publisher) {
new Thread(new Runnable() {
public void run() {
try {
AndroidPublisher.Purchases purchases = publisher.purchases();
addProcessMessage("getProducts purchases=" + purchases);
ProductPurchase product = purchases.products().get(PACKAGE_NAME, TEST_SKU, token).execute();
Integer purchaseState = product.getPurchaseState();
addProcessMessage("getProducts purchaseState=" + purchaseState);
long time = product.getPurchaseTimeMillis();
int consuptionState = product.getConsumptionState();
String developerPayload = product.getDeveloperPayload();
addProcessMessage("getProducts time=" + time + " consuptionState=" + consuptionState + " developerPayload=" + developerPayload);
} catch ( Exception e ) {
Log.e(TAG, "getProducts Exception=" + e.getMessage(), e);
setProcessFailed(e.getMessage());
}
}
}).start();
}
private class OnTokenAcquired implements AccountManagerCallback<Bundle> {
#Override
public void run(AccountManagerFuture<Bundle> accountManagerFuture) {
addProcessMessage("OnTokenAcquired");
// Get the result of the operation from the AccountManagerFuture.
try {
Bundle bundle = accountManagerFuture.getResult();
// The token is a named value in the bundle. The name of the value
// is stored in the constant AccountManager.KEY_AUTHTOKEN.
String token = bundle.getString(AccountManager.KEY_AUTHTOKEN);
addProcessMessage("OnTokenAcquired token=" + token);
processAcessSubscriptions(token);
} catch ( Exception ae ) {
Log.e(TAG, "OnTokenAcquired Exception=" + ae.getMessage(), ae);
setProcessFailed(ae.getMessage());
}
}
}
private class OnError implements Handler.Callback {
#Override
public boolean handleMessage(Message message) {
Log.i(TAG, "OnError handleMessage=" + message);
setProcessFailed(message.toString());
return false;
}
}
}

Related

Calling api.ai from Android

I am building an android app in which I am calling api.ai. I want to parse the response and display it to users. Earlier I had written code in node.js which is as below:
function sendMessageToApiAi(options,botcontext) {
var message = options.message; // Mandatory
var sessionId = options.sessionId || ""; // optinal
var callback = options.callback;
if (!(callback && typeof callback == 'function')) {
return botcontext.sendResponse("ERROR : type of options.callback should be function and its Mandatory");
}
var nlpToken = options.nlpToken;
if (!nlpToken) {
if (!botcontext.simpledb.botleveldata.config || !botcontext.simpledb.botleveldata.config.nlpToken) {
return botcontext.sendResponse("ERROR : token not set. Please set Api.ai Token to options.nlpToken or context.simpledb.botleveldata.config.nlpToken");
} else {
nlpToken = botcontext.simpledb.botleveldata.config.nlpToken;
}
}
var query = '?v=20150910&query='+ encodeURIComponent(message) +'&sessionId='+context.simpledb.roomleveldata.c1+'&timezone=Asia/Calcutta&lang=en '
var apiurl = "https://api.api.ai/api/query"+query;
var headers = { "Authorization": "Bearer " + nlpToken};
botcontext.simplehttp.makeGet(apiurl, headers, function(context, event) {
if (event.getresp) {
callback(event.getresp);
} else {
callback({})
}
});
}
My Android code is as below:
package com.example.pramod.apidev;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity{
private Button listenButton;
private TextView resultTextView;
private EditText inputText;
private static String API_URL = "https://api.api.ai/api/query";
private static String API_KEY = "d05b02dfe52f4b5f969ba1257cffac37";
private static String query;
private static String s;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listenButton = (Button) findViewById(R.id.listenButton);
resultTextView = (TextView) findViewById(R.id.resultTextView);
inputText = (EditText)findViewById(R.id.inputText);
s = inputText.getText().toString();
query = "?v=20150910&query=hi" +"&sessionId=1480181847573api&timezone=Asia/Calcutta&lang=en";
listenButton.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
try {
URL url = new URL(API_URL + query + "&apiKey=" + API_KEY);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
}
catch(Exception e) {
Log.e("ERROR", e.getMessage(), e);
}
}
});
}
}
I need help in following:
(i) How can call the Api.ai since I am getting an error 401? Can some one tell how to exactly call Api.ai using the Node.js code?
(ii) How can parse the response and display it to users?
Thanks in advance
I'm connecting with api.ai from android app.
The steps to do are the following
1. Add the dependencies:
compile 'ai.api:libai:1.2.2'
compile 'ai.api:sdk:2.0.1#aar'
2. Create an activity implementing AIListener.
3. Declare AIService,and AIDataService:
private AIService aiService;
private AIDataService aiDataService;
4. Initialize config, services and add listener:
final ai.api.android.AIConfiguration config = new ai.api.android.AIConfiguration("API_KEY",
ai.api.android.AIConfiguration.SupportedLanguages.Spanish,
ai.api.android.AIConfiguration.RecognitionEngine.System);
// Use with text search
aiDataService = new AIDataService(this, config);
// Use with Voice input
aiService = AIService.getService(this, config);
aiService.setListener(this);
5. Execute async task to make request:
AIRequest aiRequest = new AIRequest();
aiRequest.setQuery(request);
//request--any string you want to send to chat bot to get there corresponding response.
if(aiRequest==null) {
throw new IllegalArgumentException("aiRequest must be not null");
}
final AsyncTask<AIRequest, Integer, AIResponse> task =
new AsyncTask<AIRequest, Integer, AIResponse>() {
private AIError aiError;
#Override
protected AIResponse doInBackground(final AIRequest... params) {
final AIRequest request = params[0];
try {
final AIResponse response = aiDataService.request(request);
// Return response
return response;
} catch (final AIServiceException e) {
aiError = new AIError(e);
return null;
}
}
#Override
protected void onPostExecute(final AIResponse response) {
if (response != null) {
onResult(response);
} else {
onError(aiError);
}
}
};
task.execute(aiRequest);
6. onResult method
Result result = response.getResult();
If the result is a string, the string with the response will be in:
String speech = result.getFulfillment().getSpeech();
Regards.
Nuria
You can refer the official documentation of integrating API.AI here -
https://github.com/api-ai/apiai-android-client
Happy coding.

GoogleAuthUtil: get access token that will provide an email address?

I'm unable to get an access token to provide an email address. I'm using GoogleAuthUtil. (the result says the token is invalid)
I use this:
mGoogleApiClient = new GoogleApiClient.Builder (cordova.getActivity().getApplicationContext())
.addConnectionCallbacks (this)
.addOnConnectionFailedListener (this)
.addApi (Games.API)
.addScope (Games.SCOPE_GAMES)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.build ();
And this:
scope = "oauth2:" + Scopes.PROFILE + " " + "email";
Dropping " email" works to give me a valid access token -- but there's no email address in the response.
Here is my code.
package com.flyingsoftgames.googleplayservices;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.games.Players;
import com.google.android.gms.games.Games;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.android.gms.auth.GoogleAuthUtil;
import com.google.android.gms.auth.UserRecoverableAuthException;
import com.google.android.gms.auth.GooglePlayServicesAvailabilityException;
import com.google.android.gms.plus.Account;
import com.google.android.gms.plus.Plus;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.apache.cordova.PluginResult.Status;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import android.content.Context;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.app.Activity;
import android.os.AsyncTask;
import android.os.Bundle;
import org.apache.cordova.*;
import java.io.IOException;
import android.util.Log;
public class GooglePlayServices extends CordovaPlugin implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private static final String LOG_TAG = "GooglePlayServices";
private static final int REQ_SIGN_IN_REQUIRED = 55664;
public static GoogleApiClient mGoogleApiClient = null;
public CallbackContext tryConnectCallback = null;
public String accessToken = "";
private int connectionAttempts = 0;
#Override public void onConnectionFailed (ConnectionResult result) {
String errormessage = result.toString();
Log.w (LOG_TAG, errormessage);
connectionAttempts += 1;
if (!result.hasResolution() || connectionAttempts >= 2) {
Log.w (LOG_TAG, "Error: no resolution. Google Play Services connection failed.");
tryConnectCallback.error ("Error: " + errormessage + "."); tryConnectCallback = null;
return;
}
try {
result.startResolutionForResult (cordova.getActivity(), result.getErrorCode());
} catch (SendIntentException e) {
// There was an error with the resolution intent. Try again.
mGoogleApiClient.connect ();
}
}
#Override public void onConnected (Bundle connectionHint) {
String mAccountName = Plus.AccountApi.getAccountName(mGoogleApiClient);
new RetrieveTokenTask().execute (mAccountName);
Games.setViewForPopups (mGoogleApiClient, webView);
}
public void onActivityResult (int requestCode, int responseCode, Intent intent) {
if (!mGoogleApiClient.isConnecting()) mGoogleApiClient.connect ();
}
#Override public void onConnectionSuspended (int cause) {
mGoogleApiClient.connect ();
}
public boolean execute (String action, JSONArray inputs, CallbackContext callbackContext) throws JSONException {
if ("getPlayerId".equals(action)) {
String playerId = Games.Players.getCurrentPlayerId (mGoogleApiClient);
callbackContext.sendPluginResult (new PluginResult (PluginResult.Status.OK, playerId));
} else if ("tryConnect".equals(action)) {
tryConnect (callbackContext);
} else if ("getAccessToken".equals(action)) {
callbackContext.sendPluginResult (new PluginResult (PluginResult.Status.OK, accessToken));
}
return true;
}
// tryConnect runs the callback with a value of false if Google Play Services isn't available.
public void tryConnect (CallbackContext callbackContext) {
boolean isGpsAvailable = (GooglePlayServicesUtil.isGooglePlayServicesAvailable(cordova.getActivity()) == ConnectionResult.SUCCESS);
if (!isGpsAvailable) {
callbackContext.sendPluginResult (new PluginResult (PluginResult.Status.OK, false));
return;
}
tryConnectCallback = callbackContext;
mGoogleApiClient = new GoogleApiClient.Builder (cordova.getActivity().getApplicationContext())
.addConnectionCallbacks (this)
.addOnConnectionFailedListener (this)
.addApi (Games.API)
.addScope (Games.SCOPE_GAMES)
.addApi(Plus.API)
.addScope(Plus.SCOPE_PLUS_PROFILE)
.addScope(Plus.SCOPE_PLUS_LOGIN)
.build ();
mGoogleApiClient.connect ();
}
private class RetrieveTokenTask extends AsyncTask<String, Void, String> {
#Override protected String doInBackground (String... params) {
String accountName = params[0];
String scope = "oauth2:" + Scopes.PROFILE + " " + "email";
Context context = cordova.getActivity().getApplicationContext();
try {
accessToken = GoogleAuthUtil.getToken (context, accountName, scope);
} catch (IOException e) {
String errormessage = e.getMessage();
Log.e (LOG_TAG, errormessage);
if (tryConnectCallback != null) tryConnectCallback.error ("Error: " + errormessage + "."); tryConnectCallback = null;
} catch (UserRecoverableAuthException e) {
cordova.getActivity().startActivityForResult (e.getIntent(), REQ_SIGN_IN_REQUIRED);
} catch (GoogleAuthException e) {
String errormessage = e.getMessage();
Log.e (LOG_TAG, errormessage);
if (tryConnectCallback != null) tryConnectCallback.error ("Error: " + errormessage + "."); tryConnectCallback = null;
}
return accessToken;
}
#Override protected void onPostExecute (String newAccessToken) {
super.onPostExecute (newAccessToken);
accessToken = newAccessToken;
if (tryConnectCallback != null) {
String playerId = Games.Players.getCurrentPlayerId (mGoogleApiClient);
tryConnectCallback.sendPluginResult (new PluginResult (PluginResult.Status.OK, playerId));
tryConnectCallback = null;
}
}
}
}
It seems that clearing an app's permission in https://security.google.com/settings/security/permissions?hl=en does trigger a re-authorization screen, but the access token that is received from .getToken is stale. GoogleAuthUtil.clearToken (context, accessToken); needs to be used to clear the old token, or the old token must time out. Thus, we can do:
accessToken = GoogleAuthUtil.getToken(context, accountName, scope);
GoogleAuthUtil.clearToken (context, accessToken);
accessToken = GoogleAuthUtil.getToken(context, accountName, scope);
However:
It seems that this only resolves after a few iterations of re-launching the app, because GoogleAuthUtil.getToken is asynchronous when new permissions are required, and two SEPARATE permission screens pop up: one from Google (triggered from GoogleAuthUtil.getToken and one from Google+ (triggered from GoogleApiClient.Builder).
Edit:
Using the AccountPicker class eliminates the need to use GoogleApiClient.Builder!
See:
https://github.com/agamemnus/googleplaytoken

From second time "In app purchase" throwing exception in Android

I Am trying to include in app purchase and i have successfully through in showing up SKUs available.Now I want to make a fake purchase.So I used appId = "android.test.purchased". For the first time it worked flawlessly, but from next it is throwing exception as below.
Attempt to invoke virtual method 'android.content.IntentSender android.app.PendingIntent.getIntentSender()' on a null object reference
Has anybody come across such situation?
package com.inappbilling.poc;
import java.util.ArrayList;
import org.json.JSONObject;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import com.android.vending.billing.IInAppBillingService;
public class TestInAppPurchase extends Activity {
private final static String SERVICE_INTENT = "com.android.vending.billing.InAppBillingService.BIND";
private static final String _TAG = "BILLING ACTIVITY";
private final String _testSku = "android.test.purchased";
//available skus
static final String SKU_7DAYS = "7days";
static final String SKU_30DAYS = "30days";
private Button _7daysPurchase = null;
private Button _30daysPurchase = null;
private IInAppBillingService _service = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(_TAG, "created");
_7daysPurchase = ( Button ) findViewById(R.id.sevendays_btn);
_30daysPurchase = ( Button ) findViewById(R.id.thirtydays_btn);
_7daysPurchase.setOnClickListener(_purchaseListener);
_30daysPurchase.setOnClickListener(_purchaseListener);
}
#Override
protected void onStart() {
super.onStart();
}
OnClickListener _purchaseListener = new OnClickListener() {
#Override
public void onClick(View v) {
switch ( v.getId() ) {
case R.id.sevendays_btn:
doPurchase();
break;
case R.id.thirtydays_btn:
break;
}
}
};
private ServiceConnection _serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
_service = IInAppBillingService.Stub.asInterface( service );
Log.d(_TAG, _service.toString());
}
#Override
public void onServiceDisconnected(ComponentName name) {
_service = null;
Log.d(_TAG, "destroyed");
}
};
private void doPurchase(){
if ( _service == null) {
Log.e( _TAG , "Billing failed: billing service is null ");
return;
}
ArrayList testSku = new ArrayList( );
testSku.add( _testSku );
Bundle querySkus = new Bundle();
querySkus.putStringArrayList("ITEM_ID_LIST", testSku);
Bundle skuDetails ;
try {
skuDetails = _service.getSkuDetails(3, getPackageName(), "inapp", querySkus);
int response = skuDetails.getInt("RESPONSE_CODE");
if( response == 0 ){
ArrayList<String> responseList = new ArrayList<String>( );
responseList = skuDetails.getStringArrayList("DETAILS_LIST");
for( String responseString : responseList ) {
JSONObject jobj = new JSONObject( responseString );
String sku = jobj.getString("productId");
if( sku.equals( _testSku )){
Bundle buyIntentBundle = _service.getBuyIntent(3, getPackageName(), sku ,"inapp","" );
PendingIntent pendingIntent = buyIntentBundle.getParcelable("BUY_INTENT");
startIntentSenderForResult(pendingIntent.getIntentSender(),
1001, new Intent(), Integer.valueOf(0), Integer.valueOf(0),
Integer.valueOf(0));
}
}
} else {
Log.e( _TAG , "Failed " );
}
} catch (Exception e) {
Log.e( _TAG, "Caught exception !"+ e.getMessage() );
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if(requestCode == 1001 ){
String purchaseData = data.getStringExtra("INAPP_PURCHASE_DATA");
if( resultCode == RESULT_OK ){
try{
JSONObject jobj = new JSONObject( purchaseData );
String sku = jobj.getString(_testSku);
String paid = jobj.getString("price");
Log.v("SKU DATA", sku +"============"+ paid);
}catch( Exception e) {
e.printStackTrace();
}
}
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if( _serviceConnection != null ){
unbindService( _serviceConnection );
}
}
}
Hi get to know about the solution for the prob mentioned above.To get rid of this you should clear the cache of Google play app on your android phone.When we make any in app purchase are details are maintained by the Google play services.So once the a product is purchased play Isolates the particular sku,to avoid duplicate purchase.
Note - This is actually for testing purpose. Because Google play services maintains the record of all applications which have in app purchase or Oauth or any other facilities.
Hope it would help some one who is facing this problem.
When we try to purchase the already owned item we will get the null exception at Pending Intent.
So you need to check whether the product is purchased or not and then initiate the purchase only if the product is not purchased.
Product purchase state can be retrieved using the function
boolean haspurchase = inventory.hasPurchase(sku_id);
It worked for me..!!

How do I post and retrieve tweets in an Android app?

I'm trying to make a Twitter app which includes posting and retrieving tweets from the user's timeline and setting it in a list view which also updates when someone tweets.
I also wish to allow the user to upload photos to Twitter.
Here's my code:
package com.example.listtweetdemo;
import java.util.ArrayList;
import java.util.List;
import twitter4j.Paging;
import twitter4j.ResponseList;
import twitter4j.Status;
import twitter4j.Twitter;
import twitter4j.TwitterException;
import twitter4j.TwitterFactory;
import twitter4j.User;
import twitter4j.auth.AccessToken;
import twitter4j.auth.RequestToken;
import twitter4j.conf.Configuration;
import twitter4j.conf.ConfigurationBuilder;
import twitter4j.internal.org.json.JSONArray;
import twitter4j.internal.org.json.JSONObject;
import twitter4j.json.DataObjectFactory;
import android.app.Activity;
import android.app.ListActivity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.Menu;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends ListActivity {
private Button twitt;
private Button read;
private Button login;
private Button logout;
private EditText edt;
private boolean man = true;
private TextView textName;
private ListView list;
List<Status> statuses = new ArrayList<Status>();
static final String consumerKey = "RVVVPnAUa8e1XXXXXXXXX";
static final String consumerSecretKey = "eCh0Bb12n9oDmcomBdfisKZIfJmChC2XXXXXXXXXXXX";
static final String prefName = "twitter_oauth";
static final String prefKeyOauthToken = "oauth_token";
static final String prefKeyOauthSecret = "oauth_token_secret";
static final String prefKeyTwitterLogin = "isTwitterLogedIn";
static final String twitterCallbackUrl = "oauth://t4jsample";
static final String urlTwitterOauth = "auth_url";
static final String urlTwitterVerify = "oauth_verifier";
static final String urlTwitterToken = "oauth_token";
static SharedPreferences pref;
private static Twitter twitter;
private static RequestToken reqToken;
private connectionDetector cd;
AlertDailogManager alert = new AlertDailogManager();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpIds();
cd = new connectionDetector(getApplicationContext());
if(!cd.isConnectivityToInternet())
{
alert.showAlert(MainActivity.this, "Internet Connection Error", "Please Connect to working Internet connection", false);
return;
}
if(consumerKey.trim().length() == 0 || consumerSecretKey.trim().length() == 0)
{
alert.showAlert(MainActivity.this, "Twitter Oauth Token", "Please set your Twitter oauth token first!", false);
return;
}
login.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
loginToTwitter();
}
});
logout.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
logoutFromTwitter();
}
});
read.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
//Paging paging = new Paging(200); // MAX 200 IN ONE CALL. SET YOUR OWN NUMBER <= 200
try {
statuses = twitter.getHomeTimeline();
} catch (TwitterException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
String strInitialDataSet = DataObjectFactory.getRawJSON(statuses);
JSONArray JATweets = new JSONArray(strInitialDataSet);
for (int i = 0; i < JATweets.length(); i++) {
JSONObject JOTweets = JATweets.getJSONObject(i);
Log.e("TWEETS", JOTweets.toString());
}
} catch (Exception e) {
// TODO: handle exception
}
/*try {
ResponseList<Status> statii = twitter.getHomeTimeline();
statusListAdapter adapter = new statusListAdapter(getApplicationContext(), statii);
setListAdapter(adapter);
Log.d("HOME TIMELINE", statii.toString());
} catch (TwitterException e) {
e.printStackTrace();
}
//list.setVisibility(View.VISIBLE);
read.setVisibility(View.GONE);*/
}
});
twitt.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
String status = edt.getText().toString();
if(status.trim().length() > 0)
{
new updateTwitter().execute(status);
}
}
});
if(!isTwitterLogedInAlready())
{
Uri uri = getIntent().getData();
if(uri != null && uri.toString().startsWith(twitterCallbackUrl))
{
String verify = uri.getQueryParameter(urlTwitterVerify);
try
{
AccessToken accessToken = twitter.getOAuthAccessToken(reqToken,verify);
Editor edit = pref.edit();
edit.putString(prefKeyOauthToken, accessToken.getToken());
edit.putString(prefKeyOauthSecret, accessToken.getTokenSecret());
edit.putBoolean(prefKeyTwitterLogin, true);
edit.commit();
Log.d("Twitter oauth Token", ">" + accessToken.getToken());
login.setVisibility(View.INVISIBLE);
twitt.setVisibility(View.VISIBLE);
edt.setVisibility(View.VISIBLE);
read.setVisibility(View.VISIBLE);
textName.setVisibility(View.VISIBLE);
if(man == true)
{
logout.setVisibility(View.VISIBLE);
}
long userId = accessToken.getUserId();
User user = twitter.showUser(userId);
//User user = twitter.getHomeTimeline();
Status n = user.getStatus();
String userName = user.getName();
textName.setText(userName);
}
catch(Exception e)
{
Log.d("Twitter Login Error", ">" + e.getMessage());
}
}
}
}
private void setUpIds() {
twitt = (Button)findViewById(R.id.buttTwitt);
login = (Button)findViewById(R.id.buttLogin);
read = (Button)findViewById(R.id.buttRead);
edt = (EditText)findViewById(R.id.editText1);
logout = (Button)findViewById(R.id.buttLogout);
textName = (TextView)findViewById(R.id.textName);
//list = (ListView)findViewById(R.id.listView1);
pref = getApplicationContext().getSharedPreferences("myPref", 0);
}
protected void logoutFromTwitter() {
Editor e = pref.edit();
e.remove(prefKeyOauthSecret);
e.remove(prefKeyOauthToken);
e.remove(prefKeyTwitterLogin);
e.commit();
login.setVisibility(View.VISIBLE);
logout.setVisibility(View.GONE);
twitt.setVisibility(View.GONE);
edt.setVisibility(View.GONE);
read.setVisibility(View.GONE);
textName.setVisibility(View.GONE);
}
protected void loginToTwitter() {
if(!isTwitterLogedInAlready())
{
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setOAuthConsumerKey(consumerKey);
builder.setOAuthConsumerSecret(consumerSecretKey);
builder.setJSONStoreEnabled(true);
builder.setIncludeEntitiesEnabled(true);
builder.setIncludeMyRetweetEnabled(true);
builder.setIncludeRTsEnabled(true);
Configuration config = builder.build();
TwitterFactory factory = new TwitterFactory(config);
twitter = factory.getInstance();
try{
reqToken = twitter.getOAuthRequestToken(twitterCallbackUrl);
this.startActivity(new Intent(Intent.ACTION_VIEW,
Uri.parse(reqToken.getAuthenticationURL())));
}
catch(TwitterException e)
{
e.printStackTrace();
}
}
else
{
Toast.makeText(getApplicationContext(), "Already Logged In", Toast.LENGTH_LONG).show();
logout.setVisibility(View.VISIBLE);
man = false;
}
}
private boolean isTwitterLogedInAlready() {
return pref.getBoolean(prefKeyTwitterLogin, false);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
public class updateTwitter extends AsyncTask<String , String, String>{
private ProgressDialog pDialog;
#Override
protected void onPreExecute() {
super.onPreExecute();
pDialog = new ProgressDialog(MainActivity.this);
pDialog.setMessage("Updating to Twitter status..");
pDialog.setIndeterminate(false);
pDialog.setCancelable(false);
pDialog.show();
}
#Override
protected String doInBackground(String... args) {
Log.d("Tweet Text", "> " + args[0]);
String status = args[0];
try {
ConfigurationBuilder builder = new ConfigurationBuilder();
builder.setOAuthConsumerKey(consumerKey);
builder.setOAuthConsumerSecret(consumerSecretKey);
// Access Token
String access_token = pref.getString(prefKeyOauthToken, "");
// Access Token Secret
String access_token_secret = pref.getString(prefKeyOauthSecret, "");
AccessToken accessToken = new AccessToken(access_token, access_token_secret);
Twitter twitter = new TwitterFactory(builder.build()).getInstance(accessToken);
// Update status
twitter4j.Status response = twitter.updateStatus(status);
Log.d("Status", "> " + response.getText());
} catch (TwitterException e) {
// Error in updating status
Log.d("Twitter Update Error", e.getMessage());
}
return null;
}
#Override
protected void onPostExecute(String result) {
pDialog.dismiss();
runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "Status update successfully", Toast.LENGTH_SHORT).show();
edt.setText("");
}
});
}
}
}
Use the new Twitter Fabric SDK for Android. Requires sign up first. If you don't want to wait to be approved for the sign up, then I recommend using the following link
https://github.com/Rockncoder/TwitterTutorial
The link above explains how to retrieve tweets. You should be able to use the above link COMBINED with the information in the link below to POST tweets!
https://dev.twitter.com/overview/documentation

Task android sample error

I am download task-android-sample(http://code.google.com/p/google-api-java-client/issues/detail?id=479). But when i run this example on my android device, I m get error
The error appears here in this function
protected void doInBackground() throws IOException {
Log.d(Tag, "doInBackground");
List<String> result = new ArrayList<String>();
List<Task> tasks =
client.tasks().list("#default").setFields("items/title").execute().getItems();
Log.d(Tag, "трассировка");
if (tasks != null) {
for (Task task : tasks) {
result.add(task.getTitle());
}
} else {
result.add("No tasks.");
}
activity.tasksList = result;
}
description client
final com.google.api.services.tasks.Tasks client;
client = activity.service;
in what could be the problem? I am a novice, please help.
04-23 08:55:06.789: E/TasksSample(3778): com.google.api.client.googleapis.json.GoogleJsonResponseException: 403 Forbidden
04-23 08:55:06.789: E/TasksSample(3778): {
04-23 08:55:06.789: E/TasksSample(3778): "code": 403,
04-23 08:55:06.789: E/TasksSample(3778): "errors": [
04-23 08:55:06.789: E/TasksSample(3778): {
04-23 08:55:06.789: E/TasksSample(3778): "domain": "usageLimits",
04-23 08:55:06.789: E/TasksSample(3778): "message": "Access Not Configured",
04-23 08:55:06.789: E/TasksSample(3778): "reason": "accessNotConfigured"
04-23 08:55:06.789: E/TasksSample(3778): }
04-23 08:55:06.789: E/TasksSample(3778): ],
04-23 08:55:06.789: E/TasksSample(3778): "message": "Access Not Configured"
public static final String KEY = null;
make sure that you added key in place of null in ClientCredentials.java
AsyncLoadTasks
package com.google.api.services.samples.tasks.android;
import com.google.api.services.tasks.model.Task;
import android.util.Log;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
class AsyncLoadTasks extends CommonAsyncTask {
final String Tag="States";
AsyncLoadTasks(TasksSample tasksSample) {
super(tasksSample);
}
#Override
protected void doInBackground() throws IOException {
Log.d(Tag, "doInBackground");
List<String> result = new ArrayList<String>();
List<Task> tasks =
client.tasks().list("#default").setFields("items/title").execute().getItems();
Log.d(Tag, "трассировка");
if (tasks != null) {
for (Task task : tasks) {
result.add(task.getTitle());
}
} else {
result.add("No tasks.");
}
activity.tasksList = result;
}
static void run(TasksSample tasksSample) {
new AsyncLoadTasks(tasksSample).execute();
}
}
CommonAsyncTask
package com.google.api.services.samples.tasks.android;
import com.google.api.client.googleapis.extensions.android.gms.auth.GooglePlayServicesAvailabilityI OException;
import com.google.api.client.googleapis.extensions.android.gms.auth.UserRecoverableAuthIOException;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import java.io.IOException;
abstract class CommonAsyncTask extends AsyncTask<Void, Void, Boolean> {
final String Tag="States";
final TasksSample activity;
final com.google.api.services.tasks.Tasks client;
private final View progressBar;
CommonAsyncTask(TasksSample activity) {
Log.d(Tag, "CommonAsyncTask");
this.activity = activity;
client = activity.service;
progressBar = activity.findViewById(R.id.title_refresh_progress);
}
#Override
protected void onPreExecute() {
Log.d(Tag, "onPreExecute");
super.onPreExecute();
activity.numAsyncTasks++;
progressBar.setVisibility(View.VISIBLE);
}
#Override
protected final Boolean doInBackground(Void... ignored) {
Log.d(Tag, "Boolean doInBackground");
try {
doInBackground();
return true;
} catch (final GooglePlayServicesAvailabilityIOException availabilityException) {
Log.d(Tag, "1");
activity.showGooglePlayServicesAvailabilityErrorDialog(
availabilityException.getConnectionStatusCode());
} catch (UserRecoverableAuthIOException userRecoverableException) {
Log.d(Tag, "2");
activity.startActivityForResult(
userRecoverableException.getIntent(), TasksSample.REQUEST_AUTHORIZATION);
} catch (IOException e) {
Log.d(Tag, "3");
Utils.logAndShow(activity, TasksSample.TAG, e);
}
return false;
}
#Override
protected final void onPostExecute(Boolean success) {
Log.d(Tag, "onPostExecute");
super.onPostExecute(success);
if (0 == --activity.numAsyncTasks) {
progressBar.setVisibility(View.GONE);
}
if (success) {
activity.refreshView();
}
}
abstract protected void doInBackground() throws IOException;
}
TasksSample
package com.google.api.services.samples.tasks.android;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.api.client.extensions.android.http.AndroidHttp;
import com.google.api.client.googleapis.extensions.android.gms.auth.GoogleAccountCredential;
import com.google.api.client.http.HttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.gson.GsonFactory;
import com.google.api.services.tasks.TasksScopes;
import android.accounts.AccountManager;
import android.app.Activity;
import android.app.Dialog;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
public final class TasksSample extends Activity {
private static final Level LOGGING_LEVEL = Level.OFF;
private static final String PREF_ACCOUNT_NAME = "accountName";
static final String TAG = "TasksSample";
static final int REQUEST_GOOGLE_PLAY_SERVICES = 0;
static final int REQUEST_AUTHORIZATION = 1;
static final int REQUEST_ACCOUNT_PICKER = 2;
final HttpTransport transport = AndroidHttp.newCompatibleTransport();
final JsonFactory jsonFactory = new GsonFactory();
GoogleAccountCredential credential;
List<String> tasksList;
ArrayAdapter<String> adapter;
com.google.api.services.tasks.Tasks service;
int numAsyncTasks;
private ListView listView;
final String Tag="States";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d(Tag, "onCreate");
// enable logging
Logger.getLogger("com.google.api.client").setLevel(LOGGING_LEVEL);
// view and menu
setContentView(R.layout.calendarlist);
listView = (ListView) findViewById(R.id.list);
// Google Accounts
credential = GoogleAccountCredential.usingOAuth2(this, TasksScopes.TASKS);
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
credential.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));
// Tasks client
service =
new com.google.api.services.tasks.Tasks.Builder(transport, jsonFactory, credential)
.setApplicationName("Google-TasksAndroidSample/1.0").build();
}
void showGooglePlayServicesAvailabilityErrorDialog(final int connectionStatusCode) {
runOnUiThread(new Runnable() {
public void run() {
Log.d(Tag, "run");
Dialog dialog =
GooglePlayServicesUtil.getErrorDialog(connectionStatusCode, TasksSample.this,
REQUEST_GOOGLE_PLAY_SERVICES);
dialog.show();
}
});
}
void refreshView() {
Log.d(Tag, "refreshView");
adapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, tasksList);
listView.setAdapter(adapter);
}
#Override
protected void onResume() {
Log.d(Tag, "onResume");
super.onResume();
if (checkGooglePlayServicesAvailable()) {
haveGooglePlayServices();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
Log.d(Tag, "onActivityResult");
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case REQUEST_GOOGLE_PLAY_SERVICES:
if (resultCode == Activity.RESULT_OK) {
haveGooglePlayServices();
} else {
checkGooglePlayServicesAvailable();
}
break;
case REQUEST_AUTHORIZATION:
if (resultCode == Activity.RESULT_OK) {
AsyncLoadTasks.run(this);
} else {
chooseAccount();
}
break;
case REQUEST_ACCOUNT_PICKER:
if (resultCode == Activity.RESULT_OK && data != null && data.getExtras() != null) {
String accountName = data.getExtras().getString(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
credential.setSelectedAccountName(accountName);
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(PREF_ACCOUNT_NAME, accountName);
editor.commit();
AsyncLoadTasks.run(this);
}
}
break;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
Log.d(Tag, "onCreateOptionsMenu");
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Log.d(Tag, "onOptionsItemSelected");
switch (item.getItemId()) {
case R.id.menu_refresh:
AsyncLoadTasks.run(this);
break;
case R.id.menu_accounts:
chooseAccount();
return true;
}
return super.onOptionsItemSelected(item);
}
private boolean checkGooglePlayServicesAvailable() {
Log.d(Tag, "checkGooglePlayServicesAvailable");
final int connectionStatusCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
if (GooglePlayServicesUtil.isUserRecoverableError(connectionStatusCode)) {
showGooglePlayServicesAvailabilityErrorDialog(connectionStatusCode);
return false;
}
return true;
}
private void haveGooglePlayServices() {
Log.d(Tag, "haveGooglePlayServices");
// check if there is already an account selected
if (credential.getSelectedAccountName() == null) {
Log.d(Tag, "user to choose account");
// ask user to choose account
chooseAccount();
} else {
Log.d(Tag, "load calendars");
// load calendars
AsyncLoadTasks.run(this);
}
}
private void chooseAccount() {
Log.d(Tag, "chooseAccount");
startActivityForResult(credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
}
Utils
package com.google.api.services.samples.tasks.android;
import com.google.android.gms.auth.GoogleAuthException;
import com.google.api.client.googleapis.json.GoogleJsonError;
import com.google.api.client.googleapis.json.GoogleJsonResponseException;
import android.app.Activity;
import android.content.res.Resources;
import android.util.Log;
import android.widget.Toast;
public class Utils {
public static void logAndShow(Activity activity, String tag, Throwable t) {
// Log.d(Tag, "onPostExecute");
Log.e(tag, "Error", t);
String message = t.getMessage();
if (t instanceof GoogleJsonResponseException) {
GoogleJsonError details = ((GoogleJsonResponseException) t).getDetails();
if (details != null) {
message = details.getMessage();
}
} else if (t.getCause() instanceof GoogleAuthException) {
message = ((GoogleAuthException) t.getCause()).getMessage();
}
showError(activity, message);
}
/**
public static void logAndShowError(Activity activity, String tag, String message) {
String errorMessage = getErrorMessage(activity, message);
Log.e(tag, errorMessage);
showErrorInternal(activity, errorMessage);
}
public static void showError(Activity activity, String message) {
String errorMessage = getErrorMessage(activity, message);
showErrorInternal(activity, errorMessage);
}
private static void showErrorInternal(final Activity activity, final String errorMessage) {
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, errorMessage, Toast.LENGTH_LONG).show();
}
});
}
private static String getErrorMessage(Activity activity, String message) {
Resources resources = activity.getResources();
if (message == null) {
return resources.getString(R.string.error);
}
return resources.getString(R.string.error_format, message);
}
}
It is my code. What I can fix?

Categories

Resources