How to configure android packagename within Maui android project? - c#

I have created a dummy maui app. I managed to get the package name with the following code after following App information
#page "/"
<h1>Hello, world!</h1>
Welcome to your new app.
<SurveyPrompt Title="How is Blazor working for you?" />
<ul>
<li>Name: #name</li>
<li>Package: #package</li>
<li>Version: #version</li>
<li>Build: #build</li>
</ul>
#code {
private string name = AppInfo.Current.Name;
private string package = AppInfo.Current.PackageName;
private string version = AppInfo.Current.VersionString;
private string build = AppInfo.Current.BuildString;
protected override async Task OnInitializedAsync()
{
}
}
As you can see from the following image this does work it displays my android application information. but ...
My question is how to configure this Package name shows as com.companyname.blazortest. I would like to be able to supply my company name
There is no appsettings.json file, its not in the AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true" android:icon="#mipmap/appicon" android:roundIcon="#mipmap/appicon_round" android:supportsRtl="true"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
</manifest>
Im a bit stumped as to where this is configured.

You can change it manually in your .csproj file
<!-- App Identifier -->
<ApplicationId>com.companyname.app.maui</ApplicationId>
or you can change it in project properties
or if you want to change it in android project only you can do it under Android section (it will change your manifest file)

Related

.net maui poject cannot archive/Publish due to app icon

Following the changes as directed in Microsoft documentation, I made changes to my project as thus.
Android Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application android:allowBackup="true"
android:icon="#mipmap/kigoo"
android:roundIcon="#mipmap/kigoo_round"
android:supportsRtl="true">
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<queries>
<intent>
<action android:name="android.intent.action.DIAL" />
<data android:scheme="tel"/>
</intent>
<intent>
<action android:name="android.intent.action.SENDTO" />
<data android:scheme="mailto" />
</intent>
</queries>
</manifest>
In the project.csprog
<!-- App Icon -->
<MauiIcon Include="Resources\AppIcon\appicon.svg"
ForegroundFile="Resources\AppIcon\kigoo.svg" ForegroundScale="0.65" Color="#512BD4"
/>
I can deploy to the emulator and physical devices fine but...
Trying to the archive on debug mode (Just to get the errors), fails and does not show any error.
archiving in the release mode throws the following errors:
1.
Severity Code Description Project File Line Suppression State
Error APT2260 resource mipmap/kigoo_round (aka com.companyname.kigoopcmauisimple:mipmap/kigoo_round) not found. This error is likely caused by an issue with the AndroidManifest.xml file or an Android manifest generation attribute in a
source code file. KigooPCMauiSimple C:\Users{path} 1
Severity Code Description Project File Line Suppression State
Error APT2260 resource mipmap/kigoo (aka com.companyname.kigoopcmauisimple:mipmap/kigoo) not found. This error is likely caused by an issue with the AndroidManifest.xml file or an Android manifest generation attribute in a source code file. KigooPCMauiSimple
C:\Users{path} 1
Severity Code Description Project File Line Suppression State
Error APT2067 failed processing manifest. KigooPCMauiSimple C:\Program Files\dotnet\packs\Microsoft.Android.Sdk.Windows\32.0.448\tools\Xamarin.Android.Aapt2.targets 212
Please advise, I appreciate it.
I have tested it. You may need to make the following changes in the project.csprog:
<MauiIcon Include="Resources\AppIcon\kigoo.svg"
ForegroundFile="Resources\AppIcon\appicon.svg" ForegroundScale="0.65"
Color="#512BD4"/>
This is because in your Android Manifest file , you have set it like this:
android: icon="#mipmap/kigoo"
So in your project.csprog file, behind MauiIcon.Include attribute, it should also be set accordingly like this:
<MauiIcon Include="Resources\AppIcon\kigoo.svg"/>

Xamarin forms app is requiring duplicate WRITE_EXTERNAL_STORAGE entries in AndroidManifest

I'm running into a very odd issue in my Xamarin Forms app. I am trying to take a picture in my app, then use OCR to read the text, but I'm struggling to get permissions to be granted for WRITE_EXTERNAL_STORAGE. I now have to declare WRITE_EXTERNAL_STORAGE twice in my AndroidManifest in order for the app to allow me to request storage permissions or to access storage, once as a self-closing tag and once with explicit tag:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
If either is removed (leaving just one version of WRITE_EXTERNAL_STORAGE), I get the following exception when trying to request permissions for external storage or when trying to capture a picture: "You need to declare using the permission: android.permission.WRITE_EXTERNAL_STORAGE in your AndroidManifest.xml"
This ONLY affects WRITE_EXTERNAL_STORAGE...all other declared permissions (using self-closing tags) in the manifest work appropriately. It's just the write storage permission that needs this "hack."
This issue occurs on emulated devices (debug mode) AND on physical devices (via Play Store alpha track) when only one instance of the permission is listed. When debugging with both lines in the manifest, the app is able to obtain permissions to storage successfully and I can take the picture as expected. The Play Store will not accept submissions with duplicate lines in the manifest, so I am unable to submit to the store using this "hack."
This is a full copy of my AndroidManifest (without PII), including the duplicate lines I have to include in order for storage permissions to be granted successfully when debugging:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="myapp" android:versionName="3.2.2" android:installLocation="auto" android:versionCode="59">
<application android:theme="#android:style/Theme.Material.Light" android:icon="#drawable/Icon120" android:label="MyApp">
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/file_paths"></meta-data>
</provider>
</application>
<uses-feature android:name="android.hardware.camera" android:required="true" />
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="29" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
</manifest>
I also have the following line in my AssemblyInfo.cs file:
[assembly: UsesPermission(Android.Manifest.Permission.WriteExternalStorage)]
When I try to request permissions via Xamarin.Essentials or to access the camera to tke a picture via Xamarin.Essentials or CrossMedia, the app blows up with the above exception, claiming I am missing the WRITE_EXTERNAL_STORAGE permission, despite it being in the manifest once (either self-closed or with explicit tag). Any of these lines executing will result in the exception and all lines work when both entries for WRITE_EXTERNAL_STORAGE are present:
var permissionStatus = await Xamarin.Essentials.Permissions.RequestAsync<Xamarin.Essentials.Permissions.StorageWrite>();
var photo = await Xamarin.Essentials.MediaPicker.CapturePhotoAsync(new Xamarin.Essentials.MediaPickerOptions { Title = DateTime.Now.ToString("G") + ".jpg" });
var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions { Name = DateTime.Now.ToString("G") + ".jpg" });
I have tried updating all of my NuGet packages and am now on the latest versions of frameworks for the app (Xamarin Forms v5 and Xamarin.Essentials 1.6.1) but this issue still persists. I also tried completely deleting the manifest and restarting from scratch, but the same "hack" is still needed.
Has anyone run into this or have any idea of how this can be fixed?
Thank you in advance!
To anyone who has this issue, the solution was to remove all references to and uninstall the NuGet package for HockeySDK.Xamarin. As soon as I removed everything related to this, the issue resolved itself and I no longer had the problem with the manifest

Is my Universal Windows Platform software able to gain the permission that is necessary for initiation of shutdown?

I am desiring addition to my Universal Windows Platform software the ability for it to shut-down its host machine after invocation of it by 1 button-click, however, 0 methods that I have tried thus far have operated:
I have attempted to instruct Windows to shut-down, but shutdown /s /t 120 is not able to operate, specifically after invocation by my application.
Therefore, I attempted uage of native C# code. However, usage of this has informed me that it has not been permitted to invoke shutdown:
ShutdownManager.BeginShutdown(Windows.System.ShutdownKind.Shutdown, TimeSpan.FromSeconds(120));
I have used many methods, but I am not able to remediate this problem.
Relevant files
MainPage.xaml.cs
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using System;
using Windows.System;
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409.
// Delete the extra namespaces when the application is complete.
namespace Shutdown_Roulette
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
}
private void Button_click(object sender, RoutedEventArgs e)
{
ShutdownManager.BeginShutdown(Windows.System.ShutdownKind.Shutdown, TimeSpan.FromSeconds(120));
}
}
}
Package.appxmanifest
<?xml version="1.0" encoding="utf-8"?>
<Package
xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10"
xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest"
xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10"
xmlns:iot="http://schemas.microsoft.com/appx/manifest/iot/windows10"
IgnorableNamespaces="uap mp iot">
<Identity
Name="7eb73f1e-b159-4fd0-aab9-4158e57ba08a"
Publisher="CN=rokeb"
Version="1.0.0.0" />
<mp:PhoneIdentity PhoneProductId="7eb73f1e-b159-4fd0-aab9-4158e57ba08a" PhonePublisherId="00000000-0000-0000-0000-000000000000"/>
<Properties>
<DisplayName>Shutdown Roulette</DisplayName>
<PublisherDisplayName>Master Roke Julian Lockhart Beedell</PublisherDisplayName>
<Logo>Assets\StoreLogo.png</Logo>
</Properties>
<Dependencies>
<TargetDeviceFamily Name="Windows.Universal" MinVersion="10.0.0.0" MaxVersionTested="10.0.0.0" />
</Dependencies>
<Resources>
<Resource Language="x-generate"/>
</Resources>
<Applications>
<Application Id="App"
Executable="$targetnametoken$.exe"
EntryPoint="Shutdown_Roulette.App">
<uap:VisualElements
DisplayName="Shutdown Roulette"
Square150x150Logo="Assets\Square150x150Logo.png"
Square44x44Logo="Assets\Square44x44Logo.png"
Description="Shutdown Roulette"
BackgroundColor="transparent">
<uap:DefaultTile Wide310x150Logo="Assets\Wide310x150Logo.png" ShortName="Shutdown Roulette">
</uap:DefaultTile >
<uap:SplashScreen Image="Assets\SplashScreen.png" />
</uap:VisualElements>
</Application>
</Applications>
<Capabilities>
<iot:Capability Name="systemManagement"/></Capabilities>
</Package>
Please do note that I am wanting to use this command on Windows 10, rather than Windows 10 IoT; I merely am attempting to use those commands because they are the only other way I have been able to conceive of invocation of this without reliance upon either PowerShell, Python or the Windows Command Processor.
According to the description of ShowdownManager, it needs the support of IOT SDK, which means it is a platform-limited API (only valid on IOT devices).
In Windows 10 desktop devices, UWP does not have the permission to turn off the device.

Xamarin Maps Crashing in Android Emulator

I'm having a bit of an issue with the Xamarin.Forms.Maps and the exceptions are not propagated up into the debugger in a meaningful way to help me diagnose the issue.
I can get it to work, everytime I reinstall Visual Studio. It will work a couple times then eventually it will crash 100% of the time as long as the Map item is in the xaml. I am not remaking the project between running, just reinstalling Visual Studio. I'm running Visual Studio 17 Community.
The error just says:
'Your app has entered a break state, but there is no code to show because all threads were executing external code (typically system or framework code).'
I have a valid API Key, and even if I comment out ALL code relating to the Map it eventually happens other than the Xaml that will create it. If I reinstall visual studio I can manipulate the map the first few times I invoke the debugger before it fails.
I wish I could give more information, but I'm pretty new to Xamarin development so I'm a bit unsure why reinstalling Visual Studio fixes the issue, temporarily. Any insight would be much appreciated, as I've spent many hours trying to diagnose and reinstall, but have no idea what the issue could be given the error doesn't really say much of anything. I'd love to provide more information if someone has more ideas for me to check out.
In general, it also fails to deploy eventually also : / which is why I tried an install originally. I'm not sure if this is related.
MainPage.xaml.cs
using System;
using System.Linq;
using System.Text;
using Xamarin.Forms;
using Plugin.Geolocator;
using System.Threading.Tasks;
using System.Collections.Generic;
using Plugin.Geolocator.Abstractions;
namespace LawnDroneCompanion
{
public partial class MainPage : ContentPage
{
private List<Position> RecordedPositions = new List<Position>();
public MainPage()
{
InitializeComponent();
}
private void StopGeoLocatorListening()
{
BeginTrackingRoute.Text = "Begin Tracking";
BeginTrackingRoute.BackgroundColor = Color.Green;
CrossGeolocator.Current.StopListeningAsync();
}
private async void StartGeoLocatorListening(object obj, EventArgs e)
{
if (CrossGeolocator.Current.IsListening)
{
StopGeoLocatorListening();
return;
}
BeginTrackingRoute.Text = "Stop Tracking";
BeginTrackingRoute.BackgroundColor = Color.Red;
CrossGeolocator.Current.DesiredAccuracy = 10;
///This logic will run on the background automatically on iOS, however for Android and UWP you must put logic in background services. Else if your app is killed the location updates will be killed.
await CrossGeolocator.Current.StartListeningAsync(TimeSpan.FromSeconds(1), 1, true, new Plugin.Geolocator.Abstractions.ListenerSettings
{
ActivityType = Plugin.Geolocator.Abstractions.ActivityType.Other,
AllowBackgroundUpdates = true,
DeferLocationUpdates = true,
DeferralDistanceMeters = 1,
DeferralTime = TimeSpan.FromSeconds(1),
ListenForSignificantChanges = true,
PauseLocationUpdatesAutomatically = false
});
Position StartLocation = await CrossGeolocator.Current.GetLastKnownLocationAsync();
//MyMap.MoveToRegion(Xamarin.Forms.Maps.MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(StartLocation.Latitude, StartLocation.Longitude), Xamarin.Forms.Maps.Distance.FromMiles(0.2)));
CrossGeolocator.Current.PositionChanged += GeoLocateHandler;
}
private void DrawNewLocation(Plugin.Geolocator.Abstractions.Position position)
{
if(RecordedPositions.Count > 1000)
{
return;
}
RecordedPositions.Add(position);
//MyMap.MoveToRegion(Xamarin.Forms.Maps.MapSpan.FromCenterAndRadius(new Xamarin.Forms.Maps.Position(position.Latitude, position.Longitude), MyMap.VisibleRegion.Radius));
}
private void GeoLocateHandler(object sender, PositionEventArgs e)
{
Device.BeginInvokeOnMainThread(() =>
{
DrawNewLocation(e.Position);
});
}
}
}
MainPage.xaml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:local="clr-namespace:LawnDroneCompanion"
xmlns:maps="clr-namespace:Xamarin.Forms.Maps;assembly=Xamarin.Forms.Maps"
x:Class="LawnDroneCompanion.MainPage">
<ContentPage.Content>
<StackLayout>
<StackLayout VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand">
<!-- If I comment this out it works, this comment isn't in my real code -->
<maps:Map x:Name="MyMap" IsShowingUser="True" MapType="Hybrid"/>
</StackLayout>
<Button x:Name="BeginTrackingRoute" HorizontalOptions="FillAndExpand" Text="Begin Tracking" Clicked="StartGeoLocatorListening" BackgroundColor="Green" TextColor="WhiteSmoke" BorderRadius="0"/>
</StackLayout>
</ContentPage.Content>
</ContentPage>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.LawnDroneCompanion" android:installLocation="auto">
<uses-sdk android:minSdkVersion="25" />
<!-- Google Maps for Android v2 requires OpenGL ES v2 -->
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- Allow the application to access Google web-based services. -->
<!-- Google Maps for Android v2 will cache map tiles on external storage -->
<application android:label="LawnDroneCompanion.Android">
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="{IMAGINE-MY-KEY-HERE}" />
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
</application>
</manifest>

Version number in manifest file's dependentAssembly/assemblyIdentity element

I'm working with an application that includes an un-managed client DLL and a managed COM server DLL (which was a challenge in itself: Managed Reg-Free COM Server Won't Activate), and now I'm wondering what is the best way to keep the version numbers in sync. Since we are building both the client and the server, and we try to keep the version numbers of all our files in sync for every build, it looks like I need to have a process that edits all my manifest files on both the client and server ends of all my isolated COM references before a full build happens. Is there an easier way?
Example (client manifest):
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
<assemblyIdentity type="win32" name="globals" version="1.0.0.0" />
<dependency>
<dependentAssembly>
<assemblyIdentity type="win32" name="SoftBrands.FourthShift.FSCulture" version="8.0.0.999" publicKeyToken="541b4aff0f04b60a" />
</dependentAssembly>
</dependency>
</assembly>
Server Manifest:
<?xml version="1.0" encoding="utf-8"?>
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<assemblyIdentity type="win32" name="SoftBrands.FourthShift.FSCulture" version="8.0.0.999" publicKeyToken="541b4aff0f04b60a" />
<clrClass clsid="{23D4FF3D-EEDF-4F68-AD65-749958EE3B2A}"
name="SoftBrands.FourthShift.FSCulture.FSCulture"
tlbid="{8D480B22-D603-309F-9A26-EA9E9B020207}">
</clrClass>
</asmv1:assembly>
I could just do a global search and replace on version="8.0.0.999" with the current version for every build, but I suspect there might be a better way.
Your best bet is to leverage a custom MSBuild task to manipulate the project artifacts prior to compilation.
The task should accept three properties. One property for the client manifest, another property for the server manifest and the third property for the version.
Here is what the targets file might look like in MSBuild.
Manifests.targets
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="4.0">
<!-- Import Tasks -->
<!-- Be sure to sue the full namespace of the task to import -->
<UsingTask TaskName="Full.Namespace.To.UpdateManifestsTask" AssemblyFile="$(MSBuildThisFileDirectory)\MyCustomTasks.dll" />
<!-- Define the location of the client and server manifest files -->
<PropertyGroup>
<ClientManifest><!-- Location of the client manifest --></ClientManifest>
<ServerManifest><!-- Location of the server manifest --></ServerManifest>
</PropertyGroup>
<!-- Define Generate App Config Target -->
<Target Name="UpdateManifests">
<UpdateManifests ClientManifest="$(ClientManifest)" ServerManifest="$(ServerManifest)" Version="$(Version)" />
</Target>
<!-- Define Before Build Target -->
<!-- This will ensure the above target gets executed prior to compilation -->
<Target Name="BeforeBuild">
<CallTarget Targets="UpdateManifests;" />
</Target>
</Project>
Here is what the custom task might look like -
UpdateManifestsTask.cs
public class UpdateManifestsTask : Task
{
public ITaskItem ClientManifest { get; set; }
public ITaskItem ServerManifest { get; set; }
public ITaskItem Version { get; set; }
public override bool Execute()
{
var newVersion = string.Format("name=\"SoftBrands.FourthShift.FSCulture\" version=\"{0}\"", this.Version.ItemSpec);
var clientFile = File.ReadAllText(this.ClientManifest.ItemSpec);
clientFile = Regex.Replace(clientFile, "name=\"SoftBrands.FourthShift.FSCulture\" version=\"\\d*\\.\\d*\\.\\d*\\.\\d*\"", newVersion);
File.WriteAllText(this.ClientManifest.ItemSpec, clientFile);
var serverFile = File.ReadAllText(this.ClientManifest.ItemSpec);
serverFile = Regex.Replace(clientFile, "name=\"SoftBrands.FourthShift.FSCulture\" version=\"\\d*\\.\\d*\\.\\d*\\.\\d*\"", newVersion);
File.WriteAllText(this.ServerManifest.ItemSpec, serverFile);
return true;
}
}
The RegEx is a little sloppy as this was a quick and dirty example but this is effectively how you would go about doing this kind of thing.
Be sure to add references to the MSBuild libraries.
http://blogs.msdn.com/b/msbuild/archive/2006/01/21/515834.aspx
If you don't want to build a custom task you can write a small console app that does the same thing but in my opinion a custom task is cleaner.
Should you decide to go the console app route, you can leverage the BeforeBuild and AfterBuild events in your project file.
<Target Name="BeforeBuild">
<!-- Invoke console app -->
</Target>
<Target Name="AfterBuild">
</Target>

Categories