|
|
|
@@ -841,8 +841,10 @@ private: |
|
|
|
props.add (new TextPropertyComponent (androidOtherPermissions.getPropertyAsValue(), "Custom permissions", 2048, false),
|
|
|
|
"A space-separated list of other permission flags that should be added to the manifest.");
|
|
|
|
|
|
|
|
props.add (new TextPropertyComponent (androidManifestCustomXmlElements.getPropertyAsValue(), "Custom manifest xml elements", 8192, true),
|
|
|
|
"You can specify custom XML elements that will be added to AndroidManifest.xml as children of <application> element.");
|
|
|
|
props.add (new TextPropertyComponent (androidManifestCustomXmlElements.getPropertyAsValue(), "Custom manifest XML content", 8192, true),
|
|
|
|
"You can specify custom AndroidManifest.xml content overriding the default one generated by Projucer. "
|
|
|
|
"Projucer will automatically create any missing and required XML elements and attributes "
|
|
|
|
"and merge them into your custom content.");
|
|
|
|
}
|
|
|
|
|
|
|
|
//==============================================================================
|
|
|
|
@@ -1366,28 +1368,39 @@ private: |
|
|
|
//==============================================================================
|
|
|
|
XmlElement* createManifestXML() const
|
|
|
|
{
|
|
|
|
XmlElement* manifest = new XmlElement ("manifest");
|
|
|
|
XmlElement* manifest = XmlDocument::parse (androidManifestCustomXmlElements.get());
|
|
|
|
|
|
|
|
manifest->setAttribute ("xmlns:android", "http://schemas.android.com/apk/res/android");
|
|
|
|
manifest->setAttribute ("android:versionCode", androidVersionCode.get());
|
|
|
|
manifest->setAttribute ("android:versionName", project.getVersionString());
|
|
|
|
manifest->setAttribute ("package", getActivityClassPackage());
|
|
|
|
if (manifest == nullptr)
|
|
|
|
manifest = new XmlElement ("manifest");
|
|
|
|
|
|
|
|
setAttributeIfNotPresent (*manifest, "xmlns:android", "http://schemas.android.com/apk/res/android");
|
|
|
|
setAttributeIfNotPresent (*manifest, "android:versionCode", androidVersionCode.get());
|
|
|
|
setAttributeIfNotPresent (*manifest, "android:versionName", project.getVersionString());
|
|
|
|
setAttributeIfNotPresent (*manifest, "package", getActivityClassPackage());
|
|
|
|
|
|
|
|
if (! isLibrary())
|
|
|
|
{
|
|
|
|
XmlElement* screens = manifest->createNewChildElement ("supports-screens");
|
|
|
|
screens->setAttribute ("android:smallScreens", "true");
|
|
|
|
screens->setAttribute ("android:normalScreens", "true");
|
|
|
|
screens->setAttribute ("android:largeScreens", "true");
|
|
|
|
screens->setAttribute ("android:anyDensity", "true");
|
|
|
|
if (manifest->getChildByName ("supports-screens") == nullptr)
|
|
|
|
{
|
|
|
|
XmlElement* screens = manifest->createNewChildElement ("supports-screens");
|
|
|
|
screens->setAttribute ("android:smallScreens", "true");
|
|
|
|
screens->setAttribute ("android:normalScreens", "true");
|
|
|
|
screens->setAttribute ("android:largeScreens", "true");
|
|
|
|
screens->setAttribute ("android:anyDensity", "true");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
XmlElement* sdk = manifest->createNewChildElement ("uses-sdk");
|
|
|
|
sdk->setAttribute ("android:minSdkVersion", androidMinimumSDK.get());
|
|
|
|
sdk->setAttribute ("android:targetSdkVersion", androidMinimumSDK.get());
|
|
|
|
auto* sdk = getOrCreateChildWithName (*manifest, "uses-sdk");
|
|
|
|
setAttributeIfNotPresent (*sdk, "android:minSdkVersion", androidMinimumSDK.get());
|
|
|
|
setAttributeIfNotPresent (*sdk, "android:targetSdkVersion", androidMinimumSDK.get());
|
|
|
|
|
|
|
|
{
|
|
|
|
const StringArray permissions (getPermissionsRequired());
|
|
|
|
StringArray permissions (getPermissionsRequired());
|
|
|
|
|
|
|
|
forEachXmlChildElementWithTagName (*manifest, child, "uses-permission")
|
|
|
|
{
|
|
|
|
permissions.removeString (child->getStringAttribute ("android:name"), false);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = permissions.size(); --i >= 0;)
|
|
|
|
manifest->createNewChildElement ("uses-permission")->setAttribute ("android:name", permissions[i]);
|
|
|
|
@@ -1395,19 +1408,33 @@ private: |
|
|
|
|
|
|
|
if (project.getModules().isModuleEnabled ("juce_opengl"))
|
|
|
|
{
|
|
|
|
XmlElement* feature = manifest->createNewChildElement ("uses-feature");
|
|
|
|
feature->setAttribute ("android:glEsVersion", (androidMinimumSDK.get().getIntValue() >= 18 ? "0x00030000" : "0x00020000"));
|
|
|
|
feature->setAttribute ("android:required", "true");
|
|
|
|
XmlElement* glVersion = nullptr;
|
|
|
|
|
|
|
|
forEachXmlChildElementWithTagName (*manifest, child, "uses-feature")
|
|
|
|
{
|
|
|
|
if (child->getStringAttribute ("android:glEsVersion").isNotEmpty())
|
|
|
|
{
|
|
|
|
glVersion = child;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (glVersion == nullptr)
|
|
|
|
glVersion = manifest->createNewChildElement ("uses-feature");
|
|
|
|
|
|
|
|
setAttributeIfNotPresent (*glVersion, "android:glEsVersion", (androidMinimumSDK.get().getIntValue() >= 18 ? "0x00030000" : "0x00020000"));
|
|
|
|
setAttributeIfNotPresent (*glVersion, "android:required", "true");
|
|
|
|
}
|
|
|
|
|
|
|
|
if (! isLibrary())
|
|
|
|
{
|
|
|
|
XmlElement* app = manifest->createNewChildElement ("application");
|
|
|
|
app->setAttribute ("android:label", "@string/app_name");
|
|
|
|
auto* app = getOrCreateChildWithName (*manifest, "application");
|
|
|
|
setAttributeIfNotPresent (*app, "android:label", "@string/app_name");
|
|
|
|
|
|
|
|
if (androidTheme.get().isNotEmpty())
|
|
|
|
app->setAttribute ("android:theme", androidTheme.get());
|
|
|
|
setAttributeIfNotPresent (*app, "android:theme", androidTheme.get());
|
|
|
|
|
|
|
|
if (! app->hasAttribute ("android:icon"))
|
|
|
|
{
|
|
|
|
ScopedPointer<Drawable> bigIcon (getBigIcon()), smallIcon (getSmallIcon());
|
|
|
|
|
|
|
|
@@ -1417,29 +1444,66 @@ private: |
|
|
|
|
|
|
|
if (androidMinimumSDK.get().getIntValue() >= 11)
|
|
|
|
app->setAttribute ("android:hardwareAccelerated", "false"); // (using the 2D acceleration slows down openGL)
|
|
|
|
else
|
|
|
|
app->removeAttribute ("android:hardwareAccelerated");
|
|
|
|
|
|
|
|
auto* act = getOrCreateChildWithName (*app, "activity");
|
|
|
|
|
|
|
|
setAttributeIfNotPresent (*act, "android:name", getActivitySubClassName());
|
|
|
|
setAttributeIfNotPresent (*act, "android:label", "@string/app_name");
|
|
|
|
|
|
|
|
if (! act->hasAttribute ("android:configChanges"))
|
|
|
|
{
|
|
|
|
String configChanges ("keyboardHidden|orientation");
|
|
|
|
if (androidMinimumSDK.get().getIntValue() >= 13)
|
|
|
|
configChanges += "|screenSize";
|
|
|
|
|
|
|
|
act->setAttribute ("android:configChanges", configChanges);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
auto configChanges = act->getStringAttribute ("android:configChanges");
|
|
|
|
|
|
|
|
XmlElement* act = app->createNewChildElement ("activity");
|
|
|
|
act->setAttribute ("android:name", getActivitySubClassName());
|
|
|
|
act->setAttribute ("android:label", "@string/app_name");
|
|
|
|
if (androidMinimumSDK.get().getIntValue() < 13 && configChanges.contains ("screenSize"))
|
|
|
|
{
|
|
|
|
configChanges = configChanges.replace ("|screenSize", "")
|
|
|
|
.replace ("screenSize|", "")
|
|
|
|
.replace ("screenSize", "");
|
|
|
|
|
|
|
|
act->setAttribute ("android:configChanges", configChanges);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
String configChanges ("keyboardHidden|orientation");
|
|
|
|
if (androidMinimumSDK.get().getIntValue() >= 13)
|
|
|
|
configChanges += "|screenSize";
|
|
|
|
setAttributeIfNotPresent (*act, "android:screenOrientation", androidScreenOrientation.get());
|
|
|
|
|
|
|
|
act->setAttribute ("android:configChanges", configChanges);
|
|
|
|
act->setAttribute ("android:screenOrientation", androidScreenOrientation.get());
|
|
|
|
auto* intent = getOrCreateChildWithName (*act, "intent-filter");
|
|
|
|
|
|
|
|
XmlElement* intent = act->createNewChildElement ("intent-filter");
|
|
|
|
intent->createNewChildElement ("action")->setAttribute ("android:name", "android.intent.action.MAIN");
|
|
|
|
intent->createNewChildElement ("category")->setAttribute ("android:name", "android.intent.category.LAUNCHER");
|
|
|
|
auto* action = getOrCreateChildWithName (*intent, "action");
|
|
|
|
setAttributeIfNotPresent (*action, "android:name", "android.intent.action.MAIN");
|
|
|
|
|
|
|
|
for (XmlElement* e = XmlDocument::parse (androidManifestCustomXmlElements.get()); e != nullptr; e = e->getNextElement())
|
|
|
|
app->addChildElement (e);
|
|
|
|
auto* category = getOrCreateChildWithName (*intent, "category");
|
|
|
|
setAttributeIfNotPresent (*category, "android:name", "android.intent.category.LAUNCHER");
|
|
|
|
}
|
|
|
|
|
|
|
|
return manifest;
|
|
|
|
}
|
|
|
|
|
|
|
|
static XmlElement* getOrCreateChildWithName (XmlElement& element, const String& name)
|
|
|
|
{
|
|
|
|
auto* child = element.getChildByName (name);
|
|
|
|
|
|
|
|
if (child == nullptr)
|
|
|
|
child = element.createNewChildElement (name);
|
|
|
|
|
|
|
|
return child;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void setAttributeIfNotPresent (XmlElement& element, const Identifier& attribute, const String& value)
|
|
|
|
{
|
|
|
|
if (! element.hasAttribute (attribute.toString()))
|
|
|
|
element.setAttribute (attribute, value);
|
|
|
|
}
|
|
|
|
|
|
|
|
StringArray getPermissionsRequired() const
|
|
|
|
{
|
|
|
|
StringArray s;
|
|
|
|
|