2011-12-26 11 views
11

Agrego una compra en la aplicación en mi codificación, está funcionando bien durante la compra pero da error y la aplicación se cierra cuando intento agregar el código Restore_Transaction cuando la aplicación se elimina y instalado de nuevo, he añadido a continuación de codificaciónCompra InApp RESTORE_TRANSACTIONS, no puedo descifrar el código

en onCreate escribí

startService(new Intent(mContext, BillingService.class)); 
     BillingHelper.setCompletedHandler(mTransactionHandler); 

     if (BillingHelper.isBillingSupported()) { 
      BillingHelper.restoreTransactionInformation(BillingSecurity 
        .generateNonce()); 
     } 

y luego llamé manejador usando

public Handler mTransactionHandler = new Handler() { 
     public void handleMessage(android.os.Message msg) { 
      if (BillingHelper.latestPurchase.isPurchased()) { 
       showItem(); 
      } 
     }; 
    }; 

    private void showItem() { 
     purchased = Purchased.getPurchaseInfo(getApplicationContext()); 
     if (purchased == null) { 
      Date d = new Date(); 
      Toast.makeText(getApplicationContext(), "--- Upgrated ---", 
        Toast.LENGTH_LONG).show(); 
      purchased = new Purchased(getApplicationContext()); 
      purchased.isPurchased = 1; 
      purchased.purchasedDate = d.getTime(); 
      purchased.save(); 
      Intent intent = new Intent(ActorGenieActivity.this, 
        SplashScreen.class); 
      startActivity(intent); 
     } 
    } 

Respuesta

5

he encontrado la respuesta a mi pregunta, gracias a el anddev

Usted tiene que comprobar para compras no ser nula

public static void verifyPurchase(String signedData, String signature) { 
    ArrayList<VerifiedPurchase> purchases = BillingSecurity.verifyPurchase(
      signedData, signature); 
    if (purchases != null && !purchases.isEmpty()) { 
     latestPurchase = purchases.get(0); 
     confirmTransaction(new String[] { latestPurchase.notificationId }); 
     if (mCompletedHandler != null) { 
      mCompletedHandler.sendEmptyMessage(0); 
     } else { 
      Log 
        .e(
          TAG, 
          "verifyPurchase error. Handler not instantiated. Have you called setCompletedHandler()?"); 
     } 
    } 
} 

y en Confirm_Notification u hav para comprobar si hay

if (notifyIds[0] != null) 
+0

¿cuál es la solución? – Pabluez

+0

¿Lo hiciste funcionar? No recibo nada más que errores y fuerza cerca, sin embargo, realmente no puedo descifrar qué hiciste con esta respuesta. ¿Cuál es el código para la clase "Comprado"? – Hippyjim

+0

¿qué valores debería haber pasado como signedData y firma? –

1

Seguir esto:

confirmTransaction(new String[] { latestPurchase.notificationId }); 

aquí y hacer esto:

protected static void confirmTransaction(String[] notifyIds) { 
     if (amIDead()) { 
      return; 
     } 
     // there isn't a notifyid then this was the restore transaction call and this should be skipped 
     if (notifyIds[0] != null){ 
     Log.i(TAG, "confirmTransaction()"); 
     Bundle request = makeRequestBundle("CONFIRM_NOTIFICATIONS"); 
      ...... 
      ...... 
} 

funciona como un encanto me forman .. Gracias chicos ...

1

Usted puede usar el siguiente código para obtener el historial de compras:

public static ArrayList<VerifiedPurchase> verifyPurchase(String signedData, 
      String signature) { 
     if (signedData == null) { 
      //Log.e(TAG, "data is null"); 
      return null; 
     } 
     if (Constans.DEBUG) { 
      //Log.i(TAG, "signedData: " + signedData); 
     } 
     boolean verified = false; 
     if (!TextUtils.isEmpty(signature)) { 
      /** 
      * Compute your public key (that you got from the Android Market 
      * publisher site). 
      * 
      * Instead of just storing the entire literal string here embedded 
      * in the program, construct the key at runtime from pieces or use 
      * bit manipulation (for example, XOR with some other string) to 
      * hide the actual key. The key itself is not secret information, 
      * but we don't want to make it easy for an adversary to replace the 
      * public key with one of their own and then fake messages from the 
      * server. 
      * 
      * Generally, encryption keys/passwords should only be kept in 
      * memory long enough to perform the operation they need to perform. 
      */ 
      String base64EncodedPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuKgldGQPL/xV9WKLmY62UVgEm7gsPI/T/nQxRKpYN17m8Sq3gO9nWD17wXew4oNaHmMAmArS7s7eFi3Z+XiyWil1iZvEOdBOdZD502BzujPoBa4Fu9eITPBO9tzBEdvNLXf8amnsRj53TA4bcxB2O6OcXrQIv3t3n5Dg5Nn+rJpoKSNUv7NEzJagG/2NhyjIysAObbvQ5SBQ5NgRtZlvhsTeQJPMLhRAoRcTK/+47VkhrxM3PppeGjoNRryn6d+RhMjs/nydvoQtP2V76UcUu4m+daDnK3PxOnwLt50hNtQhNf3VgixVrSKfHUWp240uEz9MHstjj8BWPH9BFF/TewIDAQAB"; 
      PublicKey key = Security.generatePublicKey(base64EncodedPublicKey); 
      verified = Security.verify(key, signedData, signature); 
      if (!verified) { 
       //Log.w(TAG, "signature does not match data."); 
       return null; 
      } 
     } 

     JSONObject jObject; 
     JSONArray jTransactionsArray = null; 
     int numTransactions = 0; 
     long nonce = 0L; 
     try { 
      jObject = new JSONObject(signedData); 

      // The nonce might be null if the user backed out of the buy page. 
      nonce = jObject.optLong("nonce"); 
      jTransactionsArray = jObject.optJSONArray("orders"); 
      if (jTransactionsArray != null) { 
       numTransactions = jTransactionsArray.length(); 
      } 
     } catch (JSONException e) { 
      return null; 
     } 

     if (!Security.isNonceKnown(nonce)) { 
      //Log.w(TAG, "Nonce not found: " + nonce); 
      return null; 
     } 

     ArrayList<VerifiedPurchase> purchases = new ArrayList<VerifiedPurchase>(); 
     try { 
      for (int i = 0; i < numTransactions; i++) { 
       JSONObject jElement = jTransactionsArray.getJSONObject(i); 
       int response = jElement.getInt("purchaseState"); 
       PurchaseState purchaseState = PurchaseState.valueOf(response); 
       String productId = jElement.getString("productId"); 
       String packageName = jElement.getString("packageName"); 
       long purchaseTime = jElement.getLong("purchaseTime"); 
       String orderId = jElement.optString("orderId", ""); 
       String notifyId = null; 
       if (jElement.has("notificationId")) { 
        notifyId = jElement.getString("notificationId"); 
       } 
       String developerPayload = jElement.optString(
         "developerPayload", null); 

       // If the purchase state is PURCHASED, then we require a 
       // verified nonce. 
       if (purchaseState == PurchaseState.PURCHASED && !verified) { 
        continue; 
       } 
       purchases.add(new VerifiedPurchase(purchaseState, notifyId, 
         productId, orderId, purchaseTime, developerPayload)); 
      } 
     } catch (JSONException e) { 
      //Log.e(TAG, "JSON exception: ", e); 
      return null; 
     } 
     removeNonce(nonce); 
     return purchases; 
    } 

Usted puede llamar a este método desde el siguiente método en la clase BillingService:

private void purchaseStateChanged(int startId, String signedData, 
      String signature) { 
     ArrayList<Security.VerifiedPurchase> purchases; 
     purchases = Security.verifyPurchase(signedData, signature); 
     if (purchases == null) { 
      return; 
     } 

     ArrayList<String> notifyList = new ArrayList<String>(); 
     for (VerifiedPurchase vp : purchases) { 
      if (vp.notificationId != null) { 
       notifyList.add(vp.notificationId); 
      } 
      ResponseHandler.purchaseResponse(this, vp.purchaseState, 
        vp.productId, vp.orderId, vp.purchaseTime, 
        vp.developerPayload); 
     } 
     if (!notifyList.isEmpty()) { 
      String[] notifyIds = notifyList.toArray(new String[notifyList 
        .size()]); 
      confirmNotifications(startId, notifyIds); 
     } 
    } 
+0

Pero no podemos llamar a este método directamente como BilllingService.purchaseStateChanged (arg1, arg2). De hecho, quiero diseñar la identificación del artículo ya comprado cada vez que se inicia la aplicación. Entonces, ¿cómo puedo hacer esto? – AndroidDev

+0

No necesita llamar a este método de esa manera. Hay un flujo definido de sdk de facturación en la aplicación. Este método se invocará desde el método handleCommand (Intent intent, int startId) al que se llamará cuando esté en el método BillingService onCreate() . –

Cuestiones relacionadas