mirror of
https://github.com/pierre42100/ComunicAndroid
synced 2024-12-25 13:08:58 +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" />
|
||||
|
||||
|
||||
<!-- 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"
|
||||
|
@ -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
|
||||
*/
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
*
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -136,6 +136,7 @@ public class ConversationMessageAdapter extends RecyclerView.Adapter {
|
||||
|
||||
mMessage.setOnLongClickListener(this);
|
||||
mImage.setOnLongClickListener(this);
|
||||
mImage.setCanSaveImageToGallery(true);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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)));
|
||||
|
@ -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.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
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_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>
|
@ -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>
|
||||
|
Loading…
Reference in New Issue
Block a user