Permission Denial: requires android.permission.READ_PHONE_STATE - c#

I'm trying to detect phone calls in my android app but I receive the following message when receiving a call:
08-23 15:16:04.685 Vodafone VFD 600 Warning 850 BroadcastQueue Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } to com....LogCalls requires android.permission.READ_PHONE_STATE due to sender android (uid 1000)
08-23 15:16:04.549 Vodafone VFD 600 Warning 850 BroadcastQueue Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } to com....LogCalls requires android.permission.READ_PRIVILEGED_PHONE_STATE due to sender android (uid 1000)
My 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...." android:installLocation="preferExternal">
<uses-sdk android:minSdkVersion="15" android:targetSdkVersion="27" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<application android:label="myapp" android:icon="#drawable/logo">
</application>
</manifest>
And my broadcast receiver:
[BroadcastReceiver]
[IntentFilter(new[] {TelephonyManager.ActionPhoneStateChanged,Intent.ActionNewOutgoingCall })]
public class LogCalls : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
if (intent.Action == TelephonyManager.ActionPhoneStateChanged)
{
Console.WriteLine("state changed");
}
}
}
What I am missing ?

Firstly, third-party apps are not permitted to acquire the READ_PRIVILEGED_PHONE_STATE permission. See Privileged Permission Whitelisting:
Privileged applications are system applications located in the /system/priv-app directory on the system image. Historically, device implementers had little control over which signature|privileged permissions could be granted to privileged apps. Starting in Android 8.0, implementors can explicitly whitelist privileged apps in the system configuration XML files in the /etc/permissions directory. Apps not explicitly listed in these XML files are not granted privileged permissions.
Secondly, when your app is running on API 23 and above, you'll need to first ask the user to grant you the READ_PHONE_STATE permission at runtime, as it is considered a "dangerous" permission (see Permissions Overview).
You'll need to follow the instructions at Request App Permissions to request the permission from the user at runtime, and only once that permission is granted can your BroadcastReceiver receive the intents.

Related

How to configure android packagename within Maui android project?

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)

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

Xamarin.Android Firebase.Messaging - D/FirebaseInstanceId(13164): background sync failed: INVALID_SENDER

I am adding push notifications to a Xamarin app in development.
After following guides I've done everything that should allow it to work.
google-services.json downloaded from firebase, added to project and build action set to GoogleServicesJson
play services is available as confirmed in a check
receiver node added to AndroidManifest.xml
FirebaseIIDService implemented
Notification channel is created
mainfest receiver code:
<application android:label="RMS Metro Calendar">
<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>
</application>
FirebaseIID code (I'm not implementing registration management on the server side):
[Service]
[IntentFilter(new[] { "com.google.firebase.INSTANCE_ID_EVENT" })]
public class MyFirebaseIIDService : FirebaseInstanceIdService
{
const string TAG = "MyFirebaseIIDService";
public override void OnTokenRefresh()
{
var refreshedToken = FirebaseInstanceId.Instance.Token;
Log.Debug(TAG, "Refreshed token: " + refreshedToken);
SendRegistrationToServer(refreshedToken);
}
void SendRegistrationToServer(string token)
{
// Add custom implementation, as needed.
}
}
The app builds and deploys fine, I can sucessfully log out that Play services is available and in logging I get: FirebaseApp initialization successful
However it does not generate a Firebase instance and no Instance.Token is ever received. All I get is the following logging message:
09-19 13:48:31.576 D/FirebaseInstanceId(18578): background sync
failed: INVALID_SENDER, retry in 10s
from which is continues to retry in ever growing time scales.
I'm sure there must be something I've configured incorrectly somewhere with regards to the receiver/IID service implementation, but for the life of me cannot figure it out.
Has anyone else ever come across this? Is there a way I can test the FCM service for my configuration to get back more information on why it is failing?
Thank you!

Problem with Xamarin autostart application

I am currently developing an app to use a barcode scanner, one of the requirements is that app autostart with the device.
so, google on that I found some interest thinks, but when I implemented it fails epicly, the app does not starts.
this is mainfest :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="AppConsulta.Droid" android:versionCode="1" android:versionName="1.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="23" android:targetSdkVersion="24" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application android:label="AppConsulta.Android" android:icon="#drawable/Logo_Jumbo_Cencosud">
<activity android:name="MainActivity" />
<receiver android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
and this is my receiver
namespace AppConsulta.Droid
{
[BroadcastReceiver]
[IntentFilter(new[] { Intent.ActionBootCompleted }, Priority = (int)IntentFilterPriority.LowPriority)]
public class BootReceiver : BroadcastReceiver
{
public override void OnReceive(Context context, Intent intent)
{
Intent serviceStart = new Intent(context, typeof(MainActivity));
serviceStart.AddFlags(ActivityFlags.NewTask);
context.StartActivity(serviceStart);
}
}
}
using adb.exe I manage to extract the log of the device
and it shows this
10-22 16:33:00.412 2007 2007 E AndroidRuntime: FATAL EXCEPTION: main
10-22 16:33:00.412 2007 2007 E AndroidRuntime: Process: AppConsulta.Droid, PID: 2007
10-22 16:33:00.412 2007 2007 E AndroidRuntime: java.lang.RuntimeException: Unable to instantiate receiver AppConsulta.Droid.BootReceiver: java.lang.ClassNotFoundException: Didn't find class "AppConsulta.Droid.BootReceiver" on path: DexPathList[[zip file "/data/app/AppConsulta.Droid-1/base.apk"],nativeLibraryDirectories=[/data/app/AppConsulta.Droid-1/lib/arm, /data/app/AppConsulta.Droid-1/base.apk!/lib/armeabi-v7a, /vendor/lib, /system/lib]]

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>

Categories