EDIT: It is now clear that the problem is not the the app, but the webpage. A problem that so far only has been spotted in a android-4.4.2-webview.
I have WebViews with a custom WebChromeClient. When something wants to go full screen on a 4.2.2 or 4.3 device the custom WebChromeClient's onShowCustomView is invoked. However with 4.4.2 (specifically I've checked on the devices Nexus 7 and Galaxy S4) it has worked with HTML 5 videos, but flash video plugins trying to go full screen does not invoke onShowCustomView. Other than that the flash video plugins work fine.
I have checked that the WebChromeClient is being added on a 4.4.2 device and it is.
public final WebChromeClient fullscreenWebChromeClient = new WebChromeClient() {
private View fullscreen = null;
private WebChromeClient.CustomViewCallback fullscreenCallback;
#Override
public void onShowCustomView(View view, CustomViewCallback callback) {
super.onShowCustomView(view, callback);
fullscreenCallback = callback;
if (fullscreenMode) {
fullscreenCallback.onCustomViewHidden();
return;
}
fullscreen = view;
fullscreenMode = true;
pager.setVisibility(View.GONE);
actionbarGestureDetector.setVisibility(View.GONE);
pageViewWrapper.addView(fullscreen);
}
#Override
public void onHideCustomView() {
super.onHideCustomView();
if (! fullscreenMode) {
return;
}
pageViewWrapper.removeView(fullscreen);
pager.setVisibility(View.VISIBLE);
actionbarGestureDetector.setVisibility(View.VISIBLE);
fullscreenCallback.onCustomViewHidden();
fullscreen = null;
fullscreenMode = false;
}
};
Somewhere else:
pageWebView.setWebChromeClient(parentActivity.fullscreenWebChromeClient);
Related
I want to run some code while the splash screen is shown in a MAUI application. The official documentation has only instruction about the image (so far).
I assume I need to do a solution for each platform. I have tried to follow the instruction for Xamarin on Android and getting pretty close. I have created this Activity:
[Activity(Theme = "#style/MyTheme.Splash", MainLauncher = true, NoHistory = true)]
public class SplashActivity : MauiAppCompatActivity
{
static readonly string TAG = "X:" + typeof(SplashActivity).Name;
public override void OnCreate(Bundle savedInstanceState, PersistableBundle persistentState)
{
base.OnCreate(savedInstanceState, persistentState);
Log.Debug(TAG, "SplashActivity.OnCreate");
}
// Launches the startup task
protected override void OnResume()
{
base.OnResume();
Task startupWork = new Task(() => { SimulateStartup(); });
startupWork.Start();
}
// Simulates background work that happens behind the splash screen
async void SimulateStartup ()
{
Log.Debug(TAG, "Performing some startup work that takes a bit of time.");
await Task.Delay (3000); // Simulate a bit of startup work.
Log.Debug(TAG, "Startup work is finished - starting MainActivity.");
//StartActivity(new Intent(MainApplication.Context, typeof (MainActivity)));
}
}
My problem is that when SimulateStartup starts to run the UI is launching, despite MainActivity is never created.
In then end of MauiProgram.CreateMauiApp() I have added this:
var app = builder.Build();
Task.Run(async () =>
{
await Task.Delay(4000);
var bootstrap = app.Services.GetRequiredService<MyBootstrapService>();
await bootstrap.SetupAsync();
}).Wait();
return app;
It works on Android. In Windows there are no splash screen, so user will se nothing until the bootstrapping is ready.
I need to check current version of Installed Application. If it is not same app should navigate to app page in app store.
I am using latest version plugin for this. Its working fine with Android but not with iOS
Setings.appVersion = await CrossLatestVersion.Current.GetLatestVersionNumber();
if (Setings.appVersion == "1.0.1")
{
MainPage = new NavigationPage(new Login());
}
else
{
//lblBuildNumber.Text = DependencyService.Get<IAppVersionAndBuild>().GetBuildNumber();
MainPage = new NavigationPage(new UpdateAppPopup());
}
async void Handle_Clicked(object sender, System.EventArgs e)
{
await CrossLatestVersion.Current.OpenAppInStore("com.KIH.Consultant");
}
with this code it should navigate to app page in app store or playstore
its wokring with fine with playstore, but not working in appstore(ios)
1) Create One Interface Inside Your Main Project
public interface IAppService
{
string GetVersion();
}
2) Then Implement it inside your droid project
public class AppService : IAppService
{
public string GetVersion() {
var context = Android.App.Application.Context;
var info = context.PackageManager.GetPackageInfo(context.PackageName,
Android.Content.PM.PackageInfoFlags.MatchAll);
return info.VersionName;
}
3) Then Implement it inside your ios project
public class AppService : IAppService
{
public string GetVersion()
{
return NSBundle.MainBundle.InfoDictionary["CFBundleShortVersionString"].ToString();
}
}
4) Now you can use it like this
string v = Get<IAppService>().GetVersion();
use Xamarin.Essentials to get the current version string and version code for the app.
// Application Version (1.0.0)
var version = AppInfo.VersionString;
// Application Build Number (1)
var build = AppInfo.BuildString;
I have a Xamarin.Forms app and I am using FreshMvvm framework.
If I do this from ViewIsAppearing method of FirstPageModel:
CoreMethods.PushPageModel<SecondPageModel>();
I go the "SecondPageModel". Then, when I am in the "SecondPageModel" if I do:
CoreMethods.PopPageModel();
or press hard back button, or press title bar back button not works in Android (anything happens). I am using FreshMasterDetailNavigationContainer.
In iOS it works OK, I get back to FirstPageModel.
This is because ViewIsAppearing will always be called when the page starts displaying on the screen. When you pop the second page then go to the first page, the first page's ViewIsAppearing will fire again. It caused a dead cycle and prohibited your app from returning to the first page.
Add a property to avoid that:
bool isInitialized;
public FirstPageModel()
{
// ...
isInitialized = true;
}
protected async override void ViewIsAppearing(object sender, EventArgs e)
{
base.ViewIsAppearing(sender, e);
if (isInitialized)
{
await Task.Delay(100);
await CoreMethods.PushPageModel<SecondPageModel>();
isInitialized = false;
}
}
iOS may optimize this process, but I still recommend you to add this judgment statement.
Update:
Call it when your app has reached the main thread.
protected override void ViewIsAppearing(object sender, EventArgs e)
{
base.ViewIsAppearing(sender, e);
if (isInitialized)
{
Device.BeginInvokeOnMainThread(() =>
{
CoreMethods.PushPageModel<SecondPageModel>();
isInitialized = false;
});
}
}
I have in my ViewSwitcher a ListView and a WebView. In my ListView's adapter, I have an onclick listener that writes the clicked url in the list to sharedpreferences. I'm trying to load that url into the WebView using an onSharedPreferencesChangedListener.
This is the code in my adapter:
convertView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
viewSwitcher.showNext();
Settings.writeSettings(context, "webviewUrl",
urls.get(position));
}
});
return convertView;
And in the preference listener:
#Override
public void onSharedPreferenceChanged(SharedPreferences pref, String key) {
if (key.equals("webviewUrl")) {
Log.d("TAG", pref.getString(key, null));
WebView wv = (WebView) findViewById(R.id.rss_webview);
wv.getSettings().setJavaScriptEnabled(true);
wv.setWebViewClient(new MyWebViewClient());
wv.loadUrl("about:blank");
wv.loadUrl(pref.getString(key, null));
}
}
This works great except it only works once. The preference listener code logs the correct urls, and the code executes each time I want it to, but wv.loadUrl() method seems to do nothing after the first successful call. Can anyone explain to me why this is happening and perhaps offer a solution? Thanks.
I solved the problem by implementing a static ViewHolder on the WebView whose reference I needed to keep longer than its views' lifecycle.
private static final class WebViewHolder {
WebView wv;
}
#Override
public void onSharedPreferenceChanged(SharedPreferences pref, String key) {
WebViewHolder holder = new WebViewHolder();
if (key.equals("webviewUrl")) {
if (wv == null) {
wv = new WebView(this);
holder.wv = (WebView) findViewById(R.id.rss_webview);
holder.wv.getSettings().setJavaScriptEnabled(true);
holder.wv.setWebViewClient(new MyWebViewClient());
wv.setTag(holder);
} else {
holder = (WebViewHolder) wv.getTag();
}
holder.wv.loadUrl("about:blank");
holder.wv.loadUrl(pref.getString(key, null));
}
}
My code seems to crash on Android with NullPointer exception. But works on ios simulator.
private void CallFBInit()
{
if(!FB.IsLoggedIn){
FB.Init(OnInitComplete, OnHideUnity);
}else{
shareDialog();
}
}
private void OnInitComplete()
{
FB.Login("email,publish_actions",fbLoginCallBack);
}
private void fbLoginCallBack(FBResult result){
shareDialog();
}
#region FB.Feed() example
public bool IncludeFeedProperties = false;
private Dictionary<string, string[]> FeedProperties = new Dictionary<string, string[]>();
private void CallFBFeed(FBResult result)
{
shareDialog();
}
private void shareDialog(){
Dictionary<string, string[]> feedProperties = null;
if (IncludeFeedProperties)
{
feedProperties = FeedProperties;
}
FB.Feed(
toId: FB.UserId,
link: ConfigCS.FeedLink,
linkName: ConfigCS.FeedLinkName,
linkCaption: ConfigCS.FeedLinkCaption,
linkDescription: ConfigCS.FeedLinkDescription,
picture:ConfigCS.FeedPicture,
mediaSource: ConfigCS.FeedMediaSource,
actionName: ConfigCS.FeedActionName,
actionLink: ConfigCS.FeedActionLink,
reference: ConfigCS.FeedReference,
properties: feedProperties,
callback: CallbackForFeed
);
}
#endregion
void CallbackForFeed(FBResult result)
{
if(result.Error!=null){
errorMessage=ConfigCS.fbError+result.Text;
showError=true;
return;
}else{
Debug.Log ("FB Feed error");
}
return;
}
private void OnHideUnity(bool isGameShown)
{
Debug.Log("Is game showing? " + isGameShown);
}
#endregion
I coul'dnt figure out why. When the login dialog is shown, and returns to the app, the app crashes. But if i try again, (since the user is considered logged in), it works without a hiccup. Can somebody see any error in my code?
edit:
To be more precise
1. when user clicks share, fb login dialog opens
2. Once the user successfully logs in, and returns the app, the app crashes with nullpointer exception
I open the app again, and click share (at this point the user is already logged in before the crash) and it works.
I coul'dnt pin point the error since adb log just says NullPointException in facebook.loginActivity.
My initiating function is CallFBInit();
Edit:
One more thing i have noticed is, i have installed facebook sdk 4.3.3 but it shows 4.2.5 in the console
and in the editor
This seems to be a problem with the new 4.3.3 SDK
I have downgraded to 4.2.4 and it works fine.
Is this a known problem?