- Home /
How to remove Android permissions
I want to remove android permissions without export Google Android Project.
I put AndroidManifest.xml to 'Plugins/Android' folder. But Unity automatically merged this one.
Can I replace AndroidManifest.xml? If you know way to that, please tell me.
Answer by Mako-Infused · Aug 19, 2015 at 03:48 PM
It sounds like you want to alter the original AndroidManifest file that comes with the Unity Editor. A word of warning though: I wouldn't recommend doing this unless you're absolutely sure. Altering the base manifest will affect future projects and could create bugs, so make a back up!
Normally if you add another a manifest to the 'Plugins/Android' folder it will merge it with the existing one. However, by going to : 'C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines\androidplayer' and editing the 'AndroidManifest.xml' file located there, you can remove permissions directly (without any merge being necessary).
Some more information can be found here: http://answers.unity3d.com/questions/536095/how-to-write-an-androidmanifestxml-combining-diffe.html
Update: Another option is to rename the exported apk file extension to a zip, then you can edit the android manifest from there. This will save you the trouble of having to use a "Google Android Project".
I tried to check Android$$anonymous$$anifest.xml in 'C:\Program Files (x86)\Unity\Editor\Data\PlaybackEngines\androidplayer' and edit this. However, that has no permissions.
And I executed build, generated AP$$anonymous$$ has permission. I'm very confused.
That is pretty confusing because, to my knowledge, that's the base manifest that Unity uses. I'll look into this a little more and get back to you.
I noticed, Execute Build, Unity create 'Temp/StagingArea'. There are two manifest that 'Android$$anonymous$$anifest.xml' and 'Android$$anonymous$$anifest-main.xml'. 'Android$$anonymous$$anifest-main' is that merged 'Plugins/Android/Android$$anonymous$$anifest' and 'playbackengine/androidplayer/Android$$anonymous$$anifest'. 'Android$$anonymous$$anifest' is that 'Android$$anonymous$$anifest-main' to added permissions. I thought that I replace 'Temp/StagingArea/Android$$anonymous$$anifest' to my custom manifest has no permissions.
So, I tried this code.
[PostProcessBuild]
public static void ReplaceAndroid$$anonymous$$anifest(BuildTarget buildTarget, string pathToBuiltProject){
if (buildTarget == BuildTarget.Android) {
string manifestPath = "C:/user/~/Temp/StagingArea/Android$$anonymous$$anifest.xml";
string custom$$anonymous$$anifestPath = Application.dataPath + "/Plugins/Android/Android$$anonymous$$anifest.xml";
FileUtil.ReplaceFile(custom$$anonymous$$anifestPath, manifestPath);
}
}
However generated AP$$anonymous$$ has permissions. And 'Temp/StagingArea/Package-unaligned.apk' has permissions too.
Oh, the "PostProcessBuild" attribute is run after the build process has finished, so that's the reason why you're not getting any results. However, I'm glad you made some progress.
Unfortunately there is no way of altering how the build process works as it's being run. You can change it before it's built, but I'm not sure if that would help either since the temp file will probably just be overwritten. An alternative would be to creating your own, via the BuildPlayer method, although I'm honestly not sure that would help either.
Thanks for give me a lot of info. I decided to export Google Android Project this time.
Before I questioned to you, I exported GoogleAndroidProject and imported this to Android Studio to remove permissions. But I failed to create AP$$anonymous$$ with Android Studio. So I thought to edit Android$$anonymous$$anifest on Unity Editor.
Finally, The Path to "JD$$anonymous$$1.6" was wrong. (I wanted to signed apk with "JD$$anonymous$$1.6"). However, your answer was very helpful. Thanks.
Answer by skdev3 · Aug 16, 2019 at 12:04 PM
#if UNITY_ANDROID
using UnityEngine;
using UnityEditor;
using UnityEditor.Build;
using System.IO;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
class AndroidManifestFixBuildProcessor : MonoBehaviour, IPostprocessBuild
{
public int callbackOrder { get { return 1; } }
static string dataPath = "";
private static Thread _OnPostprocessBuildThread;
public void OnPostprocessBuild(BuildTarget target, string path)
{
Debug.Log("OnPostprocessBuild");
dataPath = Application.dataPath + "/../Temp";
Application.logMessageReceived += buildLogCallback;
if (_OnPostprocessBuildThread != null && _OnPostprocessBuildThread.IsAlive)
{
_OnPostprocessBuildThread.Interrupt();
_OnPostprocessBuildThread.Abort();
_OnPostprocessBuildThread = null;
}
_OnPostprocessBuildThread = new Thread(OnPostprocessBuildThread);
_OnPostprocessBuildThread.Start();
Debug.Log("Start OnPostprocessBuildThread");
}
private void OnPostprocessBuildThread()
{
while (true)
{
Debug.Log("Run AndroidManifestFixBuildProcessor");
AndroidManifestFixBuildProcessor.AndroidManifest(dataPath);
Thread.Sleep(400);
}
}
public static void buildLogCallback(string condition, string stackTrace, LogType type)
{
AndroidManifestFixBuildProcessor.AndroidManifest(dataPath);
if (condition.Contains("Build completed"))
{
if (_OnPostprocessBuildThread != null && _OnPostprocessBuildThread.IsAlive)
{
_OnPostprocessBuildThread.Interrupt();
_OnPostprocessBuildThread.Abort();
_OnPostprocessBuildThread = null;
}
Debug.Log("Stop OnPostprocessBuildThread");
Application.logMessageReceived -= buildLogCallback;
};
}
//
public static void AndroidManifestFinished(object sender, FinishedArgs args)
{
if (args.LinesRemoved > 0)
{
Debug.Log("<color=#FF8000>File:" + args.Filename + " LinesRemoved:" + args.LinesRemoved + " TotalLines:" + args.TotalLines + " </color>");
}
}
public static void AndroidManifest(string buildDir)
{
List<string> removedParams = new List<string>();
removedParams.Add("android.permission.BLUETOOTH");
removedParams.Add("android.permission.CHANGE_WIFI_MULTICAST_STATE");
removedParams.Add("android.permission.READ_PHONE_STATE");
TextLineRemover.OnFinished += AndroidManifestFinished;
// Debug.Log(buildDir);
string[] files = Directory.GetFiles(buildDir, "*.xml", SearchOption.AllDirectories);
foreach (string file in files)
{
string patchfile = Path.GetFullPath(file);
string TempPath = Path.GetTempPath();
string patchfileTMP = TempPath + Path.GetFileNameWithoutExtension(file) + ".tmp";
TextLineRemover.RemoveTextLines(removedParams, patchfile, patchfileTMP);
}
TextLineRemover.OnFinished -= AndroidManifestFinished;
}
}
/*
public class FixAndroidManifest
{
[MenuItem("Tools/FixAndroidManifest")]
static void FixAndroidManifestRun()
{
AndroidManifestFixBuildProcessor.AndroidManifest(Application.dataPath + "/../Temp");
}
}
*/
public static class TextLineRemover
{
public static void RemoveTextLines(IList<string> linesToRemove, string filename, string tempFilename)
{
// Initial values
int lineNumber = 0;
int linesRemoved = 0;
System.DateTime startTime = System.DateTime.Now;
// Read file
using (var sr = new StreamReader(filename))
{
// Write new file
using (var sw = new StreamWriter(tempFilename))
{
// Read lines
string line;
while ((line = sr.ReadLine()) != null)
{
lineNumber++;
// Look for text to remove
if (!ContainsString(line, linesToRemove))
{
// Keep lines that does not match
sw.WriteLine(line);
}
else
{
// Ignore lines that DO match
linesRemoved++;
InvokeOnRemovedLine(new RemovedLineArgs { RemovedLine = line, RemovedLineNumber = lineNumber });
}
}
}
}
// Delete original file
File.Delete(filename);
// ... and put the temp file in its place.
File.Move(tempFilename, filename);
// Final calculations
System.DateTime endTime = System.DateTime.Now;
InvokeOnFinished(new FinishedArgs { LinesRemoved = linesRemoved, TotalLines = lineNumber, TotalTime = endTime.Subtract(startTime), Filename = filename });
}
private static bool ContainsString(string line, IEnumerable<string> linesToRemove)
{
foreach (var lineToRemove in linesToRemove)
{
if (line.Contains(lineToRemove))
return true;
}
return false;
}
public static event RemovedLine OnRemovedLine;
public static event Finished OnFinished;
public static void InvokeOnFinished(FinishedArgs args)
{
Finished handler = OnFinished;
if (handler != null) handler(null, args);
}
public static void InvokeOnRemovedLine(RemovedLineArgs args)
{
RemovedLine handler = OnRemovedLine;
if (handler != null) handler(null, args);
}
}
public delegate void Finished(object sender, FinishedArgs args);
public class FinishedArgs
{
public int TotalLines { get; set; }
public int LinesRemoved { get; set; }
public System.TimeSpan TotalTime { get; set; }
public string Filename { get; set; }
}
public delegate void RemovedLine(object sender, RemovedLineArgs args);
public class RemovedLineArgs
{
public string RemovedLine { get; set; }
public int RemovedLineNumber { get; set; }
}
#endif //UNITY_ANDROID
Your answer
Follow this Question
Related Questions
Android Permissions API Version 1 Answer
Version 4.2.0f4 added new android permissions 0 Answers
How to check if user has given camera or location permissions (android) 0 Answers
Android Plugin and permissions 2 Answers
Check permissions on Android 2 Answers