Xamarin Form - Taking photo exception - xamarin.forms

I am getting the following exception when trying to take a photo: "Unable to get file location. This most likely means that the file provider information is not set in your Android Manifest file. Please check documentation on how to set this up in your project."
<provider android:name="androidx.core.content.FileProvider" android:authorities="MYPACKAGENAME.fileprovider" android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="#xml/file_paths"></meta-data>
</provider>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
I have a file under Resources/xml called file_paths.xml, it's BuildAction is set to AndroidResource, and looks like this:
<?xml version="1.0" encoding="UTF-8" ?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-files-path name="my_images" path="Pictures" />
<external-files-path name="my_movies" path="Movies" />
</paths>
I am using the Xam.Plugin.Media plugin (from James Montemagno), and when I call TakePhotoAsync, I get the exception
await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
Directory = "MyFolder",
SaveToAlbum = true,
CompressionQuality = 40,
CustomPhotoSize = 35,
PhotoSize = PhotoSize.Medium,
MaxWidthHeight = 1000,
});

I'm not sure if this is the solution but when I've used this library in the past I've used a different provider name. So instead of
<provider android:name="androidx.core.content.FileProvider"...
I used
<provider android:name="android.support.v4.content.FileProvider" ...

I had down a demo which used the code you had provided and the same nuget package. I also met the error. I tried many ways and when I set "android:authorities="${applicationId}.fileprovider" it worked well. So you can have a try.
The Android Manifest file:
<application android:label="App15.Android" android:theme="#style/MainTheme">
<provider android:name="androidx.core.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-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

Related

problem with Install APK Programmatically in xamarin.forms

I have scenario where I have to download apk in background and install it without prompting any dialog to user. However when I try to install it using below code File
string mypath = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryDownloads).AbsolutePath;
var filePath = Path.Combine(mypath, fileName);
if (File.Exists(filePath))
{
string extention = Android.Webkit.MimeTypeMap.GetFileExtensionFromUrl(Android.Net.Uri.FromFile(new Java.IO.File(filePath)).ToString());
string mimeType = Android.Webkit.MimeTypeMap.Singleton.GetMimeTypeFromExtension(extention);
Context context = Android.App.Application.Context;
Android.Net.Uri fileUri = FileProvider.GetUriForFile(context, context.PackageName + ".provider", new Java.IO.File(filePath));
Intent intent = new Intent(Intent.ActionView);
intent.SetDataAndType(fileUri, mimeType);
intent.AddFlags(ActivityFlags.NewTask);
intent.AddFlags(ActivityFlags.GrantReadUriPermission);
context.StartActivity(intent);
}
and below code for xml file
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_file" path="." />
</paths>
and below code for AndroidManifest.xml file
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="com.companyname.fileprovider">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.permission.INSTALL_LOCATION_PROVIDER" />
<uses-permission android:name="android.permission.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application android:label="Fileprovider.Android" android:theme="#style/MainTheme">
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"/>
</provider>
</application>
</manifest>
but when click button to open .apk file view below error
enter image description here
You cannot install APK without the prompt on Android. Actually I don't think you can do the similar thing on any modern operating system.

How to Detect Incoming MMS Messages on Android Devices using Xamarin.Forms?

I've looked at several questions on here and I'm sure I've made a mistake somewhere, but I cannot figure out why the Broadcast Receiver I made, MMSReceiver, is not notifying me that it received an MMS message via a toast or the information logs. What am I doing incorrectly?
Receiver class:
[BroadcastReceiver]
public class MMSReceiver : BroadcastReceiver
{
private static readonly string TAG = "MMS Broadcast Receiver";
public override void OnReceive(Context context, Intent intent)
{
Log.Info(TAG, "Intent received: " + intent.Action);
Toast.MakeText(context, "Received intent!", ToastLength.Short).Show();
}
}
Manifest.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.App">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<application android:label="App.Android" android:theme="#style/MainTheme">
<!-- https://stackoverflow.com/questions/11289568/monitoring-mms-received-like-sms-received-on-android -->
<receiver android:name=".MMSReceiver">
<intent-filter android:priority="1000"> IntentFilterPriority.HighPriority is equal to 1000
<action android:name="android.provider.Telephony.MMS_RECEIVED"/>
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_MMS"/>
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <!-- Automatically starts at boot. -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/> <!-- Shows a pop-up window on top of all other applications, even if the app is not running in the foreground -->
</manifest>
For the Android4.4 version, Google offers SMS_DELIVER_ACTION (SMS) and WAP_PUSH_DELIVER_ACTION (MMS) intents for default SMS usage, meaning that only default SMS can receive these two broadcasts
Try to change the receiver in your Manifest.xml to :
<receiver android:name=".MMSReceiver">
<intent-filter android:priority="1000">
<action android:name="android.provider.Telephony.WAP_PUSH_RECEIVED"/>
<data android:mimeType="application/vnd.wap.mms-message" />
</intent-filter>
</receiver>

RequestPermissionsAsync never returns

I am using the permissions plugin for Xamarin Forms .
When i call RequestPermissionsAsync the call seems stuck forever . The next line is never called .
I am doing the setup correct exactly as the documentation .
That is my code
var result = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location, Permission.Camera, Permission.Microphone, Permission.Storage);
Console.WriteLine(result) //this line is never called
Below is the manifest
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" />
<uses-permission android:name="com.commonground.streetdeploy.permission.MAPS_RECEIVE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
<uses-feature android:name="android.hardware.location" android:required="false" />
<uses-feature android:name="android.hardware.location.gps" android:required="false" />
<uses-feature android:name="android.hardware.location.network" android:required="false" />
<application android:label="Street Deploy" android:allowBackup="false" android:icon="#mipmap/icon">
<provider android:name="android.support.v4.content.FileProvider"
android:authorities="com.commonground.streetdeploy.fileprovider"
android:exported="false" android:grantUriPermissions="true">
<meta-data android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
<!--<meta-data android:name="com.google.android.geo.API_KEY" android:value="xxx" />
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="xxx" />
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="xxx" />
<meta-data android:name="com.google.android.geo.API_KEY" android:value="xxx" />-->
</application>
This is the main Activity
[Activity(Label = "Street Deploy", Icon = "#mipmap/icon", Theme = "#style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected async override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
/////////////////////////my code
await Plugin.Media.CrossMedia.Current.Initialize();
Xamarin.FormsGoogleMaps.Init(this, savedInstanceState);
UserDialogs.Init(this);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
/////////////////////////end my code
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
Plugin.CurrentActivity.CrossCurrentActivity.Current.Init(this, savedInstanceState);
LoadApplication(new App());
}
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);
}
}
Make sure that you have add user permission in specific platforms .
in iOS (info.plist)
<key>NSAppleMusicUsageDescription</key>
<string>App want to access your Music </string>
<key>NSCameraUsageDescription</key>
<string>App want to access your Camera</string>
<key>NSMicrophoneUsageDescription</key>
<string>App want to access your Microphone</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>App want to access your PhotoLibrary</string>
in Android (Manifest.xml)
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.CAMERA" />
And the line
Console.WriteLine(result);
will been called when you agree or reject the apply .

Xamarin Forms AndroidMainfest

This is my mainfest file:
<?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.Notification">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="27" />
<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="${com.companyname.Notification}.permission.C2D_MESSAGE" />
<permission android:name="${com.companyname.Notification}.permission.C2D_MESSAGE" android:protectionLevel="signature" />
<application android:label="Notification.Android" android:name="android.app.Application" android:allowBackup="true" android:icon="#mipmap/icon" android:debuggable="true">
<receiver android:name="com.onesignal.GcmBroadcastReceiver" android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="${com.companyname.Notification}" />
</intent-filter>
</receiver>
<activity android:configChanges="orientation|screenSize" android:icon="#mipmap/icon" android:label="Notification" android:theme="#style/MainTheme" android:name="md542ccf1b76a5e02a89cf2bd3ef3e134e4.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="md5dcb6eccdc824e0677ffae8ccdde42930.KeepAliveService" />
<receiver android:enabled="true" android:exported="false" android:name="md51558244f76c53b6aeda52c8a337f2c37.PowerSaveModeBroadcastReceiver" />
<provider android:name="mono.MonoRuntimeProvider" android:exported="false" android:initOrder="2147483647" android:authorities="com.companyname.Notification.mono.MonoRuntimeProvider.__mono_init__" />
<!--suppress ExportedReceiver-->
<receiver android:name="mono.android.Seppuku">
<intent-filter>
<action android:name="mono.android.intent.action.SEPPUKU" />
<category android:name="mono.android.intent.category.SEPPUKU.com.companyname.Notification" />
</intent-filter>
</receiver>
<receiver android:name="com.onesignal.NotificationOpenedReceiver" />
<service android:name="com.onesignal.GcmIntentService" />
<service android:name="com.onesignal.GcmIntentJobService" android:permission="android.permission.BIND_JOB_SERVICE" />
<service android:name="com.onesignal.RestoreJobService" android:permission="android.permission.BIND_JOB_SERVICE" />
<service android:name="com.onesignal.RestoreKickoffJobService" android:permission="android.permission.BIND_JOB_SERVICE" />
<service android:name="com.onesignal.SyncService" android:stopWithTask="true" />
<service android:name="com.onesignal.SyncJobService" android:permission="android.permission.BIND_JOB_SERVICE" />
<activity android:name="com.onesignal.PermissionsActivity" android:theme="#android:style/Theme.Translucent.NoTitleBar" />
<service android:name="com.onesignal.NotificationRestoreService" />
<receiver android:name="com.onesignal.BootUpReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
<receiver android:name="com.onesignal.UpgradeReceiver">
<intent-filter>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
</intent-filter>
</receiver>
<activity android:name="com.google.android.gms.common.api.GoogleApiActivity" android:theme="#android:style/Theme.Translucent.NoTitleBar" android:exported="false" />
<meta-data android:name="com.google.android.gms.version" android:value="#integer/google_play_services_version" />
</application>
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT" />
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />
<uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE" />
<uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT" />
<uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE" />
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE" />
<uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.READ_APP_BADGE" />
<uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS" />
<uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_READ" />
<uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_WRITE" />
</manifest>
I keep getting these errors and I don't know what is wrong!!
Severity Code Description Project File Line Suppression State
Error Tag attribute name has invalid character '$'. Notification.Android C:\Users\moham\source\repos\Notification\Notification\Notification.Android\obj\Debug\81\android\manifest\AndroidManifest.xml 14
Severity Code Description Project File Line Suppression State
Error Tag attribute name has invalid character '$'. Notification.Android C:\Users\moham\source\repos\Notification\Notification\Notification.Android\obj\Debug\81\android\manifest\AndroidManifest.xml 9
Severity Code Description Project File Line Suppression State
Error Could not copy the file "obj\x86\Debug\MainPage.xbf" because it was not found. AppXamarin.UWP
Anyone can help?
You seem to be configuring OneSignal push notifications but you haven't changed the android:name="${com.companyname.Notification}" where the name of it should actually be your apps package name which is this com.companyname.Notification in your case

Fcm Notification not Coming when App is in Kill State in React Native

When sending from FCM i.e Firebase console in react native it is easily coming in iOS and Android both but when i am sending notification from admin or backend side it is not coming when app is in kill state.
I am using react-native-fcm .
Thanx .
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE"/>
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="22" />
<application
android:name=".MainApplication"
android:allowBackup="true"
android:label="#string/app_name"
android:icon="#mipmap/brainbg"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:launchMode="singleTop"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize"
android:windowSoftInputMode="adjustResize"
android:screenOrientation="portrait" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.facebook.react.devsupport.DevSettingsActivity" />
<service android:name="com.evollu.react.fcm.MessagingService" android:enabled="true" android:exported="true">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service android:name="com.evollu.react.fcm.InstanceIdService" android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.INSTANCE_ID_EVENT"/>
</intent-filter>
</service>
<receiver android:name="com.evollu.react.fcm.FIRLocalMessagingPublisher"/>
<receiver android:enabled="true" android:exported="true" android:name="com.evollu.react.fcm.FIRSystemBootEventReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.QUICKBOOT_POWERON"/>
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
I had the same issue, resolved it by adding the code below after receiving the fcm token,
FCM.setBadgeNumber(0);
Above is for android for iOS you need to turn on background notifications in Xcode. In Xcode select your project and open capabilities and see if background modes in on. Refer to the screenshot
Here is the snippet of the code i used
export const MyNotificationReceiver = props => {
FCM.getInitialNotification().then(notif => {
});
FCM.setBadgeNumber(0); //Add this for background notification
this.notificationListener = FCM.on(FCMEvent.Notification, async notif => {
var notification_messgae = "";
try {
notification_messgae = notif.default;
} catch (error) {
notification_messgae = JSON.stringify(notif);
}
if (osDetection) {
switch (notif._notificationType) {
case NotificationType.Remote:
notif.finish(RemoteNotificationResult.NewData) //other types available: RemoteNotificationResult.NewData, RemoteNotificationResult.ResultFailed
break;
case NotificationType.NotificationResponse:
notif.finish();
break;
case NotificationType.WillPresent:
notif.finish(WillPresentNotificationResult.All) //other types available: WillPresentNotificationResult.None
break;
}
}
if (!osDetection()) {
if(notif.default)
{
FCM.presentLocalNotification({
body: notif.default,
priority: "high",
show_in_foreground: true,
large_icon: "noti_icon", // Android only
icon: "noti_icon", // as FCM payload, you can relace this with custom icon you put in mipmap
android_actions: JSON.stringify([{
id: "view",
title: 'view'
}, {
id: "dismiss",
title: 'dismiss'
}]) // for android, take syntax similar to ios's. only buttons are supported
});
}
}
});
};

Resources