I have a webview that contains pdf hyperlinks (some of them are large), when the user click on the hyperlink the pdf starts downloading and then gets viewed in the pdf vieweR.
I want to add a cancel button that stops the ongoing download, how is that possible?
how can I stop an ongoing download
The best and easy way to manage downloads is by using DownloadManager. Also
WebView provides API to set download listener which makes handling of downloads a lot easier - DownloadListener.
Here is quick example of starting and canceling downloads by clicking on a button:
public class MainActivity extends AppCompatActivity {
private Long mOnGoingDownload;
private Button mCancel;
private WebView mWebView;
private DownloadManager mDownloadManger;
protected void cancelDownload() {
if (mOnGoingDownload != null) {
mDownloadManger.remove(mOnGoingDownload);
clearDownloadingState();
Toast.makeText(this, "Download canceled", Toast.LENGTH_SHORT).show();
}
}
protected void clearDownloadingState() {
unregisterReceiver(mDownloadCompleteListener);
mCancel.setVisibility(View.GONE);
mOnGoingDownload = null;
}
BroadcastReceiver mDownloadCompleteListener = new BroadcastReceiver() {
public void onReceive(Context ctx, Intent intent) {
clearDownloadingState();
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, 0);
Uri fileUri = mDownloadManger.getUriForDownloadedFile(id);
//Open file in viewer
//...
Toast.makeText(ctx, fileUri.getLastPathSegment() + " downloaded", Toast.LENGTH_SHORT).show();
}
};
protected void startDownload(String url, String userAgent, String mimetype) {
Uri fileUri = Uri.parse(url);
String fileName = fileUri.getLastPathSegment();
String cookies = CookieManager.getInstance().getCookie(url);
DownloadManager.Request request = new DownloadManager.Request(fileUri);
request.setMimeType(mimetype)
.addRequestHeader("cookie", cookies)
.addRequestHeader("User-Agent", userAgent)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, fileName);
//register receiver for download complete event
registerReceiver(mDownloadCompleteListener, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
mCancel.setVisibility(View.VISIBLE);
mOnGoingDownload = mDownloadManger.enqueue(request);
Log.e("DownloadExample", "68|MainActivity::startDownload: Download of " + fileName + " started");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mDownloadManger = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
mCancel = (Button)findViewById(R.id.cancelDownload);
mCancel.setVisibility(View.GONE);
mCancel.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cancelDownload();
}
});
mWebView = (WebView) findViewById(R.id.webview);
mWebView.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
mWebView.setDownloadListener(new DownloadListener() {
#Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
startDownload(url, userAgent, mimetype);
}
});
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl("http://www.engineerhammad.com/2015/04/Download-Test-Files.html");
}
}
And main layout is :
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.andrii.webview.MainActivity">
<WebView
android:id="#+id/webview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_weight="1">
</WebView>
<Button
android:layout_gravity="bottom"
android:id="#+id/cancelDownload"
android:layout_width="match_parent"
android:text="Cancel donload"
android:layout_height="wrap_content" />
</FrameLayout>
Related
I am downloading audio files from a parse server. The results after running the code below is that when the client clicks the notification, it plays. However, when the client closes the music player, and opens it back up, it is no longer listed. My question is, where is this file located? I have seen methods for setting the external storage location, but I would like for it to download to the internal storage with the other downloads. How can I accomplish this?
private class DownloadFileTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
Toast.makeText(getActivity(), getString(R.string.downloading), Toast.LENGTH_SHORT).show();
super.onPreExecute();
}
#Override
protected String doInBackground(String... urls) {
String currentSong = urls[0];
try {
downloadManager = (DownloadManager) getActivity().getSystemService(Context.DOWNLOAD_SERVICE);
Uri uri = Uri.parse(currentSong);
DownloadManager.Request request = new DownloadManager.Request(uri);
request.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
downloadManager.enqueue(request);
}
catch (Exception e) {
Toast.makeText(getActivity(), e.getMessage(), Toast.LENGTH_SHORT).show();
}
return currentSong;
}
#Override
protected void onPostExecute(String s) {
Toast.makeText(getActivity(), getString(R.string.download_complete), Toast.LENGTH_SHORT).show();
super.onPostExecute(s);
}
I have the problem that on emulator some things in my app doesn't work. The thing is onDownloadListener() method. In real device, it runs perfectly: I can download image and send it by messenger e.g. In the emulator it doesn't work, the method just doesn't run itself. It is terrible, I have tried different emulators and different devices. On each device I tried it was working but none of the emulators can run this code:
public class MyExport implements DownloadListener {
private final WebView webView;
private Context context;
private Activity activity;
public MyExport(Context c, Activity a, WebView webView) {
this.activity = a;
this.context = c;
this.webView = webView;
}
#Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
System.out.println("IM IN onDwoanloadStart");
String intentType = "image/png";
String fileName = "img.png";
try {
if(url != null) {
FileOutputStream fos;
fos = context.openFileOutput(fileName, Context.MODE_PRIVATE);
//conversion stuff
fos.write(decodedStr);
fos.getFD().sync();
fos.flush();
fos.close();
Intent sendIntent = new Intent();
sendIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
sendIntent.setAction(Intent.ACTION_SEND);
File filePath = new File(String.valueOf(context.getFilesDir()));
File newFile = new File(filePath, fileName);
sendIntent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".FileProvider", newFile));
sendIntent.setType(intentType);
context.startActivity(sendIntent);
}
} catch (IOException e) {
e.printStackTrace();
}
}
#JavascriptInterface
public void runExport(){
activity.runOnUiThread(new Runnable() {
#Override
public void run() {
webView.loadUrl("javascript: obj.exportImage()");
}
});
}
And this is how I add it to the webView:
MyExport export = new MyExport(activity.getBaseContext(), activity, this.webView);
this.webView.setDownloadListener(export);
this.webView.addJavascriptInterface(export, "jsint");
When I click on the button in WebView the exportImage() from Javascript is called but the onDownloadListener is not. This is happening ONLY on emulators!
So I am stuck on a issue with my webapp that runs inside a webview from android studio.
I want download like pdf file to be downloaded and opend in the native app on the phone. This work fine by using the download manager from android studio.
How ever I also have links that start with "mailto:" and "tel:" those links give me an error when I don't override the method "shouldOverrideUrlLoading" where I can check what kind of url it is. And then open the propper inten.
So when I combine the 2 the downloadmanager and the custom NavigationHandler that extends the WebViewClient, it doesn't work as expected.
For a better understanding of what is happening.
When I hit a button with a pdf file it downloads the file gives a toast message and opens the file with the native app on the phone. This is without overriding the "shouldOverrideURLLoading" and without my class that extends the WebViewClient.
When I also use my own NavigationHandler witch extends from WebViewClient,
my urls with "mailto:" and "tel:" open with native apps on the phone.
When I now hit a button with a pdf file it is opend in a browser to be downloaded. Witch I don't want. I have tried numerous things to solf the problem but until now without succes.
I run a website app inside of a WebViewClient.
P.S. sorry for the shitty code but it's new to me and haven't find my way jet in coding in Android Studio.
My NavigationHandler class
package nl.firejob.selector;
import android.content.Intent;
import android.net.Uri;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class NavigationHandler extends WebViewClient {
private static final String TEL_PREFIX = "tel:";
private static final String MAILTO_PREFIX = "mailto:";
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if ( url.startsWith( TEL_PREFIX ) ) {
// This is a tel link, which should be opened with the native thing.
Intent tel = new Intent( Intent.ACTION_DIAL, Uri.parse( url ) );
view.getContext().startActivity( tel );
return true;
} else if ( url.startsWith( MAILTO_PREFIX ) ) {
// This is a mail link, which should be opened with the other native thing.
Intent mail = new Intent(Intent.ACTION_SENDTO);
mail.setType("message/rfc822");
mail.setData(Uri.parse( url ));
view.getContext().startActivity( mail );
return true;
} else if ( Uri.parse(url).getHost().startsWith("myurl.com") ) {
// This is what we want to show in the app, so let the WebView handle it.
return false;
}
// Otherwise, the link is not for a page on my site, so launch another Activity that handles URLs
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse( url ) );
view.getContext().startActivity( intent );
return true;
}
}
My MainActivity Class
package nl.firejob.selector;
import android.Manifest;
import android.app.DownloadManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.webkit.DownloadListener;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.Toast;
import java.io.File;
public class MainActivity extends AppCompatActivity {
private WebView mWebView;
private DownloadManager dm;
private Long myDownloadReference;
private BroadcastReceiver receiveDownloadComplete;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webView);
// Allow webview to use javascript
WebSettings webSettings = mWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
// Stop local links/redirects from opening in browser instead of WebView
mWebView.setWebViewClient(new NavigationHandler() {
#Override
public void onPageFinished(WebView view, String url) {
// Show the webview
findViewById(R.id.webView).setVisibility(View.VISIBLE);
// Hide splashscreen objects
findViewById(R.id.imageLogo).setVisibility(View.GONE);
findViewById(R.id.textLogo).setVisibility(View.GONE);
}
});
mWebView.setDownloadListener(new DownloadListener() {
#Override
public void onDownloadStart(String url, String userAgent, String contentDisposition, String mimetype, long contentLength) {
if( haveStoragePermission()) {
Log.i("download url",url);
//for downloading directly through download manager
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.allowScanningByMediaScanner();
request.setVisibleInDownloadsUi(true);
request.setDescription("Doorvoerboek").setTitle("doorvoerboek.pdf");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "doorvoerboek.pdf");
dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
myDownloadReference = dm.enqueue(request);
IntentFilter intentFilter = new IntentFilter( dm.ACTION_DOWNLOAD_COMPLETE);
receiveDownloadComplete = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
long reference = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
if (myDownloadReference == reference) {
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(reference);
Cursor cursor = dm.query(query);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(DownloadManager.COLUMN_STATUS);
int status = cursor.getInt(columnIndex);
int fileNameIndex = cursor.getColumnIndex(DownloadManager.COLUMN_TITLE);
String saveFilePath = cursor.getString(fileNameIndex);
Log.i("filename",saveFilePath);
int columnReason = cursor.getColumnIndex(DownloadManager.COLUMN_REASON);
int reason = cursor.getInt(columnReason);
switch (status){
case DownloadManager.STATUS_SUCCESSFUL:
Toast.makeText(MainActivity.this, "Download Complete", Toast.LENGTH_LONG).show();
Log.i("dir", Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() );
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath() +"/doorvoerboek.pdf");
Intent intentView = new Intent(Intent.ACTION_VIEW);
intentView.setDataAndType(Uri.fromFile(file),"application/pdf");
intentView.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
startActivity(intentView);
break;
}
}
}
};
registerReceiver(receiveDownloadComplete,intentFilter);
}
}
});
mWebView.loadUrl("http://myurl.com/");
}
public boolean haveStoragePermission() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
Log.e("Permission error","You have permission");
return true;
} else {
Log.e("Permission error","You have asked for permission");
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //you dont need to worry about these stuff below api level 23
Log.e("Permission error","You already have the permission");
return true;
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if ((keyCode == KeyEvent.KEYCODE_BACK) && mWebView.canGoBack()) {
//if Back key pressed and webview can navigate to previous page
mWebView.goBack();
// go back to previous page
return true;
}
else
{
finish();
// finish the activity
}
return super.onKeyDown(keyCode, event);
}
}
This code downloads any file.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webview = (WebView) findViewById(R.id.webView);
spinner = (ProgressBar) findViewById(R.id.progressBar1);
webview.setWebViewClient(new CustomWebViewClient());
webview.getSettings().setUseWideViewPort(true);
webview.getSettings().setLoadWithOverviewMode(true);
webview.getSettings().setBuiltInZoomControls(true);
webview.getSettings().setDisplayZoomControls(false);
webview.getSettings().setJavaScriptEnabled(true);
webview.getSettings().setDomStorageEnabled(true);
webview.setOverScrollMode(WebView.OVER_SCROLL_NEVER);
webview.loadUrl("http://www.website.com");
//Download file code stackoverflow.com
webview.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.allowScanningByMediaScanner();
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
DownloadManager dm = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
dm.enqueue(request);
Toast.makeText(getApplicationContext(), "downloading",
Toast.LENGTH_LONG).show();
}
});
// Download section of code
} // Close of onCreate
// mailto code stackoverflow.com
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if( url.startsWith("http:") || url.startsWith("https:") ) {
return false;
}
// Otherwise allow the OS to handle it
else if (url.startsWith("tel:")) {
Intent tel = new Intent(Intent.ACTION_DIAL, Uri.parse(url));
startActivity(tel);
return true;
}
else if (url.startsWith("mailto:")) {
String body = "Enter your Question, Enquiry or Feedback below:\n\n";
Intent mail = new Intent(Intent.ACTION_SEND);
Intent intent = mail.setType("application/octet-stream");
MailTo recipient = MailTo.parse(url);
mail.putExtra(Intent.EXTRA_EMAIL, new String[]{recipient.getTo()});
mail.putExtra(Intent.EXTRA_SUBJECT, "Contact");
mail.putExtra(Intent.EXTRA_TEXT, body);
startActivity(mail);
return true;
}
return true;
}
}
// mailto section of code
I make webview application. i want open both urls "rtsp://" and "market://" in default video player and play store.
i use this code. but problem is "market://" url open in play store correctly but rtsp link not open in default video player. error says page not found.
public class MainActivity extends Activity {
//private Button button;
private WebView webView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
webView = (WebView) findViewById(R.id.webView1);
startWebView("http://google.com");
this.webView.setWebViewClient(new WebViewClient());
this.webView.setDownloadListener(new DownloadListener()
{
public void onDownloadStart(String paramAnonymousString1, String paramAnonymousString2, String paramAnonymousString3, String paramAnonymousString4, long paramAnonymousLong)
{
Intent localIntent = new Intent("android.intent.action.VIEW", Uri.parse(paramAnonymousString1));
MainActivity.this.startActivity(localIntent);
}
});
this.webView.setWebViewClient(new WebViewClient()
{
public boolean shouldOverrideUrlLoading(WebView paramAnonymousWebView, String paramAnonymousString)
{
if (paramAnonymousString.startsWith("rtsp"))
{
Intent localIntent = new Intent("android.intent.action.VIEW", Uri.parse(paramAnonymousString));
MainActivity.this.startActivity(localIntent);
return true;
}
return super.shouldOverrideUrlLoading(paramAnonymousWebView, paramAnonymousString);
}
});
this.webView.setWebViewClient(new WebViewClient()
{
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getScheme().equals("market")) {
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
Activity host = (Activity) view.getContext();
host.startActivity(intent);
return true;
} catch (ActivityNotFoundException e) {
// Google Play app is not installed, you may want to open the app store link
Uri uri = Uri.parse(url);
view.loadUrl("http://play.google.com/store/apps/" + uri.getHost() + "?" + uri.getQuery());
return false;
}
}
return false;
}
});
}
I m displaying a gallery from a mobile website in webview . How can i download those images from webview ? Are there any extra settings for webview ?
This solved my problem
` `#Override
public boolean shouldOverrideUrlLoading (WebView view, String url) {
boolean shouldOverride = false;
// We only want to handle requests for image files, everything else the webview
// can handle normally
if (url.endsWith(".jpg")) {
shouldOverride = true;
Uri source = Uri.parse(url);
// Make a new request pointing to the mp3 url
DownloadManager.Request request = new DownloadManager.Request(source);
// Use the same file name for the destination
File destinationFile = new File (destinationDir, source.getLastPathSegment());
request.setDestinationUri(Uri.fromFile(destinationFile));
// Add it to the manager
manager.enqueue(request);
}
return shouldOverride;
}``
make sure to add permissions for download manager, SD read, SD write!
I think the best way to do it is to parse the html code of the page and get the images url.
Just load the URL of the image with the webview.
webview.setWebViewClient(new WebViewClient(){
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(url.contains("http://m.dudamobile.com/?source=DM_DIRECT") ){
DownloadManager dm = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
Request request = new Request(
Uri.parse(url));
enqueue = dm.enqueue(request);
return true;
}
else
{
view.loadUrl(url);
return true;
}
}}
//register your broadcast reciever of Download manager in the activity
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
long downloadId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, 0);
Query query = new Query();
query.setFilterById(enqueue);
try{
Cursor c = dm.query(query);
if (c.moveToFirst()) {
int columnIndex = c
.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == c
.getInt(columnIndex)) {
// ImageView view = (ImageView) findViewById(R.id.imageView1);
String uriString = c
.getString(c
.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
mNotificationManager.notify(1, notification);
// view.setImageURI(Uri.parse(url1));
/* Intent i = new Intent();
i.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS);
startActivity(i);*/
}
}
}catch(NullPointerException e)
{
Toast.makeText(getApplicationContext(),"Item not downloadable :( ", Toast.LENGTH_LONG).show();
}
}
}
};
registerReceiver(receiver, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
`