Skip to content
This repository has been archived by the owner on Jan 10, 2019. It is now read-only.

Commit

Permalink
Merge pull request #225 from partition/partition/save_images_feature
Browse files Browse the repository at this point in the history
Make it possible to save a picture
  • Loading branch information
fgei authored May 8, 2017
2 parents 387925a + 2b5dd71 commit 6e5b252
Show file tree
Hide file tree
Showing 3 changed files with 95 additions and 6 deletions.
1 change: 1 addition & 0 deletions res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,7 @@
<string name="action_forward">Forward</string>
<string name="action_close">Close</string>
<string name="remove">Remove</string>
<string name="save_image_context_menu_action">Save Image</string>

<string name="orbot_install_title">Install Orbot</string>
<string name="orbot_install_message">You must have Orbot installed and activated to proxy traffic through it. Would you like to install it?</string>
Expand Down
33 changes: 29 additions & 4 deletions src/com/duckduckgo/mobile/android/download/ContentDownloader.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,18 @@
package com.duckduckgo.mobile.android.download;

import java.io.File;
import java.util.UUID;

import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.DownloadManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Environment;
import android.widget.Toast;

import com.duckduckgo.mobile.android.R;
Expand All @@ -35,6 +38,31 @@ public ContentDownloader(Context context) {
}
}

@SuppressLint("NewApi")
public boolean isDownloadManagerEnabled() {
int downloadManagerState = context.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads");
return downloadManagerState != PackageManager.COMPONENT_ENABLED_STATE_DISABLED
&& downloadManagerState != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
&& downloadManagerState != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
}

@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void downloadImage(final String imageUrl) {
if (isDownloadManagerEnabled()) {
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(imageUrl));
request.setTitle(imageUrl)
.setVisibleInDownloadsUi(false)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_PICTURES, UUID.randomUUID().toString())
.setDescription(imageUrl);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.allowScanningByMediaScanner();
}
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
downloadManager.enqueue(request);
}
}

@SuppressLint("NewApi")
public void downloadContent(final String url, final String mimeType) {
// use mimeType to figure out an extension for temporary file
Expand All @@ -51,10 +79,7 @@ public void downloadContent(final String url, final String mimeType) {

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD) {

int downloadManagerState = context.getPackageManager().getApplicationEnabledSetting("com.android.providers.downloads");
if(downloadManagerState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
|| downloadManagerState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER
|| downloadManagerState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
if (!isDownloadManagerEnabled()) {
Toast.makeText(context, R.string.ToastSchemeNotSupported, Toast.LENGTH_SHORT).show();
return;
}
Expand Down
67 changes: 65 additions & 2 deletions src/com/duckduckgo/mobile/android/fragment/WebFragment.java
Original file line number Diff line number Diff line change
@@ -1,23 +1,28 @@
package com.duckduckgo.mobile.android.fragment;

import android.app.Activity;
import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v4.app.Fragment;
import android.support.v4.content.ContextCompat;
import android.support.v7.view.menu.MenuBuilder;
import android.util.Log;
import android.view.ContextMenu;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.webkit.DownloadListener;
import android.webkit.WebView;

import com.duckduckgo.mobile.android.DDGApplication;
import com.duckduckgo.mobile.android.R;
Expand Down Expand Up @@ -80,6 +85,8 @@ public class WebFragment extends Fragment {
public static final String TAG = "web_fragment";
public static final String URL = "url";
public static final String SESSION_TYPE = "session_type";
private static final int ITEM_ID_SAVE_IMAGE = 0;
private static final int REQUEST_WRITE_EXTERNAL_STORAGE = 0;

private Context context = null;

Expand Down Expand Up @@ -136,9 +143,65 @@ public void onActivityCreated(Bundle savedInstanceState) {
mainWebView.restoreState(savedInstanceState);
urlType = URLTYPE.getByCode(savedInstanceState.getInt("url_type"));
}
if (isDownloadImagesSupported()) {
registerForContextMenu(mainWebView);
}
}

@Override
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo);
WebView.HitTestResult hitTestResult = mainWebView.getHitTestResult();
if (isDownloadImagesSupported() && isImage(hitTestResult)) {
menu.setHeaderTitle(hitTestResult.getExtra());
menu.add(0, ITEM_ID_SAVE_IMAGE, 0, R.string.save_image_context_menu_action);
}
}

@Override
public boolean onContextItemSelected(MenuItem item) {
if (item.getItemId() == ITEM_ID_SAVE_IMAGE && isDownloadImagesSupported()) {
if (hasWriteExternalStoragePermission()) {
scheduleImageDownload();
} else {
requestPermissions(new String[] { Manifest.permission.WRITE_EXTERNAL_STORAGE },
REQUEST_WRITE_EXTERNAL_STORAGE);
}
return true;
}
return super.onContextItemSelected(item);
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
if (requestCode == REQUEST_WRITE_EXTERNAL_STORAGE && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
scheduleImageDownload();
} else {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}

private void scheduleImageDownload() {
String imageUrl = mainWebView.getHitTestResult().getExtra();
contentDownloader.downloadImage(imageUrl);
}

private boolean hasWriteExternalStoragePermission() {
int permission = ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE);
return permission == PackageManager.PERMISSION_GRANTED;
}

private boolean isImage(WebView.HitTestResult hitTestResult) {
int type = hitTestResult.getType();
return type == WebView.HitTestResult.IMAGE_TYPE || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE;
}

private boolean isDownloadImagesSupported() {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.GINGERBREAD
&& contentDownloader.isDownloadManagerEnabled();
}

@Override
public void onStart() {
super.onStart();
BusProvider.getInstance().register(this);
Expand Down

0 comments on commit 6e5b252

Please sign in to comment.