您好我们正在尝试将Google Play订阅信息与我们的某个Android应用相关联。第一步是授权并获得订阅json
有没有人成功使用Google Play Developer API?授权?订阅列表?
当我使用authScope =“https://www.googleapis.com/auth/androidpublisher”时; (从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());
}
}
}
我无法获得令牌,因为我在
之下获得了例外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)
当我使用authScope =“管理你的任务”时; (从另一个Google示例中获取)
private static final String authScope = "Manage your tasks";
我正在接收令牌,但是在ProductPurchase product = purchases.products()。get(PACKAGE_NAME,TEST_SKU,token).execute();
我得到了getProducts Exception = 400 Bad Request 见下文
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;
}
}
}