mirror of
https://github.com/pierre42100/ComunicAndroid
synced 2024-11-23 13:59:29 +00:00
Can save some uploaded images
This commit is contained in:
parent
5f078867f2
commit
7ad41b1754
@ -13,6 +13,10 @@
|
|||||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||||
|
|
||||||
|
|
||||||
|
<!-- To save file (eg. images) into user storage -->
|
||||||
|
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||||
|
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
android:fullBackupContent="@xml/backup_scheme"
|
android:fullBackupContent="@xml/backup_scheme"
|
||||||
|
@ -7,6 +7,8 @@ import android.widget.ImageView;
|
|||||||
|
|
||||||
import org.communiquons.android.comunic.client.data.runnables.ImageLoadRunnable;
|
import org.communiquons.android.comunic.client.data.runnables.ImageLoadRunnable;
|
||||||
|
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image load manager / helper
|
* Image load manager / helper
|
||||||
*
|
*
|
||||||
@ -95,6 +97,20 @@ public class ImageLoadHelper {
|
|||||||
clean();
|
clean();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check out whether an image view is loading or not
|
||||||
|
*
|
||||||
|
* @param v The target view
|
||||||
|
* @return TRUE if loading / FALSE else
|
||||||
|
*/
|
||||||
|
public static boolean IsLoading(View v){
|
||||||
|
|
||||||
|
return threads.containsKey(v)
|
||||||
|
&& threads.get(v) != null
|
||||||
|
&& Objects.requireNonNull(threads.get(v)).isAlive()
|
||||||
|
&& !Objects.requireNonNull(threads.get(v)).isInterrupted();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Clean the list of pending operations
|
* Clean the list of pending operations
|
||||||
*/
|
*/
|
||||||
|
@ -28,12 +28,12 @@ public class ImageLoadRunnable implements Runnable {
|
|||||||
/**
|
/**
|
||||||
* Debug tag
|
* Debug tag
|
||||||
*/
|
*/
|
||||||
private static final String TAG = "ImageLoadRunnable";
|
private static final String TAG = ImageLoadRunnable.class.getSimpleName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Image load lock
|
* Image load lock
|
||||||
*/
|
*/
|
||||||
public static ReentrantLock ImageLoadLock = null;
|
private static ReentrantLock ImageLoadLock = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An array map with all the pending images associated with their URLs
|
* An array map with all the pending images associated with their URLs
|
||||||
@ -89,11 +89,7 @@ public class ImageLoadRunnable implements Runnable {
|
|||||||
//Create the parent directory if required
|
//Create the parent directory if required
|
||||||
ImageLoadUtils.create_parent_directory(mContext);
|
ImageLoadUtils.create_parent_directory(mContext);
|
||||||
|
|
||||||
//Determine the filename for the requested URL
|
file = ImageLoadUtils.getFileForImage(mContext, url);
|
||||||
String filename = ImageLoadUtils.IMAGE_CACHE_DIRECTORY + ImageLoadUtils.get_file_name(url);
|
|
||||||
|
|
||||||
//Create file object
|
|
||||||
file = new File(mContext.getCacheDir(), filename);
|
|
||||||
|
|
||||||
//Check no thread is already running for the following image
|
//Check no thread is already running for the following image
|
||||||
if (!pendingOperation.containsKey(url)) {
|
if (!pendingOperation.containsKey(url)) {
|
||||||
@ -181,7 +177,8 @@ public class ImageLoadRunnable implements Runnable {
|
|||||||
" deleted");
|
" deleted");
|
||||||
|
|
||||||
//Delete file
|
//Delete file
|
||||||
file.delete();
|
if(!file.delete())
|
||||||
|
Log.e(TAG, "Could not delete file " + file.getPath() + " !");
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ public class ImageLoadUtils {
|
|||||||
/**
|
/**
|
||||||
* The main folder in the cache directory that stores the file
|
* The main folder in the cache directory that stores the file
|
||||||
*/
|
*/
|
||||||
public static final String IMAGE_CACHE_DIRECTORY = "img_cache/";
|
private static final String IMAGE_CACHE_DIRECTORY = "img_cache/";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the file name, based on the URL name
|
* Get the file name, based on the URL name
|
||||||
@ -30,10 +30,28 @@ public class ImageLoadUtils {
|
|||||||
* @param url The URL of the file
|
* @param url The URL of the file
|
||||||
* @return The name of the file, composed of characters that can be used in filename
|
* @return The name of the file, composed of characters that can be used in filename
|
||||||
*/
|
*/
|
||||||
public static String get_file_name(String url){
|
private static String get_file_name(String url){
|
||||||
return StringsUtils.sha1(url);
|
return StringsUtils.sha1(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the File object corresponding to an image URL
|
||||||
|
*
|
||||||
|
* Warning ! In some cases, the file might not exists
|
||||||
|
*
|
||||||
|
* @param context Application context
|
||||||
|
* @param url URL of the target image
|
||||||
|
* @return File object pointing on the image
|
||||||
|
*/
|
||||||
|
public static File getFileForImage(Context context, String url){
|
||||||
|
|
||||||
|
//Determine the filename for the requested URL
|
||||||
|
String filename = IMAGE_CACHE_DIRECTORY + ImageLoadUtils.get_file_name(url);
|
||||||
|
|
||||||
|
//Create file object
|
||||||
|
return new File(context.getCacheDir(), filename);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create cache images files parent directory if it does not exist
|
* Create cache images files parent directory if it does not exist
|
||||||
*
|
*
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package org.communiquons.android.comunic.client.ui.activities;
|
package org.communiquons.android.comunic.client.ui.activities;
|
||||||
|
|
||||||
|
import android.Manifest;
|
||||||
import android.app.Activity;
|
import android.app.Activity;
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.app.Dialog;
|
import android.app.Dialog;
|
||||||
@ -25,6 +26,7 @@ import android.widget.Toast;
|
|||||||
|
|
||||||
import org.communiquons.android.comunic.client.BuildConfig;
|
import org.communiquons.android.comunic.client.BuildConfig;
|
||||||
import org.communiquons.android.comunic.client.R;
|
import org.communiquons.android.comunic.client.R;
|
||||||
|
import org.communiquons.android.comunic.client.ui.utils.PermissionsUtils;
|
||||||
import org.communiquons.crashreporter.CrashReporter;
|
import org.communiquons.crashreporter.CrashReporter;
|
||||||
import org.communiquons.android.comunic.client.data.enums.VirtualDirectoryType;
|
import org.communiquons.android.comunic.client.data.enums.VirtualDirectoryType;
|
||||||
import org.communiquons.android.comunic.client.data.helpers.APIRequestHelper;
|
import org.communiquons.android.comunic.client.data.helpers.APIRequestHelper;
|
||||||
@ -193,6 +195,11 @@ public class MainActivity extends BaseActivity implements
|
|||||||
GetCallConfigurationTask callConfigurationTask = new GetCallConfigurationTask(this);
|
GetCallConfigurationTask callConfigurationTask = new GetCallConfigurationTask(this);
|
||||||
callConfigurationTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
callConfigurationTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
getTasksManager().addTask(callConfigurationTask);
|
getTasksManager().addTask(callConfigurationTask);
|
||||||
|
|
||||||
|
//Request a few permissions
|
||||||
|
PermissionsUtils.RequestPermissions(this,
|
||||||
|
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -91,6 +91,7 @@ class CommentsAdapter extends ArrayAdapter<Comment> {
|
|||||||
|
|
||||||
//Update comment image (if any)
|
//Update comment image (if any)
|
||||||
EnlargeableWebImageView commentImage = view.findViewById(R.id.comment_image);
|
EnlargeableWebImageView commentImage = view.findViewById(R.id.comment_image);
|
||||||
|
commentImage.setCanSaveImageToGallery(true);
|
||||||
if(comment.getImage_url().length() < 5)
|
if(comment.getImage_url().length() < 5)
|
||||||
commentImage.setVisibility(View.GONE);
|
commentImage.setVisibility(View.GONE);
|
||||||
else {
|
else {
|
||||||
|
@ -136,6 +136,7 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter {
|
|||||||
|
|
||||||
mMessage.setOnLongClickListener(this);
|
mMessage.setOnLongClickListener(this);
|
||||||
mImage.setOnLongClickListener(this);
|
mImage.setOnLongClickListener(this);
|
||||||
|
mImage.setCanSaveImageToGallery(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -415,6 +415,7 @@ public class PostsAdapter extends BaseRecyclerViewAdapter {
|
|||||||
super(itemView);
|
super(itemView);
|
||||||
|
|
||||||
mPostImage = new EnlargeableWebImageView(getContext());
|
mPostImage = new EnlargeableWebImageView(getContext());
|
||||||
|
mPostImage.setCanSaveImageToGallery(true);
|
||||||
getAdditionalViewsLayout().addView(mPostImage,
|
getAdditionalViewsLayout().addView(mPostImage,
|
||||||
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
|
||||||
UiUtils.GetPixel(getContext(), 200)));
|
UiUtils.GetPixel(getContext(), 200)));
|
||||||
|
@ -0,0 +1,44 @@
|
|||||||
|
package org.communiquons.android.comunic.client.ui.utils;
|
||||||
|
|
||||||
|
import android.app.Activity;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.support.annotation.NonNull;
|
||||||
|
import android.support.v4.app.ActivityCompat;
|
||||||
|
import android.support.v4.content.ContextCompat;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Permissions utilities
|
||||||
|
*
|
||||||
|
* @author Pierre HUBERT
|
||||||
|
*/
|
||||||
|
public class PermissionsUtils {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Request some permissions from the user
|
||||||
|
*
|
||||||
|
* @param activity Activity that perform the request
|
||||||
|
* @param permissions Requested permissions
|
||||||
|
*/
|
||||||
|
public static void RequestPermissions(@NonNull Activity activity, String[] permissions, int c){
|
||||||
|
|
||||||
|
ArrayList<String> permissionsToRequest = new ArrayList<>();
|
||||||
|
|
||||||
|
for(String permission : permissions){
|
||||||
|
if(ContextCompat.checkSelfPermission(activity, permission)
|
||||||
|
!= PackageManager.PERMISSION_GRANTED)
|
||||||
|
permissionsToRequest.add(permission);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Ask for permissions if required
|
||||||
|
if(permissionsToRequest.size() > 0){
|
||||||
|
String[] permissionsArray = permissionsToRequest.toArray(new String[0]);
|
||||||
|
assert permissionsArray != null;
|
||||||
|
ActivityCompat.requestPermissions(activity, permissionsArray, c);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -2,11 +2,22 @@ package org.communiquons.android.comunic.client.ui.views;
|
|||||||
|
|
||||||
import android.app.AlertDialog;
|
import android.app.AlertDialog;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.graphics.Bitmap;
|
||||||
|
import android.provider.MediaStore;
|
||||||
import android.util.AttributeSet;
|
import android.util.AttributeSet;
|
||||||
|
import android.util.Log;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
|
import android.view.MenuItem;
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
import android.widget.PopupMenu;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import org.communiquons.android.comunic.client.R;
|
import org.communiquons.android.comunic.client.R;
|
||||||
|
import org.communiquons.android.comunic.client.data.helpers.ImageLoadHelper;
|
||||||
|
import org.communiquons.android.comunic.client.data.utils.ImageLoadUtils;
|
||||||
|
import org.communiquons.android.comunic.client.ui.utils.BitmapUtils;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Enlargeable images view.
|
* Enlargeable images view.
|
||||||
@ -17,13 +28,21 @@ import org.communiquons.android.comunic.client.R;
|
|||||||
* Created by pierre on 4/28/18.
|
* Created by pierre on 4/28/18.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class EnlargeableWebImageView extends WebImageView {
|
public class EnlargeableWebImageView extends WebImageView implements PopupMenu.OnMenuItemClickListener {
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Debug tag
|
||||||
|
*/
|
||||||
|
private static final String TAG = EnlargeableWebImageView.class.getSimpleName();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Optional additional OnClick Listener
|
* Optional additional OnClick Listener
|
||||||
*/
|
*/
|
||||||
private OnClickListener mOnClickListener;
|
private OnClickListener mOnClickListener;
|
||||||
|
|
||||||
|
private boolean mCanSaveImageToGallery;
|
||||||
|
|
||||||
public EnlargeableWebImageView(Context context) {
|
public EnlargeableWebImageView(Context context) {
|
||||||
super(context);
|
super(context);
|
||||||
init();
|
init();
|
||||||
@ -68,6 +87,14 @@ public class EnlargeableWebImageView extends WebImageView {
|
|||||||
return mOnClickListener == null;
|
return mOnClickListener == null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isCanSaveImageToGallery() {
|
||||||
|
return mCanSaveImageToGallery;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setCanSaveImageToGallery(boolean mCanSaveImageToGallery) {
|
||||||
|
this.mCanSaveImageToGallery = mCanSaveImageToGallery;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Open the image in large dimensions
|
* Open the image in large dimensions
|
||||||
*/
|
*/
|
||||||
@ -86,5 +113,80 @@ public class EnlargeableWebImageView extends WebImageView {
|
|||||||
.show();
|
.show();
|
||||||
|
|
||||||
|
|
||||||
|
//Offer the user to save if image if possible
|
||||||
|
if(isCanSaveImageToGallery()){
|
||||||
|
image.setOnLongClickListener(this::openContextMenu);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Open context menu for the image
|
||||||
|
*/
|
||||||
|
private boolean openContextMenu(View v){
|
||||||
|
|
||||||
|
//Show popup menu
|
||||||
|
PopupMenu popupMenu = new PopupMenu(getContext(), v);
|
||||||
|
popupMenu.inflate(R.menu.image_menu);
|
||||||
|
popupMenu.setOnMenuItemClickListener(this);
|
||||||
|
|
||||||
|
if(ImageLoadHelper.IsLoading(this))
|
||||||
|
popupMenu.getMenu().findItem(R.id.action_save_image_in_gallery).setEnabled(false);
|
||||||
|
|
||||||
|
|
||||||
|
popupMenu.show();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onMenuItemClick(MenuItem item) {
|
||||||
|
|
||||||
|
|
||||||
|
if(item.getItemId() == R.id.action_save_image_in_gallery){
|
||||||
|
|
||||||
|
if(!saveImageToGallery())
|
||||||
|
Toast.makeText(getContext(), R.string.err_save_image_in_gallery, Toast.LENGTH_SHORT).show();
|
||||||
|
else
|
||||||
|
Toast.makeText(getContext(), R.string.success_save_image_in_gallery, Toast.LENGTH_SHORT).show();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Save the current image in this {@link WebImageView} into the gallery
|
||||||
|
*
|
||||||
|
* @return TRUE in case of success / FALSE else
|
||||||
|
*/
|
||||||
|
private boolean saveImageToGallery(){
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (ImageLoadHelper.IsLoading(this))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
File file = ImageLoadUtils.getFileForImage(getContext(), getCurrURL());
|
||||||
|
|
||||||
|
if (!file.isFile()) {
|
||||||
|
Log.e(TAG, "Image is not a file!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap bm = BitmapUtils.openResized(file, 1500, 1500);
|
||||||
|
|
||||||
|
//Save the image into the gallery
|
||||||
|
return MediaStore.Images.Media.insertImage(
|
||||||
|
getContext().getContentResolver(),
|
||||||
|
bm,
|
||||||
|
"Comunic image",
|
||||||
|
getCurrURL()
|
||||||
|
) != null;
|
||||||
|
|
||||||
|
} catch (Exception e){
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
10
app/src/main/res/menu/image_menu.xml
Normal file
10
app/src/main/res/menu/image_menu.xml
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||||
|
|
||||||
|
<item
|
||||||
|
android:id="@+id/action_save_image_in_gallery"
|
||||||
|
android:title="@string/action_save_image_in_gallery"
|
||||||
|
/>
|
||||||
|
|
||||||
|
|
||||||
|
</menu>
|
@ -335,4 +335,7 @@
|
|||||||
<string name="action_hang_up">Raccrocher</string>
|
<string name="action_hang_up">Raccrocher</string>
|
||||||
<string name="action_switch_camera">Changer de caméra</string>
|
<string name="action_switch_camera">Changer de caméra</string>
|
||||||
<string name="action_stop_camera">Arrêter la caméra</string>
|
<string name="action_stop_camera">Arrêter la caméra</string>
|
||||||
|
<string name="action_save_image_in_gallery">Enregistrer dans la gallerie</string>
|
||||||
|
<string name="err_save_image_in_gallery">Une erreur a survenue lors de l\'enregistrement de l\'image dans la gallerie !</string>
|
||||||
|
<string name="success_save_image_in_gallery">L\'image a bien été enregistrée dans la gallerie !</string>
|
||||||
</resources>
|
</resources>
|
@ -334,4 +334,7 @@
|
|||||||
<string name="action_hang_up">Hang up</string>
|
<string name="action_hang_up">Hang up</string>
|
||||||
<string name="action_switch_camera">Switch camera</string>
|
<string name="action_switch_camera">Switch camera</string>
|
||||||
<string name="action_stop_camera">Stop camera</string>
|
<string name="action_stop_camera">Stop camera</string>
|
||||||
|
<string name="action_save_image_in_gallery">Save in gallery</string>
|
||||||
|
<string name="err_save_image_in_gallery">Could not save the image in the gallery!</string>
|
||||||
|
<string name="success_save_image_in_gallery">Successfully saved the image into the gallery!</string>
|
||||||
</resources>
|
</resources>
|
||||||
|
Loading…
Reference in New Issue
Block a user