Android Open Source - Divide_And_Conquer_Card_Shuffler Purchase Database






From Project

Back to project page Divide_And_Conquer_Card_Shuffler.

License

The source code is released under:

MIT License

If you think the Android project Divide_And_Conquer_Card_Shuffler listed in this page is inappropriate, such as containing malicious code/tools or violating the copyright, please email info at java2s dot com, thanks.

Java Source Code

/*
 * Copyright (C) 2010 The Android Open Source Project
 */*from   w  ww .  j  av  a  2s  .c  o  m*/
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.andrewkeeton.divide.and.conquer.card.shuffler.billing;

import com.andrewkeeton.divide.and.conquer.card.shuffler.billing.Consts.PurchaseState;

import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;

/**
 * An example database that records the state of each purchase. You should use
 * an obfuscator before storing any information to persistent storage. The
 * obfuscator should use a key that is specific to the device and/or user.
 * Otherwise an attacker could copy a database full of valid purchases and
 * distribute it to others.
 */
public class PurchaseDatabase {
  private static final String TAG = "PurchaseDatabase";
  private static final String DATABASE_NAME = "purchase.db";
  private static final int DATABASE_VERSION = 1;
  private static final String PURCHASE_HISTORY_TABLE_NAME = "history";
  private static final String PURCHASED_ITEMS_TABLE_NAME = "purchased";

  // These are the column names for the purchase history table. We need a
  // column named "_id" if we want to use a CursorAdapter. The primary key is
  // the orderId so that we can be robust against getting multiple messages
  // from the server for the same purchase.
  static final String HISTORY_ORDER_ID_COL = "_id";
  static final String HISTORY_STATE_COL = "state";
  static final String HISTORY_PRODUCT_ID_COL = "productId";
  static final String HISTORY_PURCHASE_TIME_COL = "purchaseTime";
  static final String HISTORY_DEVELOPER_PAYLOAD_COL = "developerPayload";

  private static final String[] HISTORY_COLUMNS = { HISTORY_ORDER_ID_COL,
      HISTORY_PRODUCT_ID_COL, HISTORY_STATE_COL,
      HISTORY_PURCHASE_TIME_COL, HISTORY_DEVELOPER_PAYLOAD_COL };

  // These are the column names for the "purchased items" table.
  static final String PURCHASED_PRODUCT_ID_COL = "_id";
  static final String PURCHASED_QUANTITY_COL = "quantity";

  private static final String[] PURCHASED_COLUMNS = {
      PURCHASED_PRODUCT_ID_COL, PURCHASED_QUANTITY_COL };

  private SQLiteDatabase mDb;
  private DatabaseHelper mDatabaseHelper;

  public PurchaseDatabase(Context context) {
    mDatabaseHelper = new DatabaseHelper(context);
    mDb = mDatabaseHelper.getWritableDatabase();
  }

  public void close() {
    mDatabaseHelper.close();
  }

  /**
   * Inserts a purchased product into the database. There may be multiple rows
   * in the table for the same product if it was purchased multiple times or
   * if it was refunded.
   * 
   * @param orderId
   *            the order ID (matches the value in the product list)
   * @param productId
   *            the product ID (sku)
   * @param state
   *            the state of the purchase
   * @param purchaseTime
   *            the purchase time (in milliseconds since the epoch)
   * @param developerPayload
   *            the developer provided "payload" associated with the order.
   */
  private void insertOrder(String orderId, String productId,
      PurchaseState state, long purchaseTime, String developerPayload) {
    ContentValues values = new ContentValues();
    values.put(HISTORY_ORDER_ID_COL, orderId);
    values.put(HISTORY_PRODUCT_ID_COL, productId);
    values.put(HISTORY_STATE_COL, state.ordinal());
    values.put(HISTORY_PURCHASE_TIME_COL, purchaseTime);
    values.put(HISTORY_DEVELOPER_PAYLOAD_COL, developerPayload);
    mDb.replace(PURCHASE_HISTORY_TABLE_NAME, null /* nullColumnHack */,
        values);
  }

  /**
   * Updates the quantity of the given product to the given value. If the
   * given value is zero, then the product is removed from the table.
   * 
   * @param productId
   *            the product to update
   * @param quantity
   *            the number of times the product has been purchased
   */
  private void updatePurchasedItem(String productId, int quantity) {
    if (quantity == 0) {
      mDb.delete(PURCHASED_ITEMS_TABLE_NAME, PURCHASED_PRODUCT_ID_COL
          + "=?", new String[] { productId });
      return;
    }
    ContentValues values = new ContentValues();
    values.put(PURCHASED_PRODUCT_ID_COL, productId);
    values.put(PURCHASED_QUANTITY_COL, quantity);
    mDb.replace(PURCHASED_ITEMS_TABLE_NAME, null /* nullColumnHack */,
        values);
  }

  /**
   * Adds the given purchase information to the database and returns the total
   * number of times that the given product has been purchased.
   * 
   * @param orderId
   *            a string identifying the order
   * @param productId
   *            the product ID (sku)
   * @param purchaseState
   *            the purchase state of the product
   * @param purchaseTime
   *            the time the product was purchased, in milliseconds since the
   *            epoch (Jan 1, 1970)
   * @param developerPayload
   *            the developer provided "payload" associated with the order
   * @return the number of times the given product has been purchased.
   */
  public synchronized int updatePurchase(String orderId, String productId,
      PurchaseState purchaseState, long purchaseTime,
      String developerPayload) {
    insertOrder(orderId, productId, purchaseState, purchaseTime,
        developerPayload);
    Cursor cursor = mDb.query(PURCHASE_HISTORY_TABLE_NAME, HISTORY_COLUMNS,
        HISTORY_PRODUCT_ID_COL + "=?", new String[] { productId },
        null, null, null, null);
    if (cursor == null) {
      return 0;
    }
    int quantity = 0;
    try {
      // Count the number of times the product was purchased
      while (cursor.moveToNext()) {
        int stateIndex = cursor.getInt(2);
        PurchaseState state = PurchaseState.valueOf(stateIndex);
        // Note that a refunded purchase is treated as a purchase. Such
        // a friendly refund policy is nice for the user.
        if (state == PurchaseState.PURCHASED
            || state == PurchaseState.REFUNDED) {
          quantity += 1;
        }
      }

      // Update the "purchased items" table
      updatePurchasedItem(productId, quantity);
    } finally {
      if (cursor != null) {
        cursor.close();
      }
    }
    return quantity;
  }

  /**
   * Returns a cursor that can be used to read all the rows and columns of the
   * "purchased items" table.
   */
  public Cursor queryAllPurchasedItems() {
    return mDb.query(PURCHASED_ITEMS_TABLE_NAME, PURCHASED_COLUMNS, null,
        null, null, null, null);
  }

  /**
   * This is a standard helper class for constructing the database.
   */
  private class DatabaseHelper extends SQLiteOpenHelper {
    public DatabaseHelper(Context context) {
      super(context, DATABASE_NAME, null, DATABASE_VERSION);
    }

    @Override
    public void onCreate(SQLiteDatabase db) {
      createPurchaseTable(db);
    }

    @Override
    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
      // Production-quality upgrade code should modify the tables when
      // the database version changes instead of dropping the tables and
      // re-creating them.
      if (newVersion != DATABASE_VERSION) {
        Log.w(TAG, "Database upgrade from old: " + oldVersion + " to: "
            + newVersion);
        db.execSQL("DROP TABLE IF EXISTS "
            + PURCHASE_HISTORY_TABLE_NAME);
        db.execSQL("DROP TABLE IF EXISTS " + PURCHASED_ITEMS_TABLE_NAME);
        createPurchaseTable(db);
        return;
      }
    }

    private void createPurchaseTable(SQLiteDatabase db) {
      db.execSQL("CREATE TABLE " + PURCHASE_HISTORY_TABLE_NAME + "("
          + HISTORY_ORDER_ID_COL + " TEXT PRIMARY KEY, "
          + HISTORY_STATE_COL + " INTEGER, " + HISTORY_PRODUCT_ID_COL
          + " TEXT, " + HISTORY_DEVELOPER_PAYLOAD_COL + " TEXT, "
          + HISTORY_PURCHASE_TIME_COL + " INTEGER)");
      db.execSQL("CREATE TABLE " + PURCHASED_ITEMS_TABLE_NAME + "("
          + PURCHASED_PRODUCT_ID_COL + " TEXT PRIMARY KEY, "
          + PURCHASED_QUANTITY_COL + " INTEGER)");
    }
  }
}




Java Source Code List

com.andrewkeeton.divide.and.conquer.card.shuffler.AutoResizeTextView.java
com.andrewkeeton.divide.and.conquer.card.shuffler.Card.java
com.andrewkeeton.divide.and.conquer.card.shuffler.EstimateTime.java
com.andrewkeeton.divide.and.conquer.card.shuffler.MainActivity.java
com.andrewkeeton.divide.and.conquer.card.shuffler.Move.java
com.andrewkeeton.divide.and.conquer.card.shuffler.PileOfCards.java
com.andrewkeeton.divide.and.conquer.card.shuffler.SettingsActivity.java
com.andrewkeeton.divide.and.conquer.card.shuffler.SetupFragment.java
com.andrewkeeton.divide.and.conquer.card.shuffler.ShufflerFragment.java
com.andrewkeeton.divide.and.conquer.card.shuffler.billing.BillingReceiver.java
com.andrewkeeton.divide.and.conquer.card.shuffler.billing.BillingService.java
com.andrewkeeton.divide.and.conquer.card.shuffler.billing.Consts.java
com.andrewkeeton.divide.and.conquer.card.shuffler.billing.PurchaseDatabase.java
com.andrewkeeton.divide.and.conquer.card.shuffler.billing.PurchaseObserver.java
com.andrewkeeton.divide.and.conquer.card.shuffler.billing.ResponseHandler.java
com.andrewkeeton.divide.and.conquer.card.shuffler.billing.Security.java
com.andrewkeeton.divide.and.conquer.card.shuffler.billing.util.Base64DecoderException.java
com.andrewkeeton.divide.and.conquer.card.shuffler.billing.util.Base64.java