Amazon IAP 不调用监听器回调(Kindle Fire、Xamarin)
Amazon IAP not calling listener call backs (Kindle Fire, Xamarin)
我正在尝试 [使用 Xamarin 在 Android 项目中实施亚马逊应用内购买。
设置
亚马逊的官方 Xamarin SDK 不支持较新的 64 位设备,因此我创建了 own Java library binding using Amazon's Java SDK. (Documentation for the Java version)
Xamarin 为 PurchasingService
生成的绑定如下所示:
namespace Com.Amazon.Device.Iap
{
[Register ("com/amazon/device/iap/PurchasingService", DoNotGenerateAcw = true)]
public sealed class PurchasingService : Object
{
//
// Static Fields
//
private static IntPtr IS_SANDBOX_MODE_jfieldId;
[Register ("SDK_VERSION")]
public const string SdkVersion = "2.0.76.4";
internal static IntPtr java_class_handle;
private static IntPtr id_getUserData;
private static IntPtr id_getProductData_Ljava_util_Set_;
private static IntPtr id_getPurchaseUpdates_Z;
private static IntPtr id_notifyFulfillment_Ljava_lang_String_Lcom_amazon_device_iap_model_FulfillmentResult_;
private static IntPtr id_purchase_Ljava_lang_String_;
private static IntPtr id_registerListener_Landroid_content_Context_Lcom_amazon_device_iap_PurchasingListener_;
//
// Static Properties
//
internal static IntPtr class_ref {
get;
}
[Register ("IS_SANDBOX_MODE")]
public static bool IsSandboxMode {
get;
}
public static RequestId UserData {
[Register ("getUserData", "()Lcom/amazon/device/iap/model/RequestId;", "GetGetUserDataHandler")]
get;
}
//
// Properties
//
protected override IntPtr ThresholdClass {
get;
}
protected override Type ThresholdType {
get;
}
//
// Constructors
//
internal PurchasingService (IntPtr javaReference, JniHandleOwnership transfer);
//
// Static Methods
//
[Register ("getProductData", "(Ljava/util/Set;)Lcom/amazon/device/iap/model/RequestId;", "")]
public static RequestId GetProductData (ICollection<string> p0);
[Register ("getPurchaseUpdates", "(Z)Lcom/amazon/device/iap/model/RequestId;", "")]
public static RequestId GetPurchaseUpdates (bool p0);
[Register ("notifyFulfillment", "(Ljava/lang/String;Lcom/amazon/device/iap/model/FulfillmentResult;)V", "")]
public static void NotifyFulfillment (string p0, FulfillmentResult p1);
[Register ("purchase", "(Ljava/lang/String;)Lcom/amazon/device/iap/model/RequestId;", "")]
public static RequestId Purchase (string p0);
[Register ("registerListener", "(Landroid/content/Context;Lcom/amazon/device/iap/PurchasingListener;)V", "")]
public static void RegisterListener (Context p0, IPurchasingListener p1);
}
}
对于PurchasingListener
接口:
namespace Com.Amazon.Device.Iap
{
[Register ("com/amazon/device/iap/PurchasingListener", "", "Com.Amazon.Device.Iap.IPurchasingListenerInvoker")]
public interface IPurchasingListener : IJavaObject, IDisposable
{
//
// Methods
//
[Register ("onProductDataResponse", "(Lcom/amazon/device/iap/model/ProductDataResponse;)V", "GetOnProductDataResponse_Lcom_amazon_device_iap_model_ProductDataResponse_Handler:Com.Amazon.Device.Iap.IPurchasingListenerInvoker, AmazonIAP")]
void OnProductDataResponse (ProductDataResponse p0);
[Register ("onPurchaseResponse", "(Lcom/amazon/device/iap/model/PurchaseResponse;)V", "GetOnPurchaseResponse_Lcom_amazon_device_iap_model_PurchaseResponse_Handler:Com.Amazon.Device.Iap.IPurchasingListenerInvoker, AmazonIAP")]
void OnPurchaseResponse (PurchaseResponse p0);
[Register ("onPurchaseUpdatesResponse", "(Lcom/amazon/device/iap/model/PurchaseUpdatesResponse;)V", "GetOnPurchaseUpdatesResponse_Lcom_amazon_device_iap_model_PurchaseUpdatesResponse_Handler:Com.Amazon.Device.Iap.IPurchasingListenerInvoker, AmazonIAP")]
void OnPurchaseUpdatesResponse (PurchaseUpdatesResponse p0);
[Register ("onUserDataResponse", "(Lcom/amazon/device/iap/model/UserDataResponse;)V", "GetOnUserDataResponse_Lcom_amazon_device_iap_model_UserDataResponse_Handler:Com.Amazon.Device.Iap.IPurchasingListenerInvoker, AmazonIAP")]
void OnUserDataResponse (UserDataResponse p0);
}
}
我还确保 Android 清单修改为:
<receiver android:name = "com.amazon.device.iap.ResponseReceiver" >
<intent-filter>
<action android:name = "com.amazon.inapp.purchasing.NOTIFY"
android:permission = "com.amazon.inapp.purchasing.Permission.NOTIFY" />
</intent-filter>
</receiver>
Amazon App Tester 安装在我的 Kindle 上并配置了以下测试数据:
{
"IAP_ID":
{
"description":"One year Subscription",
"title":"My Subscription",
"itemType":"SUBSCRIPTION",
"price":20.00,
"subscriptionParent":"org.company.appid"
}
}
我有一个 class 的框架来测试系统是否正常工作:
public class AmazonIAPController : Java.Lang.Object, IPurchasingListener
{
const string ProductId = "IAP_ID";
private Activity uiActivity;
public AmazonIAPController()
{
}
public void SetupIAP(Activity activity) {
uiActivity = activity;
PurchasingService.RegisterListener(uiActivity, this);
// test that the Amazon system works
PurchasingService.Purchase(ProductId);
}
public void OnResume(Activity activity) {
uiActivity = activity;
PurchasingService.RegisterListener(uiActivity, this);
//PurchasingService.UserData;
PurchasingService.GetPurchaseUpdates(false);
PurchasingService.GetProductData(new string[] { ProductId });
}
public void OnProductDataResponse(ProductDataResponse response) {
var status = response.GetRequestStatus();
Debug.WriteLine("*****OnProductDataResponse");
}
public void OnPurchaseResponse(PurchaseResponse response) {
var status = response.GetRequestStatus();
Debug.WriteLine("*****OnPurchaseResponse");
}
public void OnPurchaseUpdatesResponse(PurchaseUpdatesResponse response) {
var status = response.GetRequestStatus();
Debug.WriteLine("*****OnPurchaseUpdatesResponse");
}
public void OnUserDataResponse(UserDataResponse response) {
var status = response.GetRequestStatus();
Debug.WriteLine("*****OnUserDataResponse");
}
}
测试运行
我正在尝试 运行 在我的第 5 代 Kindle Fire 上执行此操作。当应用程序启动时,用户会按预期收到 Amazon IAP 提示。如果执行了购买,它就会完成并且交易会正确显示在 Amazon App Tester 应用程序中。
问题
我在回调方法中设置了断点。这些断点永远不会被触发。 Debug.WriteLine
调用也不会出现在应用程序输出中。看来我的回调方法没有被调用。
问题的根源是 Android 清单条目与 Xamarin 生成具有代码属性的清单条目的方式冲突。
为了解决这个问题,我从清单中删除了上述条目,并在 Java 绑定项目中创建了一个附加文件,其中包含 ResponseReciever
的部分 class 和相关的清单属性如下:
using System;
using Android.App;
using Android.Content;
namespace Com.Amazon.Device.Iap
{
[BroadcastReceiver(Name = "com.amazon.device.iap.ResponseReceiver")]
[IntentFilter(new[] { "com.amazon.inapp.purchasing.NOTIFY" })]
public partial class ResponseReceiver
{
}
}
此后,清单条目已正确生成,预期的回调开始工作。
注:
您可能会注意到清单 XML 中的 android:permission
条目不在上述属性中。我找不到参考资料,但我记得在某个地方看到过,不仅不需要这个条目来让 SDK 工作,而且根据 the official Android documentation,它实际上不是 action
上的有效属性。
我正在尝试 [使用 Xamarin 在 Android 项目中实施亚马逊应用内购买。
设置
亚马逊的官方 Xamarin SDK 不支持较新的 64 位设备,因此我创建了 own Java library binding using Amazon's Java SDK. (Documentation for the Java version)
Xamarin 为 PurchasingService
生成的绑定如下所示:
namespace Com.Amazon.Device.Iap
{
[Register ("com/amazon/device/iap/PurchasingService", DoNotGenerateAcw = true)]
public sealed class PurchasingService : Object
{
//
// Static Fields
//
private static IntPtr IS_SANDBOX_MODE_jfieldId;
[Register ("SDK_VERSION")]
public const string SdkVersion = "2.0.76.4";
internal static IntPtr java_class_handle;
private static IntPtr id_getUserData;
private static IntPtr id_getProductData_Ljava_util_Set_;
private static IntPtr id_getPurchaseUpdates_Z;
private static IntPtr id_notifyFulfillment_Ljava_lang_String_Lcom_amazon_device_iap_model_FulfillmentResult_;
private static IntPtr id_purchase_Ljava_lang_String_;
private static IntPtr id_registerListener_Landroid_content_Context_Lcom_amazon_device_iap_PurchasingListener_;
//
// Static Properties
//
internal static IntPtr class_ref {
get;
}
[Register ("IS_SANDBOX_MODE")]
public static bool IsSandboxMode {
get;
}
public static RequestId UserData {
[Register ("getUserData", "()Lcom/amazon/device/iap/model/RequestId;", "GetGetUserDataHandler")]
get;
}
//
// Properties
//
protected override IntPtr ThresholdClass {
get;
}
protected override Type ThresholdType {
get;
}
//
// Constructors
//
internal PurchasingService (IntPtr javaReference, JniHandleOwnership transfer);
//
// Static Methods
//
[Register ("getProductData", "(Ljava/util/Set;)Lcom/amazon/device/iap/model/RequestId;", "")]
public static RequestId GetProductData (ICollection<string> p0);
[Register ("getPurchaseUpdates", "(Z)Lcom/amazon/device/iap/model/RequestId;", "")]
public static RequestId GetPurchaseUpdates (bool p0);
[Register ("notifyFulfillment", "(Ljava/lang/String;Lcom/amazon/device/iap/model/FulfillmentResult;)V", "")]
public static void NotifyFulfillment (string p0, FulfillmentResult p1);
[Register ("purchase", "(Ljava/lang/String;)Lcom/amazon/device/iap/model/RequestId;", "")]
public static RequestId Purchase (string p0);
[Register ("registerListener", "(Landroid/content/Context;Lcom/amazon/device/iap/PurchasingListener;)V", "")]
public static void RegisterListener (Context p0, IPurchasingListener p1);
}
}
对于PurchasingListener
接口:
namespace Com.Amazon.Device.Iap
{
[Register ("com/amazon/device/iap/PurchasingListener", "", "Com.Amazon.Device.Iap.IPurchasingListenerInvoker")]
public interface IPurchasingListener : IJavaObject, IDisposable
{
//
// Methods
//
[Register ("onProductDataResponse", "(Lcom/amazon/device/iap/model/ProductDataResponse;)V", "GetOnProductDataResponse_Lcom_amazon_device_iap_model_ProductDataResponse_Handler:Com.Amazon.Device.Iap.IPurchasingListenerInvoker, AmazonIAP")]
void OnProductDataResponse (ProductDataResponse p0);
[Register ("onPurchaseResponse", "(Lcom/amazon/device/iap/model/PurchaseResponse;)V", "GetOnPurchaseResponse_Lcom_amazon_device_iap_model_PurchaseResponse_Handler:Com.Amazon.Device.Iap.IPurchasingListenerInvoker, AmazonIAP")]
void OnPurchaseResponse (PurchaseResponse p0);
[Register ("onPurchaseUpdatesResponse", "(Lcom/amazon/device/iap/model/PurchaseUpdatesResponse;)V", "GetOnPurchaseUpdatesResponse_Lcom_amazon_device_iap_model_PurchaseUpdatesResponse_Handler:Com.Amazon.Device.Iap.IPurchasingListenerInvoker, AmazonIAP")]
void OnPurchaseUpdatesResponse (PurchaseUpdatesResponse p0);
[Register ("onUserDataResponse", "(Lcom/amazon/device/iap/model/UserDataResponse;)V", "GetOnUserDataResponse_Lcom_amazon_device_iap_model_UserDataResponse_Handler:Com.Amazon.Device.Iap.IPurchasingListenerInvoker, AmazonIAP")]
void OnUserDataResponse (UserDataResponse p0);
}
}
我还确保 Android 清单修改为:
<receiver android:name = "com.amazon.device.iap.ResponseReceiver" >
<intent-filter>
<action android:name = "com.amazon.inapp.purchasing.NOTIFY"
android:permission = "com.amazon.inapp.purchasing.Permission.NOTIFY" />
</intent-filter>
</receiver>
Amazon App Tester 安装在我的 Kindle 上并配置了以下测试数据:
{
"IAP_ID":
{
"description":"One year Subscription",
"title":"My Subscription",
"itemType":"SUBSCRIPTION",
"price":20.00,
"subscriptionParent":"org.company.appid"
}
}
我有一个 class 的框架来测试系统是否正常工作:
public class AmazonIAPController : Java.Lang.Object, IPurchasingListener
{
const string ProductId = "IAP_ID";
private Activity uiActivity;
public AmazonIAPController()
{
}
public void SetupIAP(Activity activity) {
uiActivity = activity;
PurchasingService.RegisterListener(uiActivity, this);
// test that the Amazon system works
PurchasingService.Purchase(ProductId);
}
public void OnResume(Activity activity) {
uiActivity = activity;
PurchasingService.RegisterListener(uiActivity, this);
//PurchasingService.UserData;
PurchasingService.GetPurchaseUpdates(false);
PurchasingService.GetProductData(new string[] { ProductId });
}
public void OnProductDataResponse(ProductDataResponse response) {
var status = response.GetRequestStatus();
Debug.WriteLine("*****OnProductDataResponse");
}
public void OnPurchaseResponse(PurchaseResponse response) {
var status = response.GetRequestStatus();
Debug.WriteLine("*****OnPurchaseResponse");
}
public void OnPurchaseUpdatesResponse(PurchaseUpdatesResponse response) {
var status = response.GetRequestStatus();
Debug.WriteLine("*****OnPurchaseUpdatesResponse");
}
public void OnUserDataResponse(UserDataResponse response) {
var status = response.GetRequestStatus();
Debug.WriteLine("*****OnUserDataResponse");
}
}
测试运行
我正在尝试 运行 在我的第 5 代 Kindle Fire 上执行此操作。当应用程序启动时,用户会按预期收到 Amazon IAP 提示。如果执行了购买,它就会完成并且交易会正确显示在 Amazon App Tester 应用程序中。
问题
我在回调方法中设置了断点。这些断点永远不会被触发。 Debug.WriteLine
调用也不会出现在应用程序输出中。看来我的回调方法没有被调用。
问题的根源是 Android 清单条目与 Xamarin 生成具有代码属性的清单条目的方式冲突。
为了解决这个问题,我从清单中删除了上述条目,并在 Java 绑定项目中创建了一个附加文件,其中包含 ResponseReciever
的部分 class 和相关的清单属性如下:
using System;
using Android.App;
using Android.Content;
namespace Com.Amazon.Device.Iap
{
[BroadcastReceiver(Name = "com.amazon.device.iap.ResponseReceiver")]
[IntentFilter(new[] { "com.amazon.inapp.purchasing.NOTIFY" })]
public partial class ResponseReceiver
{
}
}
此后,清单条目已正确生成,预期的回调开始工作。
注:
您可能会注意到清单 XML 中的 android:permission
条目不在上述属性中。我找不到参考资料,但我记得在某个地方看到过,不仅不需要这个条目来让 SDK 工作,而且根据 the official Android documentation,它实际上不是 action
上的有效属性。