mirror of
https://github.com/gsantner/dandelion
synced 2024-11-22 04:12:08 +01:00
Improve sharing *a lot* +GIF - add support for multiple filetypes
* now supporting GIFs too ;) * Create connection over netcipher
This commit is contained in:
parent
68be2f3a4a
commit
38cf36b46c
8 changed files with 112 additions and 209 deletions
|
@ -24,6 +24,8 @@ import android.graphics.Bitmap;
|
||||||
import android.graphics.BitmapFactory;
|
import android.graphics.BitmapFactory;
|
||||||
import android.widget.ImageView;
|
import android.widget.ImageView;
|
||||||
|
|
||||||
|
import net.gsantner.opoc.util.DownloadTask;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
public class AvatarImageLoader {
|
public class AvatarImageLoader {
|
||||||
|
@ -52,7 +54,9 @@ public class AvatarImageLoader {
|
||||||
|
|
||||||
public void startImageDownload(ImageView imageView, String avatarUrl) {
|
public void startImageDownload(ImageView imageView, String avatarUrl) {
|
||||||
if (!avatarUrl.equals("")) {
|
if (!avatarUrl.equals("")) {
|
||||||
new ImageDownloadTask(imageView, avatarFile.getAbsolutePath()).execute(avatarUrl);
|
new DownloadTask(new File(avatarFile.getAbsolutePath()), (ok, file) -> {
|
||||||
|
loadToImageView(imageView);
|
||||||
|
}).execute(avatarUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,98 +0,0 @@
|
||||||
/*
|
|
||||||
This file is part of the dandelion*.
|
|
||||||
|
|
||||||
dandelion* is free software: you can redistribute it and/or modify
|
|
||||||
it under the terms of the GNU General Public License as published by
|
|
||||||
the Free Software Foundation, either version 3 of the License, or
|
|
||||||
(at your option) any later version.
|
|
||||||
|
|
||||||
dandelion* is distributed in the hope that it will be useful,
|
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
GNU General Public License for more details.
|
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
|
||||||
along with the dandelion*.
|
|
||||||
|
|
||||||
If not, see <http://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
package com.github.dfa.diaspora_android.service;
|
|
||||||
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.graphics.BitmapFactory;
|
|
||||||
import android.os.AsyncTask;
|
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.widget.ImageView;
|
|
||||||
|
|
||||||
import com.github.dfa.diaspora_android.util.AppLog;
|
|
||||||
|
|
||||||
import java.io.FileOutputStream;
|
|
||||||
import java.io.IOException;
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import javax.net.ssl.HttpsURLConnection;
|
|
||||||
|
|
||||||
import info.guardianproject.netcipher.NetCipher;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Task that can be used to download images from URLs and store them in storage
|
|
||||||
* Created by gsantner (http://gsantner.net/) on 24.03.16.
|
|
||||||
*/
|
|
||||||
public class ImageDownloadTask extends AsyncTask<String, Void, Bitmap> {
|
|
||||||
private final ImageView imageView;
|
|
||||||
private String savePath;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Download image from URL
|
|
||||||
*
|
|
||||||
* @param imageView ImageView to set image to (null = don't set)
|
|
||||||
* @param savePath Save image to file (null = don't save)
|
|
||||||
*/
|
|
||||||
public ImageDownloadTask(@Nullable ImageView imageView, @Nullable String savePath) {
|
|
||||||
this.imageView = imageView;
|
|
||||||
this.savePath = savePath;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected Bitmap doInBackground(String... urls) {
|
|
||||||
String url = urls[0];
|
|
||||||
Bitmap bitmap = null;
|
|
||||||
FileOutputStream out = null;
|
|
||||||
InputStream inStream;
|
|
||||||
HttpsURLConnection connection;
|
|
||||||
try {
|
|
||||||
connection = NetCipher.getHttpsURLConnection(url);
|
|
||||||
inStream = connection.getInputStream();
|
|
||||||
bitmap = BitmapFactory.decodeStream(inStream);
|
|
||||||
|
|
||||||
// Save to file if not null
|
|
||||||
if (savePath != null) {
|
|
||||||
out = new FileOutputStream(savePath);
|
|
||||||
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
inStream.close();
|
|
||||||
} catch (IOException e) {/*Nothing*/}
|
|
||||||
|
|
||||||
connection.disconnect();
|
|
||||||
|
|
||||||
} catch (Exception e) {
|
|
||||||
AppLog.e(this, e.getMessage());
|
|
||||||
} finally {
|
|
||||||
try {
|
|
||||||
if (out != null) {
|
|
||||||
out.close();
|
|
||||||
}
|
|
||||||
} catch (IOException ignored) {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return bitmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void onPostExecute(Bitmap result) {
|
|
||||||
// Display on imageview if not null
|
|
||||||
if (imageView != null) {
|
|
||||||
imageView.setImageBitmap(result);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -18,30 +18,27 @@
|
||||||
*/
|
*/
|
||||||
package com.github.dfa.diaspora_android.web;
|
package com.github.dfa.diaspora_android.web;
|
||||||
|
|
||||||
import android.Manifest;
|
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
|
||||||
import android.app.DownloadManager;
|
|
||||||
import android.content.ClipData;
|
import android.content.ClipData;
|
||||||
import android.content.ClipboardManager;
|
import android.content.ClipboardManager;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.DialogInterface;
|
|
||||||
import android.content.Intent;
|
import android.content.Intent;
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.graphics.Bitmap;
|
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Environment;
|
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
import android.view.ContextMenu;
|
import android.view.ContextMenu;
|
||||||
import android.view.MenuItem;
|
import android.view.MenuItem;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import com.github.dfa.diaspora_android.BuildConfig;
|
||||||
import com.github.dfa.diaspora_android.R;
|
import com.github.dfa.diaspora_android.R;
|
||||||
import com.github.dfa.diaspora_android.activity.MainActivity;
|
import com.github.dfa.diaspora_android.util.AppSettings;
|
||||||
import com.github.dfa.diaspora_android.service.ImageDownloadTask;
|
|
||||||
import com.github.dfa.diaspora_android.util.ActivityUtils;
|
import net.gsantner.opoc.util.DownloadTask;
|
||||||
|
import net.gsantner.opoc.util.PermissionChecker;
|
||||||
|
import net.gsantner.opoc.util.ShareUtil;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Subclass of WebView which adds a context menu for long clicks on images or links to share, save
|
* Subclass of WebView which adds a context menu for long clicks on images or links to share, save
|
||||||
|
@ -81,108 +78,46 @@ public class ContextMenuWebView extends NestedWebView {
|
||||||
public boolean onMenuItemClick(MenuItem item) {
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
HitTestResult result = getHitTestResult();
|
HitTestResult result = getHitTestResult();
|
||||||
String url = result.getExtra();
|
String url = result.getExtra();
|
||||||
|
final ShareUtil shu = new ShareUtil(context).setFileProviderAuthority(BuildConfig.APPLICATION_ID);
|
||||||
|
final PermissionChecker permc = new PermissionChecker(parentActivity);
|
||||||
|
final AppSettings appSettings = new AppSettings(context);
|
||||||
|
|
||||||
switch (item.getItemId()) {
|
switch (item.getItemId()) {
|
||||||
//Save image to external memory
|
//Save image to external memory
|
||||||
case ID_SAVE_IMAGE: {
|
case ID_SAVE_IMAGE: {
|
||||||
boolean writeToStoragePermitted = true;
|
if (permc.doIfExtStoragePermissionGranted(context.getString(R.string.permissions_image))) {
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 23) {
|
File fileSaveDirectory = appSettings.getAppSaveDirectory();
|
||||||
int hasWRITE_EXTERNAL_STORAGE = parentActivity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
if (permc.mkdirIfStoragePermissionGranted(fileSaveDirectory)) {
|
||||||
if (hasWRITE_EXTERNAL_STORAGE != PackageManager.PERMISSION_GRANTED) {
|
String filename = "dandelion-" + ShareUtil.SDF_SHORT.format(new Date()) + url.substring(url.lastIndexOf("."));
|
||||||
writeToStoragePermitted = false;
|
/*Uri source = Uri.parse(url);
|
||||||
if (!parentActivity.shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
|
||||||
new AlertDialog.Builder(parentActivity)
|
|
||||||
.setMessage(R.string.permissions_image)
|
|
||||||
.setPositiveButton(context.getText(android.R.string.yes), new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 23)
|
|
||||||
parentActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
|
||||||
MainActivity.REQUEST_CODE__ACCESS_EXTERNAL_STORAGE);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setCancelable(false)
|
|
||||||
.setNegativeButton(context.getText(android.R.string.no), null)
|
|
||||||
.show();
|
|
||||||
}
|
|
||||||
parentActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
|
||||||
MainActivity.REQUEST_CODE__ACCESS_EXTERNAL_STORAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (writeToStoragePermitted) {
|
|
||||||
//Make sure, Diaspora Folder exists
|
|
||||||
File destinationFolder = new File(Environment.getExternalStorageDirectory() + "/Pictures/Diaspora");
|
|
||||||
if (!destinationFolder.exists()) {
|
|
||||||
destinationFolder.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (url != null) {
|
|
||||||
Uri source = Uri.parse(url);
|
|
||||||
DownloadManager.Request request = new DownloadManager.Request(source);
|
DownloadManager.Request request = new DownloadManager.Request(source);
|
||||||
File destinationFile = new File(Environment.getExternalStorageDirectory() + "/Pictures/Diaspora/" + System.currentTimeMillis() + ".png");
|
request.setDestinationUri(Uri.fromFile(new File(fileSaveDirectory, filename)));
|
||||||
|
((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);*/
|
||||||
request.setDestinationUri(Uri.fromFile(destinationFile));
|
new DownloadTask(new File(fileSaveDirectory, filename), (ok, dlfile) -> {
|
||||||
((DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE)).enqueue(request);
|
if (ok) {
|
||||||
|
Toast.makeText(context, context.getText(R.string.share__toast_saved_image_to_location) + " " + dlfile.getName(), Toast.LENGTH_LONG).show();
|
||||||
Toast.makeText(context, context.getText(R.string.share__toast_saved_image_to_location) + " " +
|
}
|
||||||
destinationFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
|
}).execute(url);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
case ID_SHARE_IMAGE:
|
|
||||||
if (url != null) {
|
|
||||||
boolean writeToStoragePermitted = true;
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 23) {
|
|
||||||
int hasWRITE_EXTERNAL_STORAGE = parentActivity.checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE);
|
|
||||||
if (hasWRITE_EXTERNAL_STORAGE != PackageManager.PERMISSION_GRANTED) {
|
|
||||||
writeToStoragePermitted = false;
|
|
||||||
if (!parentActivity.shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
|
|
||||||
new AlertDialog.Builder(parentActivity)
|
|
||||||
.setMessage(R.string.permissions_image)
|
|
||||||
.setPositiveButton(context.getText(android.R.string.yes), new DialogInterface.OnClickListener() {
|
|
||||||
@Override
|
|
||||||
public void onClick(DialogInterface dialog, int which) {
|
|
||||||
if (android.os.Build.VERSION.SDK_INT >= 23)
|
|
||||||
parentActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
|
||||||
MainActivity.REQUEST_CODE__ACCESS_EXTERNAL_STORAGE);
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.setNegativeButton(context.getText(android.R.string.no), null)
|
|
||||||
.show();
|
|
||||||
} else {
|
|
||||||
parentActivity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
|
|
||||||
MainActivity.REQUEST_CODE__ACCESS_EXTERNAL_STORAGE);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (writeToStoragePermitted) {
|
|
||||||
//Make sure, Diaspora Folder exists
|
|
||||||
File destinationFolder = new File(Environment.getExternalStorageDirectory() + "/Pictures/Diaspora");
|
|
||||||
if (!destinationFolder.exists()) {
|
|
||||||
destinationFolder.mkdirs();
|
|
||||||
}
|
|
||||||
|
|
||||||
final Uri local = Uri.parse(Environment.getExternalStorageDirectory() + "/Pictures/Diaspora/" + System.currentTimeMillis() + ".png");
|
|
||||||
new ImageDownloadTask(null, local.getPath()) {
|
|
||||||
@Override
|
|
||||||
protected void onPostExecute(Bitmap result) {
|
|
||||||
|
|
||||||
Uri myUri = ActivityUtils.getFileSharingUri(context, new File(local.getPath()));
|
|
||||||
Intent sharingIntent = new Intent();
|
|
||||||
sharingIntent.setAction(Intent.ACTION_SEND);
|
|
||||||
sharingIntent.putExtra(Intent.EXTRA_STREAM, myUri);
|
|
||||||
sharingIntent.setType("image/png");
|
|
||||||
sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
|
||||||
context.startActivity(Intent.createChooser(sharingIntent, getResources().getString(R.string.action_share_dotdotdot)));
|
|
||||||
}
|
|
||||||
}.execute(url);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
Toast.makeText(context, "Cannot share image: url is null", Toast.LENGTH_SHORT).show();
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case ID_SHARE_IMAGE: {
|
||||||
|
if (permc.doIfExtStoragePermissionGranted(context.getString(R.string.permissions_image))) {
|
||||||
|
File fileSaveDirectory = appSettings.getAppSaveDirectory();
|
||||||
|
if (permc.mkdirIfStoragePermissionGranted(fileSaveDirectory)) {
|
||||||
|
String filename = ".dandelion-shared" + url.substring(url.lastIndexOf("."));
|
||||||
|
new DownloadTask(new File(fileSaveDirectory, filename), (ok, dlfile) -> {
|
||||||
|
if (ok) {
|
||||||
|
Toast.makeText(context, context.getText(R.string.share__toast_saved_image_to_location) + " " + dlfile.getName(), Toast.LENGTH_LONG).show();
|
||||||
|
shu.shareStream(dlfile, "image/" + dlfile.getAbsolutePath().lastIndexOf(".") + 1);
|
||||||
|
}
|
||||||
|
}).execute(url);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
case ID_IMAGE_EXTERNAL_BROWSER:
|
case ID_IMAGE_EXTERNAL_BROWSER:
|
||||||
if (url != null) {
|
if (url != null) {
|
||||||
|
|
|
@ -108,7 +108,7 @@ public class CustomTabsHelper {
|
||||||
sPackageNameToUse = CHROMIUM;
|
sPackageNameToUse = CHROMIUM;
|
||||||
} else if (packagesSupportingCustomTabs.contains(FENNEC)) {
|
} else if (packagesSupportingCustomTabs.contains(FENNEC)) {
|
||||||
sPackageNameToUse = FENNEC;
|
sPackageNameToUse = FENNEC;
|
||||||
}else if (packagesSupportingCustomTabs.contains(KLAR)) {
|
} else if (packagesSupportingCustomTabs.contains(KLAR)) {
|
||||||
sPackageNameToUse = KLAR;
|
sPackageNameToUse = KLAR;
|
||||||
}
|
}
|
||||||
return sPackageNameToUse;
|
return sPackageNameToUse;
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
#########################################################*/
|
#########################################################*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Parses most common markdown tags. Only inline tags are supported, multiline/block syntax
|
* Parses most common markdown tags. Only inline tags are supported, multiline/block syntax
|
||||||
* is not supported (citation, multiline code, ..). This is intended to stay as easy as possible.
|
* is not supported (citation, multiline code, ..). This is intended to stay as easy as possible.
|
||||||
*
|
*
|
||||||
|
|
|
@ -48,8 +48,8 @@ package net.gsantner.opoc.preference.nonsupport;
|
||||||
import android.annotation.TargetApi;
|
import android.annotation.TargetApi;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.support.annotation.Nullable;
|
|
||||||
import android.preference.ListPreference;
|
import android.preference.ListPreference;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
|
57
app/src/main/java/net/gsantner/opoc/util/DownloadTask.java
Normal file
57
app/src/main/java/net/gsantner/opoc/util/DownloadTask.java
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
/*
|
||||||
|
This file is part of the dandelion*.
|
||||||
|
|
||||||
|
dandelion* is free software: you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation, either version 3 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
dandelion* is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License
|
||||||
|
along with the dandelion*.
|
||||||
|
|
||||||
|
If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
package net.gsantner.opoc.util;
|
||||||
|
|
||||||
|
import android.os.AsyncTask;
|
||||||
|
import android.support.annotation.Nullable;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.net.ssl.HttpsURLConnection;
|
||||||
|
|
||||||
|
import info.guardianproject.netcipher.NetCipher;
|
||||||
|
|
||||||
|
public class DownloadTask extends AsyncTask<String, Void, Boolean> {
|
||||||
|
private File _targetFile;
|
||||||
|
private Callback.a2<Boolean, File> _callback;
|
||||||
|
|
||||||
|
public DownloadTask(File targetFile, @Nullable Callback.a2<Boolean, File> callback) {
|
||||||
|
_targetFile = targetFile;
|
||||||
|
_callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Boolean doInBackground(String... urls) {
|
||||||
|
if (urls != null && urls.length > 0 && urls[0] != null) {
|
||||||
|
try {
|
||||||
|
HttpsURLConnection connection = NetCipher.getHttpsURLConnection(urls[0]);
|
||||||
|
return NetworkUtils.downloadFile(null, _targetFile, connection, null);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void onPostExecute(Boolean result) {
|
||||||
|
if (_callback != null) {
|
||||||
|
_callback.callback(result, _targetFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -53,11 +53,16 @@ public class NetworkUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean downloadFile(final URL url, final File outFile, final Callback.a1<Float> progressCallback) {
|
public static boolean downloadFile(final URL url, final File outFile, final Callback.a1<Float> progressCallback) {
|
||||||
|
return downloadFile(url, outFile, null, progressCallback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean downloadFile(final URL url, final File outFile, HttpURLConnection connection, final Callback.a1<Float> progressCallback) {
|
||||||
InputStream input = null;
|
InputStream input = null;
|
||||||
OutputStream output = null;
|
OutputStream output = null;
|
||||||
HttpURLConnection connection = null;
|
|
||||||
try {
|
try {
|
||||||
connection = (HttpURLConnection) url.openConnection();
|
if (connection == null) {
|
||||||
|
connection = (HttpURLConnection) url.openConnection();
|
||||||
|
}
|
||||||
connection.connect();
|
connection.connect();
|
||||||
input = connection.getInputStream();
|
input = connection.getInputStream();
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue