delight-im / Android-AdvancedWebView

Enhanced WebView component for Android that works as intended out of the box
MIT License
2.39k stars 574 forks source link

Help to make downloads work in Jasonette-Android Advanced Webview Branch #299

Closed vsatmydynipnet closed 3 years ago

vsatmydynipnet commented 3 years ago

I try to get downloads working since days, but unsuccessful. Have to admit, I am no dev, so double hard. For me it looks like some parts of the implementation. I use the advanced webview branch

https://github.com/jasonelle/jasonette-android/tree/advanced-webview

which has

https://github.com/delight-im/Android-AdvancedWebView

included.

Downloads are handled automatically and can be listened to

@Override
public void onDownloadRequested(String url, String suggestedFilename, String mimeType, long contentLength, String contentDisposition, String userAgent) {
    // some file is available for download
    // either handle the download yourself or use the code below

    if (AdvancedWebView.handleDownload(this, url, suggestedFilename)) {
        // download successfully handled
    }
    else {
        // download couldn't be handled because user has disabled download manager app on the device
        // TODO show some notice to the user
    }
}

but I am not good enough in Java to be able to chang/add it myself.

Any hint would be greatly appreciated.

ocram commented 3 years ago

Thanks!

Although it’s more of a question for their repository vs. this one here, you got everything right already.

If the following is all they did to integrate this library here, it’s not enough, because they missed all custom callbacks and listeners: https://github.com/jasonelle/jasonette-android/commit/08488dd804d7a63b0907b8b7008077ad8e246477

The method you have identified should be the critical one, others might be necessary for other features.

I think it should fit in app/src/main/java/com/jasonette/seed/Core/JasonViewActivity.java, on the same level as void onBackPressed().

Does that help?

vsatmydynipnet commented 3 years ago

Thank you for your reply. I tried to implement this one by adding:

--- JasonViewActivity.java.ORIG 2021-08-26 13:15:55.599885405 +0200
+++ JasonViewActivity.java  2021-08-26 13:17:13.246513986 +0200
@@ -157,6 +157,19 @@
         }
     }

+    @Override
+    public void onDownloadRequested(String url, String suggestedFilename, String mimeType, long contentLength, String contentDisposition, String userAgent) {
+        // some file is available for download
+        // either handle the download yourself or use the code below
+
+        if (AdvancedWebView.handleDownload(this, url, suggestedFilename)) {
+            // download successfully handled
+        }
+        else {
+            // download couldn't be handled because user has disabled download manager app on the device
+            // TODO show some notice to the user
+        }
+    }

     @Override
     protected void onCreate(Bundle savedInstanceState) {

but building in Android Studio says

method does not override or implement a method from a supertype :160

160 is the @Override

vsatmydynipnet commented 3 years ago

Addition: I read somewhere that somtes removing @Override helps. Triesd it, then it compiles, but then the download is not working as without the addition.

ocram commented 3 years ago

I’m sorry, there are more missing pieces. You can add back the @Override. It helps. If it does not compile, the error is somewhere else:

First, you must change

public class JasonViewActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback{

to

public class JasonViewActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback, AdvancedWebView.Listener {

Then, after

backgroundWebview = agentService.setup(JasonViewActivity.this, background, "$webcontainer@" + model.url);

you have to insert the line

((AdvancedWebView) backgroundWebview).setListener(JasonViewActivity.this, JasonViewActivity.this);

And finally, you may have to add more methods from the README, as you did with that one method, until it stops complaining that some methods are not implemented.

vsatmydynipnet commented 3 years ago

SOLVED

Thank you so much for your help! It works perfect now! For all running into the same problem:

@@ -1,5 +1,10 @@
+// patches as mentioned in
+// https://github.com/delight-im/Android-AdvancedWebView/issues/299
+// with the great help of ocram. THANK YOU SO MUCH!
+// this handles now also in-app downloads using advanced web view
+
 package com.jasonette.seed.Core;

 import android.app.SearchManager;
 import android.content.BroadcastReceiver;
 import android.content.Context;
@@ -82,11 +87,13 @@ import java.util.concurrent.Executors;

 import static com.bumptech.glide.Glide.with;

 import im.delight.android.webview.AdvancedWebView;

-public class JasonViewActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback{
+// changed for downloads
+//public class JasonViewActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback{
+public class JasonViewActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback, AdvancedWebView.Listener {
     private JasonToolbar toolbar;
     private RecyclerView listView;
     public String url;
     public JasonModel model;
     public JSONObject preload;
@@ -155,10 +162,39 @@ public class JasonViewActivity extends AppCompatActivity implements ActivityComp
         }else{
             super.onBackPressed();
         }
     }

+    // Handle Downloads
+
+    @Override
+    public void onDownloadRequested(String url, String suggestedFilename, String mimeType, long contentLength, String contentDisposition, String userAgent) {
+        // some file is available for download
+        // either handle the download yourself or use the code below
+
+        if (AdvancedWebView.handleDownload(this, url, suggestedFilename)) {
+            // download successfully handled
+        }
+        else {
+            // download couldn't be handled because user has disabled download manager app on the device
+            // TODO show some notice to the user
+        }
+    }
+
+    @Override
+    public void onExternalPageRequest(String url) { }
+
+    @Override
+    public void onPageStarted(String url, Bitmap favicon) { }
+
+    @Override
+    public void onPageFinished(String url) { }
+
+    @Override
+    public void onPageError(int errorCode, String description, String failingUrl) { }
+
+    // END Downloads

     @Override
     protected void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);
@@ -1950,10 +1986,13 @@ public class JasonViewActivity extends AppCompatActivity implements ActivityComp
                                     // therefore, unlike ios where each viewcontroller owns a web container through "$webcontainer" id,
                                     // on android we need to distinguish between multiple web containers through URL
                                     background.put("id", "$webcontainer@" + model.url);
                                     JasonAgentService agentService = (JasonAgentService)((Launcher)getApplicationContext()).services.get("JasonAgentService");
                                     backgroundWebview = agentService.setup(JasonViewActivity.this, background, "$webcontainer@" + model.url);
+                                    //Added for Downloads
+                                    ((AdvancedWebView) backgroundWebview).setListener(JasonViewActivity.this, JasonViewActivity.this);
+                                    // END
                                     backgroundWebview.setVisibility(View.VISIBLE);

                                     //  do not apply any zoom on the text.
                                     backgroundWebview.getSettings().setTextZoom(100);
                                     // not interactive by default;
ocram commented 3 years ago

Glad to hear that it works, thank you!

The only thing you don’t have yet is a status message informing the user about the result of their download.

To implement that, around the call to AdvancedWebView.handleDownload, just place a one-liner displaying a Toast or Snackbar in both the if and the else branch.