Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[url_launcher] When targeting API 30, canLaunch always retrurns false #63727

Closed
Roshanalexander opened this issue Aug 14, 2020 · 28 comments
Closed
Labels
e: OS-version specific Affects only some versions of the relevant operating system found in release: 1.20 Found to occur in 1.20 found in release: 1.22 Found to occur in 1.22 has reproducible steps The issue has been confirmed reproducible and is ready to work on p: url_launcher Plugin to launch external applications package flutter/packages repository. See also p: labels. platform-android Android applications specifically

Comments

@Roshanalexander
Copy link

Roshanalexander commented Aug 14, 2020

url_launcher fails to launch website on Android API level 30 with the following error:

E/flutter (10278): #0      _TestScreenState._launchURL (package:test/home/test_screen.dart:235:7)
E/flutter (10278): <asynchronous suspension>
E/flutter (10278): #1      _TestScreenState.renderListTile.<anonymous closure> (package:test/home/test_screen.dart:159:58)
E/flutter (10278): #2      _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:992:19)
E/flutter (10278): #3      _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1098:38)
E/flutter (10278): #4      GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:184:24)
E/flutter (10278): #5      TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:524:11)
E/flutter (10278): #6      BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:284:5)
E/flutter (10278): #7      BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:256:7)
E/flutter (10278): #8      GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:158:27)
E/flutter (10278): #9      GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:224:20)
E/flutter (10278): #10     GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:200:22)
E/flutter (10278): #11     GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:158:7)
E/flutter (10278): #12     GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:104:7)
E/flutter (10278): #13     GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:88:7)
E/flutter (10278): #14     _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter (10278): #15     _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter (10278): #16     _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter (10278): #17     _invoke1 (dart:ui/hooks.dart:267:10)
E/flutter (10278): #18     _dispatchPointerDataPacket (dart:ui/hooks.dart:176:5)
E/flutter (10278): 
@Roshanalexander Roshanalexander changed the title url_launcher fails on Android API level 30 url_launcher fails to launch website on Android API level 30 Aug 14, 2020
@Roshanalexander
Copy link
Author

Flutter Doctor Output

[✓] Flutter (Channel stable, 1.20.2, on Mac OS X 10.15.6 19G2021, locale en-US)
    • Flutter version 1.20.2 at /Users/roshanalexander/Developer/flutter
    • Framework revision bbfbf1770c (9 hours ago), 2020-08-13 08:33:09 -0700
    • Engine revision 9d5b21729f
    • Dart version 2.9.1

[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.0)
    • Android SDK at /Users/roshanalexander/Library/Android/sdk
    • Platform android-30, build-tools 30.0.0
    • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)
    • All Android licenses accepted.

[✓] Xcode - develop for iOS and macOS (Xcode 11.6)
    • Xcode at /Applications/Xcode.app/Contents/Developer
    • Xcode 11.6, Build version 11E708
    • CocoaPods version 1.9.3

[✓] Android Studio (version 4.0)
    • Android Studio at /Applications/Android Studio.app/Contents
    • Flutter plugin version 47.1.2
    • Dart plugin version 193.7361
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6222593)

[✓] IntelliJ IDEA Ultimate Edition (version 2020.2)
    • IntelliJ at /Applications/IntelliJ IDEA.app
    • Flutter plugin version 48.1.4
    • Dart plugin version 202.6397.47

[✓] VS Code (version 1.47.3)
    • VS Code at /Applications/Visual Studio Code.app/Contents
    • Flutter extension version 3.13.2

[✓] Connected device (2 available)
    • sdk gphone x86 (mobile) • emulator-5554                        • android-x86 • Android 11 (API 30) (emulator)
    • iPhone 11 Pro (mobile)  • EEC90E5D-9551-42A4-916A-6D9FCDC1829A • ios         • com.apple.CoreSimulator.SimRuntime.iOS-13-6 (simulator)

• No issues found!

@darshankawar
Copy link
Member

Hi @Roshanalexander,
Please provide a minimal complete reproducible code sample that shows the issue. Also can you try the same on emulator or device < 30 and see if you still get the error ?
Thanks.

@darshankawar darshankawar added in triage Presently being triaged by the triage team waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds labels Aug 14, 2020
@Roshanalexander
Copy link
Author

Roshanalexander commented Aug 16, 2020

Hi @darshankawar,

The issue happens only on Android API level 30. Works fine on level <=29. Also, I'm unable to reproduce this issue on sample project.

I'm using the following code in my project:

if (await canLaunch(url)) {
      await launch(
        url,
        forceSafariVC: true,
        forceWebView: true,
        enableJavaScript: true,
      );
} else {
   throw 'Could not launch $url';
}

But if I take out the canLaunch(url) check, the application successfully launches the webview with the provided URL. It seems the canLuanch(url) check is where it fails.

@no-response no-response bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Aug 16, 2020
@Roshanalexander
Copy link
Author

One thing I notice when I build my application is that, I get the following warning:

Note: /Users/roshanalexander/Developer/flutter/.pub-cache/hosted/pub.dartlang.org/url_launcher-5.5.0/android/src/main/java/io/flutter/plugins/urllauncher/WebViewActivity.java uses or overrides a deprecated API.
Note: Recompile with -Xlint:deprecation for details.

But I do not get this warning when I use a new sample application and use the url_launcher package.

@darshankawar
Copy link
Member

Hi @Roshanalexander,
That seems to be a warning which should be fine. Can you provide the url you are trying to launch ?
Thanks.

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Aug 17, 2020
@Roshanalexander
Copy link
Author

Roshanalexander commented Aug 17, 2020

@darshankawar All URL's fail. I tried https://www.apple.com and this is the result.

E/flutter (11092): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Could not launch https://www.apple.com

This issue started happening after I upgraded Flutter from v1.17 to v1.20

@no-response no-response bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Aug 17, 2020
@darshankawar
Copy link
Member

Hi @Roshanalexander,
I tried on latest Stable (1.20.2) and used the official url_launcher plugin example on emulator with api 30 and was able to launch https://www.apple.com properly without any issues.

Screen Shot 2020-08-18 at 12 59 08 PM

Can you also try the official example on api 30 and see if you still experience the issue ?
Thanks.

@darshankawar darshankawar added the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Aug 18, 2020
@Roshanalexander
Copy link
Author

Roshanalexander commented Aug 18, 2020

@darshankawar If you read what I said above, that's exactly what I said too. This issue is only happening on just my application. Even if I copy my code to the sample application, it works fine. That is why I came here looking for any suggestion to troubleshoot the issue. If you've got any input on how to figure out that, please let me know.

@no-response no-response bot removed the waiting for customer response The Flutter team cannot make further progress on this issue until the original reporter responds label Aug 18, 2020
@darshankawar darshankawar added e: OS-version specific Affects only some versions of the relevant operating system found in release: 1.20 Found to occur in 1.20 has reproducible steps The issue has been confirmed reproducible and is ready to work on p: first party p: url_launcher Plugin to launch external applications platform-android Android applications specifically and removed in triage Presently being triaged by the triage team labels Aug 18, 2020
@Roshanalexander
Copy link
Author

Roshanalexander commented Aug 18, 2020

Hey @darshankawar, I found the issue and can be reproduced on a fresh application. All you need to do is, modify the targetSdkVersion and compileSdkVersion to 30 in root/android/app/build.gradle. Then it fails to launch any URLs.

@cedsan
Copy link

cedsan commented Aug 21, 2020

I'm also having the same issue when testing on a device running on API Level 30, canLaunch returns false. It works fine when running on < 30 API Level device

@alxkzmn
Copy link

alxkzmn commented Sep 4, 2020

I'm also experiencing this issue.

@anniek-valk
Copy link

Starting from API 30, there is a restriction on package visibility.

This basically means that you will have to list all apps your app wants to interact with. This can be done by adding the <queries> element to your app's AndroidManifest.xml file. Here is more information about that.

If your app needs to interact with all the installed apps on the device, you can fall back to using the QUERY_ALL_PACKAGES permission by adding the following to your AndroidManifest.xml file: <uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/> (note that Google might change it's policy regarding the use of this permission, which could cause your app to be rejected. This is not clear yet).

@TahaTesser
Copy link
Member

I can reproduce the issue canLaunch returns false

code sample
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Material App',
      theme: ThemeData.dark(),
      home: Home(),
    );
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Material App Bar'),
      ),
      body: Center(
        child: Container(
          child: Text('Hello World'),
        ),
      ),
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.add),
        onPressed: () async => _launchURL(),
      ),
    );
  }

  _launchURL() async {
    const url = 'https://flutter.dev';

    print("canLaunch ${await canLaunch(url)}");
    // if (await canLaunch(url)) {
    //   await launch(url);
    // } else {
    //   throw 'Could not launch $url';
    // }
  }
}

I/flutter ( 7863): canLaunch false
I/flutter ( 7863): canLaunch false
flutter doctor -v
[✓] Flutter (Channel master, 1.22.0-10.0.pre.137, on Microsoft Windows [Version 10.0.19041.450], locale en-US)
    • Flutter version 1.22.0-10.0.pre.137 at C:\Code\flutter_master
    • Framework revision 37e2013774 (3 hours ago), 2020-09-11 04:05:02 -0400
    • Engine revision bdaac368f8
    • Dart version 2.10.0 (build 2.10.0-115.0.dev)


[✓] Android toolchain - develop for Android devices (Android SDK version 30.0.2)
    • Android SDK at C:\Code\sdk
    • Platform android-30, build-tools 30.0.2
    • ANDROID_HOME = C:\Code\sdk
    • Java binary at: C:\Code\android-studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)
    • All Android licenses accepted.

[✓] Chrome - develop for the web
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[✓] Visual Studio - develop for Windows (Visual Studio Community 2019 16.7.2)
    • Visual Studio at C:\Program Files (x86)\Microsoft Visual Studio\2019\Community
    • Visual Studio Community 2019 version 16.7.30413.136
    • Windows 10 SDK version 10.0.18362.0

[✓] Android Studio (version 4.0)
    • Android Studio at C:\Code\android-studio
    • Flutter plugin version 49.0.2
    • Dart plugin version 193.7547
    • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b01)

[✓] VS Code (version 1.49.0)
    • VS Code at C:\Users\Taha\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension version 3.14.1

[✓] Connected device (4 available)
    • sdk gphone x86 arm (mobile) • emulator-5554 • android-x86    • Android 11 (API 30) (emulator)
    • Windows (desktop)           • windows       • windows-x64    • Microsoft Windows [Version 10.0.19041.450]
    • Web Server (web)            • web-server    • web-javascript • Flutter Tools
    • Chrome (web)                • chrome        • web-javascript • Google Chrome 85.0.4183.102

• No issues found!

@Wes1324
Copy link

Wes1324 commented Nov 30, 2020

Personally, I don't like the uncertainty that seems to come with using the QUERY_ALL_PACKAGES permission (because Google could stop letting people use it in the future). For that reason, I did some investigation and found that adding the following to my AndroidManifest.xml allows my app to open the browser, phone app and email app on API 30:

<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="https" />
    </intent>
    <intent>
        <action android:name="android.intent.action.DIAL" />
        <data android:scheme="tel" />
    </intent>
    <intent>
        <action android:name="android.intent.action.SEND" />
        <data android:mimeType="*/*" />
    </intent>
</queries>

Just wanted to share in case it helps someone else out.

@xuala69
Copy link

xuala69 commented Jan 7, 2021

Personally, I don't like the uncertainty that seems to come with using the QUERY_ALL_PACKAGES permission (because Google could stop letting people use it in the future). For that reason, I did some investigation and found that adding the following to my AndroidManifest.xml allows my app to open the browser, phone app and email app on API 30:

<queries>
    <intent>
        <action android:name="android.intent.action.VIEW" />
        <data android:scheme="https" />
    </intent>
    <intent>
        <action android:name="android.intent.action.DIAL" />
        <data android:scheme="tel" />
    </intent>
    <intent>
        <action android:name="android.intent.action.SEND" />
        <data android:mimeType="*/*" />
    </intent>
</queries>

Just wanted to share in case it helps someone else out.

Could you please show the whole manifest file or at least show the location to put these lines of code?

@Wes1324
Copy link

Wes1324 commented Jan 7, 2021

@xuala69, the queries element should be nested within the manifest element (not the application element), like this:

<manifest>

    <!-- Nest within the manifest element, not the application element-->
    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" />
        </intent>
        <intent>
            <action android:name="android.intent.action.DIAL" />
            <data android:scheme="tel" />
        </intent>
        <intent>
            <action android:name="android.intent.action.SEND" />
            <data android:mimeType="*/*" />
        </intent>
    </queries>

    <application>
        ....
    </application>
</manifest>

@xuala69
Copy link

xuala69 commented Jan 7, 2021

@Wes1324 Thank you. Works like a charm

@jamesncl
Copy link

Maybe this issue should be re-opened until the solution by @Wes1324 is documented on the pub.dev page for url_launcher? Because this is now mandatory setup on Android for the package to work.

@MichaelM97
Copy link

FYI to use <queries> you need to bump the gradle tools & wrapper version to at least 4.0.0/6.1.1 respectively.

your_flutter_app/android/build.gradle

dependencies {
    classpath 'com.android.tools.build:gradle:4.0.0'

your_flutter_app/android/gradle/wrapper/gradle-wrapper.properties

distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-all.zip

@g-apparence
Copy link

g-apparence commented Mar 15, 2021

This fix works by generating an appBundle and running directly on the device.
However, you can't build an Apk

* What went wrong:                                                      
Execution failed for task ':app:lintVitalProductionRelease'.            
> Could not resolve all artifacts for configuration ':app:devReleaseRuntimeClasspath'.
   > Failed to transform libs.jar to match attributes {artifactType=processed-jar, org.gradle.libraryelements=jar, org.gradle.usage=java-runtime}.
      > Execution failed for JetifyTransform:.../build/app/intermediates/flutter/devRelease/libs.jar.
         > Failed to transform '.../build/app/intermediates/flutter/devRelease/libs.jar' using Jetifier. Reason: FileNotFoundException, message: .../build/app/intermediates/flutter/devRelease/libs.jar (No such file or directory). (Run with --stacktrace for more details.)
           Please file a bug at http://issuetracker.google.com/issues/new?component=460323.

Any workaround?

Edit: I added

  lintOptions {
        disable 'InvalidPackage'
        --> checkReleaseBuilds false
    }

But this is not a really good fix.

@NamanShergill
Copy link

NamanShergill commented Apr 3, 2021

@xuala69, the queries element should be nested within the manifest element (not the application element), like this:

<manifest>

    <!-- Nest within the manifest element, not the application element-->
    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" />
        </intent>
        <intent>
            <action android:name="android.intent.action.DIAL" />
            <data android:scheme="tel" />
        </intent>
        <intent>
            <action android:name="android.intent.action.SEND" />
            <data android:mimeType="*/*" />
        </intent>
    </queries>

    <application>
        ....
    </application>
</manifest>

Would this also work for "mailto:" links?

Edit: Tested, works.

@davorkomusanac
Copy link

Please update this to the url_launcher docs, since this is mandatory for it to work

@devNamanG
Copy link

A kind request to you for amending the URL launcher docs, this issue is serious and might affect all devices running API 30 or greater.

@jsuryakt
Copy link

Thank you
Adding queries to the main manifest file worked.

Also, quit the app and run it again, hot reload and hot restart doesn't work.
Make sure you run the gradle task again.

@zyllus17
Copy link

@xuala69, the queries element should be nested within the manifest element (not the application element), like this:

<manifest>

    <!-- Nest within the manifest element, not the application element-->
    <queries>
        <intent>
            <action android:name="android.intent.action.VIEW" />
            <data android:scheme="https" />
        </intent>
        <intent>
            <action android:name="android.intent.action.DIAL" />
            <data android:scheme="tel" />
        </intent>
        <intent>
            <action android:name="android.intent.action.SEND" />
            <data android:mimeType="*/*" />
        </intent>
    </queries>

    <application>
        ....
    </application>
</manifest>

This solution works for everything except for the Youtube app. Google has clarified that it will not provide access to all apps from now Preview: Use of the broad package (App) visibility (QUERY_ALL_PACKAGES) permission and only give access to apps if the app depends on it like messaging will be accessible by payment apps etc.

I am working on an app that needs to redirect to Youtube as a social media button. While using the QUERY_ALL_PACKAGES it works fine but since Google is restricting access now, how can I ask for Youtube permission only, if possible, mention it in . The webview for youtube is loading indefinitely and not working.

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. If you are still experiencing a similar issue, please open a new bug, including the output of flutter doctor -v and a minimal reproduction of the issue.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 30, 2021
@flutter-triage-bot flutter-triage-bot bot added the package flutter/packages repository. See also p: labels. label Jul 5, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
e: OS-version specific Affects only some versions of the relevant operating system found in release: 1.20 Found to occur in 1.20 found in release: 1.22 Found to occur in 1.22 has reproducible steps The issue has been confirmed reproducible and is ready to work on p: url_launcher Plugin to launch external applications package flutter/packages repository. See also p: labels. platform-android Android applications specifically
Projects
None yet
Development

No branches or pull requests