I am currently developing an Android application using Cordova. This working fine so far, but now that I want to add a Chromecast button to the UI, it does not seem to work. I followed the instructions provided here: https://developers.google.com/cast/docs/chrome_sender/integrate
And this is what my code looks so far:
var CastPlayer = function() {
//...
/* Cast player variables */
/** #type {cast.framework.RemotePlayer} */
this.remotePlayer = null;
/** #type {cast.framework.RemotePlayerController} */
this.remotePlayerController = null;
//...
};
var castPlayer = new CastPlayer();
window['__onGCastApiAvailable'] = function(isAvailable) {
if (isAvailable) {
castPlayer.initializeCastPlayer();
}
};
Inline script inside my index.html.
CastPlayer.prototype.initializeCastPlayer = function() {
var options = {};
// Set the receiver application ID to your own (created in the
// Google Cast Developer Console), or optionally
// use the chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID
options.receiverApplicationId = chrome.cast.media.DEFAULT_MEDIA_RECEIVER_APP_ID;
// Auto join policy can be one of the following three:
// ORIGIN_SCOPED - Auto connect from same appId and page origin
// TAB_AND_ORIGIN_SCOPED - Auto connect from same appId, page origin, and tab
// PAGE_SCOPED - No auto connect
options.autoJoinPolicy = chrome.cast.AutoJoinPolicy.ORIGIN_SCOPED;
cast.framework.CastContext.getInstance().setOptions(options);
this.remotePlayer = new cast.framework.RemotePlayer();
this.remotePlayerController = new cast.framework.RemotePlayerController(this.remotePlayer);
this.remotePlayerController.addEventListener(
cast.framework.RemotePlayerEventType.IS_CONNECTED_CHANGED,
this.switchPlayer.bind(this)
);
};
Content of my index.js.
In the index.html, I added the button like this:
<google-cast-launcher id="castbutton"></google-cast-launcher>
Now when I open my Cordova app via browser (Chrome AND Chromium), the cast button shows and I can use it normally. When I open the App on Android, the Button just does not show. Does anybody know what causes this and if it can be resolved?
We could not find a solution for Cordova, but managed it in Flutter.
We had the same challenge, and we searched high and low. Finally found this solution to make it work with: https://pub.dev/packages/dart_chromecast
Make sure your flutter compiler is downgraded to 13 or below. Otherwise, you will not be able to compile. Unfortunately, their code is not supported in a newer version of the flutter compiler and the author is not going to update anytime soon.
Related
I'm trying to authenticate an end-user in an android app written in C# (Xamarin.Android).
I decided to try and use NuGet package Google.Apis.Oauth.v2 which seems to expose an easy to use Oauth client.
LocalServerCodeReceiver.ReceiveCodeAsync throws the following:
I get System.NotSupportedException:"Failed to launch browser with https://XXX.auth.XXX.amazoncognito.com/login?response_type=token&client_id=XXX&redirect_uri=https%3A%2F%2Fwww.google.com&scope=profile%20openid%20email for authorization. See inner exception for details."
and it has an inner exception of System.ComponentModel.Win32Exception:"Cannot find the specified file"
Code:
var clientSecret = new Google.Apis.Auth.OAuth2.ClientSecrets();
clientSecret.ClientId = ...
clientSecret.ClientSecret = ...
var initializer = new Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow.Initializer(
"https://XXX.auth.XXX.amazoncognito.com/login",
"https://XXX.auth.XXX.amazoncognito.com/login");
initializer.Scopes = new List<string> {"profile", "openid", "email"};
initializer.ClientSecrets = clientSecret;
var flow = new Google.Apis.Auth.OAuth2.Flows.AuthorizationCodeFlow(initializer);
var authCodeRequestURL = flow.CreateAuthorizationCodeRequest("https://www.google.com");
authCodeRequestURL.ResponseType = "token";
var uri = authCodeRequestURL.Build();
var cancellationTokenSource = new System.Threading.CancellationTokenSource();
var codeReceiver = new Google.Apis.Auth.OAuth2.LocalServerCodeReceiver();
var task = codeReceiver.ReceiveCodeAsync(authCodeRequestURL, cancellationTokenSource.Token);
Do I need to ask for a specific permission in the application manifest?
Instead of redirecting to www.google.com, I've heard you can redirect to an app, I'm not really sure how to do that, is it http://my_app_package_name or http://my_app_title, something else?
Is it possible not to rely on that library for launching the browser and instead get the RequestUri and start an Activity, if so how will the app become aware the end-user completed the SignIn process and how will the app retrieve the token?
Sorry, but Google.Apis.Oauth.v2 does not support Xamarin, and there's no simple way to get it working.
Unfortunately no Google.Apis.* packages currently support Xamarin.
You might find the Xamarin.Auth package does what you want?
I've figured out how to redirect to an app after authentication in the browser completes.
It's called a "Deep Link" and it's documented at enter link description here, essentially you need to declare an IntentFilter on your Activity, which registers with the Android OS that if someone clicks or an page redirects to a specific URI, your app gets called. The token that's appended to the URI can then be read inside your app.
I have a Xamarin.Android project where I want to use Xamarin.Auth package to let user authenticate through Google sign-in page.
Here is my code at MainActivity.cs
OAuth2Authenticator auth = new OAuth2Authenticator
(
clientId: "client-id.apps.googleusercontent.com",
scope: "",
authorizeUrl: new Uri("https://accounts.google.com/o/oauth2/v2/auth"),
redirectUrl: new Uri("http://www.facebook.com/connect/login_success.html"),
// switch for new Native UI API
// true = Android Custom Tabs and/or iOS Safari View Controller
// false = Embedded Browsers used (Android WebView, iOS UIWebView)
// default = false (not using NEW native UI)
isUsingNativeUI: false
);
auth.Completed += (sender, eventArgs) =>
{
// UI presented, so it's up to us to dimiss it on Android
// dismiss Activity with WebView or CustomTabs
this.Finish();
if (eventArgs.IsAuthenticated)
{
// Use eventArgs.Account to do wonderful things
}
else
{
// The user cancelled
}
};
var ui_object = auth.GetUI(this);
StartActivity(ui_object);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.Main);
I allways ends up with folowing exception when calling auth.GetUI(this) method:
JNIEnv.FindClass(Type) caught unexpected exception: Java.Lang.ClassNotFoundException: md53c585be971e02235139fd1aef11fc0c1.WebAuthenticatorActivity ---> Java.Lang.ClassNotFoundException: Didn't find class "md53c585be971e02235139fd1aef11fc0c1.WebAuthenticatorActivity"
Can anyone see why it would do this? I've tried to google it but looks like I'm only one who gets this type of error.
I have VS 2017 15.5.2 and using Android 8.0 API 26
Solved! I remove/add my nuget packages to Xamarin.Auth and PCLCrypto and everything is working now. Google sign-in page is displayed when app starts.
I have three buttons on my website, that link to Facebook, Twitter & vk.com pages. I want to open native app, if it is installed on user device. Otherwise, I want URL fallback to be opened.
First of all, I tried to use native app schemes directly with deep-link.js plugin. But, when I tried to open native app URL scheme, when native app was not installed, Safari has shown an error, but opened URL fallback page finally. Default Android browser said that he does not know how to handle such URL scheme:
<a class="btn btn-primary" href="https://www.facebook.com/warpcompany" data-app-ios="fb://profile/838619192839881" data-app-android="fb://page/838619192839881">Facebook</a>
Then I tried to use App Links "standard", that that has so much promotion from Facebook. I even tried to use their hosted app links, to make sure I've generated everything right way. It does not work, it always redirect to website fallback. You can easily test it by yourself from https://fb.me/746134728830806
Is it possible to provide deep link on website, that will open native app without errors at least in default os browsers, or fallback silently to URL?
It is still possible, but on newer versions of the Android default browser you have to use intents instead of just trying to open the deep link. For example replace your fb://page/838619192839881 with
intent://page/838619192839881#Intent;scheme=fb;package=com.facebook.katana;end
This will fallback to Google play by default, but you can override the fallback adding a S.browser_fallback_url:
intent://page/838619192839881#Intent;scheme=fb;package=com.facebook.katana;S.browser_fallback_url=http%3A%2F%2Fwww.facebook.com%2F;end
The fallback should be url encoded.
Of course you'll have issues if the user is not on an Android phone or with an old version of the default browser (or strange browser). You can setup a bunch of conditions and replace your HTML with the correct code for each case.
The accepted answer will only work on Chrome v28 and default browsers for Android 5.0. If you want this to work on other browser like Facebook/Twitter webviews, Firefox, UC and older default browsers than 5.0, you'll need to use some code that's a little more complicated.
Add this function to your JS snippet:
var openSesame = function() {
var method = 'iframe';
var fallbackFunction = function() {
if (method == 'iframe') {
window.location = "market://details?id=com.facebook.katana";
}
};
var addIFrame = function() {
var iframe = document.createElement("iframe");
iframe.style.border = "none";
iframe.style.width = "1px";
iframe.style.height = "1px";
iframe.src = "fb://page/838619192839881";
document.body.appendChild(iframe);
};
var loadChromeIntent = function() {
method = 'intent';
document.location = "intent://page/838619192839881#Intent;scheme=fb;package=com.facebook.katana;end";
};
if (navigator.userAgent.match(/Chrome/) && !navigator.userAgent.match("Version/")) {
loadChromeIntent();
}
else if (navigator.userAgent.match(/Firefox/)) {
window.location = "fb://page/838619192839881";
}
else {
addIFrame();
}
setTimeout(fallbackFunction, 750);
};
Then your button will look like this:
Open the App
Or you can use a service like branch.io which does exactly what you're looking for automatically.
Yes it is! Have a look to this training:
https://developer.android.com/training/app-indexing/deep-linking.html
Is this the information you needed? lmk
I'm using the Google analytics plugin for MvvmCross with the following namespace:-
OCS.MvvmCross.Plugins.MvxAnalytics
https://www.nuget.org/packages/OCS.MvvmCross.Plugins.MvxAnalytics
There isn't any documentation on how to use/implement it, from my discovery, the AnalyticsConfiguration needs to be defined, then added to the DroidAnalyticsService.Configuration.
Inside the AnalyticsConfiguration, there is TrackingId, which I understand, log levels and whether to report UncaughtExceptions (set to true)
The PluginBootstrap file is included which is great, but joining the last dots are a bit of a headscratch.
Any ideas how to get this working? I've messaged the creators so if they email me back, I'll post the details here.
Thanks in Advance.
I was able to set it up and it seems that it's working properly.
You have to setup all properties inside Configuration object and then it works.
var analyticsService = new DroidAnalyticsService();
analyticsService.Configuration.AppName = "Your app name";
analyticsService.Configuration.AnonymizeIp = true;
analyticsService.Configuration.AppVersion = "App version fro xml";
analyticsService.Configuration.TrackingId = "Tracking id from google";
analyticsService.Configuration.DispatchPeriod = 30;
analyticsService.Configuration.ReportUncaughtExceptions = true;
Is there a way to open one app from another app in Air? Example: I open app A which contains a button that opens app B when clicked. Suppose both A and B are separated apps that are installed in the device and that this device could be a PlayBook, an Ipad or an Android tablet.
Thanks.
You'd have to go the Air Native Extension(ANE) route. Either create one ANE solution for iOS and Android each, or one ANE that abtracts the functionality into one solution. How to launch app A from app B on Android is not the same as on iOS. See this answer in SO.
To implement it on Android, you'd wraps the native Android Java solution in a ANE. The native Java code uses the package name of app B to launch app B from app A:
Intent intent = getPackageManager().getLaunchIntentForPackage("com.yourdoman.yourapp");
startActivity(intent);
Here is a video tutorial on how to launch an Activity through an ANE which you can build on to create your ANE. You'd have to tailor the solution to launch by domain instead of Activity.
Since I really don't know the specifics of what you are trying to do, I think I should point you here: http://www.riaspace.com/2011/08/defining-custom-url-schemes-for-your-air-mobile-applications/ It is the best answer to the question that I am aware of.
private function getHostName() : void
{
if (NativeProcess.isSupported)
{
var OS : String = Capabilities.os.toLocaleLowerCase();
var file : File;
if (OS.indexOf('win') > -1)
{
// Executable in windows
file = new File('C:\\Windows\\System32\\hostname.exe');
}
else if (OS.indexOf('mac') > -1 )
{
// Executable in mac
}
else if (OS.indexOf('linux'))
{
// Executable in linux
}
var nativeProcessStartupInfo : NativeProcessStartupInfo = new NativeProcessStartupInfo();
nativeProcessStartupInfo.executable = file;
var process : NativeProcess = new NativeProcess();
process.addEventListener(NativeProcessExitEvent.EXIT, onExitError);
process.addEventListener(ProgressEvent.STANDARD_OUTPUT_DATA, onOutput);
process.start(nativeProcessStartupInfo);
process.closeInput();
}
}
private function onOutput(event : ProgressEvent) : void
{
var strHelper : StringHelper = new StringHelper();
formStationID.text = event.target.standardOutput.readUTFBytes(event.target.standardOutput.bytesAvailable);
formStationID.text = strHelper.trimBack(formStationID.text, "\n");
formStationID.text = strHelper.trimBack(formStationID.text, "\r");
}
This code gets the workstation name. I have heard this can be done on IOS and Android, but I haven't found any proof of that yet.