The first time I use the application after confirming the permission to access the photos saved on the gallery, pickphoto async seems to do nothing.
in my opinion the problem is that it does not wait for user authorization.
in order to work correctly I have to click on the upload button of the photo more than once.
i am working with android with the latest version of the library.
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsPickPhotoSupported)
{
await DisplayAlert("Oops", "You Cannot pick an image", AppResources.Label_OK);
return;
}
var file = await CrossMedia.Current.PickPhotoAsync(new PickMediaOptions
{
PhotoSize = PhotoSize.MaxWidthHeight,
MaxWidthHeight = 800,
SaveMetaData = false
});
You could ask for the runtime permission before you load the page. After that, you do not need to click on the upload button of the photo more than once.
protected override void OnAppearing()
{
base.OnAppearing();
RunTimePermission();//ask for the runtime permission
}
I thank the people who answered me.
I found the error:
Wrong Code:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Permission[] grantResults)
{
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
Correct code:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
Related
Need help,
Application run first time accurately with ask permission activity, but on second run it stuck on permission activity view and don't skip the activity and shows only content of the Location Activity,
How can i achieve this?
My scenario:
1st time run- From Splash Screen----->Location Permission Activity--->Main Activity
2nd time rum From Splash Screen----->(App)Main Activity
**
Below is my code in Android Studio Java**
#Override
protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);
setContentView(R.layout.activity_location);
if (ContextCompat.checkSelfPermission(Location.this,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
if (ActivityCompat.shouldShowRequestPermissionRationale(Location.this,
Manifest.permission.ACCESS_FINE_LOCATION)){
ActivityCompat.requestPermissions(Location.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}else{
ActivityCompat.requestPermissions(Location.this,
new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 1);
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions,
int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 1: {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(Location.this,
Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED)
{
Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
}
startActivity(new Intent(getApplicationContext(), MainActivity.class));
finish();
return;
}
}
}
}
When calling Permissions.RequestAsync<Permissions.LocationWhenInUse>() I do not get any result and the App is getting stuck. No matter, if the user accepts or denies the request.
I've set up MainActivity as described in the documentation:
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
Now I'm trying to get the permissions the following way. But the RequestAsync call is just getting stuck and I never recieve an answer. Once the permission is granted and the app is being restarted, everything works as expected.
public async Task CheckPermissions()
{
var status = await Permissions.CheckStatusAsync<Permissions.LocationWhenInUse>();
if (status != PermissionStatus.Granted)
{
status = await Permissions.RequestAsync<Permissions.LocationWhenInUse>();
}
if (status == PermissionStatus.Granted)
{
HasLocationPermissions = true;
}
else if (status != PermissionStatus.Unknown)
{
HasLocationPermissions = false;
}
}
A synchronous blocking call further up your call stack can cause this; e.g., .Wait(), .Result, or .GetAwaiter().GetResult(). This is the classic deadlock situation described on my blog.
Since you are writing a Xamarin application, you may find this technique helpful - it's a way to start an asynchronous operation (synchronously), show a "loading..." state, and then update when the asynchronous operation completes.
I'm currently writing a Xamarin Forms app which requires use of the camera, in the code below I am requesting the permission using the Xamarin Essentials Permissions which comes back as "Granted"; immediately following that I am requesting use of the camera to take a photo, which throws the following error.
ex = {Plugin.Media.Abstractions.MediaPermissionException: Camera permission(s) are required.
The permission code
public static async Task<bool> GetPermission<TPermission>() where TPermission : BasePermission, new()
{
var hasPermission = await Permissions.CheckStatusAsync<TPermission>();
if (hasPermission == PermissionStatus.Granted)
return true;
else if (hasPermission == PermissionStatus.Disabled)
return false;
var result = await Permissions.RequestAsync<TPermission>();
if (result != PermissionStatus.Granted)
return false;
return true;
}
The photo manager code
if(!await PermissionHelpers.GetPermission<Permissions.Camera>())
{
await new ErrorAlert().Show("App can't take a picture without permission to use the camera");
return string.Empty;
}
var photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
PhotoSize = PhotoSize.Small,
SaveToAlbum = false
});
As previously said, the GetPermission method returns true, but still the error is thrown.
I'm currently running this on Android.
My AndroidManifest.xml has these permission in it.
<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 now made a sample project to showcase my issue
GitHub Repo for the issue
don't forget
Android
protected override void OnCreate(Bundle savedInstanceState) {
//...
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState); // add this line to your code, it may also be called: bundle
//...
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
Documentation
First of all, I notice you use Xam.Plugin.Media, this plugin need WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE and android.permission.CAMERA in Android, You should request these permission at runtime.
You can use following code in the MainActivity
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
TabLayoutResource = Resource.Layout.Tabbar;
ToolbarResource = Resource.Layout.Toolbar;
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
LoadApplication(new App());
if (ContextCompat.CheckSelfPermission(this, Manifest.Permission.Camera) != (int)Permission.Granted)
{
RequestPermissions(new string[] { Manifest.Permission.Camera, Manifest.Permission.WriteExternalStorage, Manifest.Permission.ReadExternalStorage }, 0);
}
}
Here is running gif.
Update
If you use this CrossMedia, you need grant Storage and Camera permission.Please open your PhotoManager.cs Add the request storage code like following code.
public class PhotoManager
{
public async Task<string> TakeNewPhoto()
{
try
{
if (!CrossMedia.IsSupported || !CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
return string.Empty;
}
if (!await PermissionHelpers.GetPermission<Permissions.Camera>())
{
return string.Empty;
}
//=====================================add above line==================================================
if (!await PermissionHelpers.GetPermission<Permissions.StorageWrite>())
{
return string.Empty;
}
var photo = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions
{
PhotoSize = PhotoSize.Small,
SaveToAlbum = false
});
if (photo != null)
{
return "photo taken successfully";
}
return string.Empty;
}
catch (Exception ex)
{
return ex.Message;
}
}
}
Here is your issueProjects' running GIF.
thank you for all of your time gone into helping me to resolve this issue.
It turned out that if you are using Xamarin essentials version 1.5.0 you need to install the CurrentActivity NuGet plugin to your android project.
Or, a better solution is update to 1.5.1 which resolves the issue entirely.
You must add permissions for camera to your Android Manifest file!
In Visual Studio right click your android project.
Go to Options -> Build -> Android Application and tick the box in required permissions that says camera.
NB: If you are going to be recording you may also want to enable microphone and audio permissions.
You must also add:
<uses-feature android:name="android.hardware.camera" />
To your android manifest.
Under Android I need some permissions to use the Google-Map API. I use the PermissionsPlugin :
https://www.nuget.org/packages/Plugin.Permissions/
Here some code :
async void RequestPermissions()
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (status != PermissionStatus.Granted)
{
if (await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
{
//NavigationHelper.CurrentPage.DisplayAlert("Need location", "Gunna need that location", "OK");
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(Permission.Location);
//Best practice to always check that the key exists
if (results.ContainsKey(Permission.Location))
status = results[Permission.Location];
}
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
PermissionsImplementation.Current.OnRequestPermissionsResult(requestCode, permissions, grantResults);
//base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
But I also noticed that the method "OnRequestPermissionsResult" is never called, and there is no dialog that ask me for permissions !!
Also, the permissions are in the manifest file too !
Any idea to solve this ?
Im always getting an error of Java.Lang.SecurityException: getLine1NumberForDisplay: Neither user 10710 nor current process has android.permission.READ_SMS. Even if I already Added the READ_SMS in AndroidManifest.xml
MyCode:
public string GetNumber()
{
TelephonyManager telephonyManager = (TelephonyManager)GetSystemService(TelephonyService);
return telephonyManager.Line1Number;
}
Thanks in Advance and Good Day :D
This is a really simple runtime permission request example.
I would highly recommend reading the Xamarin blog post and the Android doc linked below as you should show the user "why" you are requesting permission before the system dialog shows up.
[Activity(Label = "RunTimePermissions", MainLauncher = true, Icon = "#mipmap/icon")]
public class MainActivity : Activity
{
const int PermissionSMSRequestCode = 99;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
Button button = FindViewById<Button>(Resource.Id.myButton);
button.Click += delegate {
if ((int)Build.VERSION.SdkInt < 23) // Permissions accepted by the user during app install
DoSomeWork();
var permission = BaseContext.CheckSelfPermission(Manifest.Permission.ReadSms);
if (permission == Android.Content.PM.Permission.Granted) // Did the user already grant permission?
DoSomeWork();
else // Ask the user to allow/deny permission request
RequestPermissions(new string[] { Manifest.Permission.ReadSms }, PermissionSMSRequestCode);
};
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, Android.Content.PM.Permission[] grantResults)
{
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PermissionSMSRequestCode)
{
if ((grantResults.Count() > 0) && (grantResults[0] == Android.Content.PM.Permission.Granted))
DoSomeWork();
else
Log.Debug("PERM", "The user denied access!");
}
}
protected void DoSomeWork()
{
Log.Debug("PERM", "We have permission, so do something with it");
}
}
Ref: Requesting Runtime Permissions in Android Marshmallow
Ref: Requesting Permissions at Run Time