I'm trying to understand how Chrome Custom Tabs work. Following the guidelines, adding a custom item to a menu is done using a pendingIntent, such as:
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://google.com"));
PendingIntent pendingIntent = PendingIntent
.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
customTabsIntent = new CustomTabsIntent.Builder()
.addMenuItem("Visit Google Website", pendingIntent)
.build();
I know how to use pendingIntent to direct to a website or to create a 'share' action. The question is would it be possible to do more complex tasks from adding a 'Close' menu item to close the activity or to exit app; or to 'connect' that menu item to a method, so when the user clicks on it the code from the method would process. I guess the second if possible would than make an easy solution for the first.
I tried to search for the answers, but if I search how to close or end activity or app (or similar) using intent or pendingIntent, I get something with use of 'finish();' or 'startActivity(intent);' or similar, which I cannot apply here since I don't know how or from where to call it. I tried just reading about the use of intent and pendingIntent, but I cannot figure out how to, let's say close activity or process without being able to call a method.
I would appreciate any help, even some links to resources or pointers to what I would need to read/learn next to be able to understand this.
This solution is using BrodcastReceiver:
In your activity (MainActivity in this case) from which you are starting Chrome Custom Tabs (CCT), create a static field to identify if the activity was created from the Broadcastreceiver, and a setter so we can set it from the Broadcastreceiver:
// For determining if Activity was started from BroadcastReceiver
private static boolean fromBroadcastReceiver = false;
public static void setFromBroadcastReceiver(boolean bool) {
fromBroadcastReceiver = bool;
}
Create a public class for BroadcastReceiver. Overriding the onReceive method, create an instance of the MainActivity and set fromBroadcastReceiver
to true. Then create an intent with that activity and another intent for restarting using first intent. Close CCT and restart the activity using latter intent:
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.IntentCompat;
public class CctBroadcastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// Create an instance of MainActivity and set fromBroadcastReceiver flag to true.
MainActivity mainActivity = new MainActivity();
mainActivity.setFromBroadcastReceiver(true);
// Create an intent with that activity and another intent for restarting using first intent.
Intent intent = new Intent(context, mainActivity.getClass());
ComponentName compName = intent.getComponent();
Intent mainIntent = IntentCompat.makeRestartActivityTask(compName);
// Restart the activity using later intent (also close CCT)
mainIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NEW_TASK);
mainIntent.addFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
context.startActivity(mainIntent);
} // End onReceive.
} // End BroadcastReceiver class.
Don't forget to register your receiver in the AndroidManifest.xml:
...
</activity>
<receiver
android:name=".cctBroadcastReceiver"
android:enabled="true">
</receiver>
</application>
Now, inside onCreate
of the MainActivity check if it was created from the BroadcastReceiver, and if so reset the 'flag' and finish()
the activity:
// Check if activity was created from the BroadcastReceiver, and if so reset the 'flag' and finish() the activity.
if (fromBroadcastReceiver) {
setFromBroadcastReceiver(false);
finish();
return;
}
Don't forget to use your BroadcastReceiver class for creating intent and pendingIntent for CCT:
Intent broadcastIntent = new Intent(this, CctBroadcastReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, broadcastIntent, PendingIntent.FLAG_UPDATE_CURRENT);
And you're done. Basically the code inside the BroadcastReceiver closes the CCT (similar as if you clicked on the CCT default close button). Adding the 'flag' and the code inside the MainActivity further closes the MainActivity.