How to use Prime31 Google In App Billing Plugin - unity3d

I just bought "Google In App Billing Plugin for unity3d" by Prime31. I don't understand how to use it in the game that I want to develop.
Can you please show me a code example? I understand I need to use my app key, but I don't know what to do next.
And how to a I make test purchases with this plugin?
Please help as much as you can, because I am really stuck on this subject for quite a while.
This is some of my "purchase maker" object called MoneyTakerScript (inherits from MonoBehaviour):
void Start()
{
string key = "My App Key...";
GoogleIAB.init(key);
var skus = new string[] { "cl.48931", "tp.58932", "mmm.68393" };
GoogleIAB.queryInventory( skus );
TPS = GameObject.Find("TPBtn").GetComponent(typeof(TPScript)) as TPScript;
CLS = GameObject.Find("CLBtn").GetComponent(typeof(CLScript)) as CLScript;
MMM = GameObject.Find("MMBtn").GetComponent(typeof(MMMScript)) as MMMScript;
}
public void Purchase(string ProductId)
{
GoogleIAB.purchaseProduct(ProductId);
}
public void UseProduct(string ProductId)
{
if (ProductId.Contains("cl"))
{
CLS.MakeCL();
}
if (ProductId.Contains("tp"))
{
TPS.MakeTP();
}
if (ProductId.Contains("mmm"))
{
MMM.MakeMMM();
}
GoogleIAB.consumeProduct(ProductId);
}
And this is some of my "purchase listner" object code:
void purchaseSucceededEvent(GooglePurchase purchase)
{
//Debug.Log( "purchaseSucceededEvent: " + purchase );
MoneyScript.UseProduct(purchase.productId);
}
void Start()
{
MoneyScript = GameObject.Find("MoneyTaker").GetComponent(typeof(MoneyTakerScript)) as
MoneyTakerScript;
}

I found the problem and solved it!
This line was missing in my AndroidManifest.Xml for some reason:
<activity android:name="com.prime31.GoogleIABProxyActivity"></activity>
Just added the line and now I have In App Purchase!!

Related

Google Play Billing v5 - Get a product's price

In v4, I used to have SkuDetails.price to get the price of the product but now it's not available anymore in the new ProductDetails in v5.
How can I get the price of a product in this new version?
When you call getSubscriptionOfferDetails, it returns the offers available to buy for the subscription product. Then you can call getPricingPhases() to get the list of the pricing phases. Each pricing phase object has a getFormattedPrice() call to get the price of an offer's pricing phrase (https://developer.android.com/reference/com/android/billingclient/api/ProductDetails.PricingPhase)
You have to check for Available Products
fun getAvailableProducts() {
Timber.d("!!! Getting available products to buy ...")
val queryProductDetailsParams =
QueryProductDetailsParams.newBuilder()
.setProductList(
listOf(
QueryProductDetailsParams.Product.newBuilder()
.setProductId(SKU_SUBSCRIBE_MONTHLY)
.setProductType(BillingClient.ProductType.SUBS)
.build(),
QueryProductDetailsParams.Product.newBuilder()
.setProductId(SKU_SUBSCRIBE_YEARLY)
.setProductType(BillingClient.ProductType.SUBS)
.build()
))
.build()
billingClient.queryProductDetailsAsync(queryProductDetailsParams) {
billingResult,
productDetailsList ->
if (billingResult.responseCode == BillingClient.BillingResponseCode.OK) {
availableProducts.tryEmit(productDetailsList)
getPrices(productDetailsList)
} else {
Timber.d("!!!Error getting available Products to buy: ${billingResult.responseCode} ${billingResult.debugMessage}")
}
}
}
And then
private fun getPrices(productDetailsList: MutableList<ProductDetails>) {
productDetailsList.forEach{
when (it.productId) {
SKU_SUBSCRIBE_MONTHLY -> {
currency.tryEmit(it.subscriptionOfferDetails?.get(0)?.pricingPhases!!.pricingPhaseList[0]?.priceCurrencyCode.toString())
monthlyPrice.tryEmit(it.subscriptionOfferDetails?.get(0)?.pricingPhases!!.pricingPhaseList[0]?.formattedPrice.toString())
Timber.d("!!!! $it.")
}
SKU_SUBSCRIBE_YEARLY -> {
// currency.tryEmit(it.subscriptionOfferDetails?.get(0)?.pricingPhases!!.pricingPhaseList[0]?.priceCurrencyCode.toString())
yearlyPrice.tryEmit(it.subscriptionOfferDetails?.get(0)?.pricingPhases!!.pricingPhaseList[0]?.formattedPrice.toString())
Timber.d("!!!! $it.")
}
}
}
}
i use the following code to get price details.
private void queryProduct() {
QueryProductDetailsParams queryProductDetailsParams
= QueryProductDetailsParams.newBuilder().setProductList(
ImmutableList.of(QueryProductDetailsParams.Product.newBuilder()
.setProductId("your_product_id")
.setProductType(BillingClient.ProductType.INAPP).build()))
.build();
billingClient.queryProductDetailsAsync(
queryProductDetailsParams,
new ProductDetailsResponseListener() {
#Override
public void onProductDetailsResponse(#NonNull BillingResult billingResult, #NonNull List<ProductDetails> list) {
if(!list.isEmpty()){
productDetails = list.get(0);
itemdesc.setText(productDetails.getName());
itemprice.setText(productDetails.getOneTimePurchaseOfferDetails().getFormattedPrice());
itemprice.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
makePurchase();
}
});
}else {
Log.i("playsresponse", "no response from google play");
}
}
}
);

When I test an app integrated with the HMS Health Kit on my Huawei Mate 30 Pro, why cannot I obtain the number of steps?

What should I do if the error code 50005 is returned when querying the step count using the corresponding method under DataController? (The scopes of Health Kit I applied for from the Huawei Developers website have been approved.)
2020-05-26 11:41:21.195 17338-17338/com.hauwei.hmsdemo I/DataManager:
read failure 50005:Unknown authorization error
2020-05-26 11:41:21.203 17338-17338/com.hauwei.hmsdemo I/DataManager:
The following lines are used for querying the step count:
public void readSteps(View view) throws ParseException {
DataCollector dataCollector = new DataCollector.Builder().setPackageName(context)
.setDataType(DataType.DT_CONTINUOUS_STEPS_DELTA)
.setDataStreamName("STEPS_DELTA")
.setDataGenerateType(DataCollector.DATA_TYPE_RAW)
.build();
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
Date startDate = dateFormat.parse(BEGIN_TIME);
Date endDate = dateFormat.parse(END_TIME);
ReadOptions readOptions = new ReadOptions.Builder().read(dataCollector)
.setTimeRange(startDate.getTime(), endDate.getTime(), TimeUnit.MILLISECONDS)
.build();
dataController.read(readOptions).addOnSuccessListener(new OnSuccessListener<ReadReply>() {
#Override
public void onSuccess(ReadReply readReply) {
……
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(Exception e) {
……
}
});
}
There is nothing wrong with the lines you used for querying the step count. The issue lies within authorization granting. It should be noted that the data that an app can access must be within the scopes granted to the app on the Huawei Developers website and within the range of data for which the user approval has been granted on the device side.
Regarding this issue, verify that the read/write permissions for the step count data have been granted when the app is displaying the data authorization screen.
You can refer to the following code, or refer to the sample code for Health Kit at
https://developer.huawei.com/consumer/en/doc/development/HMS-Examples/healthkit_Android_sample_code.
private void dataAuthorization() {
Log.i(TAG, "begin sign in");
// The data that can be used here and its read/write permissions can only be those you have applied for from the Huawei Developers website.
List < Scope > scopeList = new ArrayList < > ();
scopeList.add(new Scope(Scopes.HEALTHKIT_STEP_BOTH));
HuaweiIdAuthParamsHelper authParamsHelper =
new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM);
HuaweiIdAuthParams authParams =
authParamsHelper.setIdToken().setAccessToken().setScopeList(scopeList).createParams();
final HuaweiIdAuthService authService =
HuaweiIdAuthManager.getService(this.getApplicationContext(), authParams);
Task < AuthHuaweiId > authHuaweiIdTask = authService.silentSignIn();
authHuaweiIdTask.addOnSuccessListener(huaweiId - > {
......
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(Exception exception) {
......
}
});
}

Unity Admob Interstitial Ads Not Showing

I know this question has been asked several times but i got stuck even though i have implemented and tried all the solutions. I follow this tutorial for interstitial ads showing:
https://developers.google.com/admob/unity/interstitial
My main goal is to show ad whenever user taps on "Restart" button for the game.
Here is my main ad manager class (which is linked with an game object):
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using GoogleMobileAds.Api;
public class AdManager : MonoBehaviour {
public string interstitial_id;
public string app_id;
public InterstitialAd interstitial;
// Use this for initialization
void Start () {
//MobileAds.Initialize(app_id);
DontDestroyOnLoad(this);
Prepare_Video();
Debug.Log("Admob ilklendirildi: " + interstitial.ToString());
}
public void Show_Video()
{
Debug.Log("Reklam hazırlık durumu: " + interstitial.IsLoaded());
if (interstitial.IsLoaded()) {
Debug.Log("Reklam hazır, gösterilecek");
interstitial.Show();
}
else
{
Prepare_Video();
interstitial.Show();
}
}
public void Destroy_Video()
{
if(interstitial != null)
{
interstitial.Destroy();
}
}
public void Prepare_Video()
{
interstitial = new InterstitialAd(interstitial_id);
AdRequest request = new AdRequest.Builder().Build();
interstitial.LoadAd(request);
}
}
I call the show method in restart action:
public void RestartScene()
{
GameStatusText.gameObject.SetActive(false);
RestartButton.gameObject.SetActive(false);
MeterText.gameObject.SetActive(false);
MeterTextTop.text = "";
Time.timeScale = 1;
TimeController.TimeLeft = 50f;
FindObjectOfType<AdManager>().Show_Video();
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}
you need Initialize admob first
Check what's going on with the scene that AdManager is assigned to, and if there is any changes to the scene, and do you have Google Ads unity asset installed in your game?
I have reinstalled the admob plugin and followed the instructions from the beginning. It worked. It seems like my plugin package was damaged and some files were missing.

Oculus entitlement gear vr

I am developing a game for Gear VR in Unity 5.6.1p1 with Oculus Utils 1.9.0. It is on technical review now on developer console. However I keep getting entitlement error even after adding it to the project.
Here is their explanation:
It appears that your app does not support entitlement checks to prevent unauthorized use of your content. Documentation on how to add entitlement checks can be found here: https://developer.oculus.com/documentation/platform/latest/concepts/pgsg-get-started-with-sdk/
And here is my entitlement code:
public class PlatformManager : MonoBehaviour
{
public static bool entitled = false;
private static PlatformManager s_instance;
private ulong m_myID;
private string m_myOculusID;
void Awake()
{
if(s_instance != null)
{
Destroy(gameObject);
return;
}
s_instance = this;
DontDestroyOnLoad(gameObject);
Core.Initialize();
}
private void Start()
{
entitled = false;
Entitlements.IsUserEntitledToApplication().OnComplete(IsEntitledCallback);
}
void IsEntitledCallback(Message msg)
{
if(msg.IsError)
{
entitled = false;
TerminateWithError(msg);
return;
}
entitled = true;
Users.GetLoggedInUser().OnComplete(GetLoggedInUserCallback);
}
public static void TerminateWithError(Message msg)
{
Debug.Log("Error: " + msg.GetError().Message);
UnityEngine.Application.Quit();
}
void GetLoggedInUserCallback(Message<User> msg)
{
if(msg.IsError)
{
TerminateWithError(msg);
return;
}
m_myID = msg.Data.ID;
m_myOculusID = msg.Data.OculusID;
}
}
I am not doing anything with ID after entitling. Should I do something? Is there a mistake in my code? I do get true value after entitling.
My app has passed entitlement check and techical review. The code was good, but I had to add a message to let the user know that he is not entitled, and then exit the app.

Uploading image to Google Drive using GWT-Google Picker

I am trying to upload an image to Google Drive using Google Picker user interface. So far i have been unsuccessful.
This is the code that i am using :
private void onCreatePicker(ViewId viewId) {
final Picker picker = PickerBuilder.create()
.setTitle("Subir imagen a Google Drive")
.addView(viewId)
.addView(DocsUploadView())
.setLocale("es")
.setOAuthToken(token_oauth2)
.setDeveloperKey(DEVELOPER_KEY)
.setCallback(buildPickerCallback(viewId))
.build();
picker.setVisible(true);
}
private JavaScriptObject DocsUploadView() {
return com.ip.gae.gartla.shared.DocsUploadView.create();
}
I request your help on what could i be missing.
Thank you for your time,
Regards,
UPDATE: It seems that my application scope was wrong. In order to generate the correct oAuth2Token, you must declare the scope which you want to generate the token for:
The following its the method I am using to generate the token:
private void tokenOauth2() {
AuthRequest req = new AuthRequest(AUTH_URL, CLIENT_ID)
.withScopes(GOOGLE_DRIVE_SCOPE); // Can specify multiple scopes here
Auth.get().login(req, new Callback<String, Throwable>() {
#Override
public void onSuccess(String token) {
token_oauth2 = token;
}
#Override
public void onFailure(Throwable caught) {
// The authentication process failed for some reason, see caught.getMessage()
}
});
}
And here it is the GOOGLE_DRIVE_SCOPE variable that i am using:
String GOOGLE_DRIVE_SCOPE = "https://www.googleapis.com/auth/drive";
So, for now this is working for me. I have attached the solution so if someone finds it out interesting enough. :-)