Google connectivity issues for Google Play Developers
Hi, we are trying to get Google Play subscription information connected to one of our Android apps. The first step is to authorize and get the json subscription
Anyone can work with the Google Play Developer API? Authorization? Subscription list?
Below is our experience
When I use authScope = " https://www.googleapis.com/auth/androidpublisher "; (took an example from Google)
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 cannot get the token because I am getting the below exception
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 = "Task Management"; (took it from another google example)
private static final String authScope = "Manage your tasks";
I get the token, but in ProductPurchase product = purchase.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;
}
}
}
+3
source to share
No one has answered this question yet
Check out similar questions: