OpenStreetMap is not showing anymore using OsmSharp and Mapsui - c#

I'm still fairly new to Visual Studio/Xamarin but I had a simple OpenStreetMap sample running awhile ago for Android that did display a map but that doesn't seem to display map anymore though I haven't changed the code for this sample in awhile as far as I recall. I'm not sure if some Visual Studio/Xamarin or MacOS update might have caused it to not work anymore.
I'm using Visual Studio for Mac community 8.4.4 (build 91) on macOS Mojava 10.14.6 and the following Packages:
Mapsui 1.4.8
OsmSharp 6.2.0
Xamarin.Android.Support.Core.Utils 28.0.0.1
Xamarin.Android.Support.CustomTabs 28.0.0.1
Xamarin.Android.Support.Design 28.0.0.1
Xamarin.Essentials 1.2.0
My MainActivity.cs file contains the following code:
using System;
using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using Mapsui;
using Mapsui.Geometries;
using Mapsui.Projection;
using Mapsui.Styles;
using Mapsui.Utilities;
using Mapsui.UI.Android;
using Mapsui.Widgets.ScaleBar;
using Mapsui.Widgets.Zoom;
using Xamarin.Essentials;
namespace mvp_android
{
[Activity(Label = "#string/app_name", Theme = "#style/AppTheme.NoActionBar", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.Main);
var mapControl = FindViewById<MapControl>(Resource.Id.mapcontrol);
var map = new Mapsui.Map();
map.Layers.Add(OpenStreetMap.CreateTileLayer());
map.Widgets.Add(
new ZoomInOutWidget(map) {
HorizontalAlignment = Mapsui.Widgets.HorizontalAlignment.Left,
VerticalAlignment = Mapsui.Widgets.VerticalAlignment.Top,
Orientation = Mapsui.Widgets.Zoom.Orientation.Horizontal,
}
);
var centerOfLondonOntario = new Point(-81.2497, 42.9837);
map.NavigateTo(SphericalMercator.FromLonLat(centerOfLondonOntario.X, centerOfLondonOntario.Y));
map.NavigateTo(map.Resolutions[9]);
mapControl.Map = map;
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.menu_main, menu);
return true;
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
int id = item.ItemId;
if (id == Resource.Id.action_settings)
{
return true;
}
return base.OnOptionsItemSelected(item);
}
private void FabOnClick(object sender, EventArgs eventArgs)
{
View view = (View)sender;
Snackbar.Make(view, "Replace with your own action", Snackbar.LengthLong)
.SetAction("Action", (Android.Views.View.IOnClickListener)null).Show();
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
And my Main.xml contains the following code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<Mapsui.UI.Android.MapControl
android:id="#+id/mapcontrol"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
Originally, this sample showed the OpenStreetMap's map centering on the London, Ontario location with zoom in/out buttons, but now it just shows a white where the map should be, still shows the zoom in/out buttons and does display the (c)OpenStreetMap watermark.
What am I missing here?

Update 2021-03-23: Since last week the "BruTile Tile Library" user agent is blocked by OpenStreetMap. This is the default of BruTile's KnownTileSource.Create. This method has a parameter to pass in your own user agent. The fix is to provide a string that is specific to your app.
The version of BruTile used in Mapsui 1.4.8 did not send the user-agent as part of it's request and at some point the openstreetmap server started blocking requests for this reason.
As a workaround you could create a custom ITileSource as described here by Matt Schneeberger:
https://github.com/Mapsui/Mapsui/issues/668#issuecomment-497947690

Related

Switching between "Tabs" (via bottom navigation) - flickering, any advice?

I am currently writing a Messenger app for my Guild, currently I got as far as, I can log in and switch between different tabs, that lists currently dummy message titles (like a whisper name).
My goal later is that once you click on one of the messages you can reply / read messages in WhatsApp style (tips welcome here as well).
But my current issue is that I use the "Bottom" navigation menu. I swap the tabs currently with new activies. But whenever I click a button the screen "flickers" like, it's restarting the whole app.
Is there some way to switch "fluid" the upper part of the app, while the menu always stays nicely at the bottom?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Views;
using Android.Widget;
namespace GuildMaster
{
[Activity(Label = "Whisper")]
public class Whisper : Activity, BottomNavigationView.IOnNavigationItemSelectedListener
{
private ListView whisperlist;
private List<string> itemlist;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_main);
BottomNavigationView navigation = FindViewById<BottomNavigationView>(Resource.Id.navigation);
navigation.SetOnNavigationItemSelectedListener(this);
whisperlist = FindViewById<ListView>(Resource.Id.whisper);
itemlist = new List<string>();
itemlist.Add("Tim");
itemlist.Add("Tom");
ArrayAdapter<string> whisper = new ArrayAdapter<string>(this, Android.Resource.Layout.SimpleListItem1, itemlist);
whisperlist.Adapter = whisper;
whisperlist.ItemClick += Listnames_ItemClick;
// Create your application here
}
public void Listnames_ItemClick(object sender, AdapterView.ItemClickEventArgs e)
{
Toast.MakeText(this, e.Position.ToString(), ToastLength.Long).Show();
}
public bool OnNavigationItemSelected(IMenuItem item)
{
switch (item.ItemId)
{
case Resource.Id.navigation_home:
StartActivity(typeof(Whisper));
return true;
case Resource.Id.navigation_dashboard:
StartActivity(typeof(Guild));
return true;
case Resource.Id.navigation_notifications:
StartActivity(typeof(Other));
return true;
}
return false;
}
}
}
you should try working with fragments instead of activities with the bottom navigation, working with an activity means u have to start a completely new screen with a new bottom navigation, if that is what you are doing then it is completely normal to "flicker" when doing so
as a solution, use an activity with an xml that holds a fragment view and a bottom navigation view, and when u switch from the bottom navigation in your activity, switch the fragments loaded within the fragment view.
this can be done with different methods, but i would suggest checking out the Navigation Component from Google, since it will also handle the backstack for you.

How to send a photo to the drawable folder after take the photo on Xamarin Android?

I'd create a xamarin android project on visual studio who take a photo from the camera, but I have a problem, I can take the photo but I don't know how I can make to the project after take the photo send the photo to the drawable folder of the project, how can I make this?
The XAML Code
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:weightSum="10">
<ImageView
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:background="#c1cdcd"
android:layout_weight="9"
android:id="#+id/imgvw1" />
<Button
android:text="Take a Photo"
android:layout_weight="1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/btnCamera" />
</LinearLayout>
The MainAcivity
using Android.App;
using Android.Widget;
using Android.OS;
using Android.Content;
using Android.Provider;
using Android.Runtime;
using Android.Graphics;
using System;
namespace Droid_Camera
{
[Activity(Label = "Droid_Camera", MainLauncher = true, Icon =
"#drawable/icon")]
public class MainActivity : Activity
{
ImageView imgView1;
Button btnCamera;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
btnCamera = FindViewById<Button>(Resource.Id.btnCamera);
imgView1 = FindViewById<ImageView>(Resource.Id.imgvw1);
btnCamera.Click += BtnCamera_Click;
}
protected override void OnActivityResult(int requestCode,
[GeneratedEnum] Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
Bitmap bitmap = (Bitmap)data.Extras.Get("data");
imgView1.SetImageBitmap(bitmap);
}
private void BtnCamera_Click(object sender, System.EventArgs e)
{
Intent intent = new Intent(MediaStore.ActionImageCapture);
StartActivityForResult(intent, 0);
}
}
You can't do this unfortunately, the Drawables folder is a compile time resource that you cannot add to in run time. Otherwise, the R.java file would not be valid.
As the comments and answers mentioned you cannot add a file at runtime to your Drawable. As a matter of fact you cannot add any file to the bundle itself in runtime.
What you can do is add your file to the filesystem. If you want the file to be 'visible' only to your app use getFilesDir(). This returns a folder path present in your application sandbox. If it's meant to be a sort of temporary file and is less than 1MB use getCacheDir()
If the file is meant to be publicly visible use getExternalStoragePublicDirectory() but for this you would need WRITE_EXTERNAL_STORAGE permission.
Check out the documentation for details

Return data from DialogFragment to calling activity

I have a DialogFragment that is working and need to return the selected item from a spinner. I've tried many methods that I've found on Stack Overflow and other places but they are all using java which doesn't (apparently) translate well to c# in Xamarin for Visual Studio 2017. To date, nothing has worked My DialogFragment layout is:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:minWidth="300dp"
android:minHeight="75dp">
<TextView
android:text="Select the department you are registering for."
android:textAppearance="?android:attr/textAppearanceMedium"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:textStyle="bold"
android:id="#+id/textView2" />
<Spinner
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
android:id="#+id/department_spinner" />
<Button
android:text="Ok"
android:layout_width="200px"
android:layout_gravity="center"
android:layout_height="34.5dp"
android:id="#+id/button_ok" />
</LinearLayout>
The class code is:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
namespace MyProject
{
class selectDepartment : DialogFragment
{
static Spinner department;
public string selection = "";
public override View OnCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState)
{
base.OnCreateView(inflater, container, savedInstanceState);
View view = inflater.Inflate(Resource.Layout.selectDepartment, container, false);
Button ok = view.FindViewById<Button>(Resource.Id.button_ok);
department = view.FindViewById<Spinner>(Resource.Id.department_spinner);
List<string> list = new List<string>();
list.Add("Select Department");
list.Add("Dept. A");
list.Add("Dept. B");
var adapter = new ArrayAdapter<string>(this.Activity, Android.Resource.Layout.SimpleSpinnerItem, list.ToArray());
department.Adapter = adapter;
ok.Click += (sender, args) =>
{
selection = string.Format("{0}", department.GetItemAtPosition(department.SelectedItemPosition));
};
return view;
}
}
}
This is the code that shows the dialog:
FragmentTransaction getdepartment = FragmentManager.BeginTransaction();
selectDepartment getDept = new selectDepartment();
getDept.Show(getdepartment , "Select Department");
// Here I attempt to read a property which contains the selection
string selection = getDept.selection;
In my last attempt, I assigned the spinner selection to a property and I attempt to read that property to get the value selected, but the dialog is (apparently) displayed on a different thread and the selection isn't chosen when that line of code is executed. I tried making my method async and await the dialog, but that just made matters worse. What am I missing?
use a custom event
public class DialogEventArgs : EventArgs
{
public string Selection { get; set; }
}
and then in selectDepartment add:
public delegate void DialogEventHandler(object sender, DialogEventArgs args);
public event DialogEventHandler Dismissed;
Finally in the button's click handler add:
if (null != Dismissed)
Dismissed(this, new DialogEventArgs { Selection = selection });
when you create the dialog, attach an event handler
selectDepartment getDept = new selectDepartment();
getDept.Dismissed += (s, e) => { /* do something with e.Selection here */ };

How to remove (Android) app title bar in Xamarin.Forms?

Is there any chance that I can remove the title bar of the app in Xamarin.Forms? I am working on a Xamarin.Forms Portable project. I tried a lot of solutions, but neither worked, I couldn't even start the app.
First attempt I tried adding this to my AndroidManifest.xml, didn't work:
android:theme="#android:style/Theme.NoTitleBar"
Second attempt I tried creating a styles.xml in Resources/values, which was:
<?xml version="1.0" encoding="utf-8" ?>
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<style name="Theme.Default" parent="#android:style/Theme"></style>
<style name="Theme.NoTitle" parent="#android:style/Theme.NoTitleBar"></style>
<style name="Theme.FullScreen" parent="#android:style/Theme.NoTitleBar.Fullscreen"></style>
</resources>
And then I added this to my AndroidManifest.xml (didn't work either)
android:theme="#style/Theme.NoTitle"
Third attempt I tried adding this to my OnCreate method in MainActivity.cs (didn't work).
RequestWindowFeature(WindowFeatures.NoTitle);
Can anyone help me with this?
If you want to remove the title bar on the initial page, the quickest and easiest way to do it is to go to to the contentpage heading in your XAML for the page and type
NavigationPage.HasNavigationBar="False"
so the XAML would like something like this
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="YourClass.YourPage"
NavigationPage.HasNavigationBar="False">
This can be done in PCL:
var page = new LoginPage();
NavigationPage.SetHasNavigationBar(page, false); // call this method every time before you push a page (no title bar)
await navigation.PushAsync(page);
If you are using old FormsApplicationActivity,
try, add this in OnCreate(Bundle bundle) method
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle)
Forms.SetTitleBarVisibility(AndroidTitleBarVisibility.Never);
Forms.Init(this, bundle);
}
This one seems do the app wide setting, but I am not so sure, as I don't use FormsApplicationActivity anymore.
Using the latest version of Xamarin.Forms I found that if you use:
await Navigation.PushAsync(new NextPage())
//Title on NextPage is displayed
await Navigation.PushModalAsync(new NextPage())
//Title on NextPage is not displayed
Nathan
i had this problem before and my solution was adding this line of code to the MainPage.xaml NavigationPage.HasNavigationBar="False"
<?xml version="1.0" encoding="utf-8" ?>
<xf:BottomBarPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:xf="clr-namespace:BottomBar.XamarinForms;assembly=BottomBar.XamarinForms"
xmlns:local="clr-namespace:App;assembly=App"
NavigationPage.HasNavigationBar="False" <-- This line !-->
x:Class="App.MainPage">
and it worked for me !
Theme = "#android:style/Theme.NoTitleBar"
.
using Android.App;
using Android.OS;
using Android.Webkit;
using Android.Views; // Webkit required for WebView
namespace LoadWebPage {
[Activity(Label = "LoadWebPage", MainLauncher = true, Icon = "#drawable/icon", Theme = "#android:style/Theme.NoTitleBar")]
public class Activity1 : Activity {
protected override void OnCreate (Bundle bundle)
For iOS this single line (e.g. in the constructor of the page) works just fine.
NavigationPage.SetHasNavigationBar(page, false);
But Android is ignoring it, also when put in the XAML of the page.
As mentioned above by Bonelol this method has to be called each time before you push a page.
I use Prism, so I can't access the creation and push of a page.
So I just created a custom renderer for NavigationPage and put this line there. Maybe this will help someone else.
[assembly: ExportRenderer(typeof(NavigationPage), typeof(CustomNavigationRenderer))]
namespace MyApp.Droid.Renderer
{
public class CustomNavigationRenderer : NavigationPageRenderer
{
public CustomNavigationRenderer(Context context) : base(context)
{
}
protected override Task<bool> OnPushAsync(Page view, bool animated)
{
NavigationPage.SetHasNavigationBar(view, false);
return base.OnPushAsync(view, animated);
}
}
}
Try This:
private ActionBar ab;
protected override void OnCreate(Bundle savedInstanceState)
{
try
{
base.OnCreate(savedInstanceState);
ab = this.ActionBar;
ab.Hide();
}
catch (Exception ex)
{
}
}
Try this one, just found it in one of view xaml in flyout tab
Shell.NavBarIsVisible="False"
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="YourClass.Views.YourPage" Shell.NavBarIsVisible="False">

Xamarin.Forms Search Widget is not showing

I tried to use Search Widget in my Xamarin.Forms project as people doing it in Xamarin.Android but it is not working. I want the same result as you see on image below.enter image description here
Here is my code:
**Main Activity :**
using System;
using Android.App;
using Android.Content.PM;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using Android.OS;
using Android.Support.V4.View;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using Android.Support.V4.App;
using Android.Support.V4.Widget;
using Android.Util;
using Android.Support.V4.Content;
namespace GitRemote.Droid
{
[Activity(Label = "GitRemote", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : FormsAppCompatActivity
{
protected override void OnCreate(Bundle bundle)
{
FormsAppCompatActivity.ToolbarResource = Resource.Layout.toolbar;
FormsAppCompatActivity.TabLayoutResource = Resource.Layout.tabs;
base.OnCreate(bundle);
Forms.Init(this, bundle);
LoadApplication(new App());
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
Android.Widget.SearchView searchView;
MenuInflater.Inflate(Resource.Menu.menu_home, menu);
var searchItem = menu.FindItem(Resource.Id.action_search);
var provider = MenuItemCompat.GetActionView(searchItem);
searchView = provider.JavaCast<Android.Widget.SearchView>();
// searchView.SetIconifiedByDefault(false);
searchView.QueryTextSubmit += (sender, args) =>
{
Toast.MakeText(this, "You searched: " + args.Query, ToastLength.Short).Show();
};
//searchView.QueryTextSubmit += (sender, args) =>
//{
// var view = sender as Android.Support.V7.Widget.SearchView;
// if ( view != null )
// view.ClearFocus();
//};
//return base.OnCreateOptionsMenu(menu);
return true;
}
}
}
**menu_home:**
<?xml version="1.0" encoding="utf-8" ?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="#+id/action_search"
android:title="#string/search"
android:icon="#android:drawable/ic_menu_search"
app:showAsAction="always|withText"
app:actionViewClass="android.widget.SearchView"/>
</menu>
I had the same problem with a Xamarin.Forms Search Component.
Xamrin.Forms has a control that is called: SearchBar. Indeed... on the Emulator is shown but when you install the application on an android device(eg. Samsung S8) the SearchBar is not Visible.
I can sugest a workaround:
Set the Height of the searchbar manually. 42 is the default for SearchBar.
HeightRequest="42"
The issue was addressed here
https://bugzilla.xamarin.com/show_bug.cgi?id=43975

Categories