Forum Discussion
FredTA
11 months agoProtege
How to launch another app from my first app (outside the store)
For context:
My team is trying to create a delivery system for VR EdTech applications at Imperial College London. For our desktop version, each individual learning app is built to an AssetBundle and DLL and uploaded to our server. Our main executable ("launcher app") can then browse those files, download them, import them directly into the program and launch them as a separate scene. This works great, since we only need to install that one main application to all our PCs, as that application can then download/install all the others.
Now, we want something similar to work on a standalone quest.
My understanding is that this isn't possible on Android (I hear you can't load new code into an app at runtime like you can with our DLL method on Windows... please correct me if I'm wrong, I'd love to know how other games on the Quest with mod support work... my mind goes to Contractors, it comes with a mod browser letting you import different game modes, there certainly seems to be actual logic that comes along with these mods rather than just assets)
The solution we're trying is to instead build each individual learning application as a standalone APK, and have our central application download those APKs and launch them.
To clarify, I need this work entirely outside the regular Quest store system. I want to sideload our launcher app onto the headsets, enable unknown sources/dev mode etc, and give the headsets to our students, who can then use the launcher app to browse and open the learning apps we have on our server. That rules our the whole "Deep Linking" thing. Furthermore, the launcher app can't have any knowledge of the learning apps it's going to launch at compile time. It can however be fed the names of the packages to launch programmatically.
Building, uploading and downloading the APK - all fine. The problem is launching that APK from inside the main program.
Here's the code from my main "launcher" application
public void LaunchApp()
{
Debug.Log("Try launch app 1");
string packageName = "com.ImperialCollegeLondon.VE2Hub24"; //This is definitely the name of the package I want to launch, works fine launching from side quest or from the headset's menu
var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
var currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
var packageManager = currentActivity.Call<AndroidJavaObject>("getPackageManager");
var launchIntent = packageManager.Call<AndroidJavaObject>("getLaunchIntentForPackage", packageName);
currentActivity.Call("startActivity", launchIntent);
}
This gives me the following error
<br>java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData(android.content.Context)' on a null object reference<br>java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.content.Intent.migrateExtraStreamToClipData(android.content.Context)' on a null object reference<br> at android.app.Instrumentation.execStartActivity(Instrumentation.java:1756)<br> at android.app.Activity.startActivityForResult(Activity.java:5411)<br> at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:728)<br> at android.app.Activity.startActivityForResult(Activity.java:5369)<br> at androidx.activity.ComponentActivity.startActivityForResult(ComponentActivity.java:709)<br> at android.app.Activity.startActivity(Activity.java:5755)<br> at android.app.Activity.startActivity(Activity.java:5708)<br> at UnityEngine.AndroidJNISafe.CheckException ()
Here's the manifest for the app I'm trying to open
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="0.1.0"
android:installLocation="0"
android:compileSdkVersion="35"
android:compileSdkVersionCodename="15"
package="com.ImperialCollegeLondon.VE2Hub24"
platformBuildVersionCode="35"
platformBuildVersionName="15">
<uses-sdk
android:minSdkVersion="32"
android:targetSdkVersion="35" />
<supports-screens
android:anyDensity="true"
android:smallScreens="true"
android:normalScreens="true"
android:largeScreens="true"
android:xlargeScreens="true" />
<supports-gl-texture
android:name="GL_KHR_texture_compression_astc_ldr" />
<uses-permission
android:name="android.permission.INTERNET" />
<uses-permission
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature
android:name="android.hardware.vr.headtracking"
android:required="true"
android:version="1" />
<uses-feature
android:glEsVersion="0x30000" />
<uses-feature
android:name="android.hardware.vulkan.version"
android:required="false" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<uses-feature
android:name="android.hardware.touchscreen.multitouch"
android:required="false" />
<uses-feature
android:name="android.hardware.touchscreen.multitouch.distinct"
android:required="false" />
<uses-permission
android:name="android.permission.READ_EXTERNAL_STORAGE" />
<permission
android:name="com.ImperialCollegeLondon.VE2Hub24.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION"
android:protectionLevel="0x2" />
<uses-permission
android:name="com.ImperialCollegeLondon.VE2Hub24.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" />
<application
android:label="@ref/0x7f0d0021"
android:icon="@ref/0x7f0c0000"
android:debuggable="true"
android:allowBackup="false"
android:extractNativeLibs="true"
android:networkSecurityConfig="@ref/0x7f100000"
android:appComponentFactory="androidx.core.app.CoreComponentFactory"
android:enableOnBackInvokedCallback="false">
<meta-data
android:name="unityplayer.SkipPermissionsDialog"
android:value="false" />
<meta-data
android:name="com.samsung.android.vr.application.mode"
android:value="vr_only" />
<meta-data
android:name="com.oculus.ossplash.background"
android:value="black" />
<meta-data
android:name="com.oculus.telemetry.project_guid"
android:value="07bc858d-06e3-41e0-b5ab-5449f36054fd" />
<meta-data
android:name="com.oculus.supportedDevices"
android:value="quest2|questpro|quest3|quest3s" />
<meta-data
android:name="unity.splash-mode"
android:value="0" />
<meta-data
android:name="unity.splash-enable"
android:value="true" />
<meta-data
android:name="unity.launch-fullscreen"
android:value="true" />
<meta-data
android:name="unity.render-outside-safearea"
android:value="true" />
<meta-data
android:name="notch.config"
android:value="portrait|landscape" />
<meta-data
android:name="unity.auto-report-fully-drawn"
android:value="true" />
<meta-data
android:name="unity.auto-set-game-state"
android:value="true" />
<meta-data
android:name="unity.strip-engine-code"
android:value="true" />
<activity
android:theme="@ref/0x7f0e00a1"
android:name="com.unity3d.player.UnityPlayerGameActivity"
android:enabled="true"
android:exported="true"
android:excludeFromRecents="true"
android:launchMode="2"
android:screenOrientation="0"
android:configChanges="0x17f0"
android:hardwareAccelerated="false"
android:resizeableActivity="false">
<intent-filter>
<category
android:name="android.intent.category.LAUNCHER" />
<category
android:name="com.oculus.intent.category.VR" />
<action
android:name="android.intent.action.MAIN" />
</intent-filter>
<meta-data
android:name="com.oculus.vr.focusaware"
android:value="true" />
<meta-data
android:name="notch_support"
android:value="true" />
</activity>
<meta-data
android:name="com.unity.xr.oculus.LowOverheadMode"
android:value="false" />
<meta-data
android:name="com.unity.xr.oculus.LateLatching"
android:value="false" />
<meta-data
android:name="com.unity.xr.oculus.LateLatchingDebug"
android:value="false" />
<provider
android:name="androidx.startup.InitializationProvider"
android:exported="false"
android:authorities="com.ImperialCollegeLondon.VE2Hub24.androidx-startup">
<meta-data
android:name="androidx.emoji2.text.EmojiCompatInitializer"
android:value="androidx.startup" />
<meta-data
android:name="androidx.lifecycle.ProcessLifecycleInitializer"
android:value="androidx.startup" />
</provider>
</application>
</manifest>
From what I can tell this manifest is all in order. interestingly, it lists the main activity as "com.unity3d.player.UnityPlayerGameActivity", rather than
com.unity3d.player.UnityPlayer", when I change my code instead to
var unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer");
I get a different error instead -
//<br>java.lang.NoSuchFieldError: no "Ljava/lang/Object;" field "currentActivity" in class "Lcom/unity3d/player/UnityPlayerGameActivity;" or its superclasses<br>java.lang.NoSuchFieldError: no "Ljava/lang/Object;" field "currentActivity" in class "Lcom/unity3d/player/UnityPlayerGameActivity;" or its superclasses<br> at UnityEngine.AndroidJNISafe.CheckException () [0x00000] in <00000000000000000000000000000000>:0 <br> at UnityEngine.AndroidJNISafe.GetStaticFieldID (System.IntPtr clazz, System.String name, System.String sig) [0x00000] in <00000000000000000000000000000000>:0 <br> at UnityEngine._AndroidJNIHelper.GetFieldID (System.IntPtr jclass, System.String fieldName, System.String signature, System.Boolean isStatic) [0x00000] in <00000000000000000000000000000000>:0 <br> at UnityEngine.AndroidJavaObject._GetStatic[FieldType] (System.String fieldName) [0x00000] in <00000000000000000000000000000000>:0 <br> at WorldLauncher.LaunchApp2 () [0x00000] in <
People tell me my first approach is more along the right lines...
So, what am I doing wrong? I've scoured the forums, but haven't found a solution that works in the modern day, on the Quest, outside the store.
Is what I'm trying to even possible? Please help!
Best,
Fred
- Found the fix, manifest needs the "query all packages" permission, like so<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.yourapp"><uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /><!-- Other permissions and application components --></manifest>
5 Replies
Replies have been turned off for this discussion
- FredTAProtegeFound the fix, manifest needs the "query all packages" permission, like so<manifest xmlns:android="http://schemas.android.com/apk/res/android"package="com.example.yourapp"><uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" /><!-- Other permissions and application components --></manifest>
- KhuYamHonored Guest
you GOD
- vercelsmithHonored Guest
It looks like your issue stems from the getLaunchIntentForPackage method returning null, which typically happens when the specified package name is incorrect, or the target app does not have a launchable activity. Since you confirmed the package name works when launching from SideQuest or the headset’s menu, you may need to explicitly specify the main activity in your intent. Try using new Intent() with setComponent(new ComponentName(packageName, "com.unity3d.player.UnityPlayerActivity")) instead of relying on getLaunchIntentForPackage. Additionally, ensure that the target app's manifest has <category android:name="android.intent.category.LAUNCHER"/> inside its activity declaration. If the issue persists, check the logs for further hints and confirm that the launcher website app has the necessary permissions to start external activities.
- FredTAProtege
Thanks for the thoughts - package name was correct and intent was launchable, what I was missing was the right permission in the manifest - see solution above
- vercelsmithHonored Guest
Since the issue was resolved by adding the right permission in the manifest, it’s likely that the missing permission was related to launching external applications or activities. In future cases like this, make sure to check the AndroidManifest.xml for necessary permissions, such as:
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
Also, ensure that the target app’s activity has the correct intent filters:
<intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter>
Quick Links
- Horizon Developer Support
- Quest User Forums
- Troubleshooting Forum for problems with a game or app
- Quest Support for problems with your device
Other Meta Support
Related Content
- 11 months ago
- 2 years ago
- 2 years ago
- 4 months ago