Ich arbeite an einer Android-App mit einem Webview, das auf eine dynamische Website eines anderen Teams verweist.
Beim Herunterladen einer Datei (meistens dynamisch umgeleitete PDF und Zip) alles, was ich bekomme, ist eine Datei im Download-Ordner, die HTML-Code enthält und eine Meldung wie "Benutzer nicht lesen" enthält die datei ", egal wie ich den download implementiere, habe ich versucht:
alle mit den gleichen Ergebnissen.
Navigieren mit normalen Browsern funktioniert problemlos, sowohl auf Desktop-PCs als auch auf Android- und iOS-Geräten.
Warum sollte Webview keinen Zugriff auf Dateien haben?
Kann eine Session-Ausgabe sein? http port?
Ich brauche wirklich ein paar Ideen ...
Ein weiterer Tipp: Wenn Sie zweimal eine Datei von demselben Link herunterladen, wird der Link auf dieselbe Datei umgeleitet, führt jedoch zu zwei unterschiedlichen Dateinamen ...
EDIT: Anstatt das WebView auf die Web-App zu verweisen, habe ich versucht, auf eine gemeinsame Webseite mit Link-Weiterleitung zu zeigen, um eine andere Datei herunterzuladen. Nun, es funktioniert einfach .. _.
Hier sind die webview.setDownloadListener - onDownloadStart()
-Parameter:
userAgent=Mozilla/5.0 (Linux; Android 4.4.2; Nexus 7 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/30.0.0.0 Safari/537.36
contentDisposition=attachment;
filename=correct_filename.pdf,
url=http://www.xxx.xx/site/downloadfile.wplus?REDIRECTFILE=D-507497120&ID_COUNTOBJ=ce_5_home&TYPEOBJ=CExFILE&LN=2
mimeType=application/octet-stream
Hier ist ein Code
wv.getSettings().setSupportMultipleWindows(true);
wv.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
wv.getSettings().setAllowFileAccess(true);
wv.getSettings().setJavaScriptEnabled(true);
wv.getSettings().setBuiltInZoomControls(true);
wv.getSettings().setDisplayZoomControls(false);
wv.getSettings().setLoadWithOverviewMode(true);
wv.getSettings().setUseWideViewPort(true);
wv.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.setDescription("Download file...");
request.setTitle(URLUtil.guessFileName(url, contentDisposition, mimetype));
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); //Notify client once download is 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();
}
}
EDIT II
Hier ist der Code, den ich verwende, wenn ich versuche, Dateien "von Hand" herunterzuladen:
auf onDownloadStart () rufe ich downloadFileAsync () auf:
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimeType, long contentLength) {
String fileName;
try {
fileName = URLUtil.guessFileName(url, contentDisposition, mimeType);
downloadFileAsync(url, fileName);
}catch (Exception e){
}
}
und das ist die AsyncTask:
private void downloadFileAsync(String url, String filename){
new AsyncTask<String, Void, String>() {
String SDCard;
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... params) {
try {
URL url = new URL(params[0]);
HttpURLConnection urlConnection = null;
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.connect();
int lengthOfFile = urlConnection.getContentLength();
//SDCard = Environment.getExternalStorageDirectory() + File.separator + "downloads";
SDCard = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS)+"";
int k = 0;
boolean file_exists;
String finalValue = params[1];
do {
if (k > 0) {
if (params[1].length() > 0) {
String s = params[1].substring(0, params[1].lastIndexOf("."));
String extension = params[1].replace(s, "");
finalValue = s + "(" + k + ")" + extension;
} else {
String fileName = params[0].substring(params[0].lastIndexOf('/') + 1);
String s = fileName.substring(0, fileName.lastIndexOf("."));
String extension = fileName.replace(s, "");
finalValue = s + "(" + k + ")" + extension;
}
}
File fileIn = new File(SDCard, finalValue);
file_exists = fileIn.exists();
k++;
} while (file_exists);
File file = new File(SDCard, finalValue);
FileOutputStream fileOutput = null;
fileOutput = new FileOutputStream(file, true);
InputStream inputStream = null;
inputStream = urlConnection.getInputStream();
byte[] buffer = new byte[1024];
int count;
long total = 0;
while ((count = inputStream.read(buffer)) != -1) {
total += count;
//publishProgress(""+(int)((total*100)/lengthOfFile));
fileOutput.write(buffer, 0, count);
}
fileOutput.flush();
fileOutput.close();
inputStream.close();
} catch (MalformedURLException e){
} catch (ProtocolException e){
} catch (FileNotFoundException e){
} catch (IOException e){
} catch (Exception e){
}
return params[1];
}
@Override
protected void onPostExecute(final String result) {
}
}.execute(url, filename);
}
genommen aus So laden Sie eine PDF von einer dynamischen URL in einer Webansicht herunter
Danke
Schließlich entschied ich mich, nach dem DownloadHandler aus dem Android Stock Browser-Code ..__ zu suchen. Der einzige auffällige Mangel in meinem Code war cookie (!!!).
Hier ist meine endgültige Arbeitsversion (DownloadManager-Methode):
wv.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);
//------------------------COOKIE!!------------------------
String cookies = CookieManager.getInstance().getCookie(url);
request.addRequestHeader("cookie", cookies);
//------------------------COOKIE!!------------------------
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();
}
});
Mit dieser Option konnte ich vollständige Dateien herunterladen. Der Download funktionierte mit anderen Optionen, aber die Dokumente schienen leer zu sein, insbesondere wenn eine Sitzung verwendet wird.
Füge folgende Zeilen zu AndroidManifest.xml
Hinzu
<uses-permission Android:name="Android.permission.INTERNET"/>
<uses-permission Android:name="Android.permission.WRITE_EXTERNAL_STORAGE"/>
Fügen Sie Ihrem WebView DownloadListener hinzu
Versuchen Sie diesen Code
wv.setDownloadListener(new DownloadListener() {
@Override
public void onDownloadStart(final String url, final String userAgent, String contentDisposition, String mimetype, long contentLength) {
//Checking runtime permission for devices above Marshmallow.
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (checkSelfPermission(Android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.v(TAG, "Permission is granted");
downloadDialog(url, userAgent, contentDisposition, mimetype);
} else {
Log.v(TAG, "Permission is revoked");
//requesting permissions.
ActivityCompat.requestPermissions(PortalActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
}
} else {
//Code for devices below API 23 or Marshmallow
Log.v(TAG, "Permission is granted");
downloadDialog(url, userAgent, contentDisposition, mimetype);
}
}
});
//downloadDialog Method
public void downloadDialog(final String url, final String userAgent, String contentDisposition, String mimetype) {
//getting filename from url.
final String filename = URLUtil.guessFileName(url, contentDisposition, mimetype);
//alertdialog
AlertDialog.Builder builder = new AlertDialog.Builder(this);
//title of alertdialog
builder.setTitle(R.string.download_title);
//message of alertdialog
builder.setMessage(getString(R.string.download_file) + ' ' + filename);
//if Yes button clicks.
builder.setPositiveButton(getString(R.string.yes), new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//DownloadManager.Request created with url.
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
//cookie
String cookie = CookieManager.getInstance().getCookie(url);
//Add cookie and User-Agent to request
request.addRequestHeader("Cookie", cookie);
request.addRequestHeader("User-Agent", userAgent);
//file scanned by MediaScannar
request.allowScanningByMediaScanner();
//Download is visible and its progress, after completion too.
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
//DownloadManager created
DownloadManager downloadManager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
//Saving files in Download folder
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, filename);
//download enqued
downloadManager.enqueue(request);
}
});
builder.setNegativeButton("No", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
//cancel the dialog if Cancel clicks
dialog.cancel();
mWebView.goBack();
}
});
//alertdialog shows.
builder.show();
}
wv.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);
//------------------------COOKIE!!------------------------
String cookies = CookieManager.getInstance().getCookie(url);
request.addRequestHeader("cookie", cookies);
//------------------------COOKIE!!------------------------
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();
}
});
danke j.c für deine antwort sie haben vermisst); am Ende des Codes ..