Xamarin Android WebAuthenticator bug - xamarin

Im having a problem using WebAuthenticator on Xamarin.Android
Everytime i try to log in via a external service (Goverment From Brazil) it returns me Java.Lang.RuntimeException: 'Unable to instantiate activity ComponentInfo
Heres the class that implements the WebAuthenticatorCallbackActivity:
using Android.App;
using Android.Content;
using Android.Content.PM;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TesouroDiretoMobile.Configuration.Droid
{
[Activity(NoHistory = true, LaunchMode = LaunchMode.SingleTop, Exported = true, Name = "br.gov.fazenda.tesouro.td.CallBackActivity", Label = "TesouroDireto")]
[IntentFilter(new[] { Android.Content.Intent.ActionView },
Categories = new[] { Android.Content.Intent.CategoryDefault, Android.Content.Intent.CategoryBrowsable },
DataScheme = "tesourodireto://retornologinunico")]
public class AutenticadorGovBr : Xamarin.Essentials.WebAuthenticatorCallbackActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
}
}
}
My android Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="auto" package="br.gov.fazenda.tesouro.td" android:versionName="2.3.13" android:versionCode="10826">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="false" android:xlargeScreens="false" android:largestWidthLimitDp="840" />
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<application android:label="Tesouro Direto" android:theme="#style/MyTheme" android:icon="#drawable/icon" android:largeHeap="true" android:allowBackup="true">
<!-- largeHeap utilizado devido a problemas encontrados no uso do plugin fingerprint -->
<meta-data android:name="com.google.firebase.messaging.default_notification_icon" android:resource="#drawable/icon" />
<meta-data android:name="com.google.firebase.messaging.default_notification_color" android:resource="#color/primary" />
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdInternalReceiver" android:exported="false" />
<receiver android:name="com.google.firebase.iid.FirebaseInstanceIdReceiver" android:exported="true" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
<activity android:name="br.gov.fazenda.tesouro.td.CallBackActivity">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="tesourodireto" android:host="retornologinunico" />
</intent-filter>
</activity>
</application>
</manifest>
The call for the authenticator
var uriBuilder = new StringBuilder(AppSettings.SegurancaBaseAddress);
uriBuilder.Append("/authorize");
uriBuilder.Append($"?response_type={AppSettings.ResponseType}");
uriBuilder.Append($"&client_id={Criptografia.Descriptografar(AppSettings.ClientId)}");
uriBuilder.Append($"&scope={AppSettings.Scope}");
uriBuilder.Append($"&redirect_uri={HttpUtility.UrlEncode(AppSettings.RedirectUri,Encoding.UTF8)}");
uriBuilder.Append($"&nonce={Guid.NewGuid()}");
uriBuilder.Append($"&state={Guid.NewGuid()}");
var authResult = await Xamarin.Essentials.WebAuthenticator.AuthenticateAsync(
new Uri(uriBuilder.ToString()),
new Uri(AppSettings.RedirectUri));
var accessToken = authResult?.Properties["code"];
await IniciarSessaoGovBr(accessToken, string.Empty);
It only happens in android, IOS it works fine
I already tryed updating the packages, changing the name, recreating it all on other branch, and the error keeps ocurring

Related

Xamarin - Fix 'Unfortunately, app has stopped' error on boot completed

I have created an app that calls boot completed class every time the phone restart. But my issue
is that I get a message that says 'Unfortunately, the app has stopped' every time I restart the phone, especially on older phones like OS 4.4.2. What could cause this issue?
My code :
Manifes.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="mypackagename" android:versionCode="1" android:versionName="1.0" android:installLocation="preferExternal">
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application android:allowBackup="true" android:label="#string/app_name" android:icon="#drawable/shortcut_icon">
<service android:enabled="true" android:name=".AppService" />
<receiver android:name=".RebootListener" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
</manifest>
Boot completed class
[BroadcastReceiver(Enabled = true)]
[IntentFilter(new[] { Android.Content.Intent.ActionBootCompleted })]
public class RebootListener : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Intent serviceIntent = new Intent(context, typeof(AppService));
context.StartService(serviceIntent);
}
}
The issue persists even if I comment out the code in the OnReceive method. I presume the problem might be in the manifest file. If I remove the boot completed code in the manifest file I stop receiving this error message.
Remove the receiver from your manifest:
<receiver android:name=".RebootListener" android:enabled="true" android:exported="true">
<intent-filter>
~~~~
</intent-filter>
You have applied the BroadcastReceiver attribute to your BroadcastReceiver subclass and thus the Xamarin.Android build process will create this in your manifest automatically using a MD5-based Java class name (which will not be just .RebootListener)

send sms from enulator android

MainActivity.java
Button sendTestSMSButton = (Button)findViewById(R.id.sendTestSMSButton);
sendTestSMSButton.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
System.out.println("Send SMS");
try
{
SmsManager smsManager = SmsManager.getDefault();
smsManager.sendTextMessage("+972526855556", null, "shenkin", null, null);
}
catch (Exception e)
{
e.printStackTrace();
}
}
});
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.smssong.admin.smstosong">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="22" />
<uses-permission android:name="android.permission.SEND_SMS" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity><!-- ATTENTION: This was auto-generated to add Google Play services to your project for
App Indexing. See https://g.co/AppIndexing/AndroidStudio for more information. -->
<meta-data
android:name="com.google.android.gms.version"
android:value="#integer/google_play_services_version" />
</application>
</manifest>
I get error "Sending SMS message: uid 10063 does not have android.permission.SEND_SMS."
Even that in the AndroidManifest.xml there is code to enable the permission.
What I am missing ?
There was permission error using illegal SDK

Nativescript location is not working?

I am trying to get the current location of user(tried in genymotion and actual android device) but always getting an error of {"nativeException":{}}. I am testing it with gps enabled and my view model code is below to access the location
var observable = require("data/observable");
var locationModule = require("location");
var LocationManager = new locationModule.LocationManager();
var enums = require('ui/enums');
var MainViewModel = (function (_super) {
__extends(MainViewModel, _super);
function MainViewModel() {
_super.call(this);
}
MainViewModel.prototype.signIn = function () {
//alert("Me");
alert(JSON.stringify(LocationManager));
alert(JSON.stringify(enums.Accuracy));
var locationOptions = {
desiredAccuracy: enums.Accuracy.high,
updateDistance: 0,
minimumUpdateTime: 5000,
maximumAge: 20000
};
LocationManager.startLocationMonitoring(function (location) {
console.log("Location received: " + location);
alert(JSON.stringify(location));
}, function (error) {
alert("Location error received");
alert(JSON.stringify(error));
}, locationOptions);
};
return MainViewModel;
})(observable.Observable);
exports.MainViewModel = MainViewModel;
exports.mainViewModel = new MainViewModel();
This is my AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.nativescript.myapp"
android:versionCode="1"
android:versionName="1.0" >
<supports-screens
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true"/>
<uses-sdk
android:minSdkVersion="17"
android:targetSdkVersion="22"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<application
android:name="com.tns.NativeScriptApplication"
android:allowBackup="true"
android:icon="#drawable/icon"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.tns.NativeScriptActivity"
android:label="#string/title_activity_kimera"
android:configChanges="keyboardHidden|orientation|screenSize">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.tns.ErrorReportActivity"/>
</application>
</manifest>
My bet would be that you haven't set the permissions in your AndroidManifest.xml (in NativeScript 1.3.0: platforms/android/src/main).
You want to have a line looking like this:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Parse Unity Push Sample not working

I am struggling of using Parse on my Unity android application. Have been working on several days but no success yet. No matter how hard I try, I couldn't get my device token registered for Android which is needed for sending push notifications to android. Below is my sample code and manifest snippet..
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:protectionLevel="signature" android:name="com.JoyDash.Movies.permission.C2D_MESSAGE" />
<uses-permission android:name="com.JoyDash.Movies.permission.C2D_MESSAGE" />
<!--Parse Push notification receiver-->
<service android:name="com.parse.PushService" />
<receiver android:name="com.parse.ParseBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>
<receiver android:name="com.JoyDash.Movies.Receiver" android:exported="false">
<intent-filter>
<action android:name="com.parse.push.intent.RECEIVE" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
</intent-filter>
</receiver>
<receiver android:name="com.parse.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.JoyDash.Movies" />
</intent-filter>
</receiver>
<!--<receiver android:name="com.parse.ParsePushBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.JoyDash.Movies" />
</intent-filter>
</receiver>
<service android:name="com.parse.ParsePushService" />-->
#if UNITY_IOS
NotificationServices.RegisterForRemoteNotificationTypes (RemoteNotificationType.Alert |
RemoteNotificationType.Badge |
RemoteNotificationType.Sound);
#endif
//ParsePush.SubscribeAsync
Debug.Log("Registration with Parse Push. : " + Application.platform);
ParsePush.ParsePushNotificationReceived += (sender, args) =>
{
if (Application.platform == RuntimePlatform.Android)
{
AndroidJavaClass parseUnityHelper = new AndroidJavaClass("com.parse.ParseUnityHelper");
AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
// Call default behavior.
Debug.Log("Calling Parse from Unity and Payload is : " + args.Payload);
parseUnityHelper.CallStatic("handleParsePushNotificationReceived", currentActivity, args.Payload.ToString());
//parseUnityHelper.CallStatic("handleParsePushNotificationReceived", currentActivity, args.Payload.StringPayload);
}
else if (Application.platform == RuntimePlatform.IPhonePlayer)
{
//IDictionary<string, object> payload = args.Payload;
//foreach (string key in payload)
//{
// Debug.Log("Payload: " + key + ": " + payload[key].ToString());
//}
}
};
//Parse Installation
Debug.Log("Device Token : " + ParseInstallation.CurrentInstallation.DeviceToken);
if (ParseInstallation.CurrentInstallation != null && !string.IsNullOrEmpty(ParseInstallation.CurrentInstallation.DeviceToken))
{
Debug.Log("Device Token : " + ParseInstallation.CurrentInstallation.DeviceToken);
}
else
{
//Create a new parse installation
//ParseInstallation.CurrentInstallation.SaveAsync().ContinueWith(t =>
// {
// if (t.IsFaulted || t.IsCanceled)
// {
// Debug.Log("Parse installation failed to save.");
// }
// else
// {
// Debug.Log("Parse installation saved successfully.");
// }
// });
//ParseInstallation.cre
Debug.Log("There is no installation data received for this device.. Now subscribing to a channel");
ParsePush.SubscribeAsync("Channel01").ContinueWith(t =>
{
if (t.IsFaulted || t.IsCanceled)
{
Debug.Log("Subscription of push notification failed.");
}
else
{
Debug.Log("Push notification subscribed successfully.");
}
});
//installation.
}
"Parse Unity Push Sample not working", agree!! boy, such a pain in the ( Y )
I've been fighting with Unity Parse Pushes for days(a week?) and I just solve it. I am so, so, happy, I want to share my happiness (first time in my life I write at StackOverflow, guess it was about time...)
Not sure if this will solve your problem, but for sure you have something wrong at this line:
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
We have to change "currentActivity" for what ever is your current activity. In my case I have written this:
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject> ("com.unity3d.player.UnityPlayerNativeActivity");
Because that's the name of my activity in my AndroidManifest.xml
<activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="#string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:launchMode="singleTask" android:screenOrientation="landscape">
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Still, it might not solve your problem. So, just in case, I copy paste my code!
AndroidManifest.xml:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:installLocation="preferExternal" package="com.XXXX.YYYY" android:versionName="1" android:versionCode="7">
<supports-screens android:smallScreens="true" android:normalScreens="true" android:largeScreens="true" android:xlargeScreens="true" android:anyDensity="true" />
<uses-feature android:glEsVersion="0x00020000" />
<uses-sdk android:minSdkVersion="9" android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<permission android:protectionLevel="signature" android:name="com.XXXX.YYYY.permission.C2D_MESSAGE" />
<uses-permission android:name="com.XXXX.YYYY.permission.C2D_MESSAGE" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:icon="#drawable/app_icon" android:label="#string/app_name" android:debuggable="false">
<service android:name="com.parse.ParsePushService" />
<receiver android:name="com.parse.ParsePushBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<action android:name="com.parse.push.intent.DELETE" />
<action android:name="com.parse.push.intent.OPEN" />
<category android:name="com.XXXX.YYYY" />
</intent-filter>
</receiver>
<activity android:name="com.unity3d.player.UnityPlayerNativeActivity" android:label="#string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" android:launchMode="singleTask" android:screenOrientation="landscape">
<meta-data android:name="unityplayer.ForwardNativeEventsToDalvik" android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.unity3d.player.UnityPlayerActivity" android:label="#string/app_name" android:configChanges="fontScale|keyboard|keyboardHidden|locale|mnc|mcc|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode|touchscreen" />
<!-- replace #drawable/push_icon with your push icon identifier -->
<meta-data android:name="com.parse.push.notification_icon" android:resource="#drawable/app_icon"/>
</application>
</manifest>
Please, replace com.XXXX.YYYY by -your- bundle identifier, in case of thetnswe would be by com.JoyDash.Movies
(funny thing: there is no GCM BroadcastReceiver as the Parse Push samples says, it was spitting errors like this error setting up push notification using parse.com and android studio)
And then I have a C# Unity Script in one of my GameObjects (actually the same than the one I use to initialize Parse):
using UnityEngine;
using System.Collections;
using Parse;
public class ParsePushRegistration : MonoBehaviour {
// Use this for initialization
void Start () {
#if UNITY_ANDROID
ParsePush.ParsePushNotificationReceived += (sender, args) => {
AndroidJavaClass parseUnityHelper = new AndroidJavaClass ("com.parse.ParseUnityHelper");
AndroidJavaClass unityPlayer = new AndroidJavaClass ("com.unity3d.player.UnityPlayer");
AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject> ("com.unity3d.player.UnityPlayerNativeActivity");
// Call default behavior.
parseUnityHelper.CallStatic ("handleParsePushNotificationReceived", currentActivity, args.StringPayload);
};
#endif
}
}
Hope it helps! If not, let me know... and we will see :)

open a youtube page in a webview on android 4.4+ using webchromeclient and play videos in same window

I am creating an android app in which I just want to load a youtube "page" of a user in a webview.
So for that there are two clients WebViewClient & WebChromeClient and to play videos we have to use WebChromeClient, but when i load the youtube page using WebChromeClient, my main activity gives me an option to open it in either chrome browser or youtube app but i want to load the page in the same webview.
NOte: It is working fine on android 4.2.2 but I am not able to make it work on 4.4+ versions
MainActivity.java
public class MainActivity extends Activity {
public static final String PAGE_URL = "http://www.youtube.com/jaambhaari";
final Activity activity = this;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webview = (WebView) findViewById(R.id.webView);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setUseWideViewPort(true);
webview.getSettings().setLoadWithOverviewMode(true);
webview.setWebViewClient(new WebViewClient(){});
webview.setWebChromeClient(new WebChromeClient(){
public void onProgressChanged(WebView view, int progress){
activity.setTitle("Loading...");
if(progress == 100){
activity.setTitle(R.string.app_name);
}
}
});
webview.loadUrl(PAGE_URL);
}
}
Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jaambhaari.jaambhaari"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:hardwareAccelerated="true"
android:theme="#style/AppTheme" >
<!-- Splash screen -->
<activity
android:name="com.jaambhaari.jaambhaari.SplashScreen"
android:label="#string/app_name"
android:screenOrientation="portrait"
android:scaleType="fitXY"
android:theme="#android:style/Theme.Black.NoTitleBar" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<data android:mimeType="application/*" />
<data android:mimeType="audio/*" />
<data android:mimeType="image/*" />
<data android:mimeType="message/*" />
<data android:mimeType="multipart/*" />
<data android:mimeType="text/*" />
<data android:mimeType="video/*" />
</intent-filter>
</activity>
<!-- Main activity -->
<activity
android:name="com.jaambhaari.jaambhaari.MainActivity"
android:label="#string/app_name" >
</activity>
</application>
</manifest>
Following are the texts I get in the console when i run it on android 4.4.2 :
Viewport target-densitydpi is not supported
FBIOGET_FSCREENINFO failed
Async pixel transfers not supported
The new webview is a mess. Lot many things are broken. I wanted to add this as a comment, but dont have enough reputation. You can go through this bug report (html video support)
https://code.google.com/p/chromium/issues/detail?id=239864
Problems are so severe, that developers are crying foul to get the old webview back
https://code.google.com/p/android/issues/detail?id=62293

Resources