2011-12-26 12 views
11

Dodaję zakup aplikacji w moim kodowaniu, działa dobrze podczas zakupu, ale daje błąd i aplikacja zamyka się, gdy próbuję dodać kod Restore_Transaction po usunięciu aplikacji i ponownie zainstalowany, dodałem poniżej kodowaniaInApp Kup RESTORE_TRANSACTIONS, nie jestem w stanie wykreślić kodu

w onCreate napisałem

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

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

a następnie zadzwoniłem do obsługi za pomocą

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); 
     } 
    } 

Odpowiedz

5

znalazłem odpowiedź na moje pytanie, thanx do anddev

Musisz sprawdzić na zakupy, aby nie być null

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()?"); 
     } 
    } 
} 

aw Confirm_Notification u hav aby sprawdzić

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

jakie jest zatem rozwiązanie? – Pabluez

+0

Czy to działa? Dostaję tylko błędy i siłę blisko, altho, nie mogę naprawdę zrozumieć, co zrobiłeś z tej odpowiedzi. Jaki jest kod dla klasy "Zakupione"? – Hippyjim

+0

jakie wartości powinienem podać jako podpisane dane i podpis? –

1

Wykonaj następujące czynności:

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

tutaj i to zrobić:

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"); 
      ...... 
      ...... 
} 

działa jak czar tworzą mnie .. Dzięki Chłopaki ...

1

można użyć poniższy kod, aby dostać historię zakupów:

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; 
    } 

Ty można wywołać tę metodę z poniższej metody w klasie 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

Ale nie możemy nazwać tej metody bezpośrednio jak BilllingService.purchaseStateChanged (arg1, arg2), Właściwie chcę wykreślić identyfikator już zakupionego przedmiotu za każdym razem, gdy aplikacja się uruchomi. W jaki sposób mogę to zrobić. – AndroidDev

+0

Nie musisz wywoływać tej metody w ten sposób. Istnieje zdefiniowany przepływ rozliczania w aplikacji sdk.Ta metoda zostanie wywołana z metody handleCommand (Intent intent, int startId), która zostanie wywołana, gdy w metodzie BillingService onCreate() . –

Powiązane problemy