Search code examples
androidfirebasechrome-custom-tabs

Opening a url in ChromeCustomTab fetched from firebase recycler view


I am trying to open links from my firebase recyclerview using ChromeCustom Tab because I learn it will improve load time. It works perfectly if I open using webview but I get App stopped when I tried to use it on ChromeCustomTab

public class VatFees extends AppCompatActivity {

private static class BlogViewHolder extends RecyclerView.ViewHolder {
    View mView;
    TextView textView_date;
    TextView textView_title;
    TextView textView_decription;
    TextView textView_link;
    ImageView imageView, imageMinimize;
    Button uriButton;
    private final Context context;

public BlogViewHolder(final View itemView) {
        super(itemView);
        mView = itemView;
        context = itemView.getContext();
        textView_date = itemView.findViewById(R.id.textDate);
        textView_title = (TextView) itemView.findViewById(R.id.title);
        textView_decription = (TextView)itemView.findViewById(R.id.description);
        textView_link = (TextView) itemView.findViewById(R.id.link);
        imageView = (ImageView) itemView.findViewById(R.id.image);
        imageMinimize = itemView.findViewById(R.id.minimize);
        uriButton = itemView.findViewById(R.id.urlBtn);

 uriButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                String toolTitle=textView_title.getText().toString();
                String topic = textView_link.getText().toString();

               final CustomTabsIntent.Builder builder = new 
CustomTabsIntent.Builder();
                CustomTabsIntent customTabsIntent = builder.build();


//I tried using (Activity)context to get pass the error
//Wrong 1st argument type. Found: 'android.content.Context', required: 'android.app.Activity' but still not working

                customTabsIntent.launchUrl((Activity) context, Uri.parse(topic));

            }
        });

Chrome implementation is like this

String url = ¨https://paul.kinlan.me/¨;
CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
CustomTabsIntent customTabsIntent = builder.build();
customTabsIntent.launchUrl(this, Uri.parse(url));

But i can't get to use this in my view.

The error on logcat is

01-22 17:34:39.158 5087-5087/com.vx.camn D/AndroidRuntime: Shutting down VM
01-22 17:34:39.159 5087-5087/com.vx.camn E/AndroidRuntime: FATAL EXCEPTION: main

Process: com.vx.camn, PID: 5087

java.lang.NoSuchMethodError: No static method startActivity(Landroid/app/Activity;Landroid/content/Intent;Landroid/os/Bundle;)V in class Landroid/support/v4/app/ActivityCompat; or its super classes (declaration of 'android.support.v4.app.ActivityCompat' appears in /data/app/com.vx.camn-2/split_lib_dependencies_apk.apk)
                                                                       at android.support.customtabs.CustomTabsIntent.launchUrl(CustomTabsIntent.java:200)
                                                                       at com.vx.camn.VatFees$BlogViewHolder$1.onClick(VatFees.java:166)
                                                                       at android.view.View.performClick(View.java:6186)
                                                                       at android.view.View$PerformClick.run(View.java:23232)
                                                                       at android.os.Handler.handleCallback(Handler.java:836)
                                                                       at android.os.Handler.dispatchMessage(Handler.java:103)
                                                                       at android.os.Looper.loop(Looper.java:203)
                                                                       at android.app.ActivityThread.main(ActivityThread.java:6289)
                                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1094)
                                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:955)
01-22 17:34:39.160 339-446/? D/AALService: enableAALEvent: 1 -> 0
01-22 17:34:39.160 339-446/? D/AALService: 01-22 05:34:39.144 BL= 175,CABC= 256, 

Solution

  • The context returned by itemView.getContext() is not an Activity.

    You need to pass a reference for the Vatfees activity to your Adapter (the code for the Adapter wasn't posted), which in turn passes it to the ViewHolder, when creating it.

    I would use a WeakReference to the Activity, to avoid leaking it.

    private static class BlogViewHolder extends RecyclerView.ViewHolder {
        ...
        Button uriButton;
        WeakReference<Activity> hostActivityReference;
    
        public BlogViewHolder(final View itemView, Activity hostActivity) {
          ...
          this.hostActivityReference = new WeakReference(hostActivity);
          uriButton = itemView.findViewById(R.id.urlBtn);
    
          uriButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                Activity hostActivity = this.hostActivityReference;
                if (hostActivity == null) {
                  // Activity has already finished?
                  return;
                }
                String toolTitle=textView_title.getText().toString();
                String topic = textView_link.getText().toString();
    
                final CustomTabsIntent.Builder builder = new CustomTabsIntent.Builder();
                CustomTabsIntent customTabsIntent = builder.build();
                customTabsIntent.launchUrl(hostActivity, Uri.parse(url));
            }
    
        }
    

    As a reference, Plaid implements something like this on itsFeedAdapter.java.