Allow to select folder for storing media
|
@ -112,5 +112,5 @@ dependencies {
|
||||||
implementation "info.guardianproject.netcipher:netcipher-okhttp3:$netCipherVersion"
|
implementation "info.guardianproject.netcipher:netcipher-okhttp3:$netCipherVersion"
|
||||||
|
|
||||||
implementation 'com.github.adrielcafe:AndroidAudioRecorder:0.3.0'
|
implementation 'com.github.adrielcafe:AndroidAudioRecorder:0.3.0'
|
||||||
|
implementation 'yogesh.firzen:MukkiyaSevaigal:1.0.6'
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,336 @@
|
||||||
|
package app.fedilab.android.filelister;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.SharedPreferences;
|
||||||
|
import android.os.Environment;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.widget.EditText;
|
||||||
|
import android.widget.ImageView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
import androidx.appcompat.widget.AppCompatEditText;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileFilter;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.Collections;
|
||||||
|
import java.util.Comparator;
|
||||||
|
import java.util.LinkedList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Objects;
|
||||||
|
|
||||||
|
import app.fedilab.android.R;
|
||||||
|
import app.fedilab.android.helper.Helper;
|
||||||
|
import yogesh.firzen.mukkiasevaigal.M;
|
||||||
|
import yogesh.firzen.mukkiasevaigal.S;
|
||||||
|
|
||||||
|
import static android.content.Context.MODE_PRIVATE;
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by root on 9/7/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class FileListerAdapter extends RecyclerView.Adapter<FileListerAdapter.FileListHolder> {
|
||||||
|
|
||||||
|
private List<File> data = new LinkedList<>();
|
||||||
|
//private File parent = Environment.getExternalStorageDirectory();
|
||||||
|
private File defaultDir = Environment.getExternalStorageDirectory();
|
||||||
|
private File selectedFile = defaultDir;
|
||||||
|
private FileListerDialog.FILE_FILTER fileFilter = FileListerDialog.FILE_FILTER.ALL_FILES;
|
||||||
|
private Context context;
|
||||||
|
private FilesListerView listerView;
|
||||||
|
private boolean unreadableDir;
|
||||||
|
|
||||||
|
|
||||||
|
FileListerAdapter(File defaultDir, FilesListerView view) {
|
||||||
|
this.defaultDir = defaultDir;
|
||||||
|
selectedFile = defaultDir;
|
||||||
|
this.context = view.getContext();
|
||||||
|
listerView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileListerAdapter(FilesListerView view) {
|
||||||
|
//parent = defaultDir;
|
||||||
|
this.context = view.getContext();
|
||||||
|
listerView = view;
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
fileLister(defaultDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDefaultDir(File dir) {
|
||||||
|
defaultDir = dir;
|
||||||
|
//parent = defaultDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
File getDefaultDir() {
|
||||||
|
return defaultDir;
|
||||||
|
}
|
||||||
|
|
||||||
|
FileListerDialog.FILE_FILTER getFileFilter() {
|
||||||
|
return fileFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFileFilter(FileListerDialog.FILE_FILTER fileFilter) {
|
||||||
|
this.fileFilter = fileFilter;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void fileLister(File dir) {
|
||||||
|
LinkedList<File> fs = new LinkedList<>();
|
||||||
|
if (dir.getAbsolutePath().equals("/")
|
||||||
|
|| dir.getAbsolutePath().equals("/storage")
|
||||||
|
|| dir.getAbsolutePath().equals("/storage/emulated")
|
||||||
|
|| dir.getAbsolutePath().equals("/mnt")) {
|
||||||
|
unreadableDir = true;
|
||||||
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
|
||||||
|
File[] vols = context.getExternalFilesDirs(null);
|
||||||
|
if (vols != null && vols.length > 0) {
|
||||||
|
for (File file : vols) {
|
||||||
|
if (file != null) {
|
||||||
|
String path = file.getAbsolutePath();
|
||||||
|
path = path.replaceAll("/Android/data/([a-zA-Z_][.\\w]*)/files", "");
|
||||||
|
fs.add(new File(path));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fs.add(Environment.getExternalStorageDirectory());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
String s = System.getenv("EXTERNAL_STORAGE");
|
||||||
|
if (!TextUtils.isEmpty(s))
|
||||||
|
fs.add(new File(s));
|
||||||
|
else {
|
||||||
|
String[] paths = getPhysicalPaths();
|
||||||
|
for (String path : paths) {
|
||||||
|
File f = new File(path);
|
||||||
|
if (f.exists())
|
||||||
|
fs.add(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
s = System.getenv("SECONDARY_STORAGE");
|
||||||
|
if (!TextUtils.isEmpty(s)) {
|
||||||
|
assert s != null;
|
||||||
|
final String[] rawSecondaryStorages = s.split(File.pathSeparator);
|
||||||
|
for (String path : rawSecondaryStorages) {
|
||||||
|
File f = new File(path);
|
||||||
|
if (f.exists())
|
||||||
|
fs.add(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unreadableDir = false;
|
||||||
|
File[] files = dir.listFiles(new FileFilter() {
|
||||||
|
@Override
|
||||||
|
public boolean accept(File file) {
|
||||||
|
switch (getFileFilter()) {
|
||||||
|
case ALL_FILES:
|
||||||
|
return true;
|
||||||
|
case AUDIO_ONLY:
|
||||||
|
return S.isAudio(file) || file.isDirectory();
|
||||||
|
case IMAGE_ONLY:
|
||||||
|
return S.isImage(file) || file.isDirectory();
|
||||||
|
case VIDEO_ONLY:
|
||||||
|
return S.isVideo(file) || file.isDirectory();
|
||||||
|
case DIRECTORY_ONLY:
|
||||||
|
return file.isDirectory();
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (files != null) {
|
||||||
|
fs = new LinkedList<>(Arrays.asList(files));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
M.L("From FileListAdapter", fs);
|
||||||
|
data = new LinkedList<>(fs);
|
||||||
|
Collections.sort(data, new Comparator<File>() {
|
||||||
|
@Override
|
||||||
|
public int compare(File f1, File f2) {
|
||||||
|
if ((f1.isDirectory() && f2.isDirectory()))
|
||||||
|
return f1.getName().compareToIgnoreCase(f2.getName());
|
||||||
|
else if (f1.isDirectory() && !f2.isDirectory())
|
||||||
|
return -1;
|
||||||
|
else if (!f1.isDirectory() && f2.isDirectory())
|
||||||
|
return 1;
|
||||||
|
else if (!f1.isDirectory() && !f2.isDirectory())
|
||||||
|
return f1.getName().compareToIgnoreCase(f2.getName());
|
||||||
|
else return 0;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
selectedFile = dir;
|
||||||
|
if (!dir.getAbsolutePath().equals("/")) {
|
||||||
|
dirUp();
|
||||||
|
}
|
||||||
|
notifyDataSetChanged();
|
||||||
|
listerView.scrollToPosition(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void dirUp() {
|
||||||
|
if (!unreadableDir) {
|
||||||
|
data.add(0, selectedFile.getParentFile());
|
||||||
|
data.add(1, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
@Override
|
||||||
|
public FileListHolder onCreateViewHolder(@NotNull ViewGroup parent, int viewType) {
|
||||||
|
SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, MODE_PRIVATE);
|
||||||
|
int theme = sharedpreferences.getInt(Helper.SET_THEME, Helper.THEME_DARK);
|
||||||
|
switch (theme){
|
||||||
|
case Helper.THEME_LIGHT:
|
||||||
|
return new FileListHolder(View.inflate(getContext(), R.layout.item_file_lister_light, null));
|
||||||
|
case Helper.THEME_DARK:
|
||||||
|
case Helper.THEME_BLACK:
|
||||||
|
return new FileListHolder(View.inflate(getContext(), R.layout.item_file_lister, null));
|
||||||
|
default:
|
||||||
|
return new FileListHolder(View.inflate(getContext(), R.layout.item_file_lister, null));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onBindViewHolder(@NotNull FileListHolder holder, int position) {
|
||||||
|
File f = data.get(position);
|
||||||
|
if (f != null) {
|
||||||
|
holder.name.setText(f.getName());
|
||||||
|
} else if (!unreadableDir) {
|
||||||
|
holder.name.setText(context.getString(R.string.new_folder));
|
||||||
|
holder.icon.setImageResource(R.drawable.ic_create_new_folder_black_48dp);
|
||||||
|
}
|
||||||
|
if (unreadableDir) {
|
||||||
|
if (f != null) {
|
||||||
|
if (position == 0) {
|
||||||
|
holder.name.setText(f.getName() + " (Internal)");
|
||||||
|
} else {
|
||||||
|
holder.name.setText(f.getName() + " (External)");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (position == 0 && f != null && !unreadableDir) {
|
||||||
|
holder.icon.setImageResource(R.drawable.ic_subdirectory_up_black_48dp);
|
||||||
|
} else if (f != null) {
|
||||||
|
if (f.isDirectory())
|
||||||
|
holder.icon.setImageResource(R.drawable.ic_folder_black_48dp);
|
||||||
|
else if (S.isImage(f))
|
||||||
|
holder.icon.setImageResource(R.drawable.ic_photo_black_48dp);
|
||||||
|
else if (S.isVideo(f))
|
||||||
|
holder.icon.setImageResource(R.drawable.ic_videocam_black_48dp);
|
||||||
|
else if (S.isAudio(f))
|
||||||
|
holder.icon.setImageResource(R.drawable.ic_audiotrack_black_48dp);
|
||||||
|
else
|
||||||
|
holder.icon.setImageResource(R.drawable.ic_insert_drive_file_black_48dp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getItemCount() {
|
||||||
|
return data.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
File getSelected() {
|
||||||
|
return selectedFile;
|
||||||
|
}
|
||||||
|
|
||||||
|
void goToDefault() {
|
||||||
|
fileLister(defaultDir);
|
||||||
|
}
|
||||||
|
|
||||||
|
class FileListHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
|
||||||
|
|
||||||
|
TextView name;
|
||||||
|
ImageView icon;
|
||||||
|
|
||||||
|
FileListHolder(View itemView) {
|
||||||
|
super(itemView);
|
||||||
|
name = itemView.findViewById(R.id.name);
|
||||||
|
icon = itemView.findViewById(R.id.icon);
|
||||||
|
itemView.findViewById(R.id.layout).setOnClickListener(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
if (data.get(getPosition()) == null) {
|
||||||
|
View view = View.inflate(getContext(), R.layout.dialog_create_folder, null);
|
||||||
|
final EditText editText = view.findViewById(R.id.edittext);
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(getContext())
|
||||||
|
.setView(view)
|
||||||
|
.setTitle(context.getString(R.string.folder_name))
|
||||||
|
.setPositiveButton("Create", new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which) {
|
||||||
|
|
||||||
|
}
|
||||||
|
});
|
||||||
|
final AlertDialog dialog = builder.create();
|
||||||
|
dialog.show();
|
||||||
|
dialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View v) {
|
||||||
|
String name = Objects.requireNonNull(editText.getText()).toString();
|
||||||
|
if (TextUtils.isEmpty(name)) {
|
||||||
|
M.T(getContext(), context.getString(R.string.valid_folder_name));
|
||||||
|
} else {
|
||||||
|
File file = new File(selectedFile, name);
|
||||||
|
if (file.exists()) {
|
||||||
|
M.T(getContext(), context.getString(R.string.folder_exists));
|
||||||
|
} else {
|
||||||
|
dialog.dismiss();
|
||||||
|
file.mkdirs();
|
||||||
|
fileLister(file);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
File f = data.get(getPosition());
|
||||||
|
selectedFile = f;
|
||||||
|
M.L("From FileLister", f.getAbsolutePath());
|
||||||
|
if (f.isDirectory()) {
|
||||||
|
fileLister(f);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String[] getPhysicalPaths() {
|
||||||
|
return new String[]{
|
||||||
|
"/storage/sdcard0",
|
||||||
|
"/storage/sdcard1", //Motorola Xoom
|
||||||
|
"/storage/extsdcard", //Samsung SGS3
|
||||||
|
"/storage/sdcard0/external_sdcard", //User request
|
||||||
|
"/mnt/extsdcard",
|
||||||
|
"/mnt/sdcard/external_sd", //Samsung galaxy family
|
||||||
|
"/mnt/external_sd",
|
||||||
|
"/mnt/media_rw/sdcard1", //4.4.2 on CyanogenMod S3
|
||||||
|
"/removable/microsd", //Asus transformer prime
|
||||||
|
"/mnt/emmc",
|
||||||
|
"/storage/external_SD", //LG
|
||||||
|
"/storage/ext_sd", //HTC One Max
|
||||||
|
"/storage/removable/sdcard1", //Sony Xperia Z1
|
||||||
|
"/data/sdext",
|
||||||
|
"/data/sdext2",
|
||||||
|
"/data/sdext3",
|
||||||
|
"/data/sdext4",
|
||||||
|
"/sdcard1", //Sony Xperia Z
|
||||||
|
"/sdcard2", //HTC One M8s
|
||||||
|
"/storage/microsd" //ASUS ZenFone 2
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Context getContext() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,185 @@
|
||||||
|
package app.fedilab.android.filelister;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.view.View;
|
||||||
|
|
||||||
|
import androidx.annotation.NonNull;
|
||||||
|
import androidx.appcompat.app.AlertDialog;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
|
||||||
|
import app.fedilab.android.R;
|
||||||
|
|
||||||
|
import static android.content.DialogInterface.BUTTON_NEGATIVE;
|
||||||
|
import static android.content.DialogInterface.BUTTON_NEUTRAL;
|
||||||
|
import static android.content.DialogInterface.BUTTON_POSITIVE;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A File Lister Dialog
|
||||||
|
*/
|
||||||
|
|
||||||
|
public class FileListerDialog {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File Filter for the FileListerDialog
|
||||||
|
*/
|
||||||
|
public enum FILE_FILTER {
|
||||||
|
/**
|
||||||
|
* List All Files
|
||||||
|
*/
|
||||||
|
ALL_FILES,
|
||||||
|
/**
|
||||||
|
* List only directories
|
||||||
|
*/
|
||||||
|
DIRECTORY_ONLY,
|
||||||
|
/**
|
||||||
|
* List Directory and Image files
|
||||||
|
*/
|
||||||
|
IMAGE_ONLY,
|
||||||
|
/**
|
||||||
|
* List Directory and Video files
|
||||||
|
*/
|
||||||
|
VIDEO_ONLY,
|
||||||
|
/**
|
||||||
|
* List Directory and Audio files
|
||||||
|
*/
|
||||||
|
AUDIO_ONLY
|
||||||
|
}
|
||||||
|
|
||||||
|
private AlertDialog alertDialog;
|
||||||
|
|
||||||
|
private FilesListerView filesListerView;
|
||||||
|
|
||||||
|
private OnFileSelectedListener onFileSelectedListener;
|
||||||
|
|
||||||
|
private FileListerDialog(@NonNull Context context) {
|
||||||
|
//super(context);
|
||||||
|
alertDialog = new AlertDialog.Builder(context).create();
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
private FileListerDialog(@NonNull Context context, int themeResId) {
|
||||||
|
//super(context, themeResId);
|
||||||
|
alertDialog = new AlertDialog.Builder(context, themeResId).create();
|
||||||
|
init(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a default instance of FileListerDialog
|
||||||
|
*
|
||||||
|
* @param context Context of the App
|
||||||
|
* @return Instance of FileListerDialog
|
||||||
|
*/
|
||||||
|
public static FileListerDialog createFileListerDialog(@NonNull Context context) {
|
||||||
|
return new FileListerDialog(context);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates an instance of FileListerDialog with the specified Theme
|
||||||
|
*
|
||||||
|
* @param context Context of the App
|
||||||
|
* @param themeId Theme Id for the dialog
|
||||||
|
* @return Instance of FileListerDialog
|
||||||
|
*/
|
||||||
|
public static FileListerDialog createFileListerDialog(@NonNull Context context, int themeId) {
|
||||||
|
return new FileListerDialog(context, themeId);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init(Context context) {
|
||||||
|
filesListerView = new FilesListerView(context);
|
||||||
|
alertDialog.setView(filesListerView);
|
||||||
|
alertDialog.setButton(BUTTON_POSITIVE, context.getString(R.string.select), new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
dialogInterface.dismiss();
|
||||||
|
if (onFileSelectedListener != null)
|
||||||
|
onFileSelectedListener.onFileSelected(filesListerView.getSelected(), filesListerView.getSelected().getAbsolutePath());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alertDialog.setButton(BUTTON_NEUTRAL, context.getString(R.string.default_directory), new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
//filesListerView.goToDefaultDir();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alertDialog.setButton(BUTTON_NEGATIVE, context.getString(R.string.cancel), new DialogInterface.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialogInterface, int i) {
|
||||||
|
dialogInterface.dismiss();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Display the FileListerDialog
|
||||||
|
*/
|
||||||
|
public void show() {
|
||||||
|
//getWindow().setLayout(WindowManager.LayoutParams.MATCH_PARENT, WindowManager.LayoutParams.MATCH_PARENT);
|
||||||
|
switch (filesListerView.getFileFilter()) {
|
||||||
|
case DIRECTORY_ONLY:
|
||||||
|
alertDialog.setTitle("Select a directory");
|
||||||
|
break;
|
||||||
|
case VIDEO_ONLY:
|
||||||
|
alertDialog.setTitle("Select a Video file");
|
||||||
|
break;
|
||||||
|
case IMAGE_ONLY:
|
||||||
|
alertDialog.setTitle("Select an Image file");
|
||||||
|
break;
|
||||||
|
case AUDIO_ONLY:
|
||||||
|
alertDialog.setTitle("Select an Audio file");
|
||||||
|
break;
|
||||||
|
case ALL_FILES:
|
||||||
|
alertDialog.setTitle("Select a file");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
alertDialog.setTitle("Select a file");
|
||||||
|
}
|
||||||
|
filesListerView.start();
|
||||||
|
alertDialog.show();
|
||||||
|
alertDialog.getButton(BUTTON_NEUTRAL).setOnClickListener(new View.OnClickListener() {
|
||||||
|
@Override
|
||||||
|
public void onClick(View view) {
|
||||||
|
filesListerView.goToDefaultDir();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Listener to know which file/directory is selected
|
||||||
|
*
|
||||||
|
* @param onFileSelectedListener Instance of the Listener
|
||||||
|
*/
|
||||||
|
public void setOnFileSelectedListener(OnFileSelectedListener onFileSelectedListener) {
|
||||||
|
this.onFileSelectedListener = onFileSelectedListener;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the initial directory to show the list of files in that directory
|
||||||
|
*
|
||||||
|
* @param file File pointing to the directory
|
||||||
|
*/
|
||||||
|
public void setDefaultDir(@NonNull File file) {
|
||||||
|
filesListerView.setDefaultDir(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the initial directory to show the list of files in that directory
|
||||||
|
*
|
||||||
|
* @param file String denoting to the directory
|
||||||
|
*/
|
||||||
|
public void setDefaultDir(@NonNull String file) {
|
||||||
|
filesListerView.setDefaultDir(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set the file filter for listing the files
|
||||||
|
*
|
||||||
|
* @param fileFilter One of the FILE_FILTER values
|
||||||
|
*/
|
||||||
|
public void setFileFilter(FILE_FILTER fileFilter) {
|
||||||
|
filesListerView.setFileFilter(fileFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,72 @@
|
||||||
|
package app.fedilab.android.filelister;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.util.AttributeSet;
|
||||||
|
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.recyclerview.widget.LinearLayoutManager;
|
||||||
|
import androidx.recyclerview.widget.RecyclerView;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by S.Yogesh on 14-02-2016.
|
||||||
|
*/
|
||||||
|
class FilesListerView extends RecyclerView {
|
||||||
|
|
||||||
|
private FileListerAdapter adapter;
|
||||||
|
|
||||||
|
FilesListerView(Context context) {
|
||||||
|
super(context);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilesListerView(Context context, @Nullable AttributeSet attrs) {
|
||||||
|
super(context, attrs);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
FilesListerView(Context context, @Nullable AttributeSet attrs, int defStyle) {
|
||||||
|
super(context, attrs, defStyle);
|
||||||
|
init();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("WrongConstant")
|
||||||
|
private void init() {
|
||||||
|
setLayoutManager(new LinearLayoutManager(getContext(), LinearLayoutManager.VERTICAL, false));
|
||||||
|
adapter = new FileListerAdapter(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void start() {
|
||||||
|
setAdapter(adapter);
|
||||||
|
adapter.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDefaultDir(File file) {
|
||||||
|
adapter.setDefaultDir(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
void setDefaultDir(String path) {
|
||||||
|
setDefaultDir(new File(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
File getSelected() {
|
||||||
|
return adapter.getSelected();
|
||||||
|
}
|
||||||
|
|
||||||
|
void goToDefaultDir() {
|
||||||
|
adapter.goToDefault();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setFileFilter(FileListerDialog.FILE_FILTER fileFilter) {
|
||||||
|
adapter.setFileFilter(fileFilter);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileListerDialog.FILE_FILTER getFileFilter() {
|
||||||
|
return adapter.getFileFilter();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,11 @@
|
||||||
|
package app.fedilab.android.filelister;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by root on 9/7/17.
|
||||||
|
*/
|
||||||
|
|
||||||
|
public interface OnFileSelectedListener {
|
||||||
|
void onFileSelected(File file, String path);
|
||||||
|
}
|
|
@ -68,6 +68,7 @@ import com.google.common.collect.ImmutableSet;
|
||||||
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
import java.io.File;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -80,12 +81,15 @@ import app.fedilab.android.animatemenu.interfaces.ScreenShotable;
|
||||||
import app.fedilab.android.asynctasks.DownloadTrackingDomainsAsyncTask;
|
import app.fedilab.android.asynctasks.DownloadTrackingDomainsAsyncTask;
|
||||||
import app.fedilab.android.asynctasks.UpdateAccountInfoAsyncTask;
|
import app.fedilab.android.asynctasks.UpdateAccountInfoAsyncTask;
|
||||||
import app.fedilab.android.client.Entities.Account;
|
import app.fedilab.android.client.Entities.Account;
|
||||||
|
import app.fedilab.android.filelister.FileListerDialog;
|
||||||
|
import app.fedilab.android.filelister.OnFileSelectedListener;
|
||||||
import app.fedilab.android.helper.Helper;
|
import app.fedilab.android.helper.Helper;
|
||||||
import app.fedilab.android.sqlite.AccountDAO;
|
import app.fedilab.android.sqlite.AccountDAO;
|
||||||
import app.fedilab.android.sqlite.Sqlite;
|
import app.fedilab.android.sqlite.Sqlite;
|
||||||
import es.dmoral.toasty.Toasty;
|
import es.dmoral.toasty.Toasty;
|
||||||
import mabbas007.tagsedittext.TagsEditText;
|
import mabbas007.tagsedittext.TagsEditText;
|
||||||
|
|
||||||
|
|
||||||
import static android.app.Activity.RESULT_OK;
|
import static android.app.Activity.RESULT_OK;
|
||||||
import static android.content.Context.MODE_PRIVATE;
|
import static android.content.Context.MODE_PRIVATE;
|
||||||
import static app.fedilab.android.fragments.ContentSettingsFragment.type.ADMIN;
|
import static app.fedilab.android.fragments.ContentSettingsFragment.type.ADMIN;
|
||||||
|
@ -1040,7 +1044,7 @@ public class ContentSettingsFragment extends Fragment implements ScreenShotable
|
||||||
|
|
||||||
set_folder = rootView.findViewById(R.id.set_folder);
|
set_folder = rootView.findViewById(R.id.set_folder);
|
||||||
set_folder.setText(targeted_folder);
|
set_folder.setText(targeted_folder);
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
/*if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
set_folder.setOnClickListener(new View.OnClickListener() {
|
set_folder.setOnClickListener(new View.OnClickListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onClick(View v) {
|
public void onClick(View v) {
|
||||||
|
@ -1052,7 +1056,25 @@ public class ContentSettingsFragment extends Fragment implements ScreenShotable
|
||||||
}else {
|
}else {
|
||||||
LinearLayout file_chooser = rootView.findViewById(R.id.file_chooser);
|
LinearLayout file_chooser = rootView.findViewById(R.id.file_chooser);
|
||||||
file_chooser.setVisibility(View.GONE);
|
file_chooser.setVisibility(View.GONE);
|
||||||
}
|
}*/
|
||||||
|
set_folder.setOnClickListener(view ->{
|
||||||
|
FileListerDialog fileListerDialog = FileListerDialog.createFileListerDialog(context, style);
|
||||||
|
fileListerDialog.setDefaultDir(targeted_folder);
|
||||||
|
fileListerDialog.setFileFilter(FileListerDialog.FILE_FILTER.DIRECTORY_ONLY);
|
||||||
|
fileListerDialog.setOnFileSelectedListener(new OnFileSelectedListener() {
|
||||||
|
@Override
|
||||||
|
public void onFileSelected(File file, String path) {
|
||||||
|
if( path == null )
|
||||||
|
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
|
||||||
|
final SharedPreferences sharedpreferences = context.getSharedPreferences(Helper.APP_PREFS, Context.MODE_PRIVATE);
|
||||||
|
SharedPreferences.Editor editor = sharedpreferences.edit();
|
||||||
|
editor.putString(Helper.SET_FOLDER_RECORD, path);
|
||||||
|
editor.apply();
|
||||||
|
set_folder.setText(path);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
fileListerDialog.show();
|
||||||
|
});
|
||||||
|
|
||||||
final Spinner set_night_mode = rootView.findViewById(R.id.set_night_mode);
|
final Spinner set_night_mode = rootView.findViewById(R.id.set_night_mode);
|
||||||
ArrayAdapter<CharSequence> adapterTheme = ArrayAdapter.createFromResource(getContext(),
|
ArrayAdapter<CharSequence> adapterTheme = ArrayAdapter.createFromResource(getContext(),
|
||||||
|
|
After Width: | Height: | Size: 309 B |
After Width: | Height: | Size: 254 B |
After Width: | Height: | Size: 239 B |
After Width: | Height: | Size: 273 B |
After Width: | Height: | Size: 424 B |
After Width: | Height: | Size: 236 B |
After Width: | Height: | Size: 224 B |
After Width: | Height: | Size: 226 B |
After Width: | Height: | Size: 191 B |
After Width: | Height: | Size: 180 B |
After Width: | Height: | Size: 197 B |
After Width: | Height: | Size: 295 B |
After Width: | Height: | Size: 173 B |
After Width: | Height: | Size: 171 B |
After Width: | Height: | Size: 399 B |
After Width: | Height: | Size: 321 B |
After Width: | Height: | Size: 307 B |
After Width: | Height: | Size: 345 B |
After Width: | Height: | Size: 548 B |
After Width: | Height: | Size: 269 B |
After Width: | Height: | Size: 270 B |
After Width: | Height: | Size: 586 B |
After Width: | Height: | Size: 473 B |
After Width: | Height: | Size: 467 B |
After Width: | Height: | Size: 506 B |
After Width: | Height: | Size: 807 B |
After Width: | Height: | Size: 349 B |
After Width: | Height: | Size: 376 B |
After Width: | Height: | Size: 806 B |
After Width: | Height: | Size: 678 B |
After Width: | Height: | Size: 661 B |
After Width: | Height: | Size: 719 B |
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 463 B |
After Width: | Height: | Size: 558 B |
|
@ -0,0 +1,8 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<rotate xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:drawable="@drawable/ic_subdirectory_arrow_left_black_48dp"
|
||||||
|
android:fromDegrees="90"
|
||||||
|
android:pivotX="50%"
|
||||||
|
android:pivotY="50%">
|
||||||
|
|
||||||
|
</rotate>
|
|
@ -0,0 +1,22 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical"
|
||||||
|
android:padding="10dp">
|
||||||
|
|
||||||
|
<com.google.android.material.textfield.TextInputLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content">
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/edittext"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/create_folder"
|
||||||
|
android:imeOptions="actionDone"
|
||||||
|
android:inputType="text"
|
||||||
|
android:maxLines="1" />
|
||||||
|
</com.google.android.material.textfield.TextInputLayout>
|
||||||
|
|
||||||
|
</LinearLayout>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:orientation="vertical">
|
||||||
|
|
||||||
|
<yogesh.firzen.filelister.FilesListerView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
/>
|
||||||
|
|
||||||
|
</android.support.constraint.ConstraintLayout>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:theme="@style/FileListerItemColor">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="5dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_folder_black_48dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_weight="0.9"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:text="@string/folder"
|
||||||
|
android:textSize="15sp"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
android:id="@+id/layout"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:theme="@style/FileListerItemColorLight">
|
||||||
|
|
||||||
|
<LinearLayout
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:orientation="horizontal"
|
||||||
|
android:padding="5dp">
|
||||||
|
|
||||||
|
<ImageView
|
||||||
|
android:id="@+id/icon"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:src="@drawable/ic_folder_black_48dp" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/name"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="match_parent"
|
||||||
|
android:layout_marginStart="20dp"
|
||||||
|
android:layout_weight="0.9"
|
||||||
|
android:gravity="center_vertical"
|
||||||
|
android:text="@string/folder"
|
||||||
|
android:textSize="15sp"
|
||||||
|
/>
|
||||||
|
</LinearLayout>
|
||||||
|
</RelativeLayout>
|
|
@ -1099,6 +1099,14 @@
|
||||||
<string name="u_interface">Interface</string>
|
<string name="u_interface">Interface</string>
|
||||||
<string name="battery">Battery</string>
|
<string name="battery">Battery</string>
|
||||||
<string name="compose">Compose</string>
|
<string name="compose">Compose</string>
|
||||||
|
<string name="new_folder">Create a new Folder here</string>
|
||||||
|
<string name="folder_name">Enter the folder name</string>
|
||||||
|
<string name="valid_folder_name">Please enter a valid folder name</string>
|
||||||
|
<string name="folder_exists">This folder already exists.\n Please provide another name for the folder</string>
|
||||||
|
<string name="select">Select</string>
|
||||||
|
<string name="default_directory">Default Directory</string>
|
||||||
|
<string name="folder">Folder</string>
|
||||||
|
<string name="create_folder">Create folder</string>
|
||||||
|
|
||||||
<plurals name="number_of_vote">
|
<plurals name="number_of_vote">
|
||||||
<item quantity="one">%d vote</item>
|
<item quantity="one">%d vote</item>
|
||||||
|
|
|
@ -347,6 +347,16 @@
|
||||||
<item name="android:background">@drawable/button_selector</item>
|
<item name="android:background">@drawable/button_selector</item>
|
||||||
</style>
|
</style>
|
||||||
|
|
||||||
|
<style name="FileListerItemColor">
|
||||||
|
<item name="android:textColor">@color/dark_text</item>
|
||||||
|
<item name="android:tint">@color/mastodonC2</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style name="FileListerItemColorLight">
|
||||||
|
<item name="android:textColor">@color/black</item>
|
||||||
|
<item name="android:tint">@color/mastodonC2</item>
|
||||||
|
</style>
|
||||||
|
|
||||||
<style name="DialogDark" parent="Theme.AppCompat.Dialog.Alert">
|
<style name="DialogDark" parent="Theme.AppCompat.Dialog.Alert">
|
||||||
<item name="android:windowBackground">@color/mastodonC1</item>
|
<item name="android:windowBackground">@color/mastodonC1</item>
|
||||||
<item name="colorAccent">@color/mastodonC4</item>
|
<item name="colorAccent">@color/mastodonC4</item>
|
||||||
|
|