How do you access android permissions in c# - c#

I'm building an application for android using Unity and I need to access permissions in the phone.
So far I've been able to reference camera and microphone, but there doesn't seem to be references for the other two permissions; storage and telephone. How do I access them?
void OnGUI()
{
//microphone
#if PLATFORM_ANDROID
if (!Permission.HasUserAuthorizedPermission(Permission.Microphone))
{
dialog.AddComponent<PermissionsRationaleDialog>();
}
if (!Permission.HasUserAuthorizedPermission(Permission.Camera))
{
dialog.AddComponent<PermissionsRationaleDialog>();
}
else if (dialog != null)
{
Destroy(dialog);
}
#endif
}
As you can see permission and camera have reference but I can't find anywhere on the internet that has the solution to this.

See in your code Permission.Microphone is actually a String. So you can use and directly the permission as if you use in Android Manifest.
This one Can be used to get the Android Storage Read and Write Permission.(Write Permission Implies Read Permission also)
using UnityEngine;
using UnityEngine.Android;
public class RequestPermissionScript : MonoBehaviour
{
void Start()
{
if (Permission.HasUserAuthorizedPermission(Permission.ExternalStorageWrite))
{
// The user authorized use of the microphone.
}
else
{
// We do not have permission to use the microphone.
// Ask for permission or proceed without the functionality enabled.
Permission.RequestUserPermission(Permission.ExternalStorageWrite);
}
}
}
This is What is said in Unity Documentation For Requesting Permission in Android
A string that describes the permission to request. For permissions
which Unity has not predefined you may also manually provide the
constant value obtained from the Android documentation here:
https://developer.android.com/guide/topics/permissions/overview#permission-groups
such as "android.permission.READ_CONTACTS".
That means instead of using permission.ExternalStorageWrite you may directly use "android.permission.WRITE_EXTERNAL_STORAGE". Similarly for any other permission that is available on Android platform.
For Telephone permission the Unity doesn't have a built-in constant defined so you need to use that permission as if we use in android. Here am just giving an example for requesting permissions for reading contacts. As I did not exactly understood what you actually meant by telephone permission. Unity has nothing to do with Android Permission these are actually set of permission strings that are understood by Android. So for some standard permissions that are most often used unity have some predefined constant string values. That is actually for ease of use for developers.
public class RequestPermissionScript : MonoBehaviour
{
void Start()
{
if (Permission.HasUserAuthorizedPermission("android.permission.READ_CONTACTS"))
{
// The user authorized use of the microphone.
}
else
{
// We do not have permission to use the microphone.
// Ask for permission or proceed without the functionality enabled.
Permission.RequestUserPermission("android.permission.READ_CONTACTS");
}
}
}
Hope this solves your issue. Thank You.

Related

How to get all available storages paths in Xamarin Forms?

I'm trying to get all the available media files -Or files with specific extensions- in the device -Either Android or IOS- but I can't find a way to do this, so instead I was trying to get all the device storages and I'll iterate through them with my own code to get the files I need.
However, I can't find a way to get the storages paths as well, but I know I get the main storage path in Android using Android.OS.Environment.ExternalStorageDirectory.AbsolutePath so maybe I can make an interface for the same for IOS, but still, that gets the main storage only, not any attached USB or Memory Cards...
So any help would be appreciated in either approaches. Thanks in advance.
Android:
Android groups the filesystem into two different types of storage: Internal Storage, External Storage.
Internal Storag: https://learn.microsoft.com/en-us/xamarin/android/platform/files/#working-with-internal-storage
You could use System.Environment.GetFolderPath() to retrieve internal storage directory like below:
/data/user/0/com.companyname/files
External Storage: https://learn.microsoft.com/en-us/xamarin/android/platform/files/external-storage?tabs=windows
The directory of the private external files would be:
/storage/emulated/0/Android/data/com.companyname.app/files/
You could get it via dependency service.
DependencyService: https://learn.microsoft.com/en-us/xamarin/xamarin-forms/app-
fundamentals/dependency-service/introduction
Create an interface IExternalStorage:
public interface IExternalStorage
{
string GetPath();
}
The implementation on the Android:
[assembly:Dependency(typeof(AndroidImplementation))]
namespace App.Droid
{
public class AndroidImplementation: IExternalStorage
{
public string GetPath()
{
Context context = Android.App.Application.Context;
var filePath = context.GetExternalFilesDir("");
return filePath.Path;
}
}
}
Then you could use it in Xamarin.Forms:
var folderPath = DependencyService.Get<IExternalStorage>(). GetPath();
IOS:
Each iOS app has its own sandbox directory. https://developer.apple.com/library/archive/documentation/FileManagement/Conceptual/FileSystemProgrammingGuide/FileSystemOverview/FileSystemOverview.html
Generally, we store user's data in the Documents folder. And we could access its path on Forms directly:
var path = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
Please note: IOS only could access photo gallery and iCloud folder.
File system access in Xamarin.iOS: https://learn.microsoft.com/en-us/xamarin/ios/app-fundamentals/file-system

Why is the Namespace "IUnityRenderPipeline" Suddenly Missing from the Vuforia Script?

I've been working in Unity the last month or so. I've gotten a few iterations of a basic AR application worked up but I've updated Unity and now my code is throwing all sorts of errors.
Last week my app was working fine when building to my Pixel phone. Now that I've updated to Unity 2018.3.9, Vuforia 8.1 is now missing the name space mentioned in the title. Does anyone have any information on this?
The app will play correctly if I restart Unity up until I try to build the application to the phone. Once I build and it fails I can't replay the application due to compiler errors.
I've typed in different namespaces in the Vuforia Script and have checked my script. Mine is the same script I've used in previous versions with zero issues. I have Vuforia in the namespace but the issue appears to be coming form the Vuforia inherent script instead.
Here's the section of the Vuforia Code that appears to have the most bugs:
\\\\
namespace Vuforia.UnityCompiled
{
public class RuntimeOpenSourceInitializer
{
static IUnityCompiledFacade sFacade;
[RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]
static void OnRuntimeMethodLoad()
{
InitializeFacade();
}
static void InitializeFacade()
{
if (sFacade != null) return;
sFacade = new OpenSourceUnityCompiledFacade();
UnityCompiledFacade.Instance = sFacade;
}
class OpenSourceUnityCompiledFacade : IUnityCompiledFacade
{
readonly IUnityRenderPipeline mUnityRenderPipeline = new UnityRenderPipeline();
public IUnityRenderPipeline UnityRenderPipeline
{
get { return mUnityRenderPipeline; }
}
}
class UnityRenderPipeline : IUnityRenderPipeline
{
public event Action<Camera[]> BeginFrameRendering;
public event Action<Camera> BeginCameraRendering;
public UnityRenderPipeline()
\\\\\
I'm not versed enough in C# to know the fine tunings of QC'ing the code other than the immediate lack of ";" in a lot of these lines.
What the app should be doing is building correctly to my phone. Once there it's an application that reads a sketch I drew, and shows a model or several renderings of the space based on the image target and virtual buttons placed in Unity.
Hello
Not sure how you created your app, but these errors look similar to ones you'd get if there was a mismatch between the Engine SDK version and the Vuforia samples. As the SDK evolves and APIs are created/changes, so do the samples to be compatible with them. Here's how you can check the versions of both (assuming you used Vuforia samples resources):
- SDK version: Unity Editor->Window->Vuforia Configuration.
- Samples version: Unity Editor->Project window: Assets/Vuforia/version.
also, you can delete the old version of Vuforia and re-import from the Package Manager in Unity.
Thanks,

Open another application from the current one

We have a UWP app in the Windows Store. From this app we would like to launch various apps on the same system. For this process we need to do 2 things.
Check if the app exists on the system
If yes, launch it. If no, give feedback
We tried a couple of things but i'm searching for the best way to do this.
We would like to launch both other UWP apps and Standalone apps.
I tried messing with the Unity PlayerPrefs, but that acts weird. It works if I make a custom PlayerPref and check if it exists from within 1 app, but as soon as I make a playerpref in the UWP and check for it in the Standalone I get nothing. And vice versa ofcourse. (Yes I know UWP saves its playerprefs somewhere else)
What would be the best general solution to this? Continue messing around with Playerprefs and search for different paths depending on the app we want to open?(Standalone, UWP) or some other way?
EDIT: What I have so far:
if (Input.GetKeyDown(KeyCode.Backspace))
{
PlayerPrefs.SetString("42069" , "testing_this");
PlayerPrefs.Save();
Debug.Log("Wrote key 42069 to registry with: -value testing_this-");
}
if (Input.GetKeyDown(KeyCode.Space))
{
if (PlayerPrefs.HasKey("42069"))
{
Debug.Log("I found the key 42069 in my registry");
cube.SetActive(true);
}
else
{
Debug.Log("I cant find key 42069 in my registry");
}
}
if (Input.GetKeyDown(KeyCode.S))
{
const string registry_key = #"SOFTWARE\DefaultCompany";
using(RegistryKey key = Registry.CurrentUser.OpenSubKey(registry_key))
{
if (key != null)
foreach (string subKeyName in key.GetSubKeyNames())
{
if (subKeyName == "RegistryTesting")
{
Debug.Log("I found the key on path: " + registry_key);
}
}
}
}
EDIT: No one? I know there is a way. All I need to do is check whether a standalone app exists from a UWP app. But I do not have acces to the register in a UWP app. I know there are some ways with bridges etc, but I have no clue how and where to start.
I encountered a somewhat similar situation but I was checking to see if the app was running and if not, start it. In my situation, the app I wanted to check and launch was not something I wrote nor was it UWP so my solution may not work for you as the capabilities to do so are restricted.
First adding restricted capabilities to the package.appxmanifest (code).
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
IgnorableNamespaces="uap mp rescap"
Then adding "appDiagnostics" capability to the app.
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="appDiagnostics" />
</Capabilities>
Now you have the ability to request permission to access running processes and check.
using System;
using System.Linq;
using System.Threading.Tasks;
using Windows.System;
using Windows.System.Diagnostics;
class ProcessChecker
{
public static async Task<bool> CheckForRunningProcess(string processName)
{
//Requests permission for app.
await AppDiagnosticInfo.RequestAccessAsync();
//Gets the running processes.
var processes = ProcessDiagnosticInfo.GetForProcesses();
//Returns result of searching for process name.
return processes.Any(processDiagnosticInfo => processDiagnosticInfo.ExecutableFileName.Contains(processName));
}
}
Launching a non UWP app/process is a bit dirty but possible.
First, a simple console (non uwp) app is needed. Replace the directoryPath in the code below with your applicable directory path.
using System;
using System.Diagnostics;
namespace Launcher
{
class Program
{
static void Main(string[] args)
{
try
{
if (args.Length != 3) return;
string executable = args[2];
string directoryPath = "C:\\Program Files (x86)\\Arduino\\hardware\\tools\\";
Process.Start(directoryPath + executable);
}
catch (Exception e)
{
Console.ReadLine();
}
}
}
}
Build the console app and place the Launcher.exe in your UWP app asset folder.
Now you need to add the capability to run the Launcher and to do so, add "runFullTrust" capability to the UWP app.
<Capabilities>
<Capability Name="internetClient" />
<rescap:Capability Name="runFullTrust" />
<rescap:Capability Name="appDiagnostics" />
</Capabilities>
For desktop, you also need to add desktop capabilities and extension to the package.appxmanifest (code).
xmlns:rescap="http://schemas.microsoft.com/appx/manifest/foundation/windows10/restrictedcapabilities"
xmlns:desktop="http://schemas.microsoft.com/appx/manifest/desktop/windows10"
IgnorableNamespaces="uap mp rescap"
Then further below in the package.appxManifest and inside .
<Extensions>
<desktop:Extension Category="windows.fullTrustProcess" Executable="Assets\Launcher.exe" >
<desktop:FullTrustProcess>
<desktop:ParameterGroup GroupId="SomeGroup1" Parameters="ProcessName1.exe"/>
<desktop:ParameterGroup GroupId="SomeGroup2" Parameters="ProcessName2.exe"/>
</desktop:FullTrustProcess>
</desktop:Extension>
</Extensions>
Finally, add the "Windows Desktop Extensions for the UWP" references needed for your app versions.
Now you can call your Launcher and start the necessary process.
public static async void LaunchProcess(int groupId)
{
switch (groupId)
{
case 1:
await FullTrustProcessLauncher.LaunchFullTrustProcessForAppAsync("SomeGroup1");
break;
case 2:
await FullTrustProcessLauncher.LaunchFullTrustProcessForAppAsync("SomeGroup2");
break;
}
}
Combining the above, one possibility may be...
public enum ProcessResult
{
ProcessAlreadyRunning,
FailedToLaunch,
SuccessfulLaunch
}
public static async Task<ProcessResult> CheckLaunchCheckProcess1()
{
if (await CheckForRunningProcess("ProcessName1.exe")) return ProcessResult.ProcessAlreadyRunning;
LaunchProcess(1);
return await CheckForRunningProcess("ProcessName1.exe") ? ProcessResult.SuccessfulLaunch : ProcessResult.FailedToLaunch;
}
This is just an example of how to accomplish launching non uwp apps within a single uwp app. For a windows store app submissions, restricted capabilities require approval and can delay or halt deployment if denied.
If the both the calling app and launching app are uwp and written by you, the appropriate solution may be using URI for app to app communication, MS doc link Launch an app with a URI

Unable to determine if the Xamarin Forms application is running in the Simulator or on the Device

I'm trying to determine if the app is running in the simulator or on the hardware (Apple iPhone) device.
Various answers are all suggesting that I do the following:
bool isSimulator = MonoTouch.ObjCRuntime.Runtime.Arch ==
MonoTouch.ObjCRuntime.Arch.SIMULATOR;
which I've added to my iOS app AppDelegate.cs file. But it does compile - I'm missing a namespace or assembly.
Here's a pic of the FULL method (with the colour coding showing it cannot find the static property):
Using Clause:
using ObjCRuntime;
Code:
bool isSimulator = Runtime.Arch == Arch.SIMULATOR;
FYI: The MonoTouch namespace is deprecated (~2012) and has been broken up into multiple namespaces within the "Xamarin.iOS" product.
Alternative approach that uses the UIDevice.CurrentDevice information:
public static class IosHelper
{
public static bool IsSimulator {
get {
return UIDevice.CurrentDevice.Model.EndsWith("Simulator") || UIDevice.CurrentDevice.Name.EndsWith("Simulator");
}
}
}
Derived from this answer.

Parse.com Android Unity Nothing works not even the test object

I have just started using Parse.com On Unity 5.0.0fb, and after getting my application to work with Parse on Unity Editor I decided to try it on my Mobile to find nothing works. I have checked the APK and Parse is inside it but when I try anything it does not work.
I have tested this with a Test APK with nothing but parse and the test script attached to a button and it also does not work.
using UnityEngine;
using System.Collections;
using Parse;
public class ScriptTest : MonoBehaviour {
public UnityEngine.UI.Text Mytext;
string mytext;
// Use this for initialization
public void MySpecial () {
ParseObject testObject = new ParseObject("TestObject");
testObject["foo"] = "bar";
testObject.SaveAsync();
mytext = "Saved";
Mytext.text = mytext;
Debug.Log (mytext);
}
// Update is called once per frame
void Update () {
}
}
It will not do anything the button will click it will say saved on my text but when I check parse TestObject nothing will be there. Is there something im missing in my build?
I have made sure stripping is also disabled.
This works 100% in editor just not in Android I have no idea or way to test iOS.
I have the exact same problem, using Unity 5.1 and Parse Unity SDK 1.5.1. It works perfectly in the editor but not on Android.
Here's my code :
ParseObject _localPlayer = new ParseObject();
Task query = _localPlayer.SaveAsync();
while (!query.IsCompleted)
yield return null;
if (!query.IsFaulted && !query.IsCanceled)
{
Debug.Log ("Player successfully created!");
}
else
{
Debug.Log("Failed to create player...");
}
The task generated with the SaveAsync() request doesn't seem to end at all (isCompleted is never true) so it becomes an infinite loop, and the actual cloud operation is not performed (no trace on the Parse dashboard). There doesn't seem to be any exception thrown and the device log doesn't show anything.
I'm really stuck at this point and haven't be able to find any solution anywhere on the web so far. :(
Using Parse SDK 1.3.2 "fixes" the issue.
-> https://parse.com/downloads/windows/Parse/1.3.2
Looks like a big fat regression. ;)
Going back to Parse Unity SDK 1.3.2 worked for me.
LogOutAsync() had to be replaced with LogOut(), but that was the only change I had to make in my code.
The solution to this problem is to reimport project settings from their blank project. It will fix any build problems you have.
The bug report, for those who would like to be kept informed:
https://developers.facebook.com/bugs/1623483557935932/

Categories