Samsung IAP - checking if an item is bought upon start up? - in-app-purchase

I just do not know how to use Samsung IAP!
I come from Google Play IAP where the IAP was pretty easy to implement. I took out all of that stuff and I started integrating the Samsung stuff. Now, I can make purchases, but what I don't understand is how to check if an item has been purchased.
My game has ads, and I have one non-consumable set up that will disable ads forever if purchased. As stated, I can purchase and disable the ads - the issue is that I want to check if that item has been purchased upon each start up, maybe in the on create. Otherwise, the ads come back upon the app closing down (I can use shared preferences, but if the app is uninstalled, the issue remains).
This is how it works in Google Play IAP. I have gone through the docs and the one example, and I understand that I can use doGetInboxList to see what items have been purchased.
However, as in the sample, this just asks for the group ID (no individual items), and even then, just says what and what isn't purchased in a list view. I have searched the code, but I can't even find where this is set. Regardless, programmitically I just want something.. anything! A boolean. Is this item with this id bought or not - yes or no. True or false. Have I missed something? Any help would be appreciated!

You are close.
Take that sample from InboxListActivity and apply to your activity:
public class YourStartUpActivity extends Activity implements OnGetInboxListener
{
private String mItemGroupId = "100000xxxxxx";
private int mIapMode = SamsungIapHelper.IAP_MODE_TEST_SUCCESS;
private int mStartNum = 1;
private int mEndNum = 15;
private String mStartDate = "20140101";
private String mEndDate = "30140101";
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//do your initializations here
SamsungIapHelper iapHelper = SamsungIapHelper.getInstance( this, mIapMode );
iapHelper.getItemInboxList( mItemGroupId,
mStartNum,
mEndNum,
mStartDate,
mEndDate,
this );
}
#Override
public void onGetItemInbox
(
ErrorVo _errorVo,
ArrayList<InboxVo> _inboxList
)
{
if( _errorVo != null &&
_errorVo.getErrorCode() == SamsungIapHelper.IAP_ERROR_NONE )
{
// TODO When inbox list has been loaded successfully,
// processes here.
if( _inboxList != null && _inboxList.size() > 0 )
{
//if you only have 1 item, you can assume that item is purchased, otherwise
//go over the _inboxList and check
//that user has purchased the correct item
}
}
}
}
Hope it helps

Related

Save State iOS - Save Value when leaving application - Xamarin

I want to save the state of my application on iOS.
The app's workflow is to select a PersonID and base on that ID, a page with Details is opened. When I click on the Person's Address, the Maps is opened... but when I get back to my application, the first page is display, not the selected PersonID's page.
How can I keep the state of the application on iOS... I couldn't find something in the documentation.
Thank you in advance!
You could use User Defaults in Xamarin iOS to save the PersonID when selecting it, and get it to show the specified view when launching the app next time.
Save the PersonID:
var plist = NSUserDefaults.StandardUserDefaults;
int personid = 1;
plist.SetDouble(personid , "PersonID ");
And get it to show next time:
public override void ViewDidAppear(bool animated)
{
var plist = NSUserDefaults.StandardUserDefaults;
var personid = plist.DoubleForKey("PersonID");
if (null != personid)
{
// load the matched data
}
}

Receipt-Validation code for iOS app, not working

I have implemented Receipt-Validation code for the first time in an iOS app, following the Raywenderlich tutorial
Even though it was working fine during the test, using Sandbox. In reality, it does not work as expected.
When the app is downloaded, all features are available from start; meaning there is no check on the purchase of the iap contents.
In the case of Sandbox I needed to make a purchase to get the receipt and "making a purchase" meant "getting the content of the iap".
And as far as I know, in the real world the receipt comes with the app.
My interpretation is that I am probably not checking what I should in the code.
Any guidance by an expert in the field would be very much appreciated.
Looking at the code, it seems that there is (indeed) not much check, other than making sure that their is a valid (well formed) receipt. But I guess I need more to check that the very contents of the IAP had been paid for.
Below is what I think is the relevant code:
func validateReceipt() {
receipt = Receipt()
if let receiptStatus = receipt?.receiptStatus {
guard receiptStatus == .validationSuccess else {
return
}
// If verification succeed, we show information contained in the receipt.
// print("Bundle Identifier: \(receipt!.bundleIdString!)")
// print("Bundle Version: \(receipt!.bundleVersionString!)")
if let originalVersion = receipt?.originalAppVersion {
//print("originalVersion: \(originalVersion)")
} else {
//print("originalVersion: Not Provided")
}
if let receiptExpirationDate = receipt?.expirationDate {
//print("Expiration Date: \(formatDateForUI(receiptExpirationDate))")
} else {
//print("Expiration Date: Not Provided")
}
if let receiptCreation = receipt?.receiptCreationDate {
//print("receiptCreation: \(formatDateForUI(receiptCreation))")
} else {
//print("receiptCreation: Not Provided")
}
// At this point we should enable full features if it is not yet the case.
.... code to unlock full features .....
}
}
You should check fields with type 17xx where you can find product identifier (field type 1702) and purchase date (field type 1704). This is described at Raywenderlich tutorial you mentioned in part Reading In-App Purchases.
So, you can check if user purchased IAP with product identifier you interested in. Product identifier is the same as you choose at App Store Connect at MyApps -> Feature -> IAP.

How to hide amazon ads in unity

So I integrated amazon mobile ads into my unity/ios project. I have it all working to where I hide the ads every time a scene changes. Every time I open a scene, the ad shows. So it's all working fine except when you change scenes really quickly. I don't want ads in the main game as it obstructs the view of the users. Every time you get to the retry scene, if you quickly switch from that scene right before an ad loads, that ad will get stuck on the next scene which makes another ad show on top of it. Every time a scene changes it should be hiding the ad not matter how fast you change scenes. Is there any way to make sure it hides the ad if an ad is shown? I'm using the code below:
void Start() {
mobileAds = AmazonMobileAdsImpl.Instance;
ApplicationKey key = new ApplicationKey();
key.StringValue = iosKey;
mobileAds.SetApplicationKey(key);
ShouldEnable enable = new ShouldEnable();
enable.BooleanValue = true;
mobileAds.EnableTesting(enable);
mobileAds.EnableLogging(enable);
Placement placement = new Placement();
placement.Dock = Dock.BOTTOM;
placement.HorizontalAlign = HorizontalAlign.CENTER;
placement.AdFit = AdFit.FIT_AD_SIZE;
response = mobileAds.CreateFloatingBannerAd(placement);
string adType = response.AdType.ToString();
long identifer = response.Identifier;
newResponse = mobileAds.LoadAndShowFloatingBannerAd(response);
bool loadingStarted = newResponse.BooleanValue;
}
void OnDestroy() {
mobileAds.CloseFloatingBannerAd(response);
response = null;
mobileAds = null;
newResponse = null;
}
When did you download the Unity Plugin? There were some issues in an early version of the plugin that this sounds like (the whole, one ad loading over top of another thing). If you have not updated it recently, try downloading the latest version from Amazon and see if the issue still occurs.
The close ad API
mobileAds.CloseFloatingBannerAd(response);
will only work if the ad is already loaded. You need to register for the ad loaded event. If the scene is destroyed, then you would close the ad when the ad loaded event tiggers.
You can register for AdLoaded event as follows, Documentation
using com.amazon.mas.cpt.ads;
bool sceneDestroyed = false; //tracks if scene is destroyed
//Obtain object used to interact with the plugin
IAmazonMobileAds mobileAds = AmazonMobileAdsImpl.Instance;
// Define event handler
private void EventHandler(Ad args)
{
if (sceneDestroyed)
{
mobileAds.CloseFloatingBannerAd(response);
}
else
{
//Do some other job
}
}
//Register for an event
mobileAds.AddAdLoadedListener(EventHandler);
void OnDestroy()
{
sceneDestroyed = true;
}

iOS inapp purchase plugin return null

I'm using cordova to make an app in iOS store an I also use https://github.com/j3k0/cordova-plugin-purchase/blob/master/doc/api.md for integrate in-app purchase.
I already create product on my iTunes connect and put the code like
function initStore(){
if (!window.store) {
log('Store not available');
return;
}
// Enable maximum logging level
store.verbosity = store.DEBUG;
// Enable remote receipt validation
//store.validator = "https://api.fovea.cc:1982/check-purchase";
// Inform the store of your products
alert('registerProducts');
store.register({
id: 'com.thegiffary.product.quran_full',
alias: 'full version',
type: store.NON_CONSUMABLE
});
// When any product gets updated, refresh the HTML.
store.when("product").updated(function (p) {
alert(JSON.stringify(p))
});
// When purchase of the full version is approved,
// show some logs and finish the transaction.
store.when("full version").approved(function (order) {
alert('You just unlocked the FULL VERSION!');
order.finish();
});
// The play button can only be accessed when the user
// owns the full version.
store.when("full version").updated(function (product) {
alert(JSON.stringify(product))
});
// When the store is ready (i.e. all products are loaded and in their "final"
// state), we hide the "loading" indicator.
//
// Note that the "ready" function will be called immediately if the store
// is already ready.
store.ready(function() {
alert('ready')
});
// When store is ready, activate the "refresh" button;
store.ready(function() {
alert('refresh-button')
});
// Alternatively, it's technically feasible to have a button that
// is always visible, but shows an alert if the full version isn't
// owned.
// ... but your app may be rejected by Apple if you do it this way.
//
// Here is the pseudo code for illustration purpose.
// myButton.onclick = function() {
// store.ready(function() {
// if (store.get("full version").owned) {
// // access the awesome feature
// }
// else {
// // display an alert
// }
// });
// };
// Refresh the store.
//
// This will contact the server to check all registered products
// validity and ownership status.
//
// It's fine to do this only at application startup, as it could be
// pretty expensive.
alert('refresh');
store.refresh();
}
When I test the code on real device, it return product with null information (please see the picture)
I'm not sure am I miss any thing when I config the in-app product? Please give me any suggestion.
Regards.
I was facing a similar problem developing an android in-app-purchasing app. I am going to take a stab in the dark and guess that the problem might be similar. My issue was that the id for my product did not match what I was trying to pull from the store.
The product id and type have to match products defined in your Apple and Google developer consoles.
In my case, when the product loaded, it had the same field values as the one you are getting now. I changed the id, and it loaded perfectly. You may want to check those two values in your store.register function.

Make a phone call from app when user presses the call button (override default behaviour)

I have a listfield in my app showing a list of contacts. I would like to call the selected contact when the user presses the green call button (instead of the default behaviour which launches the phone call log app).
This means there are 2 issues:
1) can I intercept the green call button?
2) how can I make the call from the app?
Before answering the question, it is assumed that you are keeping track of the currently selected item in the list, and you have a way of finding the related phone number.
1) Intercept the call button
You need to implement the keyDown(int, int) method in a Manager or Screen, catch the correct keycode, and return true:
protected boolean keyDown(int keycode, int time)
{
// check for the green phone button
if (keycode == 1114112)
{
/*
* Place your custom calling code here.
*/
return true; // indicates that this method has consumed the keypress
}
else
{
return super.keyDown(keycode, time);
}
}
(based on answer given at http://supportforums.blackberry.com/t5/Java-Development/Can-Over-ride-Call-Button-using-api-Issue-Shows-Context-Menu-on/m-p/252554/highlight/true#M41073)
2) Make a phone call
You need to Invoke() the phone app, passing it the phone number you wish to call:
PhoneArguments callArgs = new PhoneArguments(
PhoneArguments.ARG_CALL, "+27 83 111 1234");
Invoke.invokeApplication(Invoke.APP_TYPE_PHONE, callArgs);
So combining gives this code:
protected boolean keyDown(int keycode, int time)
{
// check for the green phone button
if (keycode == 1114112)
{
// get phone number - you must write this yourself
String number = selectedContact.getNumber(); // assume some method here depending on your solution
// make the call
PhoneArguments callArgs = new PhoneArguments(
PhoneArguments.ARG_CALL, number);
Invoke.invokeApplication(Invoke.APP_TYPE_PHONE, callArgs);
// indicate that the key has been processed
return true;
}
else
{
return super.keyDown(keycode, time);
}
}
From the Blackberry documentation:
net.rim.blackberry.api.phone
public final class Phone extends
Object
This class provides the following:
* Advanced utilities for interaction with the Phone
application. You can use the methods
in this class for finer manipulation
of the Phone application. For example,
injecting DTMF tones into active
calls.
* Access multiple lines on the device.
* Adding data to the incoming and active call screens, if supported.
Multi-line examples
Example A: Switching a line
Create a class that extends MultiLineListener.
public class MultiLineAction extends MultiLineListener
Register the class as a PhoneListener.
Phone.addPhoneListener(this);
Implement the MultiLineListener callbacks so that the app can be
notified of switching results.
public void setPreferredLineFailure(int lineId)
{
_screen.popupMessage("Switching failed");
}
public void setPreferredLineSuccess(int lineId)
{
_screen.popupMessage("Switching to " + Phone.getLineNumber(lineId) + "
completed" );
}
Invoke Phone.setPreferredLine().
Phone.setPreferredLine( Phone.getLineIds()[0]);
Example B: Initiate an outgoing call
Invoke Phone.initiateCall.
Phone.initiateCall(Phone.getLineIds()[0],
"5195550123");
Deregister the class from the phone listener before the application
is closed.
Phone.removePhoneListener(this);
Category:
Signed: This element is only accessible by signed applications. If
you intend to use this element, please
visit
http://www.blackberry.com/go/codesigning
to obtain a set of code signing keys.
Code signing is only required for
applications running on BlackBerry
smartphones; development on BlackBerry
Smartphone Simulators can occur
without code signing. Since:
BlackBerry API 4.0.0
http://www.blackberry.com/developers/docs/6.0.0api/

Resources