简体   繁体   中英

Unity GearVR get rid of "requesting permission..."

Status : not solved yet

Problem

Once I build and install an app with GearVR it asks by default:

XXX is requesting permission to access photos, media and files on your device. Allow?

Allow / Deny

I don't need my app to access any of those above. How can I get rid of this programmatically?

Edit 1

It seems that Unity automatically adds READ_EXTERNAL_STORAGE to any build for some reason. Stripping out the permission doesn't help in newer versions of Unity as the build fails with the message:

Unable to merge android manifests...

Edit 2

The OVRPlugin causes this issue and at the moment.

https://forum.unity3d.com/threads/how-to-remove-android-permission-read_external_storage.429369/

Unity forums say it is unlikely to fix. Maybe there are still some workarounds?

Edit 3

Oculus is working on it, we should receive a fix in February

https://forums.oculus.com/developer/discussion/42465/is-android-permission-read-external-storage-a-must-when-using-unity#latest

I stumble upon this some time ago and still not sure why Unity builds ask for those permissions. Anyway to get rid of them you can use an editor script as a workaround:

protected void BuildAPKCustom(string buildPath)
{
    bool manifestFileExists = false;
    if(File.Exists(Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml")))
    {
        manifestFileExists = true;
        File.Copy(Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"), Path.Combine(Application.dataPath, "Plugins/Android/tmpManifestFile.xml"));
        File.Delete(Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"));
    }

    string[] levels = new string[EditorSceneManager.sceneCount];
    for (int i = 0; i < levels.Length; i++)
    {
        levels[i] = EditorSceneManager.GetSceneAt(i).path;
    }
    BuildPipeline.BuildPlayer(levels, buildPath, BuildTarget.Android, BuildOptions.None);

    XNamespace android = "http://schemas.android.com/apk/res/android";
    string generatedXMLFilePath = Path.Combine(Application.dataPath, "../Temp/StagingArea/AndroidManifest.xml");
    XDocument doc = XDocument.Load(generatedXMLFilePath);
    IEnumerable<XElement> permissionElements = doc.Root.Elements("uses-permission");
    foreach(XElement permission in permissionElements)
    {
        int potentialIndex = PERMISSIONS_NAMES_TO_DELETE.IndexOf(permission.Attribute(android + "name").Value.Replace("android.permission.", ""));
        if(potentialIndex >= 0)
        {
            UnityEngine.Debug.Log("Permission deleted : " + PERMISSIONS_NAMES_TO_DELETE[potentialIndex]);
            permission.Remove();
        }
    }

    XElement overwritenPermission;
    for(int i = 0; i < PERMISSIONS_NAMES_TO_DELETE.Length; i++)
    {
        overwritenPermission = new XElement("uses-permission");
        overwritenPermission.Add(new XAttribute(android + "name", "android.permission." + PERMISSIONS_NAMES_TO_DELETE[i]));
        overwritenPermission.Add(new XAttribute(android + "maxSdkVersion", "18"));
        doc.Element("manifest").Add(overwritenPermission);
    }

    if(!Directory.Exists(Path.Combine(Application.dataPath, "Plugins/Android")))
    {
        Directory.CreateDirectory(Path.Combine(Application.dataPath, "Plugins/Android"));
    }

    doc.Save(Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"));

    BuildPipeline.BuildPlayer(levels, buildPath, BuildTarget.Android, BuildOptions.None);

    if(manifestFileExists)
    {
        File.Delete(Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"));
        File.Copy(Path.Combine(Application.dataPath, "Plugins/Android/tmpManifestFile.xml"), Path.Combine(Application.dataPath, "Plugins/Android/AndroidManifest.xml"));
        File.Delete(Path.Combine(Application.dataPath, "Plugins/Android/tmpManifestFile.xml"));
    }

    Process.Start(Path.GetDirectoryName(buildPath));
}

( PERMISSIONS_NAMES_TO_DELETE being a string[] of the permissions names to delete. To get the permissions names list you can look here )

What it does is:

  • get the previous AndroidManifest.xml file (if it exists) in /Android/Plugins/ folder, copy it to a temporary one and delete it
  • perform a first build to let Unity generate an AndroidManifest.xml file on his own
  • edit the manifest to "delete" unnecessary permissions
  • save the edited manifest to /Android/Plugins/
  • perform a second build with a correctly set manifest

The idea behind the permission deletion is to set the maximum API level to such a lower level, the permissions will not be usable (please note the permission MUST exists at this API level).

Hope this helps,

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM