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.
Related
I am working on a Xamarin.Forms application. I have this tabbed page renderer in iOS:
public class TabbedPageRenderer : TabbedRenderer
{
private MainPage _page;
protected override void OnElementChanged(VisualElementChangedEventArgs e)
{
base.OnElementChanged(e);
if (e.NewElement != null)
{
_page = (MainPage)e.NewElement;
}
else
{
_page = (MainPage)e.OldElement;
}
try
{
var tabbarController = (UITabBarController)this.ViewController;
if (null != tabbarController)
{
tabbarController.ViewControllerSelected += OnTabBarReselected;
}
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
private void OnTabBarReselected(object sender, UITabBarSelectionEventArgs e)
{
var tabs = Element as TabbedPage;
var playTab = tabs.Children[4];
if (TabBar.SelectedItem.Title == "Play")
{
if (tabs != null)
{
playTab.Title = "Pause";
playTab.Icon = "pause.png";
}
App.pauseCard = false;
}
else
{
if (tabs != null)
{
playTab.Title = "Play";
playTab.Icon = "play.png";
}
App.pauseCard = true;
}
}
}
This basically changes the icon on my Play tab to pause and play. This is working good in iOS. But I am struggling on how to have the same function (basically convert this to Android) in Android side.
Can any point me to the right direction? Basically help me? :-)
Note: I am pretty new with Android development.
EDIT: This is what it would look like in iOS.
Pause Mode:
Play Mode:
There is a blog post by Xamarin's James Montemagno which explains how to achieve this requirement.
Basically, it uses Custom Tab which inherits from TabbedPage which initialize an event UpdateIcons to be fired on Tab Current Page Changed event CurrentPageChanged
public class MyTabs : TabbedPage
{
//always save a reference to the current page
Page currentPage;
public MyTabs()
{
//create the pages and set the view models
//you could also do this in the page code behind
Children.Add(new TabIconsPage
{
BindingContext = new Tab1ViewModel
{
IsSelected = true
}
});
Children.Add(new TabIconsPage2
{
BindingContext = new Tab2ViewModel()
});
currentPage = Children[0];
//Register for page changes
this.CurrentPageChanged += Handle_CurrentPageChanged;
}
//Update the IsSelected state and trigger an Event that anyone can loop into.
public event EventHandler UpdateIcons;
void Handle_CurrentPageChanged(object sender, EventArgs e)
{
var currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = false;
currentPage = CurrentPage;
currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = true;
UpdateIcons?.Invoke(this, EventArgs.Empty);
}
}
Now Android needs a custom renderer to subscribe to the UpdateIcons event and perform icon changes
public class MyTabs : TabbedPage
{
//always save a reference to the current page
Page currentPage;
public MyTabs()
{
//create the pages and set the view models
//you could also do this in the page code behind
Children.Add(new TabIconsPage
{
BindingContext = new Tab1ViewModel
{
IsSelected = true
}
});
Children.Add(new TabIconsPage2
{
BindingContext = new Tab2ViewModel()
});
currentPage = Children[0];
//Register for page changes
this.CurrentPageChanged += Handle_CurrentPageChanged;
}
//Update the IsSelected state and trigger an Event that anyone can loop into.
public event EventHandler UpdateIcons;
void Handle_CurrentPageChanged(object sender, EventArgs e)
{
var currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = false;
currentPage = CurrentPage;
currentBinding = currentPage.BindingContext as IIconChange;
if (currentBinding != null)
currentBinding.IsSelected = true;
UpdateIcons?.Invoke(this, EventArgs.Empty);
}
}
With this logs:
WebSocket connection to 'wss://xxxxxx.net/' failed: WebSocket opening handshake was canceled"
"TransportWebSocket.errorHandler - Error {}"
"TransportWebSocket.closeHandler - Error {"code":1006,"text":""}"
Please help with this problem.
sp.external.TransportWebSocket = function () {
var self = this;
var socket = null;
var isOpen = false;
var listSendMsg = [];
this.openHandler = null;
this.closeHandler = null;
this.messageHandler = null;
this.errorHandler = null;
this.serverURL = '';
this.send = function (_data, _highPrioritetFlag) {
utils.logger.debug('TransportWebSocket', 'send', 'Open status:' + isOpen);
_highPrioritetFlag = _highPrioritetFlag || false;
if (isOpen) {
if (_data && typeof _data === 'object') {
try {
socket.send(JSON.stringify(_data));
}
catch (error) {
throw new Error('Invalid JSON stringify');
}
}
else {
throw new Error('The data sent must be an object');
}
}
else {
if (_highPrioritetFlag) {
listSendMsg.unshift(_data);
}
else {
listSendMsg.push(_data);
}
openSocket();
}
};
this.reopen = function () {
utils.logger.debug('TransportWebSocket', 'reopen');
openSocket();
};
this.close = function (_code) {
utils.logger.debug('TransportWebSocket', 'close');
socket.close(_code);
};
function procListMsg() {
utils.logger.debug('TransportWebSocket', 'procListMsg', 'Processing buffer messages, items:' + listSendMsg.length);
if (listSendMsg.length > 0) {
self.send(listSendMsg.shift());
setTimeout(procListMsg, 20);
}
}
function openHandler() {
utils.logger.debug('TransportWebSocket', 'openHandler', 'WebSocket.readyState:' + socket.readyState);
if (socket.readyState === WebSocket.OPEN) {
isOpen = true;
procListMsg();
if (self.openHandler) {
self.openHandler();
}
}
}
function closeHandler(error) {
utils.logger.debug('TransportWebSocket', 'closeHandler', 'Error', {code: error.code, text: error.reason});
isOpen = false;
if (socket.readyState === WebSocket.CLOSED) {
if (self.closeHandler) {
self.closeHandler(error);
}
}
}
function errorHandler(error) {
utils.logger.debug('TransportWebSocket', 'errorHandler', 'Error', {code: error.code, text: error.reason});
isOpen = false;
if (self.errorHandler) {
self.errorHandler(error);
}
}
function messageHandler(e) {
var msg = null;
if (self.messageHandler) {
try {
msg = JSON.parse(e.data);
}
catch (error) {
throw new Error('Invalid JSON format in response: ' + e.data);
}
self.messageHandler(msg);
}
}
function openSocket() {
utils.logger.debug('TransportWebSocket', 'openSocket', 'Opening');
socket = new WebSocket(self.serverURL);
socket.onopen = openHandler;
socket.onclose = closeHandler;
socket.onmessage = messageHandler;
socket.onerror = errorHandler;
}
};
I don't know if you have solved this issue, but for people encountering the same trouble and who find this thread, you may check this cordova "release" behaves differently to "debug" regarding SSL
In short, modify the file that is making the behavior different between debug and release:
platforms/android/CordovaLib/src/org/apache/cordova/engine/SystemWebViewClient.java
Comment out the content of the method onReceivedSslError and replace it with
handler.proceed();
return;
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;
}
}
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.
I have an anchor which has three elements. Each element will has to respond for a click event.
I have this as and Android web view app.
Surprisingly click event works in android browser, but when I try that android webview app, nothing happens. Please refer the code below.
I don't know what I am missing so the click events doesn't work in android webview app.
$("#cont2 li a").live('click', function (e) {
//e.preventDefault();
this.blur();
var name = $(this).attr("name");
var staffid = $(this).attr("staffid");
var recordid = $(this).attr("recordid");
var primary = $(this).attr("primary");
if (name == "deletestaff") {
// delete sales staff
var dretVal = confirm("Delete contact staff " + $(this).attr("staffname") + "?");
if (dretVal == false) {
return false;
} else {
var txtprimaryrecordid = $("#txtprimaryrecordid").val();
var txtprimarystaffid = $("#txtprimarystaffid").val();
if (txtprimaryrecordid == 'undefined') {
txtprimaryrecordid = "";
}
if (txtprimarystaffid == 'undefined') {
txtprimarystaffid = "";
}
if (txtprimaryrecordid == recordid) {
$("#txtprimaryrecordid").val("");
}
if (txtprimarystaffid == staffid) {
$("#txtprimarystaffid").val("");
}
$(this).parents('li').remove();
// show deleted item
$('#staffs input[type=checkbox]').each(function () {
var delstaffid = $(this).attr("staffid");
if (staffid == delstaffid) {
$(this).attr("checked", false).checkboxradio("refresh");
}
});
}
}
Got it. Just had to implement WebChromeClient...
private class WebChromeClient extends WebChromeClient{
#Override
public boolean onJsAlert(WebView view, String url, String message,JsResult result)
{
Log.e("alert triggered", message);
return false;
}
}