INSTALL PARSE FAILED MANIFEST MALFORMED only on some devices

My Android app fails to install on some “random”, older API devices (anything less than API level 25) with the error:

INSTALL_PARSE_FAILED_MANIFEST_MALFORMED

So, basically it seems… API < 25 ? MALFORMED : GOOD

On stack overflow they say make sure your package name is lowercase, which I’ve got.

Has anyone got any ideas?

Manifest:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="128" android:versionName="1.2.8.0" package="com.vrgamestudio.thegame" android:targetSandboxVersion="2" android:installLocation="auto">
	<uses-sdk android:targetSdkVersion="29" />
	<application android:isGame="true" android:label="@string/ApplicationName" android:icon="@drawable/GameThumbnail" android:theme="@style/Theme.Splash">
		<activity android:name="TheGame.ActivityMain" android:alwaysRetainTaskState="true" android:launchMode="singleInstance" android:screenOrientation="fullSensor" android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout">
			<intent-filter>
				<action android:name="android.intent.action.MAIN" />
				<category android:name="android.intent.category.LAUNCHER" />
			</intent-filter>
		</activity>
		<activity android:name="TheGame.ActivityTV" android:icon="@drawable/gamethumbnail" android:theme="@style/Theme.Leanback" android:banner="@drawable/banner320x180" android:alwaysRetainTaskState="true" android:launchMode="singleInstance" android:screenOrientation="fullSensor" android:configChanges="orientation|keyboard|keyboardHidden|screenSize|screenLayout">
			<intent-filter>
				<action android:name="android.intent.action.MAIN" />
				<category android:name="android.intent.category.LEANBACK_LAUNCHER" />
			</intent-filter>
		</activity>
	</application>
	<uses-feature android:name="android.hardware.gamepad" android:required="false" />
	<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
	<uses-feature android:name="android.hardware.faketouch" android:required="false" />
	<uses-feature android:name="android.hardware.telephony" android:required="false" />
	<uses-feature android:name="android.hardware.camera" android:required="false" />
	<uses-feature android:name="android.hardware.nfc" android:required="false" />
	<uses-feature android:name="android.hardware.location.gps" android:required="false" />
	<uses-feature android:name="android.hardware.microphone" android:required="false" />
	<uses-feature android:name="android.hardware.sensor" android:required="false" />
	<uses-feature android:name="android.software.leanback" android:required="false" />
	<uses-feature android:name="android.hardware.type.television" android:required="false" />
	<uses-feature android:name="android.software.leanback_only" android:required="false" />
</manifest>

Many days later and I think I’ve finally solved this one.

On older api versions (<25 and therefore you should ALWAYS do this to support them?) it seems Android requires that:

the fully qualified Namespace of the Activity Name property must be lowercase.

Therefore, when you’re communicating to Java/Android on how to start your app, in your Activity1 class you may have code like this:

namespace TheGame
{
    [Activity(Name = "thegame.ActivityMain")]
    public class Activity1 : Microsoft.Xna.Framework.AndroidGameActivity
    {
    ...
    }
}

(note: we tell Android that the namespace is lowercase namespace “thegame” then a made-up “ActivityMain”).

Then in your manifest you may do this to refer to it:

<application ....>
    <activity android.name="thegame.ActivityMain" ... >
	<intent-filter>
		<action android:name="android.intent.action.MAIN" />
		<category android:name="android.intent.category.LAUNCHER" />
	</intent-filter>
    </activity>
</application>

Just to be clear, it appears that AFTER API level 25 Android doesn’t mind if you use proper C# style Pascal casing of your namespace, in this case, “TheGame”.

This is a problem because it lulls you into a sense that all is well when in fact it certainly isn’t and you won’t know about it unless you specifically test for old API devices, or as in my case, when you see bad reviews from people saying the app won’t install for them and you begin investigation.

1 Like