Xamarin Android - How to sign in Google Play Services? - xamarin.android

I am trying to add Google Play Services to my Xamarin Android app.
I am using Play Games Services v2 SDK and trying to follow this tutorial from the Official documentation.
The Java code for signing in would be that:
GamesSignInClient gamesSignInClient = PlayGames.getGamesSignInClient(getActivity());
gamesSignInClient.isAuthenticated().addOnCompleteListener(isAuthenticatedTask -> {
boolean isAuthenticated =
(isAuthenticatedTask.isSuccessful() &&
isAuthenticatedTask.getResult().isAuthenticated());
if (isAuthenticated) {
// Continue with Play Games Services
} else {
// Disable your integration with Play Games Services or show a
// login button to ask players to sign-in. Clicking it should
// call GamesSignInClient.signIn().
}
});
How can I translate it to C#?
Anyone can help me please?
This is my best attempt, but I am getting an exception on SetJniIdentityHashCode method not implemented.
using Android.Gms.Games;
using Android.Gms.Tasks;
// ...
PlayGamesSdk.Initialize(this);
IGamesSignInClient gamesSignInClient = PlayGames.GetGamesSignInClient(this);
gamesSignInClient.IsAuthenticated().AddOnCompleteListener(
new OnCompleteListener()
);
// ...
public class OnCompleteListener : Java.Lang.Object, IOnCompleteListener
{
public void Disposed()
{
throw new NotImplementedException();
}
public void DisposeUnlessReferenced()
{
throw new NotImplementedException();
}
public void Finalized()
{
throw new NotImplementedException();
}
public void OnComplete(Task task)
{
//var isAuthenticated =
// (task.IsSuccessful &&
// ((????)task.Result).isAuthenticated())
//if (isAuthenticated)
//{
// // Continue with Play Games Services
//}
//else
//{
// // Disable your integration with Play Games Services or show a
// // login button to ask players to sign-in. Clicking it should
// // call GamesSignInClient.signIn().
//}
}
public void SetJniIdentityHashCode(int value)
{
throw new NotImplementedException();
}
public void SetJniManagedPeerState(JniManagedPeerStates value)
{
throw new NotImplementedException();
}
public void SetPeerReference(JniObjectReference reference)
{
throw new NotImplementedException();
}
}

I managed to get the authentication result in the following way, probably was just using the wrong references.
public class TaskCompleteListener : Java.Lang.Object, IOnCompleteListener
{
public void OnComplete(Android.Gms.Tasks.Task task)
{
var isAuthenticated = task.IsSuccessful &&
((AuthenticationResult)task.Result).IsAuthenticated;
if (isAuthenticated)
{
// Continue with Play Games Services
}
else
{
// Disable your integration with Play Games Services or show a
// login button to ask players to sign-in. Clicking it should
// call GamesSignInClient.signIn().
}
}
}

Related

Xamarin In App Billing Component Not Connecting To Google Play

I have went through the Xamarin IAB 'tutorial' on it's Component page. I installed the component and Google Play Billing Lib into my app, published my apk to Google Play Dev Console in Alpha and added products on the Dev Console to the app. However, when I try to test the app on a phone, anytime I click on any of the purchase buttons nothing happens. The buttons themselves worked fine I have tested them by pushing other notifications, changing colors, etc. They work with everything else, but when it comes to purchasing nothing happens, no pop-ups, no buffering or attempt to connection, literally nothing. I think my app never connects to Google Play, and I have no idea why.
My Main Activity
private InAppBillingServiceConnection _serviceConnection;
private string publicKey = "my public key";
private IList<Product> _products;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Establish Connection to Google Play Store
_serviceConnection = new InAppBillingServiceConnection(this, publicKey);
_serviceConnection.OnConnected += async () =>
{
// Load available products and any purchases
await RequestProducts();
};
// Attempt to connect to the service
_serviceConnection.Connect();
IAPHelper.Instance.Initalize(_products, _serviceConnection);
var g = new Game1();
SetContentView(g.Services.GetService<View>());
g.Run();
}
// Request a list of available products that the user can purchase by providing alist of
protected async Task RequestProducts()
{
_products = await _serviceConnection.BillingHandler.QueryInventoryAsync(new List<string>{
ReservedTestProductIDs.Purchased,
ReservedTestProductIDs.Canceled,
ReservedTestProductIDs.Refunded,
ReservedTestProductIDs.Unavailable
}, ItemType.Product);
// Were any products returned?
if (_products == null)
{
// No, abort
return;
}
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
My Helper Method
private IList<Product> _products;
private InAppBillingServiceConnection _serviceConnection;
public void Initalize(IList<Product> _products, InAppBillingServiceConnection _serviceConnection)
{
this._products = _products;
this._serviceConnection = _serviceConnection;
}
// Called when a product is clicked to buy
public bool ProductPurchasing(string id)
{
Product _selectedProduct = null;
try
{
for (int i = 0; i < _products.Count; i++)
{
if (id == _products[i].ProductId)
{
_selectedProduct = _products[i];
break;
}
}
_serviceConnection.BillingHandler.BuyProduct(_selectedProduct);
return true;
}
catch (Exception ex)
{
return false;
}
}

Detecting when a template was loaded in wpf

I am working with an attached behavior for logging user actions on a ScrollBar.
my code:
class ScrollBarLogBehavior : Behavior<ScrollBar>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);
}
void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
...
var track = (Track)AssociatedObject.Template.FindName("PART_Track", AssociatedObject);
// ** HERE is the problem: track is null ! **
...
}
How can I detect that the template has loaded and I can find the Track?
(when I call AssociatedObject.Template.LoadContent() the result containt the requested Track, so it i a matter of timing and not a matter of wrong template or naming)
Override the method OnApplyTemplate
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var textBox = Template.FindName("PART_Textbox", this) as TextBox;
}
I did not find any good way to detect when the template was loaded. However, I did find a way to find the Track:
in OnAttached() - register to Scroll event fo the ScrollBar (this can only happen after the entire template is loaded, of course):
protected override void OnAttached()
{
base.OnAttached();
_scrollHandler = new ScrollEventHandler(AssociatedObject_Scroll);
AssociatedObject.AddHandler(ScrollBar.ScrollEvent, _scrollHandler, true);
}
When handling the Scroll event, remove registration and find the Thumb:
void AssociatedObject_Scroll(object sender, ScrollEventArgs e)
{
var track = (Track)AssociatedObject.Template.FindName("PART_Track", Associated
if (track == null)
return;
AssociatedObject.RemoveHandler(ScrollBar.ScrollEvent, _scrollHandler);
// do my work with Track
...
}
If I understand correctly, you wish to create an attached behavior that will reference a template part after the ScrollBar has been loaded.
The following should work:
internal static class ScrollBarLogBehavior
{
public static readonly DependencyProperty LogUserActionProperty = DependencyProperty.RegisterAttached(
"LogUserAction",
typeof(bool),
typeof(ScrollBarLogBehavior),
new UIPropertyMetadata(default(bool), LogUserActionChanged));
public static bool GetLogUserAction(DependencyObject obj)
{
return (bool)obj.GetValue(LogUserActionProperty);
}
public static void SetLogUserAction(DependencyObject obj, bool value)
{
obj.SetValue(LogUserActionProperty, value);
}
public static void LogUserActionChanged(DependencyObject s, DependencyPropertyChangedEventArgs e)
{
if (s is ScrollBar scrollBar)
{
scrollBar.Loaded += OnScrollBarLoaded;
}
}
private static void OnScrollBarLoaded(object sender, RoutedEventArgs e)
{
if (sender is ScrollBar scrollBar)
{
if (scrollBar.Template != null)
{
// I'm not sure, but the `name` in the following method call might be case sensitive.
if (scrollBar.Template.FindName("PART_Track", scrollBar) is Track track)
{
// do work with `track` here
}
}
}
}
}
where you would "attach" the behavior in your XAML with:
<ScrollBar guiControls:ScrollBarLogBehavior.LogUserAction="True">
<!-- more here -->
</ScrollBar>
BE ADVISED: this implementation completely ignores the bool value that is being set for LogUserAction

Get BBM Chat Logs

A Simple question for every one , is there any possible way to get Blackberry BBM Logs in application , via Programming.
Following task I have done :-
Download & integrate BBM SDK in Project.
Follow the BBM Development Guide.
Here are My Code :-
public void getBBM_Logs()
{
BBMPlatformContext platformContext =null;
try
{
platformContext = BBMPlatformManager.register(new MyBBMAppPlugin());
if(platformContext != null)
{
ContactListService contactListService = platformContext.getContactListService();
BBMPlatformContactList contacts = contactListService.getContactList();
Enumeration contactsEnum = contacts.getAll();
while(contactsEnum.hasMoreElements())
{
BBMPlatformContact contact = (BBMPlatformContact)contactsEnum.nextElement();
add(new LabelField(contact.getDisplayName()));
}
}
}
catch (ControlledAccessException e)
{
// The BBM platform has been disabled
}
if (platformContext != null)
{
MyBBMPlatformContextListener platformContextListener;
platformContextListener = new MyBBMPlatformContextListener();
platformContext.setListener(platformContextListener);
}
}
private class MyBBMPlatformContextListener extends BBMPlatformContextListener
{
public void accessChanged(boolean isAccessAllowed, int accessErrorCode)
{
if (!isAccessAllowed)
{
// You cannot access the BBM platform
}
}
public void appInvoked(int reason, Object param)
{
// Code for handling different contexts for invocation
}
}
private class MyBBMAppPlugin extends BBMPlatformApplication
{
public MyBBMAppPlugin()
{
super("57888721-1e52-4171-a8a4-0559eab8efdf");
}
}
Please Let Me know , is there any possible way to get ChatLogs.
Sorry this is not possible - as I think BB regard access to chat logs from a program as a potential security exposure.

Launching the application from an url in the browser for BlackBerry?

I am developing one application where i will launch a url in the browser from which i will launch my application.
Suppose if i will click google.com, and press enter, it will launch my application. For that i tried with the HttpFilterRegistry API.
For reference i am using the HTTPFilterDemo application. But currently while launching the app, i am getting the NullPointerException.
I wrote the below code i the openFilter Method:
public Connection openFilter(String name, int mode, boolean timeouts) throws IOException {
Logger.out("Protocol", "it is inside the openFilter method");
_url = name.substring(2);
_requestHeaders = new HttpHeaders();
_responseHeaders = new HttpHeaders();
_responseHeaders.setProperty(HttpProtocolConstants.HEADER_CONTENT_TYPE, "text/html");
Logger.out("Protocol", "here it is come ::::44444444");
final int modHandle = CodeModuleManager.getModuleHandle("AppLaunchBrowser");
Logger.out("Protocol", "here is the module handle:::" + modHandle);
final ApplicationDescriptor[] apDes = CodeModuleManager.getApplicationDescriptors(modHandle);
final ApplicationDescriptor appDescriptor = new ApplicationDescriptor(apDes[0], new String[] {});
Logger.out("Protocol", "here is the app descriptor:::" + appDescriptor);
try {
final int appCode = ApplicationManager.getApplicationManager().runApplication(appDescriptor, true);
Logger.out("Protocol", "here is the app code:::" + appCode);
} catch (ApplicationManagerException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// }
return this;
}
And in the application class i am creating alternative entry point and using like below:
public class AppLaunch extends UiApplication{
public static void main(String args[])
{
Logger.out("AppLaunch", args+"length of the arguments::::" +args.length);
if((args != null) && (args.length > 0) && (args[0].equals("background")))
{
Logger.out("AppLaunch", "in the alternate entry point");
// Logger.out("AppLaunch", args+"length of the arguments::::" +args.length);
HttpFilterRegistry.registerFilter("www.google.co.in", "com.innominds.ca", false);
}
else
{
Logger.out("AppLaunch", "Inside the Applaunch");
AppLaunch theApp = new AppLaunch();
theApp.requestForeground();
Logger.out("AppLaunch", "created the app launch object");
theApp.enterEventDispatcher();
// Logger.out("AppLaunch", "in the alternate entry point");
// HttpFilterRegistry.registerFilter("www.google.co.in", "com.innominds.ca", false);
}
}
public AppLaunch()
{
checkPermissions();
showTestScreen();
}
private void checkPermissions()
{
ApplicationPermissionsManager apm = ApplicationPermissionsManager.getInstance();
ApplicationPermissions original = apm.getApplicationPermissions();
if(original.getPermission(ApplicationPermissions.PERMISSION_BROWSER_FILTER) == ApplicationPermissions.VALUE_ALLOW)
{
// All of the necessary permissions are currently available
return;
}
ApplicationPermissions permRequest = new ApplicationPermissions();
permRequest.addPermission(ApplicationPermissions.PERMISSION_BROWSER_FILTER);
boolean acceptance = ApplicationPermissionsManager.getInstance().invokePermissionsRequest(permRequest);
if(acceptance)
{
// User has accepted all of the permissions
return;
}
else
{
}
}
private void showTestScreen()
{
UiApplication.getUiApplication().pushScreen(new AppLaunchScreen());
}
}
Finally i was able to resolve this issue. Actually NPE is coming in some other callback methods because i was implementing the FilterBaseInterface.

previous instance still active error in blackberry

I created app which user can start from menu and from icon. I do not use GlobalEventListener in my app, just register ApplicationMenuitem. And now I am getting error: previous instance still active when launch my app.
Steps to reproduce not so trivial:
launch app from icon
do not close it, just switch to another app
launch app from icon again
I founded article in blackberry's forum about it , but I can't find solution where I should remove my ApplicationMenuItem: it added on phone boot and should show all the time.
My code:
public class Jingu extends UiApplication {
public static void main(String[] args) {
ApplicationManager app = ApplicationManager.getApplicationManager();
boolean keepGoing = true;
while (keepGoing) {
if (app.inStartup()) {
try {
Thread.sleep(1000);
} catch (Exception e) {}
} else {
keepGoing = false;
}
}
Jingu theApp = new Jingu();
theApp.initMenuItem();
theApp.showMainScreen();
theApp.enterEventDispatcher();
}
public Jingu() {
}
public void showMainScreen() {
showScreen(new JinguMainScreen(this));
}
public void initMenuItem() {
// Create menu item
Object o = RuntimeStore.getRuntimeStore().get(JinguMenuItem.MY_MENU_ID);
// register only if not done already.
if (o == null) {
new JinguMenuItem(this).registerInstance();
}
}
public void showScreen(Screen aScreen) {
synchronized (Application.getEventLock()) {
try {
UiApplication.getUiApplication().popScreen(aScreen);
} catch (Exception e) {
}
UiApplication.getUiApplication().pushScreen(aScreen);
}
}
}
public class JinguMenuItem extends ApplicationMenuItem {
public static final long MY_MENU_ID = 0xb9739d5240d5943dL;
private final Jingu jingu;
public JinguMenuItem(Jingu jingu) {
super(0x350100);
this.jingu = jingu;
}
public void registerInstance() {
Object menuItem = RuntimeStore.getRuntimeStore().remove(MY_MENU_ID);
if (menuItem == null) {
ApplicationMenuItemRepository amir = ApplicationMenuItemRepository.getInstance();
amir.addMenuItem(ApplicationMenuItemRepository.MENUITEM_SYSTEM, this);
RuntimeStore.getRuntimeStore().put(MY_MENU_ID, this);
}
}
public Object run(Object context) {
jingu.setDefaultFont(Font.getDefault());
jingu.setMainApp(false);
jingu.setBbmEditField(null);
jingu.showMainScreen();
return context;
}
public String toString() {
return "My Menu";
}
}
plz advice where I should delete ApplicationMenuItem in my app?
my regards,
Vadim
If you are registering an ApplicationMenuItem from your application, as a user I would consider it bad style for your application to remove and exit, even if RIM provided a way to do this. You may want to separate your application into two parts. One provides the minimal support for responding to the ApplicationMenuItem selection, that starts automatically and runs in the background. The other has all the rest and can run and exit as needed.
My solution for this situation is:
create alternative entry point and run it on app load
register menu in it
do not use runtimeStore

Resources