Хорошо, поэтому я пытался исправить это в течение нескольких дней, и я не приду сюда в поисках кого-то, кто сделает мою работу за меня, поскольку я устранял неполадки и исправлял каждое сообщение об ошибке в LogCat. Я разрабатываю игру для Android с использованием Andengine (это может быть частью проблемы, поэтому знакомство с ней может помочь). Я не делаю ничего особенного, все мои игровые действия - одна сцена, и у меня нет никакой физики или чего-то подобного, просто куча спрайтов и текстур. Я также использовал Andengine для всех других действий в моей игре, потому что я считаю, что это очень простой способ настройки графически привлекательных экранов. Одним из таких экранов является мой магазин приложений, где пользователи могут покупать пакеты уровней и новые спрайты. Биллинговая часть всего этого прекрасно работает, покупки проходят на Маркет, и там нет ничего слишком сложного ...
Когда пользователь нажимает кнопку «Купить», появляется экран рынка и загружается выбранный продукт (это реальные продукты, а не тесты Android, хотя игра не опубликована). Экран Market появляется поверх текущей активности, независимо от того, использую ли я реализацию «Android 2.0», где она является частью стека игры, или я использую реализацию «Android 1.6», и она является частью ее собственного стека. Я бы предпочел использовать реализацию Android 2.0, но если я смогу заставить работать только 1.6, я это сделаю. Так или иначе, проблема возникает, когда пользователь либо отменяет покупку с помощью кнопки «Назад», либо завершает покупку с помощью кредитной карты, что приводит как к исчезновению экрана рынка, так и к запуску новой операции, которая представляет собой просто черный экран (который в конечном итоге и вызывает силу близко). Покупка проходит успешно, но пользователь не получает продукт, потому что игровое усилие прекращает работу, прежде чем мы перейдем к коду, чтобы изменить элементы пользователя в игре. Теперь для некоторого кода я использовал этот учебник (http://www.anddev.org/advanced-tutorials-f21/simple-inapp-billing-payment-t52060.html), практически ничего не меняя. Класс BillingHelper наиболее важен, так как он содержит метод requestPurchase () и методы startBuyPageActivity (). Я вызываю запрос на покупку из своей активности StoreFront, например: это:
BillingHelper.requestPurchase(StoreFront.this, itemID);
и в onCreate the StoreFront у меня есть этот материал (как сказано в статье):
startService(new Intent(mContext, BillingService.class));
BillingHelper.setCompletedHandler(mTransactionHandler);
...
//some handler that billing needs
public Handler mTransactionHandler = new Handler(){
public void handleMessage(android.os.Message msg) {
Log.i(TAG, "Transaction complete");
Log.i(TAG, "Transaction status: "+BillingHelper.latestPurchase.purchaseState);
Log.i(TAG, "Item purchased is: "+BillingHelper.latestPurchase.productId);
if(BillingHelper.latestPurchase.isPurchased()){
//TODO do something here if we've completed our latest purchase,
//this should be with the status bar notifications and
//saved preferences
}
};
};
Так что я не думаю, что проблема в этом. Вот соответствующие части BillingHelper
protected static void requestPurchase(Context activityContext, String itemId){
if (amIDead()) {
return;
}
Log.i(TAG, "requestPurchase()");
Bundle request = makeRequestBundle("REQUEST_PURCHASE");
request.putString("ITEM_ID", itemId);
try {
Bundle response = mService.sendBillingRequest(request);
//The RESPONSE_CODE key provides you with the status of the request
Integer responseCodeIndex = (Integer) response.get("RESPONSE_CODE");
//The PURCHASE_INTENT key provides you with a PendingIntent, which you can use to launch the checkout UI
PendingIntent pendingIntent = (PendingIntent) response.get("PURCHASE_INTENT");
//The REQUEST_ID key provides you with a unique request identifier for the request
Long requestIndentifier = (Long) response.get("REQUEST_ID");
Log.i(TAG, "current request is:" + requestIndentifier);
C.ResponseCode responseCode = C.ResponseCode.valueOf(responseCodeIndex);
Log.i(TAG, "REQUEST_PURCHASE Sync Response code: "+responseCode.toString());
startBuyPageActivity(pendingIntent, new Intent(), activityContext);
} catch (RemoteException e) {
Log.e(TAG, "Failed, internet error maybe", e);
Log.e(TAG, "Billing supported: "+isBillingSupported());
}
}
То, что я пытался вызвать из StoreFront с помощью различных аргументов, таких как «ActivityContext», таких как StoreFront.this, getApplicationContext (), статическое хранилище контекста в другом месте, статическое действие, хранящееся в другом месте, getBaseContext () все, что я мог бы придумать ...
Вот другой соответствующий вид деятельности
private static void startBuyPageActivity(PendingIntent pendingIntent, Intent intent, Context context){
//android 1.6 method
try {
pendingIntent.send(context, 0, intent);
} catch (CanceledException e){
Log.e(TAG, "startBuyPageActivity CanceledException");
}
}
Ничего особенного, я просто хочу, чтобы пользователь возвращался к любому из моих различных действий (предпочтительно StoreFront), когда он либо покупает товар, либо нажимает обратно во время процесса. ПОМОГИТЕ ПОЖАЛУЙСТА!
Редактировать. Я хочу, чтобы любое возможное решение, позволяющее выставлять счета в приложении, возвращалось в мое приложение после завершения покупки, даже самое грязное решение.
EDIT
LogCat и вызовы методов, что проблема:
"BillingService Starting",
BillingHelper.setCompletedHandler(),
StoreFront.onStart() called,
StoreFront.onResume() called,
"BillingService Service starting with onCreate",
"BillingService Market Billing Service Successfully Bound",
"BillingService Market Billing Service Connected",
BillingHelper.instantiateHelper(),
then this is where I actually click the buy button in the store (all of that runs just when opening StoreFront):
BillingHelper.setCompletedHandler(),
BillingHelper.isBillingSupported(),
BillingHelper.amIDead(),
BillingHelper.makeRequestBundle(),
"BillingService isBillingSupported response was: RESULT OK",
BillingHelper.requestPurchase(),
BillingHelper.amIDead(),
"BillingService requestPurchase()",
BillingHelper.makeRequestBundle(),
"BillingService current request is ......",
"BillingService REQUEST PURCHASE Sync Response code: RESULT OK",
BillingHelper.startBuyPageActivity(),
"BillingService Recieved action: com.android.vending.billing.RESPONSE CODE",
"BillingService checkResponseCode got requestID..."
"BillingService checkResponseCode go responseCode RESULT ERROR"
(this is because I can't purchase on this device),
and then I get an Error message saying: "E 32427 Surface surface (identity=5925) is invalid, err=-19 (No such device)" and from there nothing works anymore.
Также я проверил это на другом телефоне (другой разработчик, с которым я работаю, который действительно может что-то покупать в нем, но все еще получает ошибку черного экрана), и он так и не получил сообщения обработчика, которые вы упомянули в своем комментарии
Редактировать: если бы мне пришлось угадывать, где ошибка, я бы сказал, что это
06-16 11:20:23.635: DEBUG/dalvikvm(3807): GC_EXPLICIT freed 53K, 45% free 3710K/6663K, external 1K/513K, paused 102ms
06-16 11:20:23.885: ERROR/Surface(3807): surface (identity=158) is invalid, err=-19 (No such device)
06-16 11:20:23.905: ERROR/Surface(3807): surface (identity=158) is invalid, err=-19 (No such device)
06-16 11:20:23.905: ERROR/Surface(3807): surface (identity=158) is invalid, err=-19 (No such device)
06-16 11:20:23.905: ERROR/Adreno200-EGL(3807): egliSwapWindowSurface: unable to dequeue native buffer
Обратите внимание, что прерванная исключительная ситуация ожидается от библиотеки Andengine, так что это красная сельдь.
Кроме того (я надеюсь, что это разрешено здесь), я предложу вознаграждение PayPal за решение. Если это противоречит Условиям SO, просто удалите эту строку, пожалуйста, не закрывайте этот вопрос.