Die Version der Bibliothek wurde von 1.0 auf 2.0 erhöht, daher habe ich den Inhalt neu geschrieben. Unten finden Sie den Code für den Testversuch.
Ich zeige Ihnen ein Beispiel für Code, der irgendwie funktioniert, aber auf eigenes Risiko. Da es sich um eine Geschichte handelt, bei der es um Geld geht, wird dringend empfohlen, die Informationen der Oberfamilie zu überprüfen. https://developer.android.com/google/play/billing/billing_library_overview?hl=ja
Bei der Suche nach Beispielen für die In-App-Kaufverarbeitung unter Android waren viele alt und komplex. Mit der neuen Google Play-Abrechnungsbibliothek war dies relativ einfach zu erreichen, daher werde ich mich daran erinnern.
Für dieses Verfahren sind keine Einstellungen wie "IInAppBillingService.aidl" oder "AndroidManifest.xml" erforderlich. Sie können auch testen, bevor Sie die App auf Google Play hochladen.
Hier habe ich eine einfache "Aktivität aktivieren" als Aktivität ausgewählt und den gesamten Code in die Hauptaktivität geschrieben. Der Projektname war "Billing Sample".
build.gradle
dependencies {
....
implementation 'com.android.billingclient:billing:2.0.1'
}
MainActivity.java
package xx.xx.xx.xx.billingsample;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.TextView;
import com.android.billingclient.api.AcknowledgePurchaseParams;
import com.android.billingclient.api.AcknowledgePurchaseResponseListener;
import com.android.billingclient.api.BillingClient;
import com.android.billingclient.api.BillingClientStateListener;
import com.android.billingclient.api.BillingFlowParams;
import com.android.billingclient.api.BillingResult;
import com.android.billingclient.api.Purchase;
import com.android.billingclient.api.PurchaseHistoryRecord;
import com.android.billingclient.api.PurchaseHistoryResponseListener;
import com.android.billingclient.api.PurchasesUpdatedListener;
import com.android.billingclient.api.SkuDetails;
import com.android.billingclient.api.SkuDetailsParams;
import com.android.billingclient.api.SkuDetailsResponseListener;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity
implements View.OnClickListener, PurchasesUpdatedListener, AcknowledgePurchaseResponseListener {
TextView textView1;
private BillingClient billingClient;
List<SkuDetails> mySkuDetailsList;
//Wird aufgerufen, wenn die App gestartet wird
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Bereiten Sie die Bedientasten und das Ergebnisausgabefeld vor
textView1 = findViewById(R.id.text_view1);
findViewById(R.id.button_get_skus).setOnClickListener(this);
findViewById(R.id.button_query_owned).setOnClickListener(this);
findViewById(R.id.button_purchase).setOnClickListener(this);
findViewById(R.id.button_purchase_history).setOnClickListener(this);
//Bereiten Sie den Abrechnungsclient vor
billingClient = BillingClient.newBuilder(this)
.setListener(this).enablePendingPurchases().build();
billingClient.startConnection(new BillingClientStateListener() {
@Override
public void onBillingSetupFinished(BillingResult billingResult) {
int responseCode = billingResult.getResponseCode();
if (responseCode == BillingClient.BillingResponseCode.OK) {
// The BillingClient is ready. You can query purchases here.
textView1.setText("Billing Setup OK");
} else {
showResponseCode(responseCode);
}
}
@Override
public void onBillingServiceDisconnected() {
// Try to restart the connection on the next request to
// Google Play by calling the startConnection() method.
textView1.setText("Billing Servise Disconnected. Retry");
}
});
}
//Wird aufgerufen, wenn auf die Schaltfläche geklickt wird
@Override
public void onClick(View v) {
if (v != null) {
switch (v.getId()) {
case R.id.button_get_skus:
querySkuList();
break;
case R.id.button_query_owned:
queryOwned();
break;
case R.id.button_purchase:
startPurchase("android.test.purchased");
break;
case R.id.button_purchase_history:
queryPurchaseHistory();
break;
default:
break;
}
}
}
//Wird aufgerufen, wenn die App geschlossen wird
@Override
protected void onDestroy() {
billingClient.endConnection();
super.onDestroy();
}
//Erkundigen Sie sich nach dem Artikel, den Sie kaufen möchten
void querySkuList() {
List skuList = new ArrayList<>();
skuList.add("android.test.purchased"); // prepared by Google
skuList.add("android.test.canceled");
skuList.add("android.test.refunded");
skuList.add("android.test.item_unavailable");
SkuDetailsParams.Builder params = SkuDetailsParams.newBuilder();
params.setSkusList(skuList).setType(BillingClient.SkuType.INAPP);
billingClient.querySkuDetailsAsync(params.build(),
new SkuDetailsResponseListener() {
@Override
public void onSkuDetailsResponse(BillingResult billingResult,
List<SkuDetails> skuDetailsList) {
// Process the result.
StringBuffer resultStr = new StringBuffer("");
int responseCode = billingResult.getResponseCode();
if (responseCode == BillingClient.BillingResponseCode.OK) {
//Bewahren Sie die Sku-Details für einen späteren Kaufvorgang auf
mySkuDetailsList = skuDetailsList;
//Liste anzeigen
if (skuDetailsList != null) {
for (Object item : skuDetailsList) {
SkuDetails skuDetails = (SkuDetails) item;
String sku = skuDetails.getSku();
String price = skuDetails.getPrice();
resultStr.append("Sku=" + sku + " Price=" + price + "\n");
}
} else {
resultStr.append("No Sku");
}
textView1.setText(resultStr);
} else {
showResponseCode(responseCode);
}
}
});
}
//Starten Sie den Kaufvorgang
void startPurchase(String sku) {
SkuDetails skuDetails = getSkuDetails(sku);
if (skuDetails != null) {
BillingFlowParams params = BillingFlowParams.newBuilder()
.setSkuDetails(skuDetails)
.build();
BillingResult billingResult = billingClient.launchBillingFlow(this, params);
showResponseCode(billingResult.getResponseCode());
}
}
//Details zur angegebenen SKU finden Sie in der Liste
SkuDetails getSkuDetails(String sku) {
SkuDetails skuDetails = null;
if(mySkuDetailsList==null){
textView1.setText("Exec [Get Skus] first");
}else {
for (SkuDetails sd : mySkuDetailsList) {
if (sd.getSku().equals(sku)) skuDetails = sd;
}
if (skuDetails == null) {
textView1.setText(sku + " is not found");
}
}
return skuDetails;
}
//Wird beim Aktualisieren der Kaufergebnisse aufgerufen
@Override
public void onPurchasesUpdated(BillingResult billingResult, List<Purchase> purchases) {
StringBuffer resultStr = new StringBuffer("");
int billingResultCode = billingResult.getResponseCode();
if (billingResultCode == BillingClient.BillingResponseCode.OK
&& purchases != null) {
for (Purchase purchase : purchases) {
//Genehmigen Sie den Kauf
String state = handlePurchase(purchase);
//Zeigen Sie die gekaufte Sku-Zeichenfolge und das Genehmigungsergebnis an
String sku = purchase.getSku();
resultStr.append(sku).append("\n");
resultStr.append(" State=").append(state).append("\n");
}
textView1.setText(resultStr);
} else {
// Handle error codes.
showResponseCode(billingResultCode);
}
}
//Genehmigen Sie den Kauf
String handlePurchase(Purchase purchase) {
String stateStr = "error";
int purchaseState = purchase.getPurchaseState();
if (purchaseState == Purchase.PurchaseState.PURCHASED) {
// Grant entitlement to the user.
stateStr = "purchased";
// Acknowledge the purchase if it hasn't already been acknowledged.
if (!purchase.isAcknowledged()) {
AcknowledgePurchaseParams acknowledgePurchaseParams =
AcknowledgePurchaseParams.newBuilder()
.setPurchaseToken(purchase.getPurchaseToken())
.build();
billingClient.acknowledgePurchase(acknowledgePurchaseParams, this);
}
}else if(purchaseState == Purchase.PurchaseState.PENDING){
stateStr = "pending";
}else if(purchaseState == Purchase.PurchaseState.UNSPECIFIED_STATE){
stateStr = "unspecified state";
}
return stateStr;
}
//Ergebnisse der Kaufgenehmigung zurückgegeben
@Override
public void onAcknowledgePurchaseResponse(BillingResult billingResult) {
int responseCode = billingResult.getResponseCode();
if(responseCode != BillingClient.BillingResponseCode.OK) {
showResponseCode(responseCode);
}
}
//Erkundigen Sie sich nach gekauften Artikeln (Bargeldverarbeitung)
void queryOwned(){
StringBuffer resultStr = new StringBuffer("");
Purchase.PurchasesResult purchasesResult
= billingClient.queryPurchases(BillingClient.SkuType.INAPP);
int responseCode = purchasesResult.getResponseCode ();
if(responseCode== BillingClient.BillingResponseCode.OK){
resultStr.append("Query Success\n");
List<Purchase> purchases = purchasesResult.getPurchasesList();
if(purchases.isEmpty()){
resultStr.append("Owned Nothing");
} else {
for (Purchase purchase : purchases) {
resultStr.append(purchase.getSku()).append("\n");
}
}
textView1.setText(resultStr);
}else{
showResponseCode(responseCode);
}
}
//Kaufhistorie abfragen (Netzwerkzugriffsverarbeitung)
void queryPurchaseHistory() {
billingClient.queryPurchaseHistoryAsync(BillingClient.SkuType.INAPP,
new PurchaseHistoryResponseListener() {
@Override
public void onPurchaseHistoryResponse(BillingResult billingResult,
List<PurchaseHistoryRecord> purchasesList) {
int responseCode = billingResult.getResponseCode();
if (responseCode == BillingClient.BillingResponseCode.OK) {
if (purchasesList == null || purchasesList.size() == 0) {
textView1.setText("No History");
} else {
for (PurchaseHistoryRecord purchase : purchasesList) {
// Process the result.
textView1.setText("Purchase History="
+ purchase.toString() + "\n");
}
}
} else {
showResponseCode(responseCode);
}
}
});
}
//Serverantwort anzeigen
void showResponseCode(int responseCode){
switch(responseCode){
case BillingClient.BillingResponseCode.OK:
textView1.setText("OK");break;
case BillingClient.BillingResponseCode.USER_CANCELED:
textView1.setText("USER_CANCELED");break;
case BillingClient.BillingResponseCode.SERVICE_UNAVAILABLE:
textView1.setText("SERVICE_UNAVAILABLE");break;
case BillingClient.BillingResponseCode.BILLING_UNAVAILABLE:
textView1.setText("BILLING_UNAVAILABLE");break;
case BillingClient.BillingResponseCode.ITEM_UNAVAILABLE:
textView1.setText("ITEM_UNAVAILABLE");break;
case BillingClient.BillingResponseCode.DEVELOPER_ERROR:
textView1.setText("DEVELOPER_ERROR");break;
case BillingClient.BillingResponseCode.ERROR:
textView1.setText("ERROR");break;
case BillingClient.BillingResponseCode.ITEM_ALREADY_OWNED:
textView1.setText("ITEM_ALREADY_OWNED");break;
case BillingClient.BillingResponseCode.ITEM_NOT_OWNED:
textView1.setText("ITEM_NOT_OWNED");break;
case BillingClient.BillingResponseCode.SERVICE_DISCONNECTED:
textView1.setText("SERVICE_DISCONNECTED");break;
case BillingClient.BillingResponseCode.FEATURE_NOT_SUPPORTED:
textView1.setText("FEATURE_NOT_SUPPORTED");break;
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<Button
android:id="@+id/button_get_skus"
android:text="Get Skus"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/button_query_owned"
android:text="Query Owned"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/button_purchase"
android:text="Purchase"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/button_purchase_history"
android:text="Purchase History"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
<TextView
android:id="@+id/text_view1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
</android.support.constraint.ConstraintLayout>
Öffnen Sie Build Valiants auf der Registerkarte ganz links in Android Studio und ändern Sie Build Valiant von Debug in Release.
Error: The apk for your currently selected variant (app-release-unsigned.apk) is not signed.
Klicken Sie auf "Fix" auf der rechten Seite der Fehleranzeige und geben Sie den in Google Play registrierten Schlüssel ein. Wenn Sie sich nicht registriert haben, müssen Sie sich registrieren. Die Tasteneingabe erfolgt wie folgt.