Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save whjvenyl/27312b35a9910f21573ddbb4d4061cae to your computer and use it in GitHub Desktop.
Save whjvenyl/27312b35a9910f21573ddbb4d4061cae to your computer and use it in GitHub Desktop.
How to close CustomTab

How to close CustomTab

When using CustomTab, it has no close method. To close CustomTab, should use Braodcast and call the activity which opened CustomTab again.

Good Example from Facebook SDK

I have fixed some of codes for essential behavior.

gradle setting

Add a library below.

dependencies {
    compile 'com.android.support:support-v4:+'
}

AndroidManifest.xml : Set scheme what you want.

<activity android:name=".CustomTabActivity"/>
<activity android:name=".RedirectActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data android:scheme="put scheme here" />
    </intent-filter>
</activity>

CustomTabActivity : Opens CustomTab

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.os.Bundle;
import android.support.customtabs.CustomTabsIntent;
import android.support.v4.content.LocalBroadcastManager;

public class CustomTabActivity extends Activity {
    public static final String REFRESH_ACTION =CustomTabActivity.class.getSimpleName() + ".action_refresh";
    private boolean shouldCloseCustomTab = true;
    private BroadcastReceiver redirectReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        // Custom Tab Redirects should not be creating a new instance of this activity
        if (RedirectActivity.CUSTOM_TAB_REDIRECT_ACTION.equals(getIntent().getAction())) {
            finish();
            return;
        }

        if (savedInstanceState == null) {
            String url = "https://facebook.com/";
            CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
            CustomTabsIntent customTabsIntent = builder.build();
            customTabsIntent.intent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
            customTabsIntent.launchUrl(this, Uri.parse(url));

            shouldCloseCustomTab = false;

            // This activity will receive a broadcast if it can't be opened from the back stack
            redirectReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    // Remove the custom tab on top of this activity.
                    Intent newIntent = new Intent(CustomTabActivity.this, CustomTabActivity.class);
                    newIntent.setAction(REFRESH_ACTION);
                    newIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                    startActivity(newIntent);
                }
            };
            LocalBroadcastManager.getInstance(this).registerReceiver(redirectReceiver,
                    new IntentFilter(RedirectActivity.CUSTOM_TAB_REDIRECT_ACTION)
            );
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        if (REFRESH_ACTION.equals(intent.getAction())) {
            // The custom tab is now destroyed so we can finish the redirect activity
            Intent broadcast = new Intent(RedirectActivity.DESTROY_ACTION);
            LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);
            unregisterAndFinish();
        } else if (RedirectActivity.CUSTOM_TAB_REDIRECT_ACTION.equals(intent.getAction())) {
            // We have successfully redirected back to this activity. Return the result and close.
            unregisterAndFinish();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();
        if (shouldCloseCustomTab) {
            // The custom tab was closed without getting a result.
            unregisterAndFinish();
        }
        shouldCloseCustomTab = true;
    }

    private void unregisterAndFinish() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(redirectReceiver);
        finish();
    }
}

RedirectActivity : CustomTab redirects to this activity through scheme.

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;

public class RedirectActivity extends Activity {
    private static final int CUSTOM_TAB_REDIRECT_REQUEST_CODE = 2;
    public static final String CUSTOM_TAB_REDIRECT_ACTION =
            RedirectActivity.class.getSimpleName() + ".action_customTabRedirect";
    public static final String DESTROY_ACTION =
            RedirectActivity.class.getSimpleName() + ".action_destroy";

    private BroadcastReceiver closeReceiver;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Intent intent = new Intent(this, CustomTabActivity.class);
        intent.setAction(CUSTOM_TAB_REDIRECT_ACTION);

        // these flags will open CustomTabActivity from the back stack as well as closing this
        // activity and the custom tab opened by CustomTabActivity.
        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);

        startActivityForResult(intent, CUSTOM_TAB_REDIRECT_REQUEST_CODE);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

        if (resultCode == RESULT_CANCELED) {
            // We weren't able to open CustomTabActivity from the back stack. Send a broadcast
            // instead.
            Intent broadcast = new Intent(CUSTOM_TAB_REDIRECT_ACTION);
            LocalBroadcastManager.getInstance(this).sendBroadcast(broadcast);

            // Wait for the custom tab to be removed from the back stack before finishing.
            closeReceiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    RedirectActivity.this.finish();
                }
            };
            LocalBroadcastManager.getInstance(this).registerReceiver(
                    closeReceiver,
                    new IntentFilter(RedirectActivity.DESTROY_ACTION)
            );
        }
    }

    @Override
    protected void onDestroy() {
        LocalBroadcastManager.getInstance(this).unregisterReceiver(closeReceiver);
        super.onDestroy();
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment