Can save some uploaded images

This commit is contained in:
Pierre HUBERT 2019-02-28 18:42:07 +01:00
parent 5f078867f2
commit 7ad41b1754
13 changed files with 218 additions and 11 deletions

View File

@ -13,6 +13,10 @@
<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
android:allowBackup="true"
android:fullBackupContent="@xml/backup_scheme"

View File

@ -7,6 +7,8 @@ import android.widget.ImageView;
import org.communiquons.android.comunic.client.data.runnables.ImageLoadRunnable;
import java.util.Objects;
/**
* Image load manager / helper
*
@ -95,6 +97,20 @@ public class ImageLoadHelper {
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
*/

View File

@ -28,12 +28,12 @@ public class ImageLoadRunnable implements Runnable {
/**
* Debug tag
*/
private static final String TAG = "ImageLoadRunnable";
private static final String TAG = ImageLoadRunnable.class.getSimpleName();
/**
* 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
@ -89,11 +89,7 @@ public class ImageLoadRunnable implements Runnable {
//Create the parent directory if required
ImageLoadUtils.create_parent_directory(mContext);
//Determine the filename for the requested URL
String filename = ImageLoadUtils.IMAGE_CACHE_DIRECTORY + ImageLoadUtils.get_file_name(url);
//Create file object
file = new File(mContext.getCacheDir(), filename);
file = ImageLoadUtils.getFileForImage(mContext, url);
//Check no thread is already running for the following image
if (!pendingOperation.containsKey(url)) {
@ -181,7 +177,8 @@ public class ImageLoadRunnable implements Runnable {
" deleted");
//Delete file
file.delete();
if(!file.delete())
Log.e(TAG, "Could not delete file " + file.getPath() + " !");
return;
}

View File

@ -22,7 +22,7 @@ public class ImageLoadUtils {
/**
* 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
@ -30,10 +30,28 @@ public class ImageLoadUtils {
* @param url The URL of the file
* @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);
}
/**
* 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
*

View File

@ -1,5 +1,6 @@
package org.communiquons.android.comunic.client.ui.activities;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
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.R;
import org.communiquons.android.comunic.client.ui.utils.PermissionsUtils;
import org.communiquons.crashreporter.CrashReporter;
import org.communiquons.android.comunic.client.data.enums.VirtualDirectoryType;
import org.communiquons.android.comunic.client.data.helpers.APIRequestHelper;
@ -193,6 +195,11 @@ public class MainActivity extends BaseActivity implements
GetCallConfigurationTask callConfigurationTask = new GetCallConfigurationTask(this);
callConfigurationTask.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
getTasksManager().addTask(callConfigurationTask);
//Request a few permissions
PermissionsUtils.RequestPermissions(this,
new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
}
@Override

View File

@ -91,6 +91,7 @@ class CommentsAdapter extends ArrayAdapter<Comment> {
//Update comment image (if any)
EnlargeableWebImageView commentImage = view.findViewById(R.id.comment_image);
commentImage.setCanSaveImageToGallery(true);
if(comment.getImage_url().length() < 5)
commentImage.setVisibility(View.GONE);
else {

View File

@ -136,6 +136,7 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter {
mMessage.setOnLongClickListener(this);
mImage.setOnLongClickListener(this);
mImage.setCanSaveImageToGallery(true);
}
/**

View File

@ -415,6 +415,7 @@ public class PostsAdapter extends BaseRecyclerViewAdapter {
super(itemView);
mPostImage = new EnlargeableWebImageView(getContext());
mPostImage.setCanSaveImageToGallery(true);
getAdditionalViewsLayout().addView(mPostImage,
new LinearLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
UiUtils.GetPixel(getContext(), 200)));

View File

@ -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);
}
}
}

View File

@ -2,11 +2,22 @@ package org.communiquons.android.comunic.client.ui.views;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.provider.MediaStore;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MenuItem;
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.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.
@ -17,13 +28,21 @@ import org.communiquons.android.comunic.client.R;
* 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
*/
private OnClickListener mOnClickListener;
private boolean mCanSaveImageToGallery;
public EnlargeableWebImageView(Context context) {
super(context);
init();
@ -68,6 +87,14 @@ public class EnlargeableWebImageView extends WebImageView {
return mOnClickListener == null;
}
public boolean isCanSaveImageToGallery() {
return mCanSaveImageToGallery;
}
public void setCanSaveImageToGallery(boolean mCanSaveImageToGallery) {
this.mCanSaveImageToGallery = mCanSaveImageToGallery;
}
/**
* Open the image in large dimensions
*/
@ -86,5 +113,80 @@ public class EnlargeableWebImageView extends WebImageView {
.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;
}
}
}

View 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>

View File

@ -335,4 +335,7 @@
<string name="action_hang_up">Raccrocher</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_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>

View File

@ -334,4 +334,7 @@
<string name="action_hang_up">Hang up</string>
<string name="action_switch_camera">Switch 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>