Prueba de facturación integrada en la aplicación: android.test.purchased ya poseído

122

Actualmente estoy probando la facturación integrada en la aplicación para una aplicación futura y, después de "comprar" correctamente el elemento de prueba "android.test.purchased" la primera vez, ahora recibo el código de respuesta 7 cada vez que intento comprarlo de nuevo. lo que significa que ya tengo este artículo.

12-15 23: 02: 14.149: E / IabHelper (19829): Error de facturación en la aplicación: No se puede comprar el artículo, Respuesta de error: 7: El artículo ya es de su propiedad

Por lo que tengo entendido, se supone que esta compra siempre es posible, ¿verdad? ¿Para que el desarrollador pueda probar su aplicación?

Si no es así, ¿cómo puedo "restablecer" su estado a no poseído? Estoy usando el paquete util de la muestra de facturación integrada en la aplicación de Google.

psykhi
fuente
1
mi reclutamiento son versos de tornillo de banco ... necesito el mensaje ya poseído, pero cada vez me permite comprar
Sandeep P

Respuestas:

109

Agregue este código a un hilo para iniciar la solicitud de consumo.

int response = mService.consumePurchase(3, getPackageName(), purchaseToken);

Aquí para la prueba de compra, purchaseToken es

purchaseToken = "inapp:" + getPackageName() + ":android.test.purchased";

Y

if (response == 0)

entonces el consumo es exitoso.

Tampoco olvide hacer público mService en

IabHelper.Java

entonces sería posible acceder así:

int response = mHelper.mService.consumePurchase(3, getPackageName(), purchaseToken);
Aashutosh Sharma
fuente
2
Leyenda, esto funciona, @psykhi realmente debería haberte dado los puntos. Estaba tratando de consumirlo pero no pude calcular el token de compra. Gracias
Blundell
1
¡Gracias! @prasharonnet
Y2i
1
Este es un gran ahorro de tiempo. Perfecto. Gracias.
PrivusGuru
13
¿Qué es mService? mHelper? Pero no puedo encontrar el consumoPurchase ()
Bagusflyer
1
mService es objeto de la interfaz IInAppBillingService.aidl que está vinculada con el servicio de compra iniciado para la compra de una aplicación.
Aashutosh Sharma
92

No es necesario escribir ningún código de consumo especial. Simplemente use el comando adb para borrar los datos de Google Play Store:

adb shell pm clear com.android.vending
mttmllns
fuente
1
gracias, hizo el truco, solo tuve que borrar la aplicación también, así que hice una respuesta completa disponible. Este es el enfoque adecuado para mí.
sivi
Este es el enfoque correcto para mucha gente. Agregar código a su aplicación y volver a implementarlo requiere más tiempo (juego de palabras).
Michael Labbé
9
Esta es una buena solución para un dispositivo de prueba, pero tenga cuidado: restablecerá todas sus configuraciones en la aplicación Google Play Store. Por lo tanto, prefiero no hacerlo en mi dispositivo personal.
racs
7
¡No! esta es una mala idea, perdió la compra en la aplicación de su otro producto y otras aplicaciones, la buena es que tiene que consumir el producto si desea probar su compra en la aplicación, el escenario es simplemente crear dos cosas, una para comprar y otra para consumir comprada articulo.
Rahul Mandaliya
2
@RahulMandaliya su aplicación debe ser resistente contra borrados de caché mediante el uso de la API getPurchases () para saber lo que ya se ha comprado.
mttmllns
66

Resulta que el elemento android.test.purchased se comporta como una identificación normal. Significa que si quieres poder comprarlo nuevamente, debes consumirlo en algún lugar de tu código. Creo que la documentación de Google es engañosa sobre este asunto, y que deberían agregar otra identificación estática que puede comprar sin cesar con fines de prueba.

psykhi
fuente
Use la llamada de inventario para buscar el objeto de compra y luego consumirlo; es bastante fácil una vez que lo entienda.
slott
3
Mire a continuación la respuesta de @mttmlins, o lea vvse.com/blog/blog/2016/08/26/…
IgorGanapolsky
No es del todo cierto, tengo un caso en el que no hay elemento de prueba no consumido, pero billingClient.queryPurchases()no devuelve ese elemento no consumido, por lo que ahora no puedo consumir elemento porque no puedo obtener purchaseTokende ella
Jemshit Iskenderov
28

Versión 3 en la aplicación:

IabHelper.QueryInventoryFinishedListener mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() {

    public void onQueryInventoryFinished(IabResult result, Inventory inventory) {

        .....................

        if (inventory.hasPurchase(SKU_CONTENT)) {

            mHelper.consumeAsync(inventory.getPurchase(SKU_CONTENT), null);
        }
    }
};
embo
fuente
Como una imagen vale más que mil palabras, una pieza de código completa y básica vale mil 'Agregue este código a un hilo. . . '.
Androidcoder
11

Versión 3: la forma más rápida de resolver : borrar el caché de Google Play Store permitirá que "android.test.purchased" esté disponible nuevamente.

Denis
fuente
¿No afectaría eso también a otras aplicaciones instaladas en el sistema?
IgorGanapolsky
1
@IgorGanapolsky, no. Solo se verán afectadas las compras simuladas. Las compras "reales" se almacenan en el servidor de Google y no se modificarán.
Denis
1
Borré los datos de la aplicación de Google Play, pero no funcionó. Los detalles de la compra de prueba aún existen.
Srikar Reddy
2
@Richard a través de "configuración / administrador de aplicaciones /" o arrastrando el ícono de Google Play Store desde el menú al botón "Información" (en la parte superior de la pantalla). Finalmente, simplemente haga clic en el botón "borrar caché".
Denis
1
La mejor respuesta para mi Todos los demás son buenos, pero esta definitivamente es la forma más rápida de resolver
Ignacio Roda
10

utilicé adb shell:

adb shell pm clear com.android.vending
Shwarz Andrei
fuente
9

Así es como podemos consumir el Item

 consume.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View view) {
            Thread t = new Thread(new Runnable() {
                @Override
                public void run() {
                    String purchaseToken = "inapp:" + getPackageName() + ":android.test.purchased";
                    try {
                        Log.d("","Running");
                        int response = mService.consumePurchase(3, getPackageName(), purchaseToken);
                        if(response==0)
                        {
                            Log.d("Consumed","Consumed");
                        }else {
                            Log.d("","No"+response);
                        }
                    }catch (RemoteException e)
                    {
                        Log.d("Errorr",""+e);
                    }

                }
            });
            t.start();
        }
    });
Shivaraj Patil
fuente
Funcionó para mí, había usado android.test.purchaseen algún momento lo que estaba causando problemas, la tarea de inventario en la facturación en la aplicación arrojó una gran cantidad de errores y nunca terminó. Ejecutar esto como algo único lo borró para poder reanudar el uso de mi SKU real y continuar como estaba antes. Gracias
Jon
1
Excelente respuesta. Funciona con respuestas estáticas = antes de que el apk con la facturación integrada en la aplicación habilitada se cargue en Google Play.
infero
¡Gracias! Trabajó para mi.
AndroidMechanic - Viral Patel
6

En mi opinión, si su programa no está diseñado para consumir el artículo, no necesita modificar el código para borrar la memoria de un proveedor externo. Esto hará que su código sea más frágil y luego tendrá que dedicar mucho tiempo a agregar y eliminar código que no pertenece a su software, por lo que es un mal diseño implementar una solución como esa.

La mejor solución que funcionó para mí para borrar android.test.purchased fue

adb uninstall com.yourapp.name

y entonces

adb shell pm clear com.android.vending

No necesitaba limpiar el efectivo y navegar por la configuración de mis aplicaciones o cambiar el código para eso. Necesitaba agregar el adb a las variables de ruta del sistema de Windows, lo cual era bastante sencillo. Entonces, sí, debe usar adb, que probablemente necesite de todos modos, así que ...

Simplemente agregue su C: \ ... \ android-sdk \ platform-tools; en la ruta de Windows en las variables de entorno, e imagino que también es bastante simple en Mac y Linux. Espero que ayude a alguien a pasar unos días menos implementando Android en la facturación de la aplicación.

sivi
fuente
uninstallno es necesario borrar el sku android.test.purchased .
IgorGanapolsky
4

El problema principal es que tienes que consumir android.test.purchased artículo. Pero este artículo no estará disponible en su inventario de consultas, por lo que no puede consumir usando el flujo normal.

Entonces, si está usando IabHelper, en IabHelperclase, puede cambiar temporalmente elIInAppBillingService mService a público para que sea accesible desde su IabHelper.

Luego, en tu clase, puedes consumir así,

int response = mHelper.mService.consumePurchase(3, getPackageName(), "inapp:"+getPackageName()+":android.test.purchased");

Si tiene éxito, la respuesta será 0.

Espero que esto ayude.

Tang Tung Ai
fuente
Tangente: ¿puede emitir un reembolso en un artículo administrado (con una cuenta de prueba, no parece mostrarse en el panel)?
Ed Lee
Puede llamar consumeAsync()a android.test.purchased . No hay problema con eso.
IgorGanapolsky
Para una prueba simple, esta es la mejor manera posible si usa IabHelper. Me ayudó.
Rúben
2

Para propósitos de prueba, también le sugiero que inserte un fragmento de código que borrará todos los productos que ha comprado antes de llamar a un método que inicializa el flujo de compra de gp. Eso es especialmente cómodo cuando prueba solo un elemento en este momento. Por ejemplo, así:

PurchasesResult purchasesResult = mBillingClient.queryPurchases(BillingClient.SkuType.INAPP);
    for (Purchase sourcePurchase : purchasesResult.getPurchasesList()) {
        if(sourcePurchase != null){

            ConsumeResponseListener listener = new ConsumeResponseListener() {
                @Override
                public void onConsumeResponse(String outToken, @BillingResponse int responseCode) {

                    System.out.println("all consumed");
                }
            };
            mBillingClient.consumeAsync(sourcePurchase.getPurchaseToken(), listener);
        }else{
            System.out.println("null");
        }
    }

// and then initiate whole process with clear "shoping basket"

BillingFlowParams.Builder builder = new BillingFlowParams.Builder()
        .setSku(itemName).setType(BillingClient.SkuType.INAPP);
nitrato de sodio
fuente
2

vaya a la consola de Google Play y abra la pestaña Gestión de pedidos. Allí puede reembolsar / cancelar compras de prueba.

Sai Nadh
fuente
1

Si está en un entorno de prueba

1) En el caso de android.test.purchased, puedo restablecer el pago falso reiniciando el dispositivo Android (consumió el inventario).

2) En InApp util hay un archivo llamado Security.java, hazlo como sigue, por temporal. Dado que el pago de prueba (falso) siempre devuelve falso debido a una excepción de seguridad.

public static boolean verifyPurchase(String base64PublicKey,
                                     String signedData, String signature) {
    return true; }

Luego, en su OnIabPurchaseFinishedListener, llame a fechInvForconsumeItem ()

IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener
            = new IabHelper.OnIabPurchaseFinishedListener() {
        public void onIabPurchaseFinished(IabResult result,
                                          Purchase purchase)
        {
            if (result.isFailure()) {
                // Handle error
                Log.e("123","Failure");

                return;
            }
            else if (purchase.getSku().equals(ITEM_SKU)) {
                Log.e("123","PURCAsed");
                fechInvForconsumeItem(); // Restart device if not consume

            }

        }
    };

El fechInvForconsumeItem () es

    public void fechInvForconsumeItem() {
    mHelper.queryInventoryAsync(mReceivedInventoryListener);
}
IabHelper.QueryInventoryFinishedListener mReceivedInventoryListener
        = new IabHelper.QueryInventoryFinishedListener() {
    public void onQueryInventoryFinished(IabResult result,
                                         Inventory inventory) {


        if (result.isFailure()) {
            // Handle failure
            Log.e("11","Failure");



        } else {
            Log.e("11","suc");
            mHelper.consumeAsync(inventory.getPurchase(ITEM_SKU),
                    mConsumeFinishedListener);
        }


    }
};

Consume Listener es

    IabHelper.OnConsumeFinishedListener mConsumeFinishedListener =
        new IabHelper.OnConsumeFinishedListener() {
            public void onConsumeFinished(Purchase purchase,
                                          IabResult result) {

                if (result.isSuccess()) {
                } else {
                    // handle error
                    Log.e("11","sucConsume");
                }
            }
        };
Ebin Joy
fuente
0
IabHelper.QueryInventoryFinishedListener 
       mQueryFinishedListener = new IabHelper.QueryInventoryFinishedListener() {
       public void onQueryInventoryFinished(IabResult result, Inventory inventory)   
       {
          if (result.isFailure()) {
             return;
           }          
          try {

                if(inventory.hasPurchase("product_sku_id"))
                {   
                     isItemEnable= true;
                     mHelper.consumeAsync(inventory.getPurchase("product_sku_id"),null);            
                }
                else
                {
                       isItemEnable = false;
                }           

            } catch (Exception e) {
                e.printStackTrace();
            }
       }

    };
Girish Patel
fuente
-1

En mi caso, parece que Google no registra una compra del artículo. Más bien, la copia local de Google Play Services almacena en caché la compra. De esa forma, cuando se realiza una segunda solicitud en el mismo dispositivo, android.test.purchased already ownedaparece. Sin embargo, usar otro dispositivo o restablecer el dispositivo borra la caché y permite que se repita la compra.

Tad
fuente
-1

En mi caso, solo necesitaba borrar el caché de las aplicaciones. Después de borrar la caché, pude iniciar el flujo de compra nuevamente.

Desde mi dispositivo (4.4.2), navegué a "Configuración-> Administrador de aplicaciones". A continuación, seleccioné la aplicación de la pestaña "DESCARGADO" y luego "Borrar caché".

usuario6089948
fuente
-2

Ésta es la diferencia entre artículos consumibles y no consumibles; Los artículos no consumibles (con lo que parece estar lidiando aquí) tienen su estado registrado de manera persistente, mientras que los artículos consumibles se pueden comprar varias veces. Tendrás que ir a tu consola de administración de Play y cancelar / reembolsar la venta para probarla nuevamente.

addaon
fuente
1
Pero la cosa es que no tengo ningún "poder" sobre estos artículos "falsos", y no veo dónde podría cambiar el estado de la venta, ya que no son compras reales. El documento de Google dice sobre android.test.purchased: cuando realiza una solicitud de facturación en la aplicación con este ID de producto, Google Play responde como si hubiera comprado un artículo con éxito. Así que estoy bastante confundido: /
psykhi
¿Sigue haciendo pruebas de respuesta estática? Si es así, solo necesita cambiar la respuesta estática que se envía. Sin embargo, parece que está preparado para "Probar compras dentro de la aplicación utilizando sus propios ID de producto", que realiza compras reales con pedidos cancelables.
Adda el
Todavía estoy atascado con las ID estáticas. Lo que me gustaría es poder probar una compra en la aplicación con el ID android.test.purchased. Simplemente funcionó la primera vez, cuando siempre debería funcionar según lo que entiendo del documento de Google. ¡Perdón si no lo tuve claro!
psykhi
Mi mala interpretación, lo siento. En ese caso ... no lo sé. Definitivamente se supone que devuelve el éxito cada vez, no he visto el caso que estás viendo. Lo siento.
Adda el
Intentaré volver a ver el problema después de una buena noche de sueño :) ¡Gracias por tu ayuda!
psykhi