I want to display a custom message to the user for app permission. I am using Plugin.Permissions for App permission. When i run the current code and run application this popup message display Allow {App Name} to access this device location?. Below is the function currently i am using.
public static async Task<bool> GetPermissions()
{
bool permissionsGranted = true;
var permissionsStartList = new List<Permission>()
{
Permission.Location,
Permission.Camera
};
var permissionsNeededList = new List<Permission>();
try
{
foreach (var permission in permissionsStartList)
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(permission);
if (status != PermissionStatus.Granted)
{
permissionsNeededList.Add(permission);
}
}
}
catch (Exception ex)
{
}
var results = await CrossPermissions.Current.RequestPermissionsAsync(permissionsNeededList.ToArray());
try
{
foreach (var permission in permissionsNeededList)
{
var status = PermissionStatus.Unknown;
//Best practice to always check that the key exists
if (results.ContainsKey(permission))
status = results[permission];
if (status == PermissionStatus.Granted || status == PermissionStatus.Unknown)
{
permissionsGranted = true;
}
else
{
permissionsGranted = false;
break;
}
}
}
catch (Exception ex)
{
}
return permissionsGranted;
}
Thanks for your help and comments
Sadly there is no way to customize the text in the permission dialogs.
These are system dialogs and the app has no control over their content.
Quote from https://developer.android.com/training/permissions/requesting#perm-request
When your app receives PERMISSION_DENIED from checkSelfPermission(), you need to prompt the user for that permission. Android provides several methods you can use to request a permission, such as requestPermissions(), as shown in the code snippet below. Calling these methods brings up a standard Android dialog, which you cannot customize.
How this is displayed to the user depends on the device Android version as well as the target version of your application, as described in the Permissions Overview.
Related
I'm making an application in Unity which uses the phone's camera and the user's location. I want these permission popups to be shown to the user, after they've read why I want them to give permission. So pressing the "Accept" button in the app should check if the app has a certain permission and if not: ask that permission.
So in short, what I need is:
- A way to check if the app has a specific permission
- A way to trigger the permission popup
- (Nice to have:) A way to check if permission was granted or denied in said popup
I've already built exactly this for Android, as android provides ways to do so.
After googling, I've found that iOS will prompt permissionpopups when the app starts a certain service that requires an ungranted permission. This means I could simply start up the location service or camera to check if the app has these permissions. I think this is a dirty fix, though, as it requires the app to start services that are not needed at that time.
Welcome to StackOverflow!
You can use this library: https://github.com/jamesmontemagno/PermissionsPlugin
If you want to retrieve the location permission, you can use this code:
try
{
var status = await CrossPermissions.Current.CheckPermissionStatusAsync(Permission.Location);
if (status != PermissionStatus.Granted)
{
if(await CrossPermissions.Current.ShouldShowRequestPermissionRationaleAsync(Permission.Location))
{
await 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];
}
if (status == PermissionStatus.Granted)
{
var results = await CrossGeolocator.Current.GetPositionAsync(10000);
LabelGeolocation.Text = "Lat: " + results.Latitude + " Long: " + results.Longitude;
}
else if(status != PermissionStatus.Unknown)
{
await DisplayAlert("Location Denied", "Can not continue, try again.", "OK");
}
}
catch (Exception ex)
{
LabelGeolocation.Text = "Error: " + ex;
}
I have looked around a lot of MS Dynamics CRM blogs and SO questions and tried all the solutions but they haven't worked.
The problem I am facing is as follows: I am trying to loop through an excel file with company names and company type. I then find company with matching names in CRM and set values for some custom fields depending on the company type in excel. When I do this though code for a single company it works fine however when I try to run a loop for a large number of companies I am constantly getting:
SecLib::CrmCheckPrivilege failed. Returned hr = -2147220943 on UserId: xxxxxx and PrivilegeType: Read.
The user in question has all privilleges and is an admin user with Read/Write CAL. Also like I pointed out I am able to do the updates for a single record. But when run as a loop that very same record throws an error.
I have been unable to find a solution for this so any help would be much appreciated. I am using MS Dynamics CRM online.
Here's my code:
while (!parser.EndOfData)
{
counter++;
if (counter >= 20)
{
try
{
counter = 0;
context.SaveChanges();
}
catch (Exception exc)
{
while (exc != null)
{
System.Diagnostics.Debug.WriteLine("ERROR: " + exc.Message);
exc = exc.InnerException;
}
continue;
}
}
//Processing row
string[] fields = parser.ReadFields();
foreach (string field in fields)
{
//TODO: Process field
company.Add(fields[0]);
category.Add(fields[1]);
var currAccs = context.CreateQuery<Account>().Where(x => x.Name.Contains(fields[0])).ToList();
if (currAccs != null)
{
foreach (var currAcc in currAccs)
{
System.Diagnostics.Debug.WriteLine("Processing: " + currAcc.Name);
currAcc.cir_MediaOwner = false;
currAcc.cir_Agency = false;
currAcc.cir_AdvertiserBrand = false;
if (fields[1].Contains("MO"))
{
currAcc.cir_MediaOwner = true;
}
if (fields[1].Contains("A"))
{
currAcc.cir_Agency = true;
}
if (fields[1].Contains("B"))
{
currAcc.cir_AdvertiserBrand = true;
}
try
{
context.UpdateObject(currAcc);
}
catch (Exception exc)
{
while (exc != null)
{
System.Diagnostics.Debug.WriteLine("ERROR: " + exc.Message);
exc = exc.InnerException;
}
continue;
}
}
}
break;
}
}
It is possible that you have either a Workflow or Plugin Step related to account and create/update message, impersonated with an User without the proper privileges.
For workflows, these could have the option "execute as: the owner of the workflow" (link)
For plug-in steps, these have an option "Run in User's Context" that can be set to a fix user (link)
My app needs a button to 'restore previous purchases'
Here's my code which is triggered when button is pressed
#if DEBUG
var receipt = await CurrentAppSimulator.GetAppReceiptAsync();
#else
var receipt = await CurrentApp.GetAppReceiptAsync();
#endif
var xmlRcpt = new XmlDocument();
xmlRcpt.LoadXml(receipt);
XmlNodeList xmlProductIdNodes = xmlRcpt.SelectNodes("/Receipt/ProductReceipt/#ProductId");
if (xmlProductIdNodes.Count == 0)
{
try
{
var md = new MessageDialog("Unable to verify purchase");
await md.ShowAsync();
}
catch { }
return;
}
foreach (var node in xmlProductIdNodes)
{
if (node.InnerText == "Product1")
{
//Enable feature 1
}
else if (node.InnerText == "Product2")
{
//Enable feature 2
}
}
The problem is after publishing the app, "unable to verify purchase" is being hit. So is there something wrong with the xml parsing (this is my first time with xml) Or something else?
App targets windows phone 8.1 xaml
UPDATE 1: Somehow I feel, the problem is with the understanding of how store updates licenses. I tried a different approach since my only aim is to check whether a product is purchased or not. I submitted a beta app with this code using a button:
var receipt = CurrentApp.LicenseInformation.ProductLicenses;
if (receipt["Product1"].IsActive)
{
try
{
var md = new MessageDialog("Product 1 enabled", "Success!");
await md.ShowAsync();
}
catch { }
return;
}
else
{
try
{
var md = new MessageDialog("Could not verify purchase");
await md.ShowAsync();
}
catch { }
}
Now the problem is, first time "could not verify" is hit. Then, I make the free purchase of Product1. Product1 verifies successfully. This is as expected. Now if I uninstall the app and reinstall, again the same behaviour i.e. the could not verify purchase.
How can I make sure that the licenseinformation gets the most recent information even after reinstall? Or anyway to trigger a refresh?
Will LoadListingInformationAsync() refresh the license?
I cannot seem to be able to find that a certain user is a member of a DeployUsersProduction group. Here's what I have so far:
[OperationBehavior(Impersonation = ImpersonationOption.Required)]
public Modes GetDeployMode()
{
bool isProd = false;
WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();
if (windowsIdentity == null || windowsIdentity.Groups == null) { return Modes.DUS; }
foreach (IdentityReference identityReference in windowsIdentity.Groups)
{
try
{
var reference = identityReference;
string group = reference.Translate(typeof (NTAccount)).Value.Trim();
if (!String.Equals(group, "DeployUsersProduction", StringComparison.OrdinalIgnoreCase)) { continue; }
isProd = true;
break;
}
catch (Exception ex)
{
// Silent catch due to the [Some or all identity references could not be translated]
// error that sometimes occurs while trying to map an identity.
}
}
return isProd ? Modes.Prod : Modes.DUS;
}
I've got all the config, spn, db, perms, etc correct as far as I can tell. I just have one user that should be returning Modes.Prod and it's not.
The answer wasn't that my approach was wrong, it was the fact that I needed to prefix my group that I was searching for with its domain:
if (!String.Equals(group, #"DOMAIN\DeployUsersProd", StringComparison.OrdinalIgnoreCase)) { continue; }
Special thanks to #DJ KRAZE for the links that led me to writing my own Console app that outputted the groups so I could figure this out!
I am trying to use WCF to do some remote user management things. I and reusing some code I had on a server 2003 box and worked fine, but on my windows 7 test box when I check to see if the user who called the function is administrator it says it is not.
[OperationBehavior(Impersonation=ImpersonationOption.Required)]
public string SetPassword(string username)
{
WindowsPrincipal principal = new WindowsPrincipal(OperationContext.Current.ServiceSecurityContext.WindowsIdentity);
System.Diagnostics.Debug.Print(WindowsIdentity.GetCurrent().Name);
System.Diagnostics.Debug.Print(principal.Identity.Name);
if (principal.IsInRole(WindowsBuiltInRole.Administrator))
{
//try
{
lock (Watchdog.m_principalContext)
{
using (UserPrincipal up = UserPrincipal.FindByIdentity(Watchdog.m_principalContext, username))
{
string newpassword = CreateRandomPassword();
up.SetPassword(newpassword);
up.Save();
return newpassword;
}
}
}
//catch
{
return null;
}
}
else
throw new System.Security.SecurityException("User not administrator");
}
principal.IsInRole(WindowsBuiltInRole.Administrator) is returning false every time. Both my current identity and principal.idenity are the correct user to be impersonated. and that user is a member of the administrators user group.
I think it has to do with UAC that was implemented in windows vista and up. this will be a issue because the production machine this will be going on to is a win2k8-r2 box.
Any suggestions on what to do?
Take a look at this article, under the section, "Coping with Windows Vista" , a very well written article with about UAC and checking Admin privs programatically.
As I did not want to do all that work (from RandomNoob's post) for check if the user is an administrator and the service is already running in a administrative context, I decided to just drop impersonation. I created a new user group called WCFUsers and anyone who will be using the service was added to that group. It now does the System.DirectoryServices.AccountManagement operations in its own context.
[OperationBehavior(Impersonation=ImpersonationOption.NotAllowed)]
public string SetPassword(string username)
{
WindowsPrincipal principal = new WindowsPrincipal(OperationContext.Current.ServiceSecurityContext.WindowsIdentity);
if (principal.IsInRole("WCFUsers"))
{
try
{
lock (Watchdog.m_principalContext)
{
using (UserPrincipal up = UserPrincipal.FindByIdentity(Watchdog.m_principalContext, username))
{
string newpassword = CreateRandomPassword();
up.SetPassword(newpassword);
up.Save();
return newpassword;
}
}
}
catch
{
return null;
}
}
else
return null;
}