[Solved] Launch URL doesn't work in Android for SDK target 30

If you want to add a button in your app to open an external webpage you would use a Launch URL blueprint block to do this. I’m on my first Android app and working my way through the Google Play requirements. One such requirement is the SDK target for new apps must be set to 30. In SDK target 29 the Launch URL block worked, in 30 it doesn’t.

It seems there is a new permission requirement now. In your project settings, go to the Advanced APK Packaging section → Extra Permissions → Add a new array element: android.permission.QUERY_ALL_PACKAGES

As a secondary point, for AAB packaging, in the App Bundles section, make sure you check Generate bundle (AAB) and in the APK Packaging section check Package game inside .apk. If you are using the save game functionality, in the APK Packaging section, check Use ExternalFilesDir for UE4Game files to enable file writes.

2 Likes

See above.

According to Google, this permission is kind of sensitive and may be rejected.
Explained here

Looking for a less intrusive method.

@BOB.cat did you find a solution?
I’m also looking for a way to open URLs in the browser, as it was possible before SDK target 30 :confused:

Okay so I was looking into this in a bit more detail. As others already wrote, adding the android.permission.QUERY_ALL_PACKAGES works, but is definitely not recommended.

The easiest way of solving this is to upgrade the project to 4.27. With 4.27 the following commit fixes this issue for SDK target 30: https://github.com/EpicGames/UnrealEngine/commit/e49afc395b171e1d0c39e2d79b16ca2be8ea982c

In case upgrading isn’t an option for some reason, there are 2 things that are required additionally to make launching URLs work for SDK target 30 without adding the QUERY_ALL_PACKAGES permission:

As described here, the android manifest file needs to be extended to properly handle queries to intents of other apps - like when opening a link in a browser.
This can be done using a UPL file to edit the manifest, as this file is assembled while packaging the project. A neat explanation of how to create and use such a file to modify the manifest can be found here
For the UPL file use this content to add the required lines to the manifest:

<?xml version="1.0" encoding="utf-8"?>
<root xmlns:android="http://schemas.android.com/apk/res/android">
    <androidManifestUpdates>
        <addElements tag="manifest">  
          <queries>
            <intent>
              <action android:name="android.intent.action.VIEW" />
              <category android:name="android.intent.category.BROWSABLE" />
              <data android:scheme="http" />
            </intent>
            <intent>
              <action android:name="android.intent.action.VIEW" />
              <category android:name="android.intent.category.BROWSABLE" />
              <data android:scheme="https" />
            </intent>
          </queries>
        </addElements>
    </androidManifestUpdates>
</root>

In addition to that, you need to use a source build of the engine to add the following to line 4204 in Engine/Build/Android/Java/src/com/epicgames/ue4/GameActivity.java.template:

BrowserIntent.addCategory(Intent.CATEGORY_BROWSABLE);

You can check the above linked github commit to see the full code and where the above shown line needs to be added exactly.

2 Likes

so what is the bad side of the first method?

By first method you mean adding the android.permission.QUERY_ALL_PACKAGES permission, right?

It is basically in our all interest to give apps on our android devices only those permissions that are really required. Otherwise, in case each app has all permissions, you wont be able to tell if some of them are now spying on your phone calls or maybe tracking what apps you are having installed - where the latter would be doable using the QUERY_ALL_PACKAGES permission.

Therefore Android ranks this permission as “high risk” / “sensitive” and only allows it to be used if actually required by your app. This means, when just using it as a shortcut to open links, your app will pretty likely never be approved to be published on the play store.

You can read more about it here, as @BOB.cat wrote already:

Here a quote (from link above) explaining further when the usage of this permission would be allowed:

To use this permission, your app must fall within permitted uses below, and have a core purpose to search for all apps on the device. You must be able to adequately justify why a less intrusive method of app visibility will not sufficiently enable your app’s policy-compliant user-facing core functionality.
Core functionality is defined as the main purpose of the app. Without this core ability to search for all apps on the device, the app is “broken” or becomes unusable. The core functionality, as well as any core features that comprise this core functionality, must all be prominently documented and promoted in the app’s description.

1 Like

@Featuriing so can i use Android SDK 29 is better than without using QUERY_ALL_PACKAGES permission with SDK 30 right?

i mean Android SDK 29 is better right? for “Launch URL”

for me am using LAUNCH URL for Deep Link

Yes, in theory that would be correct @ganbaa_elmer

But Google requires you to use target sdk 30 to be able to publish a new app, unfortunately.
You can read more about that here: Meet Google Play's target API level requirement  |  Android Developers

The easiest solution is to just upgrade to 4.27 :slight_smile:

1 Like

@Featuriing i followed your instruction but it didn’t work
My DeepLink didn’t work. Maybe i misunderstood some steps:
Can you instruct for us to step by step.

Please help me

@ganbaa_elmer are you trying to open a deepLink from an application like whatsapp, which then should automatically open your own app?
Or are you trying to open a link like https://twitter.com using the LaunchURL node from within your app, which then should bring up the installed twitter app?

@Featuriing am trying to open app by using Launch URL. source app is my ue4 game and destination apps is already installed apps on my phone. Not websites, not like https://twitter.com
i mean i need to open Twitter app on my mobile phone. (Android and IOS)
for Android SDK 29 its working fine but on SDK 30 it didn’t work.

@Featuriing any suggestions?
please step by step instructions

@ganbaa_elmer actually using launchURL with “https://twitter.com” on your android smartphone should automatically open the twitter app.
What happens if you launch lets say https://google.com? Is the browser opening on android?

As I wrote in my initial post: There are 2 things you need to do. You have to add the to your android manifest file using a custom UPL file. And you have to edit the engine source code to add the CATEGORY_BROWSABLE to the browserIntent before starting it. Once these two things are done (and the engine is recompiled) you should be able to properly open apps like twitter, using http://twitter.com, for example.

Check my initial post, as well as the links that I was sharing there, for more detailed instructions :slight_smile:

1 Like

Not working on 4.27 at all

Hello

So I can use Android SDK 29 better than not using QUERY_ALL_PACKAGES permission with SDK 30 right?

I mean Android SDK 29 is better right?

helo

i found a solution https://modilimitado.com/hole-house-apk you can click here for reference It

Hello,

I also struggled with this problem.

I didn’t wan’t to have the QUERY_ALL_PACKAGES activated for my app while still being able to use the Launch URL node to open the Google Maps App on Android.
I found a solution that doesn’t require to recompile the whole engine at this link which I translated in my language with google translate.

It tells you to edit the java file Engine/Build/Android/Java/src/com/epicgames/ue4/GameActivity.java.template
in the engine folder and comment out some lines that call the getPackageManager() function which requires that QUERY_ALL_PACKAGES permission:

//if (BrowserIntent.resolveActivity(getPackageManager()) != null)
//{
    Log.debug("[JAVA} AndroidThunkJava_LaunchURL: Starting activity");
    startActivity(BrowserIntent);
//}

On my specific case it worked and maybe someone will find this useful here :slight_smile: