Duda con descarga de un archivo dentro de un WebView - Android Studio

  • Respuestas:3
  • AbiertoSin chinchetaSin solución
  • Posts del Foro: 2

1 ago. 2017 23:59:58 vía Web

Saludos ante todo, estoy desarrollando una aplicación web con Andoir Studio 2.3 y tengo un problema al intentar descargar un archivo dentro de un webView..

Mi código para permitir descargas es el siguiente:

myWebView.setDownloadListener(new DownloadListener()
    {

        @Override

        public void onDownloadStart(String url, String userAgent,
                                    String contentDisposition, String mimeType,
                                    long contentLength) {

            DownloadManager.Request request = new DownloadManager.Request(
                    Uri.parse(url));

            request.setMimeType(mimeType);

            String cookies = CookieManager.getInstance().getCookie(url);

            request.addRequestHeader("cookie", cookies);

            request.addRequestHeader("User-Agent", userAgent);

            request.setDescription("Downloading file...");

            request.setTitle(URLUtil.guessFileName(url, contentDisposition,
                    mimeType));

            request.allowScanningByMediaScanner();

            request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
            request.setDestinationInExternalPublicDir(
                    Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(
                            url, contentDisposition, mimeType));
            DownloadManager dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
            dm.enqueue(request);
            Toast.makeText(getApplicationContext(), "Downloading File",
                    Toast.LENGTH_LONG).show();
        }});

Ya he agregado el permiso correspondiente:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

Pero al lanzar mi aplicación me dice "se ha detenido la aplicación..."

No se si es algún problema del código, estoy intentando descargar un archivo PDF/Excel generado por la extensión HTML Button de las datatables de Jquery (En el siguiente enlace pueden ver una tabla como la que estoy usando para exportar la info en formato PDF:
[no puedo poner enlaces pero la ruta es: extensions/buttons/examples/initialisation/export dentro del sitio de datatables.net]

Si alguien puede decirme si el código está bien le agradecería, así me podría enfocar solamente en la parte web de la aplicación.

Muchas gracias de antemano.

Contestar
  • Posts del Foro: 1

24 ene. 2020 17:03:10 vía Web

buenas mi buen Jose Enrique, tu código a la fecha de hoy funciona demasiado bien, lo integre en una prueba dentro de un Webview que realice y funciono de maravilla, la única diferencia entre el tuyo y mio son 2 lineas, la siguiente:
myRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
y en el Manifest:

quedando el codigo de la siguiente manera (MainActivity.java):

wv1.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {

            //Variable objeto para enlazar la descarga
            DownloadManager.Request myRequest = new DownloadManager.Request(Uri.parse(url));

            //Permitir tipos de red para descargar archivos
            myRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);

            myRequest.setMimeType(mimetype);
            String cookies = CookieManager.getInstance().getCookie(url);
            myRequest.addRequestHeader("cookie",cookies);
            myRequest.addRequestHeader("User-Agent",userAgent);
            myRequest.setDescription("Nube - Archivo descargado");
            myRequest.setTitle(URLUtil.guessFileName(url,contentDisposition,mimetype));

            /*NOTA: esta version de descarga fue desaprobada en las versiones Android API 29 en adelante
            evitando el acceso directo a los dispositivos de almacenamiento externo*/
            myRequest.allowScanningByMediaScanner();
            myRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);

            myRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimetype));

            DownloadManager myManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
            myManager.enqueue(myRequest);

            Toast.makeText(MainActivity.this,"Descargando archivo...",Toast.LENGTH_LONG).show();
        }
    });

si no te llego a funcionar lo más seguro es que fue tu back de la pagina, saludos buen hombre.

José Enrique

Contestar
  • Posts del Foro: 2

24 ene. 2020 17:39:15 vía Web

Vale, intentaré eso, recuerdo que a la final tuve que resolver de otra forma pero ya no recuerdo.. igual probaré eso en mi próxima webview.. Muchas gracias :D

Contestar
  • Posts del Foro: 1

25 mar. 2020 15:59:00 vía Web

Lo implemente a mi aplicación y al momento de descargar dice Se cerró la aplicación y se sale: este es el código de toda mi activity

package com.suptecsoft.MC_APK;

import android.app.Activity;
import android.app.AlertDialog.Builder;
import android.app.DownloadManager;
import android.content.Context;
import android.content.DialogInterface;
import android.content.BroadcastReceiver;
import android.content.DialogInterface.OnClickListener;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.ParcelFileDescriptor;
import android.view.KeyEvent;
import android.webkit.GeolocationPermissions.Callback;
import android.webkit.JavascriptInterface;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebSettings.PluginState;
import android.webkit.WebStorage.QuotaUpdater;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.webkit.DownloadListener;
import android.webkit.URLUtil;
import android.webkit.CookieManager;
import android.widget.ProgressBar;
import android.widget.Toast;

import java.io.File;
import java.io.FileNotFoundException;

public class Actividad extends Activity {
private final int PAGE_REEIRECT;
private final int PAGE_STARTED;
private final int REQUEST_CODE_ASK_MULTPLE_PERMISSIONS;
private boolean canExitApp;
ProgressBar carga;
public String fileName;
WebView webView;
private int webViewPreviousState;

class AnonymousClass_1 extends WebViewClient {
    final /* synthetic */ Actividad this$0;

    AnonymousClass_1(Actividad r1_Actividad) {
        super();
        this$0 = r1_Actividad;
    }

    public boolean shouldOverrideUrlLoading(WebView r2_WebView, String r3_String) {
        return false;
    }
}

class AnonymousClass_2 extends WebChromeClient {
    final /* synthetic */ Actividad this$0;

    AnonymousClass_2(Actividad r1_Actividad) {
        super();
        this$0 = r1_Actividad;
    }

    public void onExceededDatabaseQuota(String r3_String, String r4_String, long r5j, long r7j, long r9j, QuotaUpdater r11_QuotaUpdater) {
        r11_QuotaUpdater.updateQuota(5242880);
    }

    public void onGeolocationPermissionShowPrompt(String r3_String, Callback r4_Callback) {
        r4_Callback.invoke(r3_String, true, false);
    }

    public void onProgressChanged(WebView r3_WebView, int r4i) {
        this$0.carga.setProgress(0);
        this$0.carga.setVisibility(0);
        this$0.setProgress(r4i * 1000);
        this$0.carga.incrementProgressBy(r4i);
        if (r4i == 100) {
            this$0.carga.setVisibility(8);
        }
    }
}

class AnonymousClass_3 implements Runnable {
    final /* synthetic */ Actividad this$0;

    AnonymousClass_3(Actividad r1_Actividad) {
        super();
        this$0 = r1_Actividad;
    }

    public void run() {
        this$0.canExitApp = false;
    }
}

class AnonymousClass_4 implements OnClickListener {
    final /* synthetic */ Actividad this$0;
    private final /* synthetic */ Callback val$callback;
    private final /* synthetic */ String val$origin;

    AnonymousClass_4(Actividad r1_Actividad, Callback r2_Callback, String r3_String) {
        super();
        this$0 = r1_Actividad;
        val$callback = r2_Callback;
        val$origin = r3_String;
    }

    public void onClick(DialogInterface r5_DialogInterface, int r6i) {
        val$callback.invoke(val$origin, true, false);
    }
}

class AnonymousClass_5 implements OnClickListener {
    final /* synthetic */ Actividad this$0;
    private final /* synthetic */ Callback val$callback;
    private final /* synthetic */ String val$origin;

    AnonymousClass_5(Actividad r1_Actividad, Callback r2_Callback, String r3_String) {
        super();
        this$0 = r1_Actividad;
        val$callback = r2_Callback;
        val$origin = r3_String;
    }

    public void onClick(DialogInterface r4_DialogInterface, int r5i) {
        val$callback.invoke(val$origin, false, false);
    }
}

public class JavascriptHandler {
    final /* synthetic */ Actividad this$0;

    public JavascriptHandler(Actividad r1_Actividad) {
        super();
        this$0 = r1_Actividad;
    }

    @JavascriptInterface
    public void jsCallbackTwo(String r1_String) {
    }

    @JavascriptInterface
    public void vali() {
    }
}

class MyJavaScriptInterface {
    private Context ctx;
    final /* synthetic */ Actividad this$0;

    MyJavaScriptInterface(Actividad r1_Actividad, Context r2_Context) {
        super();
        this$0 = r1_Actividad;
        ctx = r2_Context;
    }

    public void showHTML(String r4_String) {
        new Builder(ctx).setTitle("HTML").setMessage(r4_String).setPositiveButton(17039370, null).setCancelable(false).create().show();
    }
}


public Actividad() {
    super();
    canExitApp = false;
    REQUEST_CODE_ASK_MULTPLE_PERMISSIONS = 124;
    PAGE_STARTED = 1;
    PAGE_REEIRECT = 2;
    fileName = "myfile.html";
}

public void onBackPressed() {
    if (!canExitApp) {
        canExitApp = true;
        Toast.makeText(this, "Vuelva a presionar para salir", 0).show();
        new Handler().postDelayed(new AnonymousClass_3(this), 2000);
    } else {
        super.onBackPressed();
    }
}

protected void onCreate(Bundle r5_Bundle) {
    super.onCreate(r5_Bundle);
    setContentView(R.layout.layout);
    carga = (ProgressBar) findViewById(R.id.Carga);
    webView = (WebView) findViewById(R.id.simpleWebView);
    webView.getSettings().setJavaScriptEnabled(true);
    webView.getSettings().setGeolocationEnabled(true);
    webView.getSettings().setAppCacheEnabled(true);
    webView.getSettings().setDomStorageEnabled(true);
    webView.getSettings().setGeolocationDatabasePath(getFilesDir().getPath());
    webView.getSettings().setDatabasePath(new StringBuilder("/data/data/").append(webView.getContext().getPackageName()).append("/databases/").toString());
    webView.addJavascriptInterface(new JavascriptHandler(this), "Android");
    webView.loadUrl(new StringBuilder("file:///android_asset/").append(fileName).toString());
    webView.getSettings().setPluginState(PluginState.ON);
    WebSettings r0_WebSettings = webView.getSettings();
    r0_WebSettings.setDatabaseEnabled(true);
    r0_WebSettings.setDatabasePath(getApplicationContext().getDir("database", 0).getPath());
    webView.setWebViewClient(new AnonymousClass_1(this));
    webView.setWebChromeClient(new AnonymousClass_2(this));

    webView.setDownloadListener(new DownloadListener() {

@Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
//Variable objeto para enlazar la descarga
DownloadManager.Request myRequest = new DownloadManager.Request(Uri.parse(url));
//Permitir tipos de red para descargar archivos
myRequest.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
myRequest.setMimeType(mimetype);
String cookies = CookieManager.getInstance().getCookie(url);
myRequest.addRequestHeader("cookie",cookies);
myRequest.addRequestHeader("User-Agent",userAgent);
myRequest.setDescription("Nube - Archivo descargado");
myRequest.setTitle(URLUtil.guessFileName(url,contentDisposition,mimetype));
/NOTA: esta version de descarga fue desaprobada en las versiones Android API 29 en adelante evitando el acceso directo a los dispositivos de almacenamiento externo/
myRequest.allowScanningByMediaScanner();
myRequest.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
myRequest.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, URLUtil.guessFileName(url, contentDisposition, mimetype));
DownloadManager myManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
myManager.enqueue(myRequest);
Toast.makeText(Actividad.this,"Descargando archivo...",Toast.LENGTH_LONG).show();
}
});

}

public void onGeolocationPermissionsShowPrompt(String r5_String, Callback r6_Callback) {
    r6_Callback.invoke(r5_String, true, false);
    Builder r0_Builder = new Builder(this);
    r0_Builder.setTitle("Locations");
    r0_Builder.setMessage("Would like to use your Current Location ").setCancelable(true).setPositiveButton("Allow", new AnonymousClass_4(this, r6_Callback, r5_String)).setNegativeButton("Don't Allow", new AnonymousClass_5(this, r6_Callback, r5_String));
    r0_Builder.create().show();
}

public boolean onKeyDown(int r2i, KeyEvent r3_KeyEvent) {
    if (r2i == 4) {
        if (webView.canGoBack()) {
            webView.goBack();
            return true;
        } else {
            finish();
            return super.onKeyDown(r2i, r3_KeyEvent);
        }
    } else {
        return super.onKeyDown(r2i, r3_KeyEvent);
    }
}

}

Contestar
Recomendado por NextPit