I'm trying to implement InAppBilling (Android) subscription. I'm trying to use component (Xamarin.InAppBilling). I can purchase the subscription but when I trying to get purchases item by subcription, nothing returns for me. How are you implementing IAB (Android) subscription? Someone have a example?
[EDITED]
public class PurchaseManager : IPlayListener
{
MLActivity2 _act;
BillingService m_service;
int m_requestId = 1;
//String _productId = "subscription.test";
//atributos IAB
String _publicKey = "";
String _productId = "";
public bool _premium;
public PurchaseManager(MLActivity2 act)
{
_act = act;
IniciarPurchase();
}
public void OnActivityResult (int requestCode, Result resultCode, Intent data)
{
m_service.HandleActivityResult(requestCode, (int)resultCode, data);
}
public void Finalizar()
{
if (m_service != null)
m_service.Dispose();
}
//Process referentes a IAB
private void IniciarPurchase ()
{
Security.ExpectSignature = false;
m_service = new BillingService(_act, this, _publicKey);
var connTask = m_service.Connect();
//Load inventory on start-up
connTask.ContinueWith(t =>
{
if (t.Result)
{
VerificarAssinatura();
}
});
}
public void Connected()
{
}
public void Disconnected()
{
}
private void VerificarAssinatura()
{
//Existing purchases
m_service.SendRequest<GetPurchasesResponse>(new GetPurchases(play.billing.v3.Consts.ITEM_TYPE_SUBS, m_requestId++)).ContinueWith(tGP =>
{
_act.RunOnUiThread(() =>
{
if (tGP.Result.Success)
{
foreach (Purchase item in tGP.Result.PurchasedItems)
MLActivity2.UiShowToast(_act, "", "Order id" + item.OrderId, true);
if (tGP.Result.PurchasedItems.Count == 0)
MLActivity2.UiShowToast(_act, "", "nao tem item", true);
}
else
MLActivity2.UiShowToast(_act, _act.GetString(Resource.String.msg_erro), "Purchases request failure. Error: " + tGP.Result.Message, false);
});
});
//Existing purchases
m_service.SendRequest<GetPurchasesResponse>(new GetPurchases(play.billing.v3.Consts.ITEM_TYPE_INAPP, m_requestId++)).ContinueWith(tGP =>
{
_act.RunOnUiThread(() =>
{
if (tGP.Result.Success)
{
foreach (Purchase item in tGP.Result.PurchasedItems)
MLActivity2.UiShowToast(_act, "", "Order id" + item.OrderId, true);
if (tGP.Result.PurchasedItems.Count == 0)
MLActivity2.UiShowToast(_act, "", "nao tem item", true);
}
else
MLActivity2.UiShowToast(_act, _act.GetString(Resource.String.msg_erro), "2222Purchases request failure. Error: " + tGP.Result.Message, false);
});
});
}
public void JaPossuiAssinatura()
{
MLActivity2.UiShowToast(_act, _act.GetString(Resource.String.assinatura_japossui_titulo), _act.GetString(Resource.String.assinatura_japossui_texto), true);
}
public void Comprar ()
{
var req = new Buy(_productId, m_requestId++);
m_service.SendRequest<Response>(req).ContinueWith(t =>
{
_act.RunOnUiThread(() =>
{
if (t.Result.Success)
VerificarAssinatura();
else
MLActivity2.UiShowToast(_act, _act.GetString(Resource.String.msg_erro), "Purchases request failure. Error: " + t.Result.Message, false);
});
});
}
void CompraComSucesso()
{
MLActivity2.UiShowToast(_act, _act.GetString(Resource.String.assinatura_sucesso_titulo), _act.GetString(Resource.String.assinatura_sucesso_texto), true);
}
void ErroNaCompra()
{
//MLActivity2.UiShowToast(_act, _act.GetString(Resource.String.msg_erro), _act.GetString(Resource.String.assinatura_problema), false);
}
}
Adding a code snippet always helps to get the right answer faster. Don't forget it next time ;)
When you query purchases, make sure you use correct item type: subscription (and not the product). If you have both, you have to do two queries - one for products and one for subscriptions.
Related
Currently i have 2 users:
Tester1 and AnotherTester
I've been trying to create a public group channel using my Tester1
but whenever i try to create one.
It's not showing in my list using AnotherTester
Here is my code in creating public group channel
GroupChannelParams params = new GroupChannelParams()
.setPublic(true)
.setDiscoverable(true)
.setEphemeral(false)
// .addUserIds(users)
.setDistinct(false)
.setName(channelName);
GroupChannel.createChannel(params, new GroupChannel.GroupChannelCreateHandler() {
#Override
public void onResult(GroupChannel groupChannel, SendBirdException e) {
if (e != null) { // Error.
Toast.makeText(context, "" + e.getMessage(), Toast.LENGTH_SHORT).show();
Logs.logError(e.getMessage());
retrySendConnection(context, String.valueOf(e.getCode()), e.getMessage());
return;
} else {
// inviteUser(groupChannel);
Logs.logData(groupChannel.getUrl());
Intent i = new Intent(MainActivity.this, channelChatActivity.class);
i.putExtra("channelUrl", groupChannel.getUrl());
startActivity(i);
}
}
});
So Tester1 is the one that created a public group channel
but when i switch to AnotherTester, it doesn't show the public group channel.
Here is my code in retrieving AnotherTester channels
GroupChannelListQuery channelListQuery1 = GroupChannel.createMyGroupChannelListQuery();
channelListQuery1.setIncludeEmpty(true);
channelListQuery1.next(new GroupChannelListQuery.GroupChannelListQueryResultHandler() {
#Override
public void onResult(List<GroupChannel> list, SendBirdException e) {
if (e != null) {
Logs.logError(e.getMessage());// Error.
return;
} else {
groupChannelList.addAll(list);
groupChannelAdapter = new groupChannelAdapter(context, groupChannelList);
initializeRecyclerView(channelAdapter);
}
}
});
i hope you can help me.
You need to do atleast one message in that , then it will show to another user. Please try once to send one message.
Please try this code :-
private void createGroupChannel(List<String> userIds, boolean distinct, final String toID) {
GroupChannel.createChannelWithUserIds(userIds, distinct, "tsg-chat-" + SessionUtils.getCurrentMemberId(this) + "-" + toID, "", "", new GroupChannel.GroupChannelCreateHandler() {
#Override
public void onResult(GroupChannel groupChannel, SendBirdException e) {
if (e != null) {
// Error!
return;
}
}
});
}
guys.
I'm trying to use vk api sdk in Xamarin.Android. I create a request:
var token = VKHelper.GetVkUserToken(App.Data.Setting.List);
var iparams = new Dictionary<string, Java.Lang.Object>();
iparams.Add(VKApiConst.UserId, VKBuffer.Friend.Id);
iparams.Add("type", "invite");
iparams.Add("access_token", token);
v = new VKRequest("apps.sendRequest", new VKParameters(iparams));
By clicking in button I call ExecuteWithListener:
v.ExecuteWithListener(new ReqvList(new Action(o =>
{
RunOnUiThread(() =>
{
if (o.IsComplete)
{
try
{
showCustomAlert(Resource.Drawable.checkmark, GetString(Resource.String.SentInvite), Android.Graphics.Color.Argb(100, 0, 0, 200));
}
catch { }
}
else
{
try
{
showCustomAlert(Resource.Drawable.ic_post, GetString(Resource.String.NotSentInvite) + "\n" + GetString(o.MessageId), Android.Graphics.Color.Argb(100, 200, 0, 0));
}
catch { }
}
});
})));
Listener:
public class ReqvList : VKRequest.VKRequestListener
{
Action<CallBackVKResponse> Complete;
CallBackVKResponse callBackVKResponse = new CallBackVKResponse
{
IsComplete = false,
MessageId = 0
};
public ReqvList(Action<CallBackVKResponse> Complete)
{
this.Complete = Complete;
}
public override void OnComplete(VKResponse p0)
{
base.OnComplete(p0);
var response = p0.Json.ToString();
callBackVKResponse.IsComplete = true;
Complete(callBackVKResponse);
}
public override void OnError(VKError p0)
{
int errorCode = p0.ApiError != null ? p0.ApiError.ErrorCode : 0;
callBackVKResponse.IsComplete = false;
if (errorCode == 15)
callBackVKResponse.MessageId = Resource.String.VkInviteError;
Complete(callBackVKResponse);
base.OnError(p0);
}
}
Summary: if I press to invite a friend, I will see a "vkontakte" dialog window with suggest message (here you can accept or skip). If I press "invite" a friend which has disabled to invite him (or her) then it works fine. This is:
....
else
{
try
{
showCustomAlert(Resource.Drawable.ic_post, GetString(Resource.String.NotSentInvite) + "\n" + GetString(o.MessageId), Android.Graphics.Color.Argb(100, 200, 0, 0));
}
catch { }
}
....
But if a user has enabled to invite him (or her) then listener won't work and my app will freeze. In the phone you can press back button and the app will unfreez and after I can press again the button - invite will has worked fine. Listener OnComplete works only the second time. This is:
...
if (o.IsComplete)
{
try
{
showCustomAlert(Resource.Drawable.checkmark, GetString(Resource.String.SentInvite), Android.Graphics.Color.Argb(100, 0, 0, 200));
}
catch { }
}
...
Help please.
I have a asp.net web forms site which runs well in PC. However when I try to access it from mobile it gives an object reference error. The site is asp.net 4.5.1 and used normal asp.net server controls.
public partial class index : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
LoginView lView = (LoginView)this.Master.FindControl("LoginView1");
lView.Visible = false;
if (Request.QueryString["exp"] != null)
{
string msg = "Session expired please login.";
ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), "$(function() { LoginFail('" + msg + "'); });", true);
}
}
protected void btnLogin_Click(object sender, EventArgs e)
{
ManchesterContext context = new ManchesterContext();
if (Membership.ValidateUser(txtUserId.Text, txtPassword.Text))
{
MembershipUser user = Membership.GetUser(txtUserId.Text);
aspnet_Users dbUser = context.aspnet_Users.Where(u => u.UserName.Equals(user.UserName)).FirstOrDefault();
if (dbUser.PassUpdated)//This means user has already changed default password. Perform login.
{
SetAuthenticationCookie(user);
aspnet_Users dbEntry = context.aspnet_Users.Where(u => u.UserName == user.UserName).FirstOrDefault();
SessionInfo.InitSession(dbEntry.UserId, dbEntry.UserName);
Session.Add("USR_KEY", dbEntry.UserId);
FormsAuthentication.RedirectFromLoginPage(user.UserName,false);
}
else //User has not updated default password.
{
Session.Add("TEMP_USR", txtUserId.Text);
Session.Add("TEMP_PASS", txtPassword.Text);
Response.Redirect("ChangePassword.aspx");
}
}
else
{
string msg = "Invalid User Id or Password.";
ScriptManager.RegisterStartupScript(this, this.GetType(), Guid.NewGuid().ToString(), "$(function() { LoginFail('" + msg + "'); });", true);
}
}
public void SetAuthenticationCookie(MembershipUser user)
{
Response.Cookies.Clear();
var cookie = new HttpCookie(FormsAuthentication.FormsCookieName)
{
Expires = System.DateTime.Now.AddDays(-1),
HttpOnly = true
};
HttpContext.Current.Response.Cookies.Add(cookie);
return;
}
}
Is there an equivalent to this for android please?
[[NSNotificationCenter defaultCenter] postNotification:[NSNotification notificationWithName:CDVPageDidLoadNotification object:self.webView]];
Edit:
This is the CordovaActivity.java
private boolean displayAd = false;
public void setDisplayAd(boolean displayAd) {
this.displayAd = displayAd;
Log.d("SomeTag" , displayAd?"true":"false");
}
public boolean getDisplayAd() {
return this.displayAd;
}
public Object onMessage(String id, Object data) {
if (!"onScrollChanged".equals(id)) {
LOG.d(TAG, "onMessage(" + id + "," + data + ")");
}
if("onPageStarted".equals(id)) {
setDisplayAd(true);
LOG.d(TAG, "TRUE");
}
return null;}
And in my Main Activity I am calling displayAd method in my onResume:
public void onResume(){
super.onResume();
displayAd();
}
And my displayAd Method:
private void displayAd() {
if(super.getDisplayAd()){
buildAd();
mInterstitialAd.show();
Toast.makeText(getActivity(), "Ad loaded", Toast.LENGTH_SHORT).show();
setDisplayAd(false);
Log.d("Hello", displayAd ? "true" : "false");
} else {
setDisplayAd(true);
Log.d("Hello1", displayAd ? "true" : "false");
Toast.makeText(getActivity(), "Ad NOT loaded", Toast.LENGTH_SHORT).show();
}
}
On android, the class CordovaWebViewClient do a this.appView.postMessage("onPageFinished", url); when it finish loading the page
But listening to it isn't as easy as on iOS
CordovaInterface has a method public Object onMessage(String id, Object data);
Your main activity should be extending CordovaActivity, and as CordovaActivity implements CordovaInterface, you could override the public Object onMessage(String id, Object data) from CordovaActivity from your main activity, but I'm not sure if that's a good idea.
To override the onMessage , copy the whole onMessage from CordovaActivity and paste it on your main activity, be aware that the onMessage from CordovaActivity won't be executed anymore.
#Override
public Object onMessage(String id, Object data) {
if (!"onScrollChanged".equals(id)) {
LOG.d(TAG, "overrided onMessage(" + id + "," + data + ")");
}
if("onPageFinished".equals(id)) {
//Show the ad here
}
if ("splashscreen".equals(id)) {
if ("hide".equals(data.toString())) {
this.removeSplashScreen();
}
else {
// If the splash dialog is showing don't try to show it again
if (this.splashDialog == null || !this.splashDialog.isShowing()) {
String splashResource = preferences.getString("SplashScreen", null);
if (splashResource != null) {
splashscreen = getResources().getIdentifier(splashResource, "drawable", getClass().getPackage().getName());
}
this.showSplashScreen(this.splashscreenTime);
}
}
}
else if ("spinner".equals(id)) {
if ("stop".equals(data.toString())) {
this.spinnerStop();
this.appView.setVisibility(View.VISIBLE);
}
}
else if ("onReceivedError".equals(id)) {
JSONObject d = (JSONObject) data;
try {
this.onReceivedError(d.getInt("errorCode"), d.getString("description"), d.getString("url"));
} catch (JSONException e) {
e.printStackTrace();
}
}
else if ("exit".equals(id)) {
this.endActivity();
}
return null;
}
With using plugin "device"
var app = {
initialize: function () {
this.bindEvents();
},
bindEvents: function () {
document.addEventListener('deviceready', this.onDeviceReady, false);
//this.onDeviceReady();
},
// deviceready Event Handler
//
// The scope of 'this' is the event. In order to call the 'receivedEvent'
// function, we must explicitly call 'app.receivedEvent(...);'
onDeviceReady: function () {
app.receivedEvent('deviceready');
},
receivedEvent: function (id) {
if ('deviceready' == id) {
StatusBar.overlaysWebView(false);
this.prepareDB();
}
console.log('Received Event: ' + id);
}
}
so here is my code for connecting and getting the values:
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using Facebook;
using SmartLocalization;
public class mainMenuFacebook : MonoBehaviour {
public string FBname;
public string FBsurname;
Dictionary<string, string> profile = new Dictionary<string, string>();
// Use this for initialization
void OnMouseDown()
{
FB.Login("publish_actions,public_profile", LoginCallback); // logine tıklama
}
void Awake() {
FB.Init(SetInit, OnHideUnity); //facebook başlangıcı
}
private void SetInit()
{
if (FB.IsLoggedIn)
{
// Util.Log("Already logged in");
OnLoggedIn();
}
}
private void OnHideUnity(bool isGameShown)
{
if (!isGameShown)
{
// pause the game - we will need to hide
Time.timeScale = 0;
}
else
{
// start the game back up - we're getting focus again
Time.timeScale = 1;
}
}
void LoginCallback(FBResult result)
{
Util.Log("LoginCallback");
if (FB.IsLoggedIn)
{ gameObject.guiTexture.enabled = false;
OnLoggedIn();
}
}
void OnLoggedIn()
{
FB.API("/me?fields=first_name,last_name,email", Facebook.HttpMethod.GET, APICallback); // adını ve idyi çekiyoruz.
}
void APICallback(FBResult result)
{
if (result.Error != null)
{
// Let's just try again
// FB.API("/me?fields=id,first_name,last_name,email,friends.limit(100).fields(first_name,last_name,id)", Facebook.HttpMethod.GET, APICallback);
return;
}
Debug.Log(result.Text);
profile = Util.DeserializeJSONProfile(result.Text);
FBname = profile["first_name"];
FBsurname = profile["last_name"]; // **IT GIVES ERROR**
Debug.Log(FBsurname + " " + FBname);
//PlayerPrefs.SetString("surname",profile["last_name"]);
//PlayerPrefs.SetString("email",profile["email"]);
gameObject.guiTexture.enabled = false;
GameObject.Find("Wellcome").guiText.enabled = true;
GameObject.Find("Wellcome").guiText.text = LanguageManager.Instance.GetTextValue("menu.hosgeldin") + " <b><color=#ffa500ff>" + FBname + "</color></b>, <i>" + LanguageManager.Instance.GetTextValue("menu.cikis") +"</i>";
PlayerPrefs.SetString("name",FBname);
}
}
when i only try to get first_name everything is okay. But i need to get last_name and email too. I think i cant serialize because when i try to Debug.Log(profile.Count); it shows 1.
How can i fix it?
Given error is:
KeyNotFoundException: The given key was not present in the dictionary.
System.Collections.Generic.Dictionary`2[System.String,System.String].get_Item (System.String key) (at /Users/builduser/buildslave/mono-runtime-and-classlibs/build/mcs/class/corlib/System.Collections.Generic/Dictionary.cs:150)
mainMenuFacebook.APICallback (.FBResult result) (at Assets/Scripts/mainMenuFacebook.cs:84)
Facebook.AsyncRequestString+<Start>c__Iterator0.MoveNext ()
Try this:
public void OnMouseDown()
{
List<string> permissions = new List<string>() { "public_profile", "email" };
FB.LogInWithReadPermissions(permissions,AuthCallback);
Debug.Log("Facebook Login");
}
In AuthCallback: if user logs in successfully, get info from FB api.
private void AuthCallback(ILoginResult result)
{
if(FB.IsLoggedIn)
{
GetInfo();
}
else
{
Debug.Log("User cancelled login");
}
}
FB API returns json result, so you will need FacebookUser class to deserialize it.
class FacebookUser
{
public string id;
public string first_name;
public string last_name;
public string email;
}
public void GetInfo()
{
FB.API("/me?fields=id,first_name,last_name,email", HttpMethod.GET, result =>
{
if(result.Error != null)
{
Debug.Log("Result error");
}
var facebookUser = Newtonsoft.Json.JsonConvert.DeserializeObject<FacebookUser>(result.RawResult);
Debug.Log(" facebook id - " + facebookUser.id);
Debug.Log(" facebook first name - " + facebookUser.first_name);
Debug.Log(" facebook last name - " + facebookUser.last_name);
Debug.Log(" facebook email - " + facebookUser.email);
});
}
NOTE: You should have Email permission from facebook to access it.
Check it in Graph API Explorer