Added option to rename file. Folders' content is now refreshable. Many improvements.

parent c49490e8
......@@ -3,12 +3,15 @@ package com.systemallica.gallery;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.content.ContextCompat;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
......@@ -22,20 +25,26 @@ import java.io.File;
import java.util.ArrayList;
import java.util.Collections;
import butterknife.BindView;
import butterknife.ButterKnife;
public class FolderActivity extends AppCompatActivity {
final ArrayList<File> list_of_files = new ArrayList<>();
final ArrayList<String> list_of_paths = new ArrayList<>();
String folder;
GridView gridView;
GridViewAdapterImages gridAdapter;
int columns = 3;
@BindView(R.id.swipelayout) SwipeRefreshLayout swipeLayout;
@BindView(R.id.placeholderNoImages) TextView text;
@BindView(R.id.gridViewFolder) GridView gridView;
@BindView(R.id.toolbar) Toolbar toolbar;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_folder);
Toolbar toolbar = findViewById(R.id.toolbar);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
// Get name of folder passed with the intent
......@@ -55,6 +64,14 @@ public class FolderActivity extends AppCompatActivity {
int app_primary = ContextCompat.getColor(this, R.color.app_primary);
getWindow().setNavigationBarColor(app_primary);
}
// Set on swipe refresh listener
swipeLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
@Override
public void onRefresh() {
startRefresh();
}
});
}
@Override
......@@ -95,6 +112,45 @@ public class FolderActivity extends AppCompatActivity {
}
}
private void startRefresh(){
swipeLayout.setRefreshing(true);
// Sleep main thread for better UI feedback
new DummySleep().execute();
}
private class DummySleep extends AsyncTask<Void, Void, Void> {
static final int TASK_DURATION = 2 * 1000; // 2 seconds
@Override
protected Void doInBackground(Void... params) {
// Sleep for a small amount of time to simulate a background-task
try {
Thread.sleep(TASK_DURATION);
} catch (InterruptedException e) {
e.printStackTrace();
}
return null;
}
@Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
endRefresh();
}
}
private void endRefresh(){
// Refresh data
loadImages(folder, columns);
// Stop the refreshing indicator
swipeLayout.setRefreshing(false);
}
private void loadImages(String folder, int columns){
// Define the cursor and get path and bitmap of images
......@@ -108,6 +164,8 @@ public class FolderActivity extends AppCompatActivity {
list_of_files.clear();
list_of_paths.clear();
Log.e("test", "load");
// Images-------------------------------------------------------------------------------
uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
......@@ -163,8 +221,7 @@ public class FolderActivity extends AppCompatActivity {
for (File file : list_of_files) {
list_of_paths.add(file.getPath());
}
// Find GridView to populate
gridView = findViewById(R.id.gridViewFolder);
// Set number of columns
gridView.setNumColumns(columns);
// Create and set the adapter (context, layout_of_image, list_of_images)
......@@ -232,31 +289,48 @@ public class FolderActivity extends AppCompatActivity {
list_of_paths.remove(list_of_paths.get(position));
list_of_files.remove(list_of_files.get(position));
gridAdapter.notifyDataSetChanged();
// Set result of activity to 0 -> One pic deleted
setResult(0);
// One pic deleted
setResult(2);
}
// The only image of the folder was deleted
if(resultCode == 2) {
TextView text = findViewById(R.id.placeholderNoImages);
else if(resultCode == 2) {
text.setText(R.string.no_images);
// Set result of activity to 1 -> Folder emptied
// Folder emptied
setResult(1);
}
// The first image of the folder was deleted, need a new thumbnail
if(resultCode == 3) {
// Set result of activity to 2 -> Thumbnail needs change
else if(resultCode == 3) {
// Thumbnail needs change
setResult(2);
}
// UI needs to be reloaded
else if(resultCode == 4) {
// One image was renamed
int position = data.getIntExtra("file", 0);
list_of_paths.remove(list_of_paths.get(position));
list_of_files.remove(list_of_files.get(position));
gridAdapter.notifyDataSetChanged();
// Reload
loadImages(folder, columns);
setResult(2);
}
// Simple UI refresh
else if(resultCode == 5) {
// Reload
loadImages(folder, columns);
setResult(2);
}
}else if (requestCode == 2){
if(resultCode == 1) {
// One video was deleted
// One video was deleted/renamed
int position = data.getIntExtra("file", 0);
list_of_paths.remove(list_of_paths.get(position));
list_of_files.remove(list_of_files.get(position));
gridAdapter.notifyDataSetChanged();
// Set result of activity to 0 -> One video deleted
setResult(0);
// Reload
loadImages(folder, columns);
// Set result
setResult(2);
}
}
}
......
......@@ -21,6 +21,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.TextView;
......@@ -103,7 +104,7 @@ public class ImageActivity extends AppCompatActivity {
public void onPageSelected(int position) {
// Set title to current image's name
positionArray = mPager.getCurrentItem();
toolbar.setTitle(new File(list_of_images.get(positionArray)).getName());
toolbar.setTitle(Utils.getBaseName(new File(list_of_images.get(positionArray))));
}
@Override
......@@ -146,6 +147,14 @@ public class ImageActivity extends AppCompatActivity {
if(resultCode == 1) {
// Update UI
deleteVideo();
}else if(resultCode == 2) {
// Change toolbar text
String name = data.getStringExtra("name");
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(name);
mPagerAdapter.notifyDataSetChanged();
// Reload images when leaving activity
setResult(5);
}
}
}
......@@ -328,6 +337,10 @@ public class ImageActivity extends AppCompatActivity {
deleteImage(file);
return true;
case R.id.action_rename:
renameFile(file);
return true;
case R.id.action_details:
showDetails(file);
return true;
......@@ -337,7 +350,62 @@ public class ImageActivity extends AppCompatActivity {
}
}
void showDetails(final File image){
private void renameFile(final File file){
runOnUiThread(new Runnable() {
public void run() {
// Inflate layout and get views
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.rename_dialog, null);
TextView old_name = layout.findViewById(R.id.old_name);
final EditText new_name = layout.findViewById(R.id.new_name);
String set = "Old name: " + Utils.getBaseName(file);
old_name.setText(set);
// Create and show dialog
AlertDialog.Builder builder = new AlertDialog.Builder(ImageActivity.this);
builder.setView(layout)
.setTitle(R.string.rename_rename)
.setPositiveButton(R.string.action_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Change toolbar text
Toolbar toolbar = findViewById(R.id.toolbar);
toolbar.setTitle(new_name.getText().toString());
// Build path with new name
String newName;
String folderPath = file.getParentFile().getPath();
newName = folderPath + "/" + new_name.getText().toString() + Utils.getExtension(file);
// Rename the file and set activity result
if(file.renameTo(new File(newName))){
//Remove image from MediaStore
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
//Add new file to MediaStore
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(newName))));
// Send intent
Intent intent = new Intent();
intent.putExtra("file", positionArray);
// Set result of activity
setResult(4, intent);
}
}
})
.setNegativeButton(R.string.action_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Close AlertDialog
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
});
}
private void showDetails(final File image){
runOnUiThread(new Runnable() {
public void run() {
......@@ -392,7 +460,7 @@ public class ImageActivity extends AppCompatActivity {
builder.setView(layout)
.setTitle(R.string.details_image)
.setIcon(R.drawable.ic_information_outline_black_48dp)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
.setPositiveButton(R.string.action_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Close AlertDialog
}
......
......@@ -47,6 +47,7 @@ public class MainActivity extends AppCompatActivity {
@BindView(R.id.swipelayout) SwipeRefreshLayout swipeLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
......@@ -358,7 +359,7 @@ public class MainActivity extends AppCompatActivity {
list_of_folders.remove(folder_position);
gridAdapter.notifyDataSetChanged();
}
if(resultCode == 0 || resultCode == 2) {
if(resultCode == 2) {
startRefresh();
}
}
......
......@@ -28,7 +28,7 @@ class Utils {
}
static class ImageFileFilter implements FileFilter {
private final String[] okFileExtensions = new String[] { "jpg", "jpeg", "png", "gif" };
private final String[] okFileExtensions = new String[]{"jpg", "jpeg", "png", "gif"};
public boolean accept(File file) {
for (String extension : okFileExtensions) {
......@@ -41,7 +41,7 @@ class Utils {
}
static class VideoFileFilter implements FileFilter {
private final String[] okFileExtensions = new String[] { "mp4", "3gp" };
private final String[] okFileExtensions = new String[]{"mp4", "3gp"};
public boolean accept(File file) {
for (String extension : okFileExtensions) {
......@@ -54,7 +54,7 @@ class Utils {
}
static class MediaFileFilter implements FileFilter {
private final String[] okFileExtensions = new String[] { "jpg", "jpeg", "png", "gif", "mp4", "3gp" };
private final String[] okFileExtensions = new String[]{"jpg", "jpeg", "png", "gif", "mp4", "3gp"};
public boolean accept(File file) {
for (String extension : okFileExtensions) {
......@@ -65,16 +65,17 @@ class Utils {
return false;
}
}
static boolean isVideo(String file){
return(file.endsWith(".mp4") || file.endsWith(".3gp"));
static boolean isVideo(String file) {
return (file.endsWith(".mp4") || file.endsWith(".3gp"));
}
static boolean isVideoOrGif(String file){
return(file.endsWith(".mp4") || file.endsWith(".3gp") || file.endsWith(".gif"));
static boolean isVideoOrGif(String file) {
return (file.endsWith(".mp4") || file.endsWith(".3gp") || file.endsWith(".gif"));
}
static boolean isGif(String file){
return(file.endsWith(".gif"));
static boolean isGif(String file) {
return (file.endsWith(".gif"));
}
static String getMimeType(String url) {
......@@ -85,4 +86,24 @@ class Utils {
}
return type;
}
// Returns name of file without its extension
static String getBaseName(File file) {
String name = file.getName();
int pos = name.lastIndexOf(".");
if(pos >0){
name = name.substring(0, pos);
}
return name;
}
// Returns extension of file (including the dot)
static String getExtension(File file) {
String extension = file.getName();
int pos = extension.lastIndexOf(".");
if(pos >0){
extension = extension.substring(pos, extension.length());
}
return extension;
}
}
......@@ -16,6 +16,7 @@ import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.widget.EditText;
import android.widget.TextView;
import com.google.android.exoplayer2.ExoPlayerFactory;
......@@ -41,6 +42,9 @@ import java.util.Formatter;
import java.util.GregorianCalendar;
import java.util.Locale;
import butterknife.BindView;
import butterknife.ButterKnife;
public class VideoActivity extends AppCompatActivity {
private final Handler mHideHandler = new Handler();
......@@ -69,21 +73,20 @@ public class VideoActivity extends AppCompatActivity {
};
private boolean mVisible;
private SimpleExoPlayerView playerView;
private SimpleExoPlayer player;
String videoPath;
int position_intent;
@BindView(R.id.toolbar) Toolbar toolbar;
@BindView(R.id.video_view) SimpleExoPlayerView playerView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video);
Toolbar toolbar = findViewById(R.id.toolbar);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
mVisible = true;
playerView = findViewById(R.id.video_view);
playerView.hideController();
Intent intent = getIntent();
......@@ -96,7 +99,7 @@ public class VideoActivity extends AppCompatActivity {
// Display arrow to return to previous activity
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
// Set current title
getSupportActionBar().setTitle(new File(videoPath).getName());
getSupportActionBar().setTitle(Utils.getBaseName(new File(videoPath)));
}
// Make navBar translucent
......@@ -170,6 +173,10 @@ public class VideoActivity extends AppCompatActivity {
deleteVideo(file);
return true;
case R.id.action_rename:
renameFile(file);
return true;
case R.id.action_details:
showDetails(file);
return true;
......@@ -179,6 +186,60 @@ public class VideoActivity extends AppCompatActivity {
}
}
private void renameFile(final File file){
runOnUiThread(new Runnable() {
public void run() {
// Inflate layout and get views
LayoutInflater inflater = getLayoutInflater();
View layout = inflater.inflate(R.layout.rename_dialog, null);
TextView old_name = layout.findViewById(R.id.old_name);
final EditText new_name = layout.findViewById(R.id.new_name);
String set = "Old name: " + Utils.getBaseName(file);
old_name.setText(set);
// Create and show dialog
AlertDialog.Builder builder = new AlertDialog.Builder(VideoActivity.this);
builder.setView(layout)
.setTitle(R.string.rename_rename)
.setPositiveButton(R.string.action_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Change toolbar text
toolbar.setTitle(new_name.getText().toString());
// Build path with new name
String newName;
String folderPath = file.getParentFile().getPath();
newName = folderPath + "/" + new_name.getText().toString() + Utils.getExtension(file);
// Rename the file and set activity result
if(file.renameTo(new File(newName))){
//Remove image from MediaStore
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
//Add new file to MediaStore
sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(new File(newName))));
// Send intent
Intent intent = new Intent();
intent.putExtra("name", new_name.getText().toString());
// Set result of activity
setResult(2, intent);
}
}
})
.setNegativeButton(R.string.action_cancel, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Close AlertDialog
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
});
}
private void shareVideo(File video){
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("video/*");
......@@ -186,7 +247,7 @@ public class VideoActivity extends AppCompatActivity {
startActivity(Intent.createChooser(shareIntent, "Share image using"));
}
void showDetails(final File image){
private void showDetails(final File image){
runOnUiThread(new Runnable() {
public void run() {
......@@ -241,7 +302,7 @@ public class VideoActivity extends AppCompatActivity {
builder.setView(layout)
.setTitle(R.string.details_video)
.setIcon(R.drawable.ic_information_outline_black_48dp)
.setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
.setPositiveButton(R.string.action_ok, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Close AlertDialog
}
......
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
<android.support.v4.widget.SwipeRefreshLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/swipelayout"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context="com.systemallica.gallery.MainActivity"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:context="com.systemallica.gallery.FolderActivity"
tools:showIn="@layout/activity_folder">
tools:showIn="@layout/activity_main">
<GridView
android:id="@+id/gridViewFolder"
......@@ -35,4 +36,4 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</android.support.constraint.ConstraintLayout>
</android.support.v4.widget.SwipeRefreshLayout>
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:focusable="true"
android:focusableInTouchMode="true">
<TextView
android:id="@+id/old_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginTop="16dp"
android:layout_marginEnd="8dp"
android:text="@string/rename_old_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<EditText
android:id="@+id/new_name"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="24dp"
android:selectAllOnFocus="true"
android:ems="5"
android:text="@string/rename_new_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/old_name" />
</android.support.constraint.ConstraintLayout>
\ No newline at end of file
......@@ -15,8 +15,14 @@
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_details"
android:id="@+id/action_rename"
android:orderInCategory="0"
android:title="@string/action_rename"
app:showAsAction="never" />
<item
android:id="@+id/action_details"
android:orderInCategory="1"
android:title="@string/action_details"
app:showAsAction="never" />
......
......@@ -15,8 +15,14 @@
app:showAsAction="ifRoom"/>
<item
android:id="@+id/action_details"
android:id="@+id/action_rename"
android:orderInCategory="0"
android:title="@string/action_rename"
app:showAsAction="never" />
<item
android:id="@+id/action_details"
android:orderInCategory="1"
android:title="@string/action_details"
app:showAsAction="never" />
......
......@@ -32,4 +32,11 @@
<string name="about_library">Librerías utilizadas:</string>
<string name="about_contact">Contacto:</string>
<string name="about_rate">Tap aquí para calificar la app!</string>
<string name="action_ok">OK</string>
<string name="action_rename">Renombrar</string>
<string name="action_cancel">Cancelar</string>
<string name="desc_overlay">Icono de vídeo</string>
<string name="rename_rename">Renombrar archivo</string>
<string name="rename_old_name">Viejo nombre</string>
<string name="rename_new_name">Nuevo nombre</string>
</resources>
\ No newline at end of file
......@@ -8,11 +8,14 @@
<string name="action_share">Share</string>
<string name="action_details">Details</string>
<string name="action_about">About</string>
<string name="action_rename">Rename</string>
<string name="action_cancel">Cancel</string>
<string name="action_ok">OK</string>
<string name="desc_folder">Folder thumbnail</string>
<string name="desc_image">Image thumbnail</string>
<string name="desc_full_image">Full image</string>
<string name="desc_check">Check</string>
<string name="desc_check" translatable="false">Check</string>
<string name="desc_overlay">Video overlay</string>
<string name="title_activity_folder">Folder</string>
......@@ -27,7 +30,6 @@
<string name="delete_title">Warning!</string>
<string name="delete_message">This will delete the file forever, are you sure?</string>
<string name="ok" translatable="false">OK</string>
<string name="details_image">Image details</string>
<string name="details_video">Video details</string>
<string name="details_name_title">Name</string>
......@@ -36,6 +38,10 @@
<string name="details_type_title">Type</string>
<string name="details_modified_title">Modified</string>
<string name="rename_rename">Rename file</string>
<string name="rename_old_name">Old name</string>
<string name="rename_new_name">New name</string>
<string name="about_name">Gallery version:</string>
<string name="about_developed">Developed by:</string>
<string name="about_developer" translatable="false">Systemallica</string>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment