Created
December 5, 2016 11:22
-
-
Save webserveis/1a0ac26f22e5f30fed99c0e3718ba038 to your computer and use it in GitHub Desktop.
Basic system bill inapp
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.content.Intent; | |
import android.content.IntentFilter; | |
import android.graphics.Color; | |
import android.os.Bundle; | |
import android.support.annotation.NonNull; | |
import android.support.design.widget.FloatingActionButton; | |
import android.support.design.widget.Snackbar; | |
import android.support.v7.app.AlertDialog; | |
import android.support.v7.app.AppCompatActivity; | |
import android.support.v7.widget.Toolbar; | |
import android.util.Base64; | |
import android.util.Log; | |
import android.view.Menu; | |
import android.view.MenuItem; | |
import android.view.View; | |
import android.widget.Button; | |
import android.widget.TextView; | |
import com.google.android.gms.common.ConnectionResult; | |
import com.google.android.gms.common.api.GoogleApiClient; | |
import com.google.android.gms.common.api.ResultCallback; | |
import com.google.android.gms.wearable.Node; | |
import com.google.android.gms.wearable.NodeApi; | |
import com.google.android.gms.wearable.Wearable; | |
import com.webserveis.app.splitpaywear.util.IabBroadcastReceiver; | |
import com.webserveis.app.splitpaywear.util.IabHelper; | |
import com.webserveis.app.splitpaywear.util.IabResult; | |
import com.webserveis.app.splitpaywear.util.Inventory; | |
import com.webserveis.app.splitpaywear.util.Purchase; | |
import com.webserveis.app.splitpaywear.util.ThemeUtils; | |
/* | |
https://gist.github.com/gabrielemariotti/117b05aad4db251f7534 | |
http://stackoverflow.com/questions/30050299/how-to-launch-android-wear-activity-from-mobile | |
Bill inapp | |
Facturación integrada | |
https://developer.android.com/google/play/billing/index.html | |
https://www.dexa-dev.com/android-in-app-billing-empezamos-con-el-codigo-iv/ | |
https://inducesmile.com/android/android-in-app-billing-v3-purchase-using-serviceconnection-example-tutorial/ | |
http://www.techotopia.com/index.php/An_Android_Studio_Google_Play_In-app_Billing_Tutorial#Installing_the_Google_Play_Billing_Library | |
http://stackoverflow.com/questions/8735931/android-in-app-billing-tutorial => for multiple activities | |
Seguridad y diseño | |
https://developer.android.com/google/play/billing/billing_best_practices.html#key | |
Random string payload | |
http://stackoverflow.com/questions/18613520/what-should-be-the-developer-payload-in-android-in-app-billing-v3-api | |
*/ | |
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, | |
IabBroadcastReceiver.IabBroadcastListener { | |
private GoogleApiClient mGoogleApiClient; | |
private String TAG = MainActivity.class.getSimpleName(); | |
private IabHelper mHelper; | |
private IabBroadcastReceiver mBroadcastReceiver; | |
private IabHelper.QueryInventoryFinishedListener mGotInventoryListener; | |
// Does the user have the premium upgrade? | |
boolean mIsPremium = false; | |
static final String SKU_PREMIUM = "premium"; | |
//static final String SKU_PREMIUM = "android.test.purchased"; | |
//static final String SKU_PREMIUM = "android.test.canceled"; | |
//static final String SKU_PREMIUM = "android.test.refunded"; | |
//static final String SKU_PREMIUM = "android.test.item_unavailable"; | |
// (arbitrary) request code for the purchase flow | |
static final int RC_REQUEST = 10001; | |
private IabHelper.OnIabPurchaseFinishedListener mPurchaseFinishedListener; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
/* | |
Intent serviceIntent = | |
new Intent("com.android.vending.billing.InAppBillingService.BIND"); | |
serviceIntent.setPackage("com.android.vending"); | |
bindService(serviceIntent, mServiceConn, Context.BIND_AUTO_CREATE); | |
*/ | |
/** | |
* IN APP BILLING IMPLEMENTATION | |
*/ | |
//String base64EncodedPublicKey = "YOU_APP_PUBLIC_KEY"; | |
mHelper = new IabHelper(this, base64EncodedPublicKey); | |
// enable debug logging (for a production application, you should set this to false). | |
mHelper.enableDebugLogging(true); | |
Log.d(TAG, "Starting setup."); | |
mHelper.startSetup(new IabHelper.OnIabSetupFinishedListener() { | |
@Override | |
public void onIabSetupFinished(IabResult result) { | |
Log.d(TAG, "Setup finished."); | |
if (!result.isSuccess()) { | |
Log.e(TAG, "In-app Billing setup failed: " + result); | |
} else { | |
Log.d(TAG, "In-app Billing is set up OK"); | |
} | |
if (mHelper == null) return; | |
mBroadcastReceiver = new IabBroadcastReceiver((IabBroadcastReceiver.IabBroadcastListener) MainActivity.this); | |
IntentFilter broadcastFilter = new IntentFilter(IabBroadcastReceiver.ACTION); | |
registerReceiver(mBroadcastReceiver, broadcastFilter); | |
// IAB is fully set up. Now, let's get an inventory of stuff we own. | |
Log.d(TAG, "Setup successful. Querying inventory."); | |
try { | |
mHelper.queryInventoryAsync(mGotInventoryListener); | |
} catch (IabHelper.IabAsyncInProgressException e) { | |
complain("Error querying inventory. Another async operation in progress."); | |
} | |
} | |
}); | |
mGotInventoryListener = new IabHelper.QueryInventoryFinishedListener() { | |
public void onQueryInventoryFinished(IabResult result, Inventory inventory) { | |
Log.d(TAG, "Query inventory finished."); | |
// Have we been disposed of in the meantime? If so, quit. | |
if (mHelper == null) return; | |
// Is it a failure? | |
if (result.isFailure()) { | |
complain("Failed to query inventory: " + result); | |
return; | |
} | |
Log.d(TAG, "QUERY inventory was successful."); | |
// Do we have the premium upgrade? | |
Purchase premiumPurchase = inventory.getPurchase(SKU_PREMIUM); | |
mIsPremium = (premiumPurchase != null && verifyDeveloperPayload(premiumPurchase)); | |
Log.d("PREMIUM =","User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM")); | |
alert("User is " + (mIsPremium ? "PREMIUM" : "NOT PREMIUM")); | |
Log.d(TAG, "Initial inventory query finished; enabling main UI."); | |
} | |
}; | |
// Callback for when a purchase is finished cuando se ha establecido el pago | |
mPurchaseFinishedListener = new IabHelper.OnIabPurchaseFinishedListener() { | |
public void onIabPurchaseFinished(IabResult result, Purchase purchase) { | |
Log.d(TAG, "Purchase finished: " + result + ", purchase: " + purchase); | |
// if we were disposed of in the meantime, quit. | |
if (mHelper == null) return; | |
if (result.isFailure()) { | |
if (result.getResponse() == 7) { | |
complain("Ya tiene el producto "); | |
} else { | |
complain("Error purchasing: " + result); | |
} | |
return; | |
} | |
if (!verifyDeveloperPayload(purchase)) { | |
complain("Error purchasing. Authenticity verification failed."); | |
return; | |
} | |
Log.w(TAG, "Purchase successful."); | |
if (purchase.getSku().equals(SKU_PREMIUM)) { | |
// bought the premium upgrade! | |
Log.w(TAG, "Purchase is premium upgrade. Congratulating user."); | |
alert("Thank you for upgrading to premium!"); | |
mIsPremium = true; | |
} | |
} | |
}; | |
Button myButton1 = (Button) findViewById(R.id.btn_getpremium); | |
if (myButton1 != null) { | |
myButton1.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View v) { | |
String payload = "mypurchasetoken"; | |
try { | |
mHelper.launchPurchaseFlow(MainActivity.this, SKU_PREMIUM, RC_REQUEST, | |
mPurchaseFinishedListener, payload); | |
} catch (IabHelper.IabAsyncInProgressException e) { | |
e.printStackTrace(); | |
} | |
} | |
}); | |
} | |
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); | |
setSupportActionBar(toolbar); | |
//toolbar.setPopupTheme(R.style.AppThemeGreen_PopupOverlay); | |
final TextView myTextView = (TextView) findViewById(R.id.textView); | |
mGoogleApiClient = new GoogleApiClient.Builder(this) | |
.addApi(Wearable.API) | |
.addConnectionCallbacks(this) | |
.addOnConnectionFailedListener(this) | |
.build(); | |
mGoogleApiClient.connect(); | |
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab); | |
fab.setOnClickListener(new View.OnClickListener() { | |
@Override | |
public void onClick(View view) { | |
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG) | |
.setAction("Action", null).show(); | |
int intColor = ThemeUtils.getColor(MainActivity.this, R.color.colorAccent); | |
Log.d(TAG, "colors.xml colorAccent: " + intColor); | |
String hexColor = ThemeUtils.colorIntToHex(intColor); | |
Log.d(TAG, "colors.xml colorAccent: " + hexColor); | |
myTextView.setTextColor(intColor); | |
intColor = ThemeUtils.getThemeAttribute(MainActivity.this, R.attr.colorAccent); | |
intColor = ThemeUtils.getThemeAttribute(MainActivity.this, android.R.attr.textColorSecondary); | |
hexColor = ThemeUtils.colorIntToHex(intColor); | |
Log.d(TAG, "textColorPrimary Int: " + intColor); | |
Log.d(TAG, "textColorPrimary: " + hexColor); | |
myTextView.setTextColor(Color.parseColor(hexColor)); | |
} | |
}); | |
} | |
@Override | |
public boolean onCreateOptionsMenu(Menu menu) { | |
// getMenuInflater().inflate(R.menu.menu_main, menu); | |
return true; | |
} | |
@Override | |
public boolean onOptionsItemSelected(MenuItem item) { | |
int id = item.getItemId(); | |
if (id == R.id.action_settings) { | |
return true; | |
} | |
return super.onOptionsItemSelected(item); | |
} | |
@Override | |
public void onConnected(Bundle bundle) { | |
Log.d("GoogleApi", "onConnected: " + bundle); | |
Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).setResultCallback(new ResultCallback<NodeApi.GetConnectedNodesResult>() { | |
@Override | |
public void onResult(NodeApi.GetConnectedNodesResult getConnectedNodesResult) { | |
for (Node node : getConnectedNodesResult.getNodes()) { | |
Log.d(TAG, "onResult: " + node.getDisplayName()); | |
//sendMessage(node.getId()); | |
} | |
} | |
}); | |
} | |
@Override | |
public void onConnectionSuspended(int i) { | |
Log.d("GoogleApi", "onConnectionSuspended: " + i); | |
} | |
@Override | |
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { | |
Log.d("GoogleApi", "onConnectionFailed: " + connectionResult); | |
} | |
@Override | |
protected void onActivityResult(int requestCode, int resultCode, Intent data) { | |
Log.d(TAG, "onActivityResult(" + requestCode + "," + resultCode + "," + data); | |
if (mHelper == null) return; | |
// Pass on the activity result to the helper for handling | |
if (!mHelper.handleActivityResult(requestCode, resultCode, data)) { | |
super.onActivityResult(requestCode, resultCode, data); | |
} else { | |
Log.d(TAG, "onActivityResult handled by IABUtil."); | |
} | |
} | |
@Override | |
public void onDestroy() { | |
super.onDestroy(); | |
// very important: | |
if (mBroadcastReceiver != null) { | |
unregisterReceiver(mBroadcastReceiver); | |
} | |
if (mHelper != null) { | |
mHelper.disposeWhenFinished(); | |
mHelper = null; | |
} | |
} | |
public static String xorEncrypt(String input, String key) { | |
byte[] inputBytes = input.getBytes(); | |
int inputSize = inputBytes.length; | |
byte[] keyBytes = key.getBytes(); | |
int keySize = keyBytes.length - 1; | |
byte[] outBytes = new byte[inputSize]; | |
for (int i = 0; i < inputSize; i++) { | |
outBytes[i] = (byte) (inputBytes[i] ^ keyBytes[i % keySize]); | |
} | |
return new String(Base64.encode(outBytes, Base64.DEFAULT)); | |
} | |
public static String xorDecrypt(String input, String key) { | |
byte[] inputBytes = Base64.decode(input, Base64.DEFAULT); | |
int inputSize = inputBytes.length; | |
byte[] keyBytes = key.getBytes(); | |
int keySize = keyBytes.length - 1; | |
byte[] outBytes = new byte[inputSize]; | |
for (int i = 0; i < inputSize; i++) { | |
outBytes[i] = (byte) (inputBytes[i] ^ keyBytes[i % keySize]); | |
} | |
return new String(outBytes); | |
} | |
void complain(String message) { | |
Log.e(TAG, "**** TrivialDrive Error: " + message); | |
alert("Error: " + message); | |
} | |
void alert(String message) { | |
AlertDialog.Builder bld = new AlertDialog.Builder(this); | |
bld.setMessage(message); | |
bld.setNeutralButton("OK", null); | |
Log.d(TAG, "Showing alert dialog: " + message); | |
bld.create().show(); | |
} | |
@Override | |
public void receivedBroadcast() { | |
// Received a broadcast notification that the inventory of items has changed | |
Log.d(TAG, "Received broadcast notification. Querying inventory."); | |
try { | |
mHelper.queryInventoryAsync(mGotInventoryListener); | |
} catch (IabHelper.IabAsyncInProgressException e) { | |
complain("Error querying inventory. Another async operation in progress."); | |
} | |
} | |
public boolean verifyDeveloperPayload(Purchase p) { | |
String payload = p.getDeveloperPayload(); | |
return true; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment