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
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;
}
}
}
}
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);
}
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 ?
Our application should have the functionality to save Application files to Google Drive. Of course, using the local configured account.
From Android API i tried to figure out some clue. But android API with Xamarin implementation seems very tough for me.
I have installed Google Play Services- Drive from Xamarin Components but there are no examples listed from which we can refer the flow and functionality.
The basic steps (see the link below for full details):
Create GoogleApiClient with the Drive API and Scope
Try to connect (login) the GoogleApiClient
The first time you try to connect it will fail as the user has not selected a Google Account that should be used
Use StartResolutionForResult to handle this condition
When GoogleApiClient is connected
Request a Drive content (DriveContentsResult) to write the file contents to.
When the result is obtained, write data into the Drive content.
Set the metadata for the file
Create the Drive-based file with the Drive content
Note: This example assumes that you have Google Drive installed on your device/emulator and you have registered your app in Google's Developer API Console with the Google Drive API Enabled.
C# Example:
[Activity(Label = "DriveOpen", MainLauncher = true, Icon = "#mipmap/icon")]
public class MainActivity : Activity, GoogleApiClient.IConnectionCallbacks, IResultCallback, IDriveApiDriveContentsResult
{
const string TAG = "GDriveExample";
const int REQUEST_CODE_RESOLUTION = 3;
GoogleApiClient _googleApiClient;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.Main);
Button button = FindViewById<Button>(Resource.Id.myButton);
button.Click += delegate
{
if (_googleApiClient == null)
{
_googleApiClient = new GoogleApiClient.Builder(this)
.AddApi(DriveClass.API)
.AddScope(DriveClass.ScopeFile)
.AddConnectionCallbacks(this)
.AddOnConnectionFailedListener(onConnectionFailed)
.Build();
}
if (!_googleApiClient.IsConnected)
_googleApiClient.Connect();
};
}
protected void onConnectionFailed(ConnectionResult result)
{
Log.Info(TAG, "GoogleApiClient connection failed: " + result);
if (!result.HasResolution)
{
GoogleApiAvailability.Instance.GetErrorDialog(this, result.ErrorCode, 0).Show();
return;
}
try
{
result.StartResolutionForResult(this, REQUEST_CODE_RESOLUTION);
}
catch (IntentSender.SendIntentException e)
{
Log.Error(TAG, "Exception while starting resolution activity", e);
}
}
public void OnConnected(Bundle connectionHint)
{
Log.Info(TAG, "Client connected.");
DriveClass.DriveApi.NewDriveContents(_googleApiClient).SetResultCallback(this);
}
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
{
base.OnActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_CODE_RESOLUTION)
{
switch (resultCode)
{
case Result.Ok:
_googleApiClient.Connect();
break;
case Result.Canceled:
Log.Error(TAG, "Unable to sign in, is app registered for Drive access in Google Dev Console?");
break;
case Result.FirstUser:
Log.Error(TAG, "Unable to sign in: RESULT_FIRST_USER");
break;
default:
Log.Error(TAG, "Should never be here: " + resultCode);
return;
}
}
}
void IResultCallback.OnResult(Java.Lang.Object result)
{
var contentResults = (result).JavaCast<IDriveApiDriveContentsResult>();
if (!contentResults.Status.IsSuccess) // handle the error
return;
Task.Run(() =>
{
var writer = new OutputStreamWriter(contentResults.DriveContents.OutputStream);
writer.Write("Stack Overflow");
writer.Close();
MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
.SetTitle("New Text File")
.SetMimeType("text/plain")
.Build();
DriveClass.DriveApi
.GetRootFolder(_googleApiClient)
.CreateFile(_googleApiClient, changeSet, contentResults.DriveContents);
});
}
public void OnConnectionSuspended(int cause)
{
throw new NotImplementedException();
}
public IDriveContents DriveContents
{
get
{
throw new NotImplementedException();
}
}
public Statuses Status
{
get
{
throw new NotImplementedException();
}
}
}
Ref: https://developers.google.com/drive/android/create-file