We were planning to use Vivox as our VoiP solution for our game coming to the official Meta Quest Store.
But Bluetooth permissions are not accepted.
We tried the following:
- Create custom manifest (bluetooth permission still present)
- adding:
<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove" /> to custom manifest, still bluetooth permission present
- adding:
<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" tools:node="remove" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" tools:node="remove" />
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" tools:node="remove" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" tools:node="remove" />
<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove" />
permission still added.
- adding
<uses-permission android:name="android.permission.BLUETOOTH" android:maxSdkVersion="1"/>, still permission for bluetooth perssists.
So it seems we are forced to remove Vivox as our solution and go with another vendor.
Is there anything we missed?
Hi,
Can you please try the following steps:
-
Add xmlns:tools=“http://schemas.android.com/tools” to the <manifest …> tag.
For example, something like the following, but including any other tags already existing in the <manifest …> tag:
<manifest xmlns:tools="http://schemas.android.com/tools">
-
Add these two lines under the <manifest …> tag:
<uses-permission android:name="android.permission.BLUETOOTH" tools:node="remove"/>```
After rebuilding your application and reinstalling you should have the following occur:
- No popup related to nearby devices.
- Bluetooth permission is denied.
- Nearby devices permissions is not listed in the permissions of your installed application.
- Connecting a BT device to the Android device nothing happens related to BT; all audio is rendered and captured through the speakerphone.
Hi Dylan,
We tested your solution and android.permission.BLUETOOTH_CONNECT was gone but not the android.permission.BLUETOOTH permission.
Is there a specific order and are we missing or do the need to be at a specific location in the manifest?
thank you so much
I know this is out of date, but for anybody who hits it in future, I found the final step to solving the above problem. Dylan is correct in how to remove the unwanted permissions, and in general it works. However if the oculus xr package from unity is included, it’s got a fun little ‘helpful’ line in OculusBuildProcessor.cs:
RemoveNameValueElementInTag(manifestDoc, nodePath, “uses-permission”, “android:name”, “android.permission.BLUETOOTH”);
Intended to remove that permission if introduced by unity for the microphone. However when using the above technique to prevent VIVOX adding it, the effect of the Oculus helpful line is to remove your removal 
I had to take a copy of the com.unity.xr.oculus package and comment out that line in OculusBuildProcessor.cs
Update: taking a copy of the xr package breaks everything, so whilst my above comment is accurate in terms of the problem, I sadly don’t yet have a solution!
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Xml;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEditor.Android;
using UnityEditor.Build;
using UnityEditor.Build.Reporting;
using Unity.XR.Oculus;
using UnityEditor;
using UnityEditor.XR.Management;
using UnityEngine.XR.Management;
namespace UnityEditor.XR.Oculus
{
#if UNITY_ANDROID
class AfterOculusSDKManifestProcessing : IPostGenerateGradleAndroidProject
{
static readonly string k_AndroidURI = "http://schemas.android.com/apk/res/android";
static readonly string k_AndroidManifestPath = "/src/main/AndroidManifest.xml";
public void OnPostGenerateGradleAndroidProject(string path)
{
if(!OculusBuildTools.OculusLoaderPresentInSettingsForBuildTarget(BuildTargetGroup.Android))
return;
var manifestPath = path + k_AndroidManifestPath;
var manifestDoc = new XmlDocument();
manifestDoc.Load(manifestPath);
//get manifest xml node
var manifest_node = manifestDoc.SelectSingleNode("/manifest");
//list of permissions that must be gone!
string[] DODGY_PERMISSIONS = {"android.permission.BLUETOOTH", "android.permission.BLUETOOTH_CONNECT", "android.permission.MODIFY_AUDIO_SETTINGS"};
//remove any existing requests for these permissions
var existing_nodes = manifest_node.ChildNodes.Cast<XmlNode>().Where(x => x.Name=="uses-permission").ToList();
foreach (var node in existing_nodes)
{
var attr = node.Attributes["android:name"];
if (attr != null)
{
string val = attr.Value;
if (DODGY_PERMISSIONS.Contains(val))
manifest_node.RemoveChild(node);
}
}
//explicitly add the permissions with the "remove" attribute
foreach (var permission in DODGY_PERMISSIONS)
{
var permission_element = manifestDoc.CreateElement("uses-permission");
permission_element.SetAttribute("name", k_AndroidURI, permission);
permission_element.SetAttribute("node", "http://schemas.android.com/tools", "remove");
manifest_node.AppendChild(permission_element);
}
manifestDoc.Save(manifestPath);
}
public int callbackOrder { get { return 10001; } }
void DebugPrint(XmlDocument doc)
{
var sw = new System.IO.StringWriter();
var xw = XmlWriter.Create(sw);
doc.Save(xw);
Debug.Log(sw);
}
}
#endif
}
Fixes it for anybody else hitting this issue ^^
Thanks for sharing, that fixed it for me as well.