GithubHelp home page GithubHelp logo

braintree / browser-switch-android Goto Github PK

View Code? Open in Web Editor NEW
27.0 19.0 24.0 863 KB

Open a url in a browser or Chrome Custom Tab and receive a response as the result of user interaction.

License: MIT License

Java 95.58% Shell 4.42%
android browser-switch chrome-custom-tabs

browser-switch-android's Introduction

Android Browser Switch

GitHub Actions Tests

Android Browser Switch makes it easy to open a url in a browser or Chrome Custom Tab and receive a response as the result of user interaction, either cancel or response data from the web page.

Setup

Add the library to your dependencies in your build.gradle:

dependencies {
  implementation 'com.braintreepayments.api:browser-switch:2.6.1'
}

To preview the latest work in progress builds, add the following SNAPSHOT dependency in your build.gradle:

dependencies {
  implementation 'com.braintreepayments.api:browser-switch:2.6.2-SNAPSHOT'
}

You will also need to add the Sonatype snapshots repo to your top-level build.gradle to import SNAPSHOT builds:

allprojects {
    repositories {
        maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots/'
        }
    }
}

AndroidManifest.xml

Declare an activity that you own as a deep link target in your AndroidManifest.xml:

<activity android:name="com.myapp.MyDeepLinkTargetActivity"
    android:launchMode="singleTask"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <data android:scheme="my-custom-url-scheme"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>
    </intent-filter>
</activity>

Note: The scheme you define must use all lowercase letters. This is due to scheme matching on the Android framework being case sensitive, expecting lower case. The scheme must also be valid according to RFC 2396.

If these requirements are not met, an error will be returned and no browser switch will occur.

Usage

A browser switch can be initiated by calling BrowserSwitchClient#start(). Use BrowserSwitchOptions to configure options for browser switching:

val browserSwitchOptions = BrowserSwitchOptions()
    .requestCode(MY_REQUEST_CODE)
    .url("https://site-to-load.com?callbackURL=my-custom-url-scheme%3A%2F%2Fsuccess")
    .returnUrlScheme("my-custom-url-scheme")
browserSwitchClient.start(activity, browserSwitchOptions)

In the above example, notice the encoded callbackURL parameter is forwarded to the website that will be loaded. The callback url must have the same custom scheme set in BrowserSwitchOptions. When this URL is loaded by the site, the Android OS will re-direct the user to the deep link destination Activity defined in the AndroidManifest.xml.

To capture a browser switch result, override your deep link target Activity with the following code snippet:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    browserSwitchClient.deliverResult(this)?.let { result ->
        when (result) {
            BrowserSwitchStatus.OK -> {
                // the browser switch returned data in the return uri
                // TODO: handle success
            }
            BrowserSwitchStatus.CANCEL -> {
                // the user canceled and returned to your app return uri is null
                // TODO: handle cancelation
            }
        }
    }
}

Launch Modes

If your deep link target Activity has android:launchMode="singleTop", android:launchMode="singleTask", or android:launchMode="singleInstance", add the following code snippet to your deep link target Activity:

override fun onNewIntent(newIntent: Intent?) {
    super.onNewIntent(intent)
    intent = newIntent
}

Versions

This SDK abides by our Client SDK Deprecation Policy. For more information on the potential statuses of an SDK check our developer docs.

Major version number Status Released Deprecated Unsupported
2.x.x Active February 2021 TBA TBA
1.x.x Inactive June 2020 April 2022 April 2023

Help

License

Android Browser Switch is open source and available under the MIT license. See the LICENSE file for more info.

browser-switch-android's People

Contributors

braintreeps avatar caarmen avatar crookedneighbor avatar epreuve avatar lkorth avatar quinnjn avatar sarahkoop avatar sestevens avatar sshropshire avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

browser-switch-android's Issues

Payments

Please help me get my payments

Method to use custom activity transition

General information

  • SDK/Library version: 0.2.0

Feature Request

Request to add method

public void browserSwitch(int requestCode, Intent intent, Bundle options) { ... }

(Bundle argument), so that we can customize activity start animation.
I'll be happy make PR, please let me know.

Don't crash when no browsers (or activities that can handle a URL) are installed on the device

General information

  • SDK/Library version: only with 2.10.0
  • Environment: Production
  • Android Version and Device:
    • Samsung Galaxy J1 - OS 5.1.1
    • LG M1 - OS 5.1.1
    • LG Phoenix 2 - OS 6.0
    • Alcatel 5085C - OS 7.0

Issue description

Follow up from: braintree/braintree_android/issues/195 reported by @simonlinj

When browser-switch-android tries to launch an Intent to open a URL on a device that has no activities that can open a URL it should report it as an error.

Original issue description:
Receiving a few crash reports after upgrading the SDK to 2.10.0. Had no issues on previews versions.

Fatal Exception: android.content.ActivityNotFoundException: No Activity found to handle Intent { act=android.intent.action.VIEW dat=https://assets.braintreegateway.com/mobile/three-d-secure-redirect/0.1.4/index.html?AcsUrl=https://0eaf.cardinalcommerce.com/EAFService/jsp/v1/redirect&PaReq=P.8ccf9XXXXXXXXX&TermUrl=https://api.braintreegateway.com:443/merchants/XXXXXXXX/client_api/v1/payment_methods/XXXXXXXXX/three_d_secure/authenticate?authorization_fingerprint=XXXXX&authorization_fingerprint_64=XXXXXXXXX&ReturnUrl=https://assets.braintreegateway.com/mobile/three-d-secure-redirect/0.1.4/redirect.html?redirect_url=XXX.XXXXX.XXXXXX.braintree://x-callback-url/braintree/threedsecure? flg=0x10000000 }
       at android.app.Instrumentation.checkStartActivityResult(Instrumentation.java:1781)
       at android.app.Instrumentation.execStartActivity(Instrumentation.java:1501)
       at android.app.ContextImpl.startActivity(ContextImpl.java:1404)
       at android.app.ContextImpl.startActivity(ContextImpl.java:1386)
       at android.content.ContextWrapper.startActivity(ContextWrapper.java:323)
       at com.braintreepayments.browserswitch.BrowserSwitchFragment.browserSwitch(BrowserSwitchFragment.java:137)
       at com.braintreepayments.browserswitch.BrowserSwitchFragment.browserSwitch(BrowserSwitchFragment.java:107)
       at com.braintreepayments.api.ThreeDSecure.launchBrowserSwitch(ThreeDSecure.java:218)
       at com.braintreepayments.api.ThreeDSecure.access$000(ThreeDSecure.java:35)
       at com.braintreepayments.api.ThreeDSecure$2$1.success(ThreeDSecure.java:153)
       at com.braintreepayments.api.internal.HttpClient$3.run(HttpClient.java:288)
       at android.os.Handler.handleCallback(Handler.java:739)
       at android.os.Handler.dispatchMessage(Handler.java:95)
       at android.os.Looper.loop(Looper.java:135)
       at android.app.ActivityThread.main(ActivityThread.java:5422)
       at java.lang.reflect.Method.invoke(Method.java)
       at java.lang.reflect.Method.invoke(Method.java:372)
       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:707)

No any browsers on the device

Good afternoon!

Thank you for your work!
But what if there is no browser on the device? Is it possible to track this situation when switching?

BrowserAwitch into App

Hi
we use

  • drop-in:6.7.0
  • which depends on browser-switch:2.3.2
  • Any Android version
  • Any device

we use browser-switch in an special PayPalPlus flow.
Our App has an Intent filter to open in case an URL is for our web side.
We do this for the "Google Search Api" to link into our app or for generic mailing to our customer (Web and App customer)
In case the App is installed the app is opens, if not the browser is opens.

Now the problem :
The payment browser switch url got to our Web side (JavaScript Payment side) but also the app is registered to the url.
Example https://www.domain.com/payment/obj/angular-apps/standalone/paypal-plus-installments/?s......

AndroidManifest.xml

         <intent-filter android:autoVerify="true">
                <action android:name="android.intent.action.VIEW" />
                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />
                <data
                    android:host="www.domain.com"
                    android:scheme="https" >
                </data>
            </intent-filter>

In case of an browser switch the app is opened because BrowserSwitchClient.start()
Didn't check for the possibility the App is also registered to the browserSwitchUrl.

customTabsInternalClient.launchUrl(activity, browserSwitchUrl, launchAsNewTask);

class ChromeCustomTabsInternalClient {
....
    void launchUrl(Context context, Uri url, boolean launchAsNewTask) {
        CustomTabsIntent customTabsIntent = customTabsIntentBuilder.build();
        if (launchAsNewTask) {
            customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        }
        customTabsIntent.launchUrl(context, url);
    }
}

Here is no customTabsIntent.setPackage("browser.package we found");

An solution cut be to check if the App is registered for the browserSwitchUrl
And if so set the customTabsIntent.intent.setPackage("Browser we found");
before customTabsIntent.launchUrl(context, url);

    private void checkAppPackageForActionView(Activity activity, Intent launchUrlInBrowser, String urlToLoad) {
        String applicationPackageName = activity.getPackageName();

        PackageManager pm = activity.getPackageManager();
        Intent activityIntent = new Intent().setAction(Intent.ACTION_VIEW)
                .setData(Uri.parse(urlToLoad));

        List<ResolveInfo> resolvedActivityList = pm.queryIntentActivities(activityIntent, 0);
        boolean packageView = false;

        ArrayList<ResolveInfo> packagesSupportingCustomTabs = new ArrayList<>();
        for (ResolveInfo info : resolvedActivityList) {
            Intent serviceIntent = new Intent();
            serviceIntent.setAction(ACTION_CUSTOM_TABS_CONNECTION);
            serviceIntent.setPackage(info.activityInfo.packageName);

            // check if application package also handle the url
            if (applicationPackageName == null || info.activityInfo.packageName.equals(applicationPackageName)) {
                packageView = true;
            } else {
                packagesSupportingCustomTabs.add(info);
            }
        }
        if (packagesSupportingCustomTabs.size() > 0 && packageView) {
            ResolveInfo info = packagesSupportingCustomTabs.get(0);
            if (info != null && info.activityInfo != null ) {
                launchUrlInBrowser.setPackage(info.activityInfo.packageName);
            }
        }
    }

This check must be for installed ChromeCustomTab and for the activity.startActivity part in the BrowserSwitchClient

Regards

Stephan

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.