Added the file picker

This commit is contained in:
Lyndon
2017-10-27 00:11:25 +02:00
parent 6deb9fd517
commit 7cd48da622
72 changed files with 4352 additions and 30 deletions

View File

@@ -1,5 +1,5 @@
def getGitSha() {
return 'git rev-parse --short HEAD'.execute([], project.rootDir).text.trim();
return 'git rev-parse --short HEAD'.execute([], project.rootDir).text.trim()
}
buildscript {
@@ -7,8 +7,8 @@ buildscript {
mavenCentral()
maven { url 'https://maven.fabric.io/public' }
}
dependencies {
classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8'
classpath 'io.fabric.tools:gradle:1.+'
}
}
@@ -22,21 +22,21 @@ repositories {
maven { url "https://jitpack.io" }
}
apply plugin: 'com.neenbedankt.android-apt'
apply plugin: 'me.tatarka.retrolambda'
apply plugin: 'realm-android'
android {
compileSdkVersion 25
buildToolsVersion "25.0.3"
compileSdkVersion 26
buildToolsVersion '26.0.2'
defaultConfig {
applicationId "de.beyondsoft.ownchat"
minSdkVersion 19
targetSdkVersion 25
targetSdkVersion 26
versionCode 2
versionName "1.1"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
signingConfigs {
release {
storeFile file('../ownChat.jks')
@@ -45,20 +45,24 @@ android {
keyPassword '6fhnfqm07tvbagm3t6k4'
}
}
buildTypes {
debug {
ext.enableCrashlytics = false
}
release {
signingConfig signingConfigs.release
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
buildConfigField "String", "GIT_VERSION_SHA", "\"" + getGitSha() + "\""
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
lintOptions {
abortOnError false
disable 'InvalidPackage'
@@ -86,8 +90,8 @@ dependencies {
// emojis
// circle progress
// event bus
compile 'com.android.support:appcompat-v7:25.3.1'
compile 'com.android.support:design:25.3.1'
compile 'com.android.support:appcompat-v7:26.1.0'
compile 'com.android.support:design:26.1.0'
compile 'com.jakewharton:butterknife:8.4.0'
compile 'com.google.dagger:dagger:2.7'
compile 'io.reactivex:rxjava:1.1.6'
@@ -96,23 +100,22 @@ dependencies {
compile 'com.squareup.retrofit2:retrofit:2.1.0'
compile 'com.squareup.retrofit2:converter-gson:2.1.0'
compile 'com.squareup.retrofit2:adapter-rxjava:2.1.0'
compile 'com.squareup.okhttp3:okhttp:3.4.1'
compile 'com.squareup.okhttp3:okhttp:3.7.0'
compile 'com.squareup.okhttp3:logging-interceptor:3.4.1'
compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'de.hdodenhof:circleimageview:2.1.0'
compile 'com.scottyab:secure-preferences-lib:0.1.4'
compile 'com.google.firebase:firebase-messaging:10.2.0'
compile 'com.google.firebase:firebase-messaging:11.4.2'
compile 'hani.momanii.supernova_emoji_library:supernova-emoji-library:0.0.2'
compile 'com.github.lzyzsd:circleprogress:1.2.1'
compile 'org.greenrobot:eventbus:3.0.0'
testCompile 'junit:junit:4.12'
apt 'com.jakewharton:butterknife-compiler:8.4.0'
apt 'com.google.dagger:dagger-compiler:2.7'
annotationProcessor 'com.jakewharton:butterknife-compiler:8.4.0'
annotationProcessor 'com.google.dagger:dagger-compiler:2.7'
provided 'javax.annotation:jsr250-api:1.0'
}
task adp2upload(type: Exec, dependsOn: "build") {
ext {
channel = "bewoplaner-chat"
slug = "bewoplaner-chat"
@@ -121,6 +124,8 @@ task adp2upload(type: Exec, dependsOn: "build") {
file = "build/outputs/apk/app-release.apk"
notes = "Nightly build for BeWoPlaner Chat"
}
commandLine 'upload_build.sh', "-c", "$channel", "-v", "$versionCode", "-p", "android", "-a", "$slug", "-f", "$file", "-i", "$identifier", "-n", "$notes"
}
apply plugin: 'com.google.gms.google-services'

View File

@@ -85,6 +85,18 @@
android:resource="@xml/provider_paths" />
</provider>
<provider
android:authorities="${applicationId}.provider"
android:name=".filepicker.utils.FilePickerProvider"
android:exported="false"
android:grantUriPermissions="true"
>
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths"
/>
</provider>
<receiver
android:name="de.beyondsoft.ownchat.data.firebase.ReplyNotificationReceiver"
android:enabled="true"

View File

@@ -4,9 +4,6 @@
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!--<title>Terms</title>
-->
<style type="text/css">
body {margin:20px; font-family: "Roboto", Arial, "sans-serif"; font-size:17px; line-height:1.4em}

View File

@@ -0,0 +1,33 @@
package de.beyondsoft.ownchat.filepicker;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.support.annotation.LayoutRes;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import de.beyondsoft.ownchat.filepicker.utils.Orientation;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public abstract class BaseFilePickerActivity extends AppCompatActivity {
protected void onCreate(@Nullable Bundle savedInstanceState, @LayoutRes int layout) {
super.onCreate(savedInstanceState);
setContentView(layout);
Orientation orientation = PickerManager.getInstance().getOrientation();
if(orientation==Orientation.PORTRAIT_ONLY) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
} else if(orientation== Orientation.LANDSCAPE_ONLY) {
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
initView();
}
protected abstract void initView();
}

View File

@@ -0,0 +1,12 @@
package de.beyondsoft.ownchat.filepicker;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class FilePickerActivity extends BaseFilePickerActivity implements
ImagePickerFragmentListener,
DocFragment.DocFragmentListener,
DocPickerFragment.DocPickerFragmentListener,
MediaPickerFragment.MediaPickerFragmentListener {
}

View File

@@ -0,0 +1,157 @@
package de.beyondsoft.ownchat.filepicker;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.v4.app.Fragment;
import java.util.ArrayList;
import de.beyondsoft.ownchat.filepicker.models.FileType;
import de.beyondsoft.ownchat.filepicker.utils.Orientation;
/**
* Created by Lyndon on 27-Oct-2017.
*/
public class FilePickerBuilder {
private final Bundle mPickerOptionsBundle;
public FilePickerBuilder()
{
mPickerOptionsBundle = new Bundle();
}
public static FilePickerBuilder getInstance()
{
return new FilePickerBuilder();
}
public FilePickerBuilder setMaxCount(int maxCount)
{
PickerManager.getInstance().setMaxCount(maxCount);
return this;
}
public FilePickerBuilder setActivityTheme(int theme)
{
PickerManager.getInstance().setTheme(theme);
return this;
}
public FilePickerBuilder setSelectedFiles(ArrayList<String> selectedPhotos)
{
mPickerOptionsBundle.putStringArrayList(FilePickerConst.KEY_SELECTED_MEDIA, selectedPhotos);
return this;
}
public FilePickerBuilder enableVideoPicker(boolean status)
{
PickerManager.getInstance().setShowVideos(status);
return this;
}
public FilePickerBuilder enableImagePicker(boolean status)
{
PickerManager.getInstance().setShowImages(status);
return this;
}
public FilePickerBuilder setCameraPlaceholder(@DrawableRes int drawable)
{
PickerManager.getInstance().setCameraDrawable(drawable);
return this;
}
public FilePickerBuilder showGifs(boolean status)
{
PickerManager.getInstance().setShowGif(status);
return this;
}
public FilePickerBuilder showFolderView(boolean status)
{
PickerManager.getInstance().setShowFolderView(status);
return this;
}
public FilePickerBuilder enableDocSupport(boolean status)
{
PickerManager.getInstance().setDocSupport(status);
return this;
}
public FilePickerBuilder enableCameraSupport(boolean status)
{
PickerManager.getInstance().setEnableCamera(status);
return this;
}
public FilePickerBuilder withOrientation(Orientation orientation)
{
PickerManager.getInstance().setOrientation(orientation);
return this;
}
public FilePickerBuilder addFileSupport(String title, String[] extensions, @DrawableRes int drawable)
{
PickerManager.getInstance().addFileType(new FileType(title,extensions,drawable));
return this;
}
public FilePickerBuilder addFileSupport(String title, String[] extensions)
{
PickerManager.getInstance().addFileType(new FileType(title,extensions,0));
return this;
}
public void pickPhoto(Activity context)
{
mPickerOptionsBundle.putInt(FilePickerConst.EXTRA_PICKER_TYPE,FilePickerConst.MEDIA_PICKER);
start(context,FilePickerConst.MEDIA_PICKER);
}
public void pickPhoto(Fragment context)
{
mPickerOptionsBundle.putInt(FilePickerConst.EXTRA_PICKER_TYPE,FilePickerConst.MEDIA_PICKER);
start(context,FilePickerConst.MEDIA_PICKER);
}
public void pickFile(Activity context)
{
mPickerOptionsBundle.putInt(FilePickerConst.EXTRA_PICKER_TYPE,FilePickerConst.DOC_PICKER);
start(context,FilePickerConst.DOC_PICKER);
}
public void pickFile(Fragment context)
{
mPickerOptionsBundle.putInt(FilePickerConst.EXTRA_PICKER_TYPE,FilePickerConst.DOC_PICKER);
start(context,FilePickerConst.DOC_PICKER);
}
private void start(Activity context, int pickerType)
{
PickerManager.getInstance().setProviderAuthorities(context.getApplicationContext().getPackageName() + ".droidninja.filepicker.provider");
Intent intent = new Intent(context, FilePickerActivity.class);
intent.putExtras(mPickerOptionsBundle);
if(pickerType==FilePickerConst.MEDIA_PICKER)
context.startActivityForResult(intent,FilePickerConst.REQUEST_CODE_PHOTO);
else
context.startActivityForResult(intent,FilePickerConst.REQUEST_CODE_DOC);
}
private void start(Fragment fragment, int pickerType)
{
PickerManager.getInstance().setProviderAuthorities(fragment.getContext().getApplicationContext().getPackageName() + ".droidninja.filepicker.provider");
Intent intent = new Intent(fragment.getActivity(), FilePickerActivity.class);
intent.putExtras(mPickerOptionsBundle);
if(pickerType==FilePickerConst.MEDIA_PICKER)
fragment.startActivityForResult(intent,FilePickerConst.REQUEST_CODE_PHOTO);
else
fragment.startActivityForResult(intent,FilePickerConst.REQUEST_CODE_DOC);
}
}

View File

@@ -0,0 +1,49 @@
package de.beyondsoft.ownchat.filepicker;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class FilePickerConst {
public static final int REQUEST_CODE_PHOTO = 233;
public static final int REQUEST_CODE_DOC = 234;
public static final int REQUEST_CODE_MEDIA_DETAIL = 235;
final static int DEFAULT_MAX_COUNT = 9;
public final static int DEFAULT_COLUMN_NUMBER = 3;
public final static int MEDIA_PICKER = 0x11;
public final static int DOC_PICKER = 0x12;
public final static String KEY_SELECTED_MEDIA = "SELECTED_PHOTOS";
public final static String KEY_SELECTED_DOCS = "SELECTED_DOCS";
public final static String EXTRA_PICKER_TYPE = "EXTRA_PICKER_TYPE";
public final static String EXTRA_SHOW_GIF = "SHOW_GIF";
public final static String EXTRA_FILE_TYPE = "EXTRA_FILE_TYPE";
public final static String EXTRA_BUCKET_ID = "EXTRA_BUCKET_ID";
public final static String ALL_PHOTOS_BUCKET_ID = "ALL_PHOTOS_BUCKET_ID";
public final static String PPT_MIME_TYPE = "application/mspowerpoint";
public final static int FILE_TYPE_MEDIA = 1;
public final static int FILE_TYPE_DOCUMENT = 2;
public final static int MEDIA_TYPE_IMAGE=1;
public final static int MEDIA_TYPE_VIDEO=3;
public enum FILE_TYPE{
PDF,
WORD,
EXCEL,
PPT,
TXT,
UNKNOWN
}
final static String PDF = "PDF";
final static String PPT = "PPT";
final static String DOC = "DOC";
final static String XLS = "XLS";
final static String TXT = "TXT";
}

View File

@@ -0,0 +1,194 @@
package de.beyondsoft.ownchat.filepicker;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.adapters.FileAdapterListener;
import de.beyondsoft.ownchat.filepicker.adapters.ImageGridAdapter;
import de.beyondsoft.ownchat.filepicker.models.ImageDirectory;
import de.beyondsoft.ownchat.filepicker.models.Media;
import de.beyondsoft.ownchat.filepicker.utils.AndroidLifecycleUtils;
import de.beyondsoft.ownchat.filepicker.utils.MediaStoreHelper;
/**
* Created by Lyndon on 27-Oct-2017.
*/
public class MediaDetailsActivity extends BaseFilePickerActivity implements FileAdapterListener {
private static final int SCROLL_THRESHOLD = 30;
private RecyclerView recyclerView;
private TextView emptyView;
private RequestManager mGlideRequestManager;
private ImageGridAdapter photoGridAdapter;
private int fileType;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState, R.layout.activity_media_details);
}
@Override
protected void initView() {
mGlideRequestManager = Glide.with(this);
Intent intent = getIntent();
if (intent != null) {
fileType = intent.getIntExtra(FilePickerConst.EXTRA_FILE_TYPE,FilePickerConst.MEDIA_TYPE_IMAGE);
ImageDirectory photoDirectory = intent.getParcelableExtra(ImageDirectory.class.getSimpleName());
if(photoDirectory!=null) {
setUpView(photoDirectory);
if(getSupportActionBar()!=null)
{
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(photoDirectory.getName());
}
}
}
}
private void setUpView(ImageDirectory photoDirectory) {
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
emptyView = (TextView) findViewById(R.id.empty_view);
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL);
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// Log.d(">>> Picker >>>", "dy = " + dy);
if (Math.abs(dy) > SCROLL_THRESHOLD) {
mGlideRequestManager.pauseRequests();
} else {
resumeRequestsIfNotDestroyed();
}
}
@Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
resumeRequestsIfNotDestroyed();
}
}
});
getDataFromMedia(photoDirectory.getBucketId());
}
private void getDataFromMedia(String bucketId) {
Bundle mediaStoreArgs = new Bundle();
mediaStoreArgs.putBoolean(FilePickerConst.EXTRA_SHOW_GIF, false);
mediaStoreArgs.putString(FilePickerConst.EXTRA_BUCKET_ID, bucketId);
mediaStoreArgs.putInt(FilePickerConst.EXTRA_FILE_TYPE, fileType);
if(fileType==FilePickerConst.MEDIA_TYPE_IMAGE) {
MediaStoreHelper.getPhotoDirs(this, mediaStoreArgs,
dirs -> updateList(dirs));
}
else if(fileType==FilePickerConst.MEDIA_TYPE_VIDEO)
{
MediaStoreHelper.getVideoDirs(this, mediaStoreArgs,
dirs -> updateList(dirs));
}
}
private void updateList(List<ImageDirectory> dirs) {
ArrayList<Media> medias = new ArrayList<>();
for (int i = 0; i < dirs.size(); i++) {
medias.addAll(dirs.get(i).getMedias());
}
Collections.sort(medias,new Comparator<Media>() {
@Override
public int compare(Media a, Media b) {
return b.getId() - a.getId();
}
});
if(medias.size()>0) {
emptyView.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
else {
emptyView.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
return;
}
if(photoGridAdapter!=null)
{
photoGridAdapter.setData(medias);
photoGridAdapter.notifyDataSetChanged();
}
else
{
photoGridAdapter = new ImageGridAdapter(this, mGlideRequestManager, (ArrayList<Media>) medias,PickerManager.getInstance().getSelectedPhotos(),false, this);
recyclerView.setAdapter(photoGridAdapter);
}
}
private void resumeRequestsIfNotDestroyed() {
if (!AndroidLifecycleUtils.canLoadImage(this)) {
return;
}
mGlideRequestManager.resumeRequests();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.picker_menu, menu);
return super.onCreateOptionsMenu(menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
int i = item.getItemId();
if (i == R.id.action_done) {
setResult(RESULT_OK, null);
finish();
return true;
} else if (i == android.R.id.home) {
onBackPressed();
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onItemSelected() {
if(PickerManager.getInstance().getMaxCount()==1) {
setResult(RESULT_OK, null);
finish();
}
}
@Override
public void onBackPressed() {
setResult(RESULT_CANCELED, null);
finish();
}
}

View File

@@ -0,0 +1,232 @@
package de.beyondsoft.ownchat.filepicker;
import java.util.ArrayList;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.models.BaseFile;
import de.beyondsoft.ownchat.filepicker.models.FileType;
import de.beyondsoft.ownchat.filepicker.utils.Orientation;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class PickerManager {
private static PickerManager mInstance = new PickerManager();
private int mMaxCount = FilePickerConst.DEFAULT_MAX_COUNT;
private int mCurrentCount;
private boolean mShowImages = true;
private int mCameraDrawble = R.drawable.orca_attach_camera_normal;
public static PickerManager getInstance() {
return mInstance;
}
private ArrayList<String> mediaFiles;
private ArrayList<String> docFiles;
private ArrayList<FileType> fileTypes;
private int theme = R.style.AppTheme;
private boolean showVideos;
private boolean showGif;
private boolean docSupport = true;
private boolean enableCamera = true;
private Orientation orientation = Orientation.UNSPECIFIED;
private boolean showFolderView = true;
private String providerAuthorities;
private PickerManager() {
mediaFiles = new ArrayList<>();
docFiles = new ArrayList<>();
fileTypes = new ArrayList<>();
}
public void setMaxCount(int count) {
clearSelections();
this.mMaxCount = count;
}
public int getMaxCount() {
return mMaxCount;
}
public int getCurrentCount() {
return mCurrentCount;
}
public void add(String path, int type) {
if (path != null && shouldAdd()) {
if (!mediaFiles.contains(path) && type == FilePickerConst.FILE_TYPE_MEDIA)
mediaFiles.add(path);
else if (type == FilePickerConst.FILE_TYPE_DOCUMENT)
docFiles.add(path);
else
return;
mCurrentCount++;
}
}
public void add(ArrayList<String> paths, int type) {
for (int index = 0; index < paths.size(); index++) {
add(paths.get(index), type);
}
}
public void remove(String path, int type) {
if ((type == FilePickerConst.FILE_TYPE_MEDIA) && mediaFiles.contains(path)) {
mediaFiles.remove(path);
mCurrentCount--;
} else if (type == FilePickerConst.FILE_TYPE_DOCUMENT) {
docFiles.remove(path);
mCurrentCount--;
}
}
public boolean shouldAdd() {
return mCurrentCount < mMaxCount;
}
public ArrayList<String> getSelectedPhotos() {
return mediaFiles;
}
public ArrayList<String> getSelectedFiles() {
return docFiles;
}
public ArrayList<String> getSelectedFilePaths(ArrayList<BaseFile> files) {
ArrayList<String> paths = new ArrayList<>();
for (int index = 0; index < files.size(); index++) {
paths.add(files.get(index).getPath());
}
return paths;
}
public void clearSelections() {
docFiles.clear();
mediaFiles.clear();
fileTypes.clear();
mCurrentCount = 0;
mMaxCount = 0;
}
public int getTheme() {
return theme;
}
public void setTheme(int theme) {
this.theme = theme;
}
public boolean showVideo() {
return showVideos;
}
public void setShowVideos(boolean showVideos) {
this.showVideos = showVideos;
}
public boolean showImages() {
return mShowImages;
}
public void setShowImages(boolean showImages) {
this.mShowImages = showImages;
}
public boolean isShowGif() {
return showGif;
}
public void setShowGif(boolean showGif) {
this.showGif = showGif;
}
public boolean isShowFolderView() {
return showFolderView;
}
public void setShowFolderView(boolean showFolderView) {
this.showFolderView = showFolderView;
}
public void addFileType(FileType fileType)
{
fileTypes.add(fileType);
}
public void addDocTypes()
{
String[] pdfs = {"pdf"};
fileTypes.add(new FileType(FilePickerConst.PDF,pdfs,R.drawable.document));
String[] docs = {"doc","docx", "dot","dotx"};
fileTypes.add(new FileType(FilePickerConst.DOC,docs,R.drawable.document));
String[] ppts = {"ppt","pptx"};
fileTypes.add(new FileType(FilePickerConst.PPT,ppts,R.drawable.document));
String[] xlss = {"xls","xlsx"};
fileTypes.add(new FileType(FilePickerConst.XLS,xlss,R.drawable.document));
String[] txts = {"txt"};
fileTypes.add(new FileType(FilePickerConst.TXT,txts,R.drawable.document));
}
public ArrayList<FileType> getFileTypes()
{
return fileTypes;
}
public boolean isDocSupport() {
return docSupport;
}
public void setDocSupport(boolean docSupport) {
this.docSupport = docSupport;
}
public boolean isEnableCamera() {
return enableCamera;
}
public void setEnableCamera(boolean enableCamera) {
this.enableCamera = enableCamera;
}
public Orientation getOrientation() {
return orientation;
}
public void setOrientation(Orientation orientation) {
this.orientation = orientation;
}
public String getProviderAuthorities() {
return providerAuthorities;
}
public void setProviderAuthorities(String providerAuthorities) {
this.providerAuthorities = providerAuthorities;
}
public void setCameraDrawable(int drawable) {
this.mCameraDrawble = drawable;
}
public int getCameraDrawable()
{
return mCameraDrawble;
}
}

View File

@@ -0,0 +1,9 @@
package de.beyondsoft.ownchat.filepicker.adapters;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public interface FileAdapterListener {
void onItemSelected();
}

View File

@@ -0,0 +1,122 @@
package de.beyondsoft.ownchat.filepicker.adapters;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.text.format.Formatter;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.CheckBox;
import android.widget.ImageView;
import android.widget.TextView;
import java.util.List;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.models.Document;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class FileListAdapter extends SelectableAdapter<FileListAdapter.FileViewHolder, Document> {
private final Context context;
private final FileAdapterListener mListener;
public FileListAdapter(Context context, List<Document> items, List<String> selectedPaths, FileAdapterListener fileAdapterListener) {
super(items, selectedPaths);
this.context = context;
this.mListener = fileAdapterListener;
}
@Override
public FileViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(R.layout.item_doc_layout, parent, false);
return new FileViewHolder(itemView);
}
@Override
public void onBindViewHolder(final FileViewHolder holder, int position) {
final Document document = getItems().get(position);
holder.imageView.setImageResource(document.getFileType().getDrawable());
holder.fileNameTextView.setText(document.getTitle());
holder.fileSizeTextView.setText(Formatter.formatShortFileSize(context, Long.parseLong(document.getSize())));
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
onItemClicked(document,holder);
}
});
holder.checkBox.setOnCheckedChangeListener(null);
holder.checkBox.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
onItemClicked(document,holder);
}
});
holder.checkBox.setChecked(isSelected(document));
holder.itemView.setBackgroundResource(isSelected(document) ? R.color.colorLeftChat : android.R.color.white);
holder.checkBox.setVisibility(isSelected(document) ? View.VISIBLE : View.GONE);
holder.checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
toggleSelection(document);
holder.itemView.setBackgroundResource(isChecked ? R.color.colorLeftChat : android.R.color.white);
if(mListener!=null) {
mListener.onItemSelected();
}
});
}
private void onItemClicked(Document document, FileViewHolder holder)
{
if(PickerManager.getInstance().getMaxCount()==1)
{
PickerManager.getInstance().add(document.getPath(), FilePickerConst.FILE_TYPE_DOCUMENT);
if(mListener!=null)
mListener.onItemSelected();
}
else {
if (holder.checkBox.isChecked()) {
PickerManager.getInstance().remove(document.getPath(), FilePickerConst.FILE_TYPE_DOCUMENT);
holder.checkBox.setChecked(!holder.checkBox.isChecked());
holder.checkBox.setVisibility(View.GONE);
} else if (PickerManager.getInstance().shouldAdd()) {
PickerManager.getInstance().add(document.getPath(), FilePickerConst.FILE_TYPE_DOCUMENT);
holder.checkBox.setChecked(!holder.checkBox.isChecked());
holder.checkBox.setVisibility(View.VISIBLE);
}
}
}
@Override
public int getItemCount() {
return getItems().size();
}
public static class FileViewHolder extends RecyclerView.ViewHolder {
CheckBox checkBox;
ImageView imageView;
TextView fileNameTextView;
TextView fileSizeTextView;
public FileViewHolder(View itemView) {
super(itemView);
checkBox = (CheckBox) itemView.findViewById(R.id.checkbox);
imageView = (ImageView) itemView.findViewById(R.id.file_iv);
fileNameTextView = (TextView) itemView.findViewById(R.id.file_name_tv);
fileSizeTextView = (TextView) itemView.findViewById(R.id.file_size_tv);
}
}
}

View File

@@ -0,0 +1,143 @@
package de.beyondsoft.ownchat.filepicker.adapters;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.TextView;
import com.bumptech.glide.RequestManager;
import java.io.File;
import java.util.ArrayList;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.models.ImageDirectory;
import de.beyondsoft.ownchat.filepicker.utils.AndroidLifecycleUtils;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class FolderGridAdapter extends SelectableAdapter<FolderGridAdapter.ImageViewHolder, ImageDirectory> {
private final Context context;
private final RequestManager glide;
private final boolean showCamera;
private int imageSize;
public final static int ITEM_TYPE_CAMERA = 100;
public final static int ITEM_TYPE_PHOTO = 101;
private FolderGridAdapterListener folderGridAdapterListener;
public interface FolderGridAdapterListener{
void onCameraClicked();
void onFolderClicked(ImageDirectory photoDirectory);
}
public FolderGridAdapter(Context context, RequestManager requestManager, ArrayList<ImageDirectory> photos, ArrayList<String> selectedPaths, boolean showCamera)
{
super(photos, selectedPaths);
this.context = context;
this.glide = requestManager;
this.showCamera = showCamera;
setColumnNumber(context,3);
}
@Override
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(R.layout.item_folder_layout, parent, false);
return new ImageViewHolder(itemView);
}
@Override
public int getItemViewType(int position) {
if(showCamera)
return (position == 0) ? ITEM_TYPE_CAMERA : ITEM_TYPE_PHOTO;
else
return ITEM_TYPE_PHOTO;
}
@Override
public void onBindViewHolder(final ImageViewHolder holder, int position) {
if(getItemViewType(position) == ITEM_TYPE_PHOTO) {
final ImageDirectory photoDirectory = getItems().get(showCamera?position-1:position);
if(AndroidLifecycleUtils.canLoadImage(holder.imageView.getContext())) {
glide.load(new File(photoDirectory.getCoverPath()))
.override(imageSize, imageSize)
.placeholder(R.drawable.document)
.thumbnail(0.5f)
.into(holder.imageView);
}
holder.folderTitle.setText(photoDirectory.getName());
holder.folderCount.setText(String.valueOf(photoDirectory.getMedias().size()));
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(folderGridAdapterListener!=null)
folderGridAdapterListener.onFolderClicked(photoDirectory);
}
});
holder.bottomOverlay.setVisibility(View.VISIBLE);
}
else
{
holder.imageView.setImageResource(PickerManager.getInstance().getCameraDrawable());
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(folderGridAdapterListener!=null)
folderGridAdapterListener.onCameraClicked();
}
});
holder.bottomOverlay.setVisibility(View.GONE);
}
}
private void setColumnNumber(Context context, int columnNum) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
int widthPixels = metrics.widthPixels;
imageSize = widthPixels / columnNum;
}
@Override
public int getItemCount() {
if(showCamera)
return getItems().size()+1;
return getItems().size();
}
public void setFolderGridAdapterListener(FolderGridAdapterListener onClickListener)
{
this.folderGridAdapterListener = onClickListener;
}
public static class ImageViewHolder extends RecyclerView.ViewHolder {
ImageView imageView;
TextView folderTitle;
TextView folderCount;
View bottomOverlay;
View selectBg;
public ImageViewHolder(View itemView) {
super(itemView);
imageView = (ImageView) itemView.findViewById(R.id.iv_photo);
folderTitle = (TextView) itemView.findViewById(R.id.folder_title);
folderCount = (TextView) itemView.findViewById(R.id.folder_count);
bottomOverlay = itemView.findViewById(R.id.bottomOverlay);
selectBg = itemView.findViewById(R.id.transparent_bg);
}
}
}

View File

@@ -0,0 +1,185 @@
package de.beyondsoft.ownchat.filepicker.adapters;
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.CheckBox;
import android.widget.ImageView;
import com.bumptech.glide.RequestManager;
import java.io.File;
import java.util.ArrayList;
import butterknife.BindView;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.models.Media;
import de.beyondsoft.ownchat.filepicker.utils.AndroidLifecycleUtils;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class ImageGridAdapter extends SelectableAdapter<ImageGridAdapter.ImageViewHolder, Media> {
private final Context context;
private final RequestManager glide;
private final boolean showCamera;
private final FileAdapterListener mListener;
private int imageSize;
public final static int ITEM_TYPE_CAMERA = 100;
public final static int ITEM_TYPE_PHOTO = 101;
private View.OnClickListener cameraOnClickListener;
public ImageGridAdapter(Context context,
RequestManager requestManager,
ArrayList<Media> medias,
ArrayList<String> selectedPaths,
boolean showCamera,
FileAdapterListener photoGridAdapterListener)
{
super(medias, selectedPaths);
this.context = context;
this.glide = requestManager;
this.showCamera = showCamera;
this.mListener = photoGridAdapterListener;
setColumnNumber(context,3);
}
@Override
public ImageViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View itemView = LayoutInflater.from(context).inflate(R.layout.item_image_layout, parent, false);
return new ImageViewHolder(itemView);
}
@Override
public int getItemViewType(int position) {
if(showCamera) {
return (position == 0) ? ITEM_TYPE_CAMERA : ITEM_TYPE_PHOTO;
} else {
return ITEM_TYPE_PHOTO;
}
}
@Override
public void onBindViewHolder(final ImageViewHolder holder, int position) {
if(getItemViewType(position) == ITEM_TYPE_PHOTO) {
final Media media = getItems().get(showCamera?position-1:position);
if(AndroidLifecycleUtils.canLoadImage(holder.imageView.getContext())) {
glide.load(new File(media.getPath()))
.override(imageSize, imageSize)
.placeholder(R.drawable.document)
.thumbnail(0.5f)
.into(holder.imageView);
}
if(media.getMediaType()== FilePickerConst.MEDIA_TYPE_VIDEO) {
holder.videoIcon.setVisibility(View.VISIBLE);
} else {
holder.videoIcon.setVisibility(View.GONE);
}
holder.itemView.setOnClickListener(v -> onItemClicked(holder,media));
//in some cases, it will prevent unwanted situations
holder.checkBox.setVisibility(View.GONE);
holder.checkBox.setOnCheckedChangeListener(null);
holder.checkBox.setOnClickListener(view -> onItemClicked(holder,media));
//if true, your checkbox will be selected, else unselected
holder.checkBox.setChecked(isSelected(media));
holder.selectBg.setVisibility(isSelected(media) ? View.VISIBLE : View.GONE);
holder.checkBox.setVisibility(isSelected(media) ? View.VISIBLE : View.GONE);
holder.checkBox.setOnCheckedChangeListener((buttonView, isChecked) -> {
toggleSelection(media);
holder.selectBg.setVisibility(isChecked ? View.VISIBLE : View.GONE);
if (isChecked)
{
holder.checkBox.setVisibility(View.VISIBLE);
PickerManager.getInstance().add(media.getPath(), FilePickerConst.FILE_TYPE_MEDIA);
}
else
{
holder.checkBox.setVisibility(View.GONE);
PickerManager.getInstance().remove(media.getPath(),FilePickerConst.FILE_TYPE_MEDIA);
}
if(mListener != null) {
mListener.onItemSelected();
}
});
}
else
{
holder.imageView.setImageResource(PickerManager.getInstance().getCameraDrawable());
holder.checkBox.setVisibility(View.GONE);
holder.itemView.setOnClickListener(cameraOnClickListener);
holder.videoIcon.setVisibility(View.GONE);
}
}
private void onItemClicked(ImageViewHolder holder, Media media) {
if(PickerManager.getInstance().getMaxCount() == 1) {
PickerManager.getInstance().add(media.getPath(), FilePickerConst.FILE_TYPE_MEDIA);
if(mListener!=null) {
mListener.onItemSelected();
}
}
else if (holder.checkBox.isChecked() || PickerManager.getInstance().shouldAdd()) {
holder.checkBox.setChecked(!holder.checkBox.isChecked());
}
}
private void setColumnNumber(Context context, int columnNum) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics metrics = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(metrics);
int widthPixels = metrics.widthPixels;
imageSize = widthPixels / columnNum;
}
@Override
public int getItemCount() {
if(showCamera) {
return getItems().size() + 1;
}
return getItems().size();
}
public void setCameraListener(View.OnClickListener onClickListener)
{
this.cameraOnClickListener = onClickListener;
}
public static class ImageViewHolder extends RecyclerView.ViewHolder {
@BindView(R.id.checkbox)
CheckBox checkBox;
@BindView(R.id.iv_photo)
ImageView imageView;
@BindView(R.id.video_icon)
ImageView videoIcon;
@BindView(R.id.transparent_bg)
View selectBg;
public ImageViewHolder(View itemView) {
super(itemView);
}
}
}

View File

@@ -0,0 +1,41 @@
package de.beyondsoft.ownchat.filepicker.adapters;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentManager;
import android.support.v4.app.FragmentPagerAdapter;
import java.util.ArrayList;
import java.util.List;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class SectionsPagerAdapter extends FragmentPagerAdapter {
private final List<Fragment> mFragmentList = new ArrayList<>();
private final List<String> mFragmentTitles = new ArrayList<>();
public SectionsPagerAdapter(FragmentManager fm) {
super(fm);
}
@Override
public Fragment getItem(int position) {
return mFragmentList.get(position);
}
@Override
public int getCount() {
return mFragmentList.size();
}
public void addFragment(Fragment fragment, String title) {
mFragmentList.add(fragment);
mFragmentTitles.add(title);
}
@Override
public CharSequence getPageTitle(int position) {
return mFragmentTitles.get(position);
}
}

View File

@@ -0,0 +1,15 @@
package de.beyondsoft.ownchat.filepicker.adapters;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public interface Selectable<T> {
boolean isSelected(T item);
void toggleSelection(T item);
void clearSelection();
int getSelectedItemCount();
}

View File

@@ -0,0 +1,72 @@
package de.beyondsoft.ownchat.filepicker.adapters;
import android.support.v7.widget.RecyclerView;
import java.util.ArrayList;
import java.util.List;
import de.beyondsoft.ownchat.filepicker.models.BaseFile;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder, T extends BaseFile> extends RecyclerView.Adapter<VH> implements Selectable<T> {
private List<T> items;
protected List<T> selectedPhotos;
public SelectableAdapter(List<T> items, List<String> selectedPaths) {
this.items = items;
selectedPhotos = new ArrayList<>();
addPathsToSelections(selectedPaths);
}
private void addPathsToSelections(List<String> selectedPaths) {
if(selectedPaths==null)
return;
for (int index = 0; index < items.size(); index++) {
for (int jindex = 0; jindex < selectedPaths.size(); jindex++) {
if(items.get(index).getPath().equals(selectedPaths.get(jindex)))
{
selectedPhotos.add(items.get(index));
}
}
}
}
@Override
public boolean isSelected(T photo) {
return selectedPhotos.contains(photo);
}
@Override
public void toggleSelection(T photo) {
if (selectedPhotos.contains(photo)) {
selectedPhotos.remove(photo);
} else {
selectedPhotos.add(photo);
}
}
@Override
public void clearSelection() {
selectedPhotos.clear();
}
@Override
public int getSelectedItemCount() {
return selectedPhotos.size();
}
public void setData(List<T> items) {
this.items = items;
}
public List<T> getItems()
{
return items;
}
}

View File

@@ -0,0 +1,122 @@
package de.beyondsoft.ownchat.filepicker.cursors;
import android.content.Context;
import android.database.Cursor;
import android.os.AsyncTask;
import android.provider.MediaStore;
import android.text.TextUtils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.cursors.loadercallbacks.FileResultCallback;
import de.beyondsoft.ownchat.filepicker.models.Document;
import de.beyondsoft.ownchat.filepicker.models.FileType;
import static android.provider.BaseColumns._ID;
import static android.provider.MediaStore.MediaColumns.DATA;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class DocScannerTask extends AsyncTask<Void,Void,List<Document>> {
final String[] DOC_PROJECTION = {
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DATA,
MediaStore.Files.FileColumns.MIME_TYPE,
MediaStore.Files.FileColumns.SIZE,
MediaStore.Images.Media.DATE_ADDED,
MediaStore.Files.FileColumns.TITLE
};
private final FileResultCallback<Document> resultCallback;
private final Context mContext;
public DocScannerTask(Context context, FileResultCallback<Document> fileResultCallback)
{
this.mContext = context;
this.resultCallback = fileResultCallback;
}
@Override
protected List<Document> doInBackground(Void... voids) {
ArrayList<Document> documents = new ArrayList<>();
final String[] projection = DOC_PROJECTION;
String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "!="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE + " AND "
+ MediaStore.Files.FileColumns.MEDIA_TYPE + "!="
+ MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO ;
final Cursor cursor = mContext.getContentResolver().query(MediaStore.Files.getContentUri("external"),
projection,
selection,
null,
MediaStore.Files.FileColumns.DATE_ADDED + " DESC");
if(cursor!=null) {
documents = getDocumentFromCursor(cursor);
cursor.close();
}
return documents;
}
@Override
protected void onPostExecute(List<Document> documents) {
super.onPostExecute(documents);
if (resultCallback != null) {
resultCallback.onResultCallback(documents);
}
}
private ArrayList<Document> getDocumentFromCursor(Cursor data)
{
ArrayList<Document> documents = new ArrayList<>();
while (data.moveToNext()) {
int imageId = data.getInt(data.getColumnIndexOrThrow(_ID));
String path = data.getString(data.getColumnIndexOrThrow(DATA));
String title = data.getString(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.TITLE));
if(path!=null) {
FileType fileType = getFileType(PickerManager.getInstance().getFileTypes(),path);
if(fileType != null && !(new File(path).isDirectory())) {
Document document = new Document(imageId, title, path);
document.setFileType(fileType);
String mimeType = data.getString(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.MIME_TYPE));
if (mimeType != null && !TextUtils.isEmpty(mimeType)) {
document.setMimeType(mimeType);
} else {
document.setMimeType("");
}
document.setSize(data.getString(data.getColumnIndexOrThrow(MediaStore.Files.FileColumns.SIZE)));
if (!documents.contains(document)) {
documents.add(document);
}
}
}
}
return documents;
}
private FileType getFileType(ArrayList<FileType> types, String path) {
for(int index = 0; index < types.size(); index++) {
for(String string : types.get(index).extensions) {
if(path.endsWith(string)) {
return types.get(index);
}
}
}
return null;
}
}

View File

@@ -0,0 +1,50 @@
package de.beyondsoft.ownchat.filepicker.cursors;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.content.CursorLoader;
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class ImageDirectoryLoader extends CursorLoader {
final String[] IMAGE_PROJECTION = {
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DATA,
MediaStore.Images.Media.BUCKET_ID,
MediaStore.Images.Media.BUCKET_DISPLAY_NAME,
MediaStore.Images.Media.DATE_ADDED,
MediaStore.Images.Media.TITLE
};
public ImageDirectoryLoader(Context context, Bundle args) {
super(context);
String bucketId = args.getString(FilePickerConst.EXTRA_BUCKET_ID, null);
int mediaType = args.getInt(FilePickerConst.EXTRA_FILE_TYPE, FilePickerConst.MEDIA_TYPE_IMAGE);
setProjection(null);
setUri(MediaStore.Files.getContentUri("external"));
setSortOrder(MediaStore.Images.Media._ID + " DESC");
String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "=" + MediaStore.Files.FileColumns.MEDIA_TYPE_IMAGE;
if(mediaType== FilePickerConst.MEDIA_TYPE_VIDEO) {
selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "=" + MediaStore.Files.FileColumns.MEDIA_TYPE_VIDEO;
}
if(bucketId!=null) {
selection += " AND " + MediaStore.Images.Media.BUCKET_ID + "='" + bucketId + "'";
}
setSelection(selection);
}
private ImageDirectoryLoader(Context context, Uri uri, String[] projection, String selection, String[] selectionArgs, String sortOrder) {
super(context, uri, projection, selection, selectionArgs, sortOrder);
}
}

View File

@@ -0,0 +1,11 @@
package de.beyondsoft.ownchat.filepicker.cursors.loadercallbacks;
import java.util.List;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public interface FileResultCallback<T> {
void onResultCallback(List<T> files);
}

View File

@@ -0,0 +1,94 @@
package de.beyondsoft.ownchat.filepicker.cursors.loadercallbacks;
import android.content.Context;
import android.database.Cursor;
import android.os.Bundle;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.Loader;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.cursors.ImageDirectoryLoader;
import de.beyondsoft.ownchat.filepicker.models.ImageDirectory;
import static android.provider.BaseColumns._ID;
import static android.provider.MediaStore.Files.FileColumns.MEDIA_TYPE;
import static android.provider.MediaStore.Images.ImageColumns.BUCKET_DISPLAY_NAME;
import static android.provider.MediaStore.Images.ImageColumns.BUCKET_ID;
import static android.provider.MediaStore.MediaColumns.DATA;
import static android.provider.MediaStore.MediaColumns.DATE_ADDED;
import static android.provider.MediaStore.MediaColumns.TITLE;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class ImageDirLoaderCallback implements LoaderManager.LoaderCallbacks<Cursor> {
public final static int INDEX_ALL_PHOTOS = 0;
private WeakReference<Context> context;
private FileResultCallback<ImageDirectory> resultCallback;
public ImageDirLoaderCallback(Context context, FileResultCallback<ImageDirectory> resultCallback) {
this.context = new WeakReference<>(context);
this.resultCallback = resultCallback;
}
@Override
public Loader<Cursor> onCreateLoader(int id, Bundle args) {
return new ImageDirectoryLoader(context.get(), args);
}
@Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
if (data == null) {
return;
}
List<ImageDirectory> directories = new ArrayList<>();
while (data.moveToNext()) {
int imageId = data.getInt(data.getColumnIndexOrThrow(_ID));
String bucketId = data.getString(data.getColumnIndexOrThrow(BUCKET_ID));
String name = data.getString(data.getColumnIndexOrThrow(BUCKET_DISPLAY_NAME));
String path = data.getString(data.getColumnIndexOrThrow(DATA));
String fileName = data.getString(data.getColumnIndexOrThrow(TITLE));
int mediaType = data.getInt(data.getColumnIndexOrThrow(MEDIA_TYPE));
ImageDirectory photoDirectory = new ImageDirectory();
photoDirectory.setBucketId(bucketId);
photoDirectory.setName(name);
if (!directories.contains(photoDirectory)) {
if(path.toLowerCase().endsWith("gif")) {
if (PickerManager.getInstance().isShowGif()) {
photoDirectory.addPhoto(imageId, fileName, path, mediaType);
}
}
else
{
photoDirectory.addPhoto(imageId, fileName, path, mediaType);
}
photoDirectory.setDateAdded(data.getLong(data.getColumnIndexOrThrow(DATE_ADDED)));
directories.add(photoDirectory);
} else {
directories.get(directories.indexOf(photoDirectory)).addPhoto(imageId, fileName, path, mediaType);
}
}
if (resultCallback != null) {
resultCallback.onResultCallback(directories);
}
}
@Override
public void onLoaderReset(Loader<Cursor> loader) {
}
}

View File

@@ -0,0 +1,35 @@
package de.beyondsoft.ownchat.filepicker.fragments;
import android.support.v4.app.Fragment;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class BaseFragment extends Fragment {
public static final String FILE_TYPE="FILE_TYPE";
public BaseFragment() {
// Required empty public constructor
}
protected void fadeIn(View view)
{
Animation bottomUp = AnimationUtils.loadAnimation(getContext(),
android.R.anim.fade_in);
view.startAnimation(bottomUp);
view.setVisibility(View.VISIBLE);
}
protected void fadeOut(View view)
{
Animation bottomUp = AnimationUtils.loadAnimation(getContext(),
android.R.anim.fade_out);
view.startAnimation(bottomUp);
view.setVisibility(View.GONE);
}
}

View File

@@ -0,0 +1,132 @@
package de.beyondsoft.ownchat.filepicker.fragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import java.util.List;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.adapters.FileAdapterListener;
import de.beyondsoft.ownchat.filepicker.adapters.FileListAdapter;
import de.beyondsoft.ownchat.filepicker.models.Document;
import de.beyondsoft.ownchat.filepicker.models.FileType;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class DocFragment extends BaseFragment implements FileAdapterListener {
private static final String TAG = DocFragment.class.getSimpleName();
RecyclerView recyclerView;
TextView emptyView;
private DocFragmentListener mListener;
private FileListAdapter fileListAdapter;
private FileType fileType;
public DocFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_image_picker, container, false);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof DocFragmentListener) {
mListener = (DocFragmentListener) context;
} else {
throw new RuntimeException(context.toString() + " must implement ImagePickerFragmentListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
public static DocFragment newInstance(FileType fileType) {
DocFragment photoPickerFragment = new DocFragment();
Bundle bun = new Bundle();
bun.putParcelable(FILE_TYPE, fileType);
photoPickerFragment.setArguments(bun);
return photoPickerFragment;
}
public FileType getFileType() {
return getArguments().getParcelable(FILE_TYPE);
}
@Override
public void onItemSelected() {
mListener.onItemSelected();
}
public interface DocFragmentListener {
void onItemSelected();
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView(view);
}
private void initView(View view) {
fileType = getArguments().getParcelable(FILE_TYPE);
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
emptyView = (TextView) view.findViewById(R.id.empty_view);
recyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));
recyclerView.setVisibility(View.GONE);
}
public void updateList(List<Document> dirs) {
if(getView()==null)
return;
if(dirs.size()>0)
{
recyclerView.setVisibility(View.VISIBLE);
emptyView.setVisibility(View.GONE);
FileListAdapter fileListAdapter = (FileListAdapter) recyclerView.getAdapter();
if(fileListAdapter==null) {
fileListAdapter = new FileListAdapter(getActivity(), dirs, PickerManager.getInstance().getSelectedFiles(), this);
recyclerView.setAdapter(fileListAdapter);
}
else
{
fileListAdapter.setData(dirs);
fileListAdapter.notifyDataSetChanged();
}
}
else
{
recyclerView.setVisibility(View.GONE);
emptyView.setVisibility(View.VISIBLE);
}
}
}

View File

@@ -0,0 +1,156 @@
package de.beyondsoft.ownchat.filepicker.fragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ProgressBar;
import com.android.internal.util.Predicate;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.adapters.SectionsPagerAdapter;
import de.beyondsoft.ownchat.filepicker.cursors.loadercallbacks.FileResultCallback;
import de.beyondsoft.ownchat.filepicker.models.Document;
import de.beyondsoft.ownchat.filepicker.models.FileType;
import de.beyondsoft.ownchat.filepicker.utils.MediaStoreHelper;
import de.beyondsoft.ownchat.filepicker.utils.TabLayoutHelper;
import de.beyondsoft.ownchat.filepicker.utils.Utils;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class DocPickerFragment extends BaseFragment {
private static final String TAG = DocPickerFragment.class.getSimpleName();
TabLayout tabLayout;
ViewPager viewPager;
private ArrayList<String> selectedPaths;
private ProgressBar progressBar;
private DocPickerFragmentListener mListener;
public DocPickerFragment() {
// Required empty public constructor
}
public interface DocPickerFragmentListener{
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_doc_picker, container, false);
}
public static DocPickerFragment newInstance(ArrayList<String> selectedPaths) {
DocPickerFragment docPickerFragment = new DocPickerFragment();
docPickerFragment.selectedPaths = selectedPaths;
return docPickerFragment;
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof DocPickerFragmentListener) {
mListener = (DocPickerFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement DocPickerFragmentListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
setViews(view);
initView();
}
private void initView() {
setUpViewPager();
setData();
}
private void setViews(View view) {
tabLayout = (TabLayout) view.findViewById(R.id.tabs);
viewPager = (ViewPager) view.findViewById(R.id.viewPager);
progressBar = (ProgressBar) view.findViewById(R.id.progress_bar);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
}
private void setData() {
MediaStoreHelper.getDocs(getActivity(), new FileResultCallback<Document>() {
@Override
public void onResultCallback(List<Document> files) {
if(!isAdded()) return;
progressBar.setVisibility(View.GONE);
setDataOnFragments(files);
}
});
}
private void setDataOnFragments(List<Document> files) {
SectionsPagerAdapter sectionsPagerAdapter = (SectionsPagerAdapter) viewPager.getAdapter();
if(sectionsPagerAdapter!=null)
{
for (int index = 0; index < sectionsPagerAdapter.getCount(); index++) {
DocFragment docFragment = (DocFragment) getChildFragmentManager()
.findFragmentByTag(
"android:switcher:" + R.id.viewPager + ":"+index);
if(docFragment!=null)
{
FileType fileType = docFragment.getFileType();
if(fileType!=null)
docFragment.updateList(filterDocuments(fileType.extensions, files));
}
}
}
}
private void setUpViewPager() {
SectionsPagerAdapter adapter = new SectionsPagerAdapter(getChildFragmentManager());
ArrayList<FileType> supportedTypes = PickerManager.getInstance().getFileTypes();
for (int index = 0; index < supportedTypes.size(); index++) {
adapter.addFragment(DocFragment.newInstance(supportedTypes.get(index)),supportedTypes.get(index).title);
}
viewPager.setOffscreenPageLimit(supportedTypes.size());
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
TabLayoutHelper mTabLayoutHelper = new TabLayoutHelper(tabLayout, viewPager);
mTabLayoutHelper.setAutoAdjustTabModeEnabled(true);
}
private ArrayList<Document> filterDocuments(final String[] type, List<Document> documents)
{
final Predicate<Document> docType = new Predicate<Document>() {
public boolean apply(Document document) {
return document.isThisType(type);
}
};
return new ArrayList<>(Utils.filter(new HashSet<>(documents),docType));
}
}

View File

@@ -0,0 +1,9 @@
package de.beyondsoft.ownchat.filepicker.fragments;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public interface ImagePickerFragmentListener {
void onItemSelected();
}

View File

@@ -0,0 +1,244 @@
package de.beyondsoft.ownchat.filepicker.fragments;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.OrientationHelper;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.StaggeredGridLayoutManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.adapters.FileAdapterListener;
import de.beyondsoft.ownchat.filepicker.adapters.ImageGridAdapter;
import de.beyondsoft.ownchat.filepicker.cursors.loadercallbacks.FileResultCallback;
import de.beyondsoft.ownchat.filepicker.models.ImageDirectory;
import de.beyondsoft.ownchat.filepicker.models.Media;
import de.beyondsoft.ownchat.filepicker.utils.AndroidLifecycleUtils;
import de.beyondsoft.ownchat.filepicker.utils.ImageCaptureManager;
import de.beyondsoft.ownchat.filepicker.utils.MediaStoreHelper;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class MediaDetailPickerFragment extends BaseFragment implements FileAdapterListener {
private static final String TAG = MediaDetailPickerFragment.class.getSimpleName();
private static final int SCROLL_THRESHOLD = 30;
RecyclerView recyclerView;
TextView emptyView;
private ImagePickerFragmentListener mListener;
private ImageGridAdapter photoGridAdapter;
private ImageCaptureManager imageCaptureManager;
private RequestManager mGlideRequestManager;
private int fileType;
public MediaDetailPickerFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_image_picker, container, false);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof ImagePickerFragmentListener) {
mListener = (ImagePickerFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement PhotoPickerFragmentListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public static MediaDetailPickerFragment newInstance(int fileType) {
MediaDetailPickerFragment mediaDetailPickerFragment = new MediaDetailPickerFragment();
Bundle bun = new Bundle();
bun.putInt(FILE_TYPE, fileType);
mediaDetailPickerFragment.setArguments(bun);
return mediaDetailPickerFragment;
}
@Override
public void onItemSelected() {
mListener.onItemSelected();
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGlideRequestManager = Glide.with(this);
}
@Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView(view);
}
private void initView(View view) {
recyclerView = view.findViewById(R.id.recyclerview);
emptyView = view.findViewById(R.id.empty_view);
fileType = getArguments().getInt(FILE_TYPE);
imageCaptureManager = new ImageCaptureManager(getActivity());
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL);
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// Log.d(">>> Picker >>>", "dy = " + dy);
if (Math.abs(dy) > SCROLL_THRESHOLD) {
mGlideRequestManager.pauseRequests();
} else {
resumeRequestsIfNotDestroyed();
}
}
@Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
resumeRequestsIfNotDestroyed();
}
}
});
getDataFromMedia();
}
private void getDataFromMedia() {
Bundle mediaStoreArgs = new Bundle();
mediaStoreArgs.putInt(FilePickerConst.EXTRA_FILE_TYPE, fileType);
if(fileType==FilePickerConst.MEDIA_TYPE_IMAGE) {
MediaStoreHelper.getPhotoDirs(getActivity(), mediaStoreArgs,
dirs -> updateList(dirs));
}
else if(fileType==FilePickerConst.MEDIA_TYPE_VIDEO)
{
MediaStoreHelper.getVideoDirs(getActivity(), mediaStoreArgs,
dirs -> updateList(dirs));
}
}
private void updateList(List<ImageDirectory> dirs) {
ArrayList<Media> medias = new ArrayList<>();
for (int i = 0; i < dirs.size(); i++) {
medias.addAll(dirs.get(i).getMedias());
}
Collections.sort(medias,new Comparator<Media>() {
@Override
public int compare(Media a, Media b) {
return b.getId() - a.getId();
}
});
if(medias.size()>0) {
emptyView.setVisibility(View.GONE);
}
else {
emptyView.setVisibility(View.VISIBLE);
}
if(photoGridAdapter!=null)
{
photoGridAdapter.setData(medias);
photoGridAdapter.notifyDataSetChanged();
}
else
{
photoGridAdapter = new ImageGridAdapter(getActivity(), mGlideRequestManager, (ArrayList<Media>) medias, PickerManager.getInstance().getSelectedPhotos(),(fileType==FilePickerConst.MEDIA_TYPE_IMAGE) && PickerManager.getInstance().isEnableCamera(), this);
recyclerView.setAdapter(photoGridAdapter);
photoGridAdapter.setCameraListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
Intent intent = imageCaptureManager.dispatchTakePictureIntent(getActivity());
if(intent!=null)
startActivityForResult(intent, ImageCaptureManager.REQUEST_TAKE_PHOTO);
else
Toast.makeText(getActivity(), R.string.no_camera_exists, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode)
{
case ImageCaptureManager.REQUEST_TAKE_PHOTO:
if(resultCode== Activity.RESULT_OK)
{
String imagePath = imageCaptureManager.galleryAddPic();
if(imagePath!=null && PickerManager.getInstance().getMaxCount()==1)
{
PickerManager.getInstance().add(imagePath, FilePickerConst.FILE_TYPE_MEDIA);
mListener.onItemSelected();
}
else {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
getDataFromMedia();
}
}, 1000);
}
}
break;
}
}
private void resumeRequestsIfNotDestroyed() {
if (!AndroidLifecycleUtils.canLoadImage(this)) {
return;
}
mGlideRequestManager.resumeRequests();
}
}

View File

@@ -0,0 +1,265 @@
package de.beyondsoft.ownchat.filepicker.fragments;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.Nullable;
import android.support.v7.widget.DefaultItemAnimator;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.Toast;
import com.bumptech.glide.Glide;
import com.bumptech.glide.RequestManager;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
import de.beyondsoft.ownchat.filepicker.MediaDetailsActivity;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.adapters.FolderGridAdapter;
import de.beyondsoft.ownchat.filepicker.cursors.loadercallbacks.FileResultCallback;
import de.beyondsoft.ownchat.filepicker.models.ImageDirectory;
import de.beyondsoft.ownchat.filepicker.utils.AndroidLifecycleUtils;
import de.beyondsoft.ownchat.filepicker.utils.GridSpacingItemDecoration;
import de.beyondsoft.ownchat.filepicker.utils.ImageCaptureManager;
import de.beyondsoft.ownchat.filepicker.utils.MediaStoreHelper;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class MediaFolderPickerFragment extends BaseFragment implements FolderGridAdapter.FolderGridAdapterListener {
private static final String TAG = MediaFolderPickerFragment.class.getSimpleName();
private static final int SCROLL_THRESHOLD = 30;
RecyclerView recyclerView;
TextView emptyView;
private ImagePickerFragmentListener mListener;
private FolderGridAdapter photoGridAdapter;
private ImageCaptureManager imageCaptureManager;
private RequestManager mGlideRequestManager;
private int fileType;
public MediaFolderPickerFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_media_folder_picker, container, false);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof ImagePickerFragmentListener) {
mListener = (ImagePickerFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement PhotoPickerFragmentListener");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public static MediaFolderPickerFragment newInstance(int fileType) {
MediaFolderPickerFragment photoPickerFragment = new MediaFolderPickerFragment();
Bundle bun = new Bundle();
bun.putInt(FILE_TYPE, fileType);
photoPickerFragment.setArguments(bun);
return photoPickerFragment;
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGlideRequestManager = Glide.with(this);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView(view);
}
private void initView(View view) {
recyclerView = (RecyclerView) view.findViewById(R.id.recyclerview);
emptyView = (TextView) view.findViewById(R.id.empty_view);
fileType = getArguments().getInt(FILE_TYPE);
imageCaptureManager = new ImageCaptureManager(getActivity());
GridLayoutManager layoutManager = new GridLayoutManager(getActivity(), 2);
int spanCount = 2; // 2 columns
int spacing = 5; // 5px
boolean includeEdge = false;
recyclerView.addItemDecoration(new GridSpacingItemDecoration(spanCount, spacing, includeEdge));
recyclerView.setLayoutManager(layoutManager);
recyclerView.setItemAnimator(new DefaultItemAnimator());
recyclerView.addOnScrollListener(new RecyclerView.OnScrollListener() {
@Override public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
// Log.d(">>> Picker >>>", "dy = " + dy);
if (Math.abs(dy) > SCROLL_THRESHOLD) {
mGlideRequestManager.pauseRequests();
} else {
resumeRequestsIfNotDestroyed();
}
}
@Override public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
resumeRequestsIfNotDestroyed();
}
}
});
getDataFromMedia();
}
private void getDataFromMedia() {
Bundle mediaStoreArgs = new Bundle();
mediaStoreArgs.putBoolean(FilePickerConst.EXTRA_SHOW_GIF, PickerManager.getInstance().isShowGif());
mediaStoreArgs.putInt(FilePickerConst.EXTRA_FILE_TYPE, fileType);
if(fileType==FilePickerConst.MEDIA_TYPE_IMAGE) {
MediaStoreHelper.getPhotoDirs(getActivity(), mediaStoreArgs,
dirs -> updateList(dirs));
}
else if(fileType==FilePickerConst.MEDIA_TYPE_VIDEO)
{
MediaStoreHelper.getVideoDirs(getActivity(), mediaStoreArgs,
dirs -> updateList(dirs));
}
}
private void updateList(List<ImageDirectory> dirs) {
Log.i("updateList",""+dirs.size());
if(dirs.size()>0) {
emptyView.setVisibility(View.GONE);
recyclerView.setVisibility(View.VISIBLE);
}
else {
emptyView.setVisibility(View.VISIBLE);
recyclerView.setVisibility(View.GONE);
return;
}
ImageDirectory photoDirectory = new ImageDirectory();
photoDirectory.setBucketId(FilePickerConst.ALL_PHOTOS_BUCKET_ID);
if(fileType==FilePickerConst.MEDIA_TYPE_VIDEO)
{
photoDirectory.setName(getString(R.string.all_videos));
}
else if(fileType==FilePickerConst.MEDIA_TYPE_IMAGE)
{
photoDirectory.setName(getString(R.string.all_photos));
}
else {
photoDirectory.setName(getString(R.string.all_files));
}
if(dirs.size()>0 && dirs.get(0).getMedias().size()>0)
{
photoDirectory.setDateAdded(dirs.get(0).getDateAdded());
photoDirectory.setCoverPath(dirs.get(0).getMedias().get(0).getPath());
}
for (int i = 0; i < dirs.size(); i++) {
photoDirectory.addPhotos(dirs.get(i).getMedias());
}
dirs.add(0,photoDirectory);
if(photoGridAdapter!=null)
{
photoGridAdapter.setData(dirs);
photoGridAdapter.notifyDataSetChanged();
}
else
{
photoGridAdapter = new FolderGridAdapter(getActivity(), mGlideRequestManager, (ArrayList<ImageDirectory>) dirs, null, (fileType== FilePickerConst.MEDIA_TYPE_IMAGE) && PickerManager.getInstance().isEnableCamera());
recyclerView.setAdapter(photoGridAdapter);
photoGridAdapter.setFolderGridAdapterListener(this);
}
}
@Override
public void onCameraClicked() {
try {
Intent intent = imageCaptureManager.dispatchTakePictureIntent(getActivity());
if(intent!=null)
startActivityForResult(intent, ImageCaptureManager.REQUEST_TAKE_PHOTO);
else
Toast.makeText(getActivity(), R.string.no_camera_exists, Toast.LENGTH_SHORT).show();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onFolderClicked(ImageDirectory photoDirectory) {
Intent intent = new Intent(getActivity(), MediaDetailsActivity.class);
intent.putExtra(ImageDirectory.class.getSimpleName(),photoDirectory);
intent.putExtra(FilePickerConst.EXTRA_FILE_TYPE,fileType);
getActivity().startActivityForResult(intent, FilePickerConst.REQUEST_CODE_MEDIA_DETAIL);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode)
{
case ImageCaptureManager.REQUEST_TAKE_PHOTO:
if(resultCode== Activity.RESULT_OK)
{
String imagePath = imageCaptureManager.galleryAddPic();
if(imagePath!=null && PickerManager.getInstance().getMaxCount()==1)
{
PickerManager.getInstance().add(imagePath, FilePickerConst.FILE_TYPE_MEDIA);
mListener.onItemSelected();
}
else {
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
getDataFromMedia();
}
}, 1000);
}
}
break;
}
}
private void resumeRequestsIfNotDestroyed() {
if (!AndroidLifecycleUtils.canLoadImage(this)) {
return;
}
mGlideRequestManager.resumeRequests();
}
}

View File

@@ -0,0 +1,107 @@
package de.beyondsoft.ownchat.filepicker.fragments;
import android.content.Context;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.view.ViewPager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
import de.beyondsoft.ownchat.filepicker.PickerManager;
import de.beyondsoft.ownchat.filepicker.adapters.SectionsPagerAdapter;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class MediaPickerFragment extends BaseFragment {
TabLayout tabLayout;
ViewPager viewPager;
private MediaPickerFragmentListener mListener;
public MediaPickerFragment() {
// Required empty public constructor
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_media_picker, container, false);
}
@Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof MediaPickerFragmentListener) {
mListener = (MediaPickerFragmentListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement MediaPickerFragment");
}
}
@Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public static MediaPickerFragment newInstance() {
MediaPickerFragment photoPickerFragment = new MediaPickerFragment();
return photoPickerFragment;
}
public interface MediaPickerFragmentListener {
}
@Override
public void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onViewCreated(View view, @Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
initView(view);
}
private void initView(View view) {
tabLayout = view.findViewById(R.id.tabs);
viewPager = view.findViewById(R.id.viewPager);
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
SectionsPagerAdapter adapter = new SectionsPagerAdapter(getChildFragmentManager());
if(PickerManager.getInstance().showImages()) {
if (PickerManager.getInstance().isShowFolderView())
adapter.addFragment(MediaFolderPickerFragment.newInstance(FilePickerConst.MEDIA_TYPE_IMAGE), getString(R.string.images));
else
adapter.addFragment(MediaDetailPickerFragment.newInstance(FilePickerConst.MEDIA_TYPE_IMAGE), getString(R.string.images));
}
else
tabLayout.setVisibility(View.GONE);
if(PickerManager.getInstance().showVideo())
{
if(PickerManager.getInstance().isShowFolderView())
adapter.addFragment(MediaFolderPickerFragment.newInstance(FilePickerConst.MEDIA_TYPE_VIDEO), getString(R.string.videos));
else
adapter.addFragment(MediaDetailPickerFragment.newInstance(FilePickerConst.MEDIA_TYPE_VIDEO), getString(R.string.videos));
}
else
tabLayout.setVisibility(View.GONE);
viewPager.setAdapter(adapter);
tabLayout.setupWithViewPager(viewPager);
}
}

View File

@@ -0,0 +1,90 @@
package de.beyondsoft.ownchat.filepicker.models;
import android.os.Parcel;
import android.os.Parcelable;
import de.beyondsoft.ownchat.filepicker.utils.Utils;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class BaseFile implements Parcelable {
protected int id;
protected String name;
protected String path;
public BaseFile() {}
public BaseFile(int id, String name, String path) {
this.id = id;
this.name = name;
this.path = path;
}
protected BaseFile(Parcel in) {
id = in.readInt();
name = in.readString();
path = in.readString();
}
public static final Parcelable.Creator<BaseFile> CREATOR = new Parcelable.Creator<BaseFile>() {
@Override
public BaseFile createFromParcel(Parcel in) {
return new BaseFile(in);
}
@Override
public BaseFile[] newArray(int size) {
return new BaseFile[size];
}
};
public boolean isImage() {
String[] types = {"jpg","jpeg","png","gif"};
return Utils.contains(types, this.path);
}
@Override
public boolean equals(Object o) {
if(this == o) {
return true;
}
if(!(o instanceof BaseFile)) {
return false;
}
BaseFile baseFile = (BaseFile) o;
return id == baseFile.id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeInt(id);
parcel.writeString(name);
parcel.writeString(path);
}
}

View File

@@ -0,0 +1,92 @@
package de.beyondsoft.ownchat.filepicker.models;
import java.io.File;
import de.beyondsoft.ownchat.filepicker.utils.Utils;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class Document extends BaseFile {
private String mimeType;
private String size;
private FileType fileType;
public Document(int id, String title, String path) {
super(id,title,path);
}
public Document() {
super(0,null,null);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Document)) return false;
Document document = (Document) o;
return id == document.id;
}
@Override
public int hashCode() {
return id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMimeType() {
return mimeType;
}
public void setMimeType(String mimeType) {
this.mimeType = mimeType;
}
public String getSize() {
return size;
}
public void setSize(String size) {
this.size = size;
}
public String getTitle() {
return new File(this.path).getName();
}
public void setTitle(String title) {
this.name = title;
}
public boolean isThisType(String[] types)
{
return Utils.contains(types, this.path);
}
public FileType getFileType()
{
return fileType;
}
public void setFileType(FileType fileType) {
this.fileType = fileType;
}
}

View File

@@ -0,0 +1,65 @@
package de.beyondsoft.ownchat.filepicker.models;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.DrawableRes;
import de.beyondsoft.ownchat.R;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class FileType implements Parcelable {
public String title;
@DrawableRes
public int drawable;
public String[] extensions;
public FileType(String title, String[] extensions, int drawable) {
this.title = title;
this.extensions = extensions;
this.drawable = drawable;
}
protected FileType(Parcel in) {
title = in.readString();
drawable = in.readInt();
extensions = in.createStringArray();
}
public static final Parcelable.Creator<FileType> CREATOR = new Parcelable.Creator<FileType>() {
@Override
public FileType createFromParcel(Parcel in) {
return new FileType(in);
}
@Override
public FileType[] newArray(int size) {
return new FileType[size];
}
};
public int getDrawable()
{
if(drawable == 0) {
return R.drawable.document;
}
return drawable;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(title);
parcel.writeInt(drawable);
parcel.writeStringArray(extensions);
}
}

View File

@@ -0,0 +1,172 @@
package de.beyondsoft.ownchat.filepicker.models;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
import java.util.ArrayList;
import java.util.List;
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class ImageDirectory extends BaseFile implements Parcelable {
private String bucketId;
private String coverPath;
private String name;
private long dateAdded;
private List<Media> medias = new ArrayList<>();
public ImageDirectory()
{
super();
}
public ImageDirectory(int id, String name, String path) {
super(id, name, path);
}
protected ImageDirectory(Parcel in) {
bucketId = in.readString();
coverPath = in.readString();
name = in.readString();
dateAdded = in.readLong();
}
public static final Creator<ImageDirectory> CREATOR = new Creator<ImageDirectory>() {
@Override
public ImageDirectory createFromParcel(Parcel in) {
return new ImageDirectory(in);
}
@Override
public ImageDirectory[] newArray(int size) {
return new ImageDirectory[size];
}
};
@Override
public boolean equals(Object o) {
if(this == o) {
return true;
}
if(!(o instanceof ImageDirectory)) {
return false;
}
ImageDirectory directory = (ImageDirectory) o;
boolean hasId = !TextUtils.isEmpty(bucketId);
boolean otherHasId = !TextUtils.isEmpty(directory.bucketId);
return hasId && otherHasId && TextUtils.equals(bucketId, directory.bucketId) && TextUtils.equals(name, directory.name);
}
@Override
public int hashCode() {
if (TextUtils.isEmpty(bucketId)) {
if (TextUtils.isEmpty(name)) {
return 0;
}
return name.hashCode();
}
int result = bucketId.hashCode();
if (TextUtils.isEmpty(name)) {
return result;
}
result = 31 * result + name.hashCode();
return result;
}
public String getCoverPath() {
if(medias!=null && medias.size()>0) {
return medias.get(0).getPath();
}
return coverPath;
}
public void setCoverPath(String coverPath) {
this.coverPath = coverPath;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public long getDateAdded() {
return dateAdded;
}
public void setDateAdded(long dateAdded) {
this.dateAdded = dateAdded;
}
public List<Media> getMedias() {
return medias;
}
public void setMedias(List<Media> medias) {
this.medias = medias;
}
public List<String> getPhotoPaths() {
List<String> paths = new ArrayList<>(medias.size());
for (Media media : medias) {
paths.add(media.getPath());
}
return paths;
}
public void addPhoto(int id, String name, String path, int mediaType) {
medias.add(new Media(id, name, path, mediaType));
}
public void addPhoto(Media media) {
medias.add(media);
}
public void addPhotos(List<Media> photosList) {
medias.addAll(photosList);
}
public String getBucketId() {
if(bucketId.equals(FilePickerConst.ALL_PHOTOS_BUCKET_ID)) {
return null;
}
return bucketId;
}
public void setBucketId(String bucketId) {
this.bucketId = bucketId;
}
@Override
public int describeContents() {
return 0;
}
@Override
public void writeToParcel(Parcel parcel, int i) {
parcel.writeString(bucketId);
parcel.writeString(coverPath);
parcel.writeString(name);
parcel.writeLong(dateAdded);
}
}

View File

@@ -0,0 +1,65 @@
package de.beyondsoft.ownchat.filepicker.models;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class Media extends BaseFile {
public int mediaType;
public Media(int id, String name, String path, int mediaType) {
super(id, name, path);
this.mediaType = mediaType;
}
public Media() {
super(0,null,null);
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Media)) return false;
Media media = (Media) o;
return id == media.id;
}
@Override
public int hashCode() {
return id;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getMediaType() {
return mediaType;
}
public void setMediaType(int mediaType) {
this.mediaType = mediaType;
}
}

View File

@@ -0,0 +1,45 @@
package de.beyondsoft.ownchat.filepicker.utils;
import android.app.Activity;
import android.content.Context;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentActivity;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class AndroidLifecycleUtils {
public static boolean canLoadImage(Fragment fragment) {
if (fragment == null) {
return true;
}
FragmentActivity activity = fragment.getActivity();
return canLoadImage(activity);
}
public static boolean canLoadImage(Context context) {
if (context == null) {
return true;
}
if (!(context instanceof Activity)) {
return true;
}
Activity activity = (Activity) context;
return canLoadImage(activity);
}
private static boolean canLoadImage(Activity activity) {
if (activity == null) {
return true;
}
boolean destroyed = activity.isDestroyed();
return !(destroyed || activity.isFinishing());
}
}

View File

@@ -0,0 +1,10 @@
package de.beyondsoft.ownchat.filepicker.utils;
import android.support.v4.content.FileProvider;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class FilePickerProvider extends FileProvider {
}

View File

@@ -0,0 +1,72 @@
package de.beyondsoft.ownchat.filepicker.utils;
import android.text.TextUtils;
import java.io.File;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class FileUtils {
public static int getTypeDrawable(String path) {
return R.drawable.document;
}
public static FilePickerConst.FILE_TYPE getFileType(String path) {
String fileExtension = Utils.getFileExtension(new File(path));
if(TextUtils.isEmpty(fileExtension)) {
return FilePickerConst.FILE_TYPE.UNKNOWN;
}
if(isExcelFile(path)) {
return FilePickerConst.FILE_TYPE.EXCEL;
}
if(isDocFile(path)) {
return FilePickerConst.FILE_TYPE.WORD;
}
if(isPPTFile(path)) {
return FilePickerConst.FILE_TYPE.PPT;
}
if(isPDFFile(path)) {
return FilePickerConst.FILE_TYPE.PDF;
}
if(isTxtFile(path)) {
return FilePickerConst.FILE_TYPE.TXT;
} else {
return FilePickerConst.FILE_TYPE.UNKNOWN;
}
}
public static boolean isExcelFile(String path) {
String[] types = {"xls","xlsx"};
return Utils.contains(types, path);
}
public static boolean isDocFile(String path) {
String[] types = {"doc","docx", "dot","dotx"};
return Utils.contains(types, path);
}
public static boolean isPPTFile(String path) {
String[] types = {"ppt","pptx"};
return Utils.contains(types, path);
}
public static boolean isPDFFile(String path) {
String[] types = {"pdf"};
return Utils.contains(types, path);
}
public static boolean isTxtFile(String path) {
String[] types = {"txt"};
return Utils.contains(types, path);
}
}

View File

@@ -0,0 +1,76 @@
package de.beyondsoft.ownchat.filepicker.utils;
import android.support.v4.app.Fragment;
import android.support.v4.app.FragmentTransaction;
import android.support.v7.app.AppCompatActivity;
import de.beyondsoft.ownchat.R;
import de.beyondsoft.ownchat.page.common.BaseFragment;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class FragmentUtil {
public static boolean hadFragment(AppCompatActivity activity) {
return activity.getSupportFragmentManager().getBackStackEntryCount() != 0;
}
public static void replaceFragment(AppCompatActivity activity, int contentId, BaseFragment fragment) {
FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_left_in, R.anim.slide_left_out);
transaction.replace(contentId, fragment, fragment.getClass().getSimpleName());
transaction.addToBackStack(null);
transaction.commit();
}
public static void addFragment(AppCompatActivity activity, int contentId, BaseFragment fragment) {
FragmentTransaction transaction = activity.getSupportFragmentManager().beginTransaction();
transaction.setCustomAnimations(R.anim.slide_left_in, R.anim.slide_left_out);
transaction.add(contentId, fragment, fragment.getClass().getSimpleName());
transaction.commit();
}
public static void removeFragment(AppCompatActivity activity, BaseFragment fragment) {
activity.getSupportFragmentManager().beginTransaction()
.remove(fragment)
.commit();
}
public static void showFragment(AppCompatActivity activity, BaseFragment fragment) {
activity.getSupportFragmentManager().beginTransaction()
.show(fragment)
.commit();
}
public static void hideFragment(AppCompatActivity activity, BaseFragment fragment) {
activity.getSupportFragmentManager().beginTransaction()
.hide(fragment)
.commit();
}
public static void attachFragment(AppCompatActivity activity, BaseFragment fragment) {
activity.getSupportFragmentManager().beginTransaction()
.attach(fragment)
.commit();
}
public static void detachFragment(AppCompatActivity activity, BaseFragment fragment) {
activity.getSupportFragmentManager().beginTransaction()
.detach(fragment)
.commit();
}
public static Fragment getFragmentByTag(AppCompatActivity appCompatActivity, String tag)
{
return appCompatActivity.getSupportFragmentManager().findFragmentByTag(tag);
}
}

View File

@@ -0,0 +1,43 @@
package de.beyondsoft.ownchat.filepicker.utils;
import android.graphics.Rect;
import android.support.v7.widget.RecyclerView;
import android.view.View;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class GridSpacingItemDecoration extends RecyclerView.ItemDecoration {
private int spanCount;
private int spacing;
private boolean includeEdge;
public GridSpacingItemDecoration(int spanCount, int spacing, boolean includeEdge) {
this.spanCount = spanCount;
this.spacing = spacing;
this.includeEdge = includeEdge;
}
@Override
public void getItemOffsets(Rect outRect, View view, RecyclerView parent, RecyclerView.State state) {
int position = parent.getChildAdapterPosition(view); // item position
int column = position % spanCount; // item column
if (includeEdge) {
outRect.left = spacing - column * spacing / spanCount; // spacing - column * ((1f / spanCount) * spacing)
outRect.right = (column + 1) * spacing / spanCount; // (column + 1) * ((1f / spanCount) * spacing)
if (position < spanCount) { // top edge
outRect.top = spacing;
}
outRect.bottom = spacing; // item bottom
} else {
outRect.left = column * spacing / spanCount; // column * ((1f / spanCount) * spacing)
outRect.right = spacing - (column + 1) * spacing / spanCount; // spacing - (column + 1) * ((1f / spanCount) * spacing)
if (position >= spanCount) {
outRect.top = spacing; // item top
}
}
}
}

View File

@@ -0,0 +1,123 @@
package de.beyondsoft.ownchat.filepicker.utils;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.text.TextUtils;
import android.util.Log;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import de.beyondsoft.ownchat.filepicker.PickerManager;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class ImageCaptureManager {
private final static String CAPTURED_PHOTO_PATH_KEY = "mCurrentPhotoPath";
public static final int REQUEST_TAKE_PHOTO = 0x101;
private String mCurrentPhotoPath;
private Context mContext;
public ImageCaptureManager(Context mContext) {
this.mContext = mContext;
}
private File createImageFile() throws IOException {
// Create an image file name
// String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.ENGLISH).format(new Date());
String imageFileName = "JPEG_" + System.currentTimeMillis() + ".jpg";
File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
if (!storageDir.exists()) {
if (!storageDir.mkdir()) {
Log.e("TAG", "Throwing Errors....");
throw new IOException();
}
}
File image = new File(storageDir, imageFileName);
// File.createTempFile(
// imageFileName, /* prefix */
// ".jpg", /* suffix */
// storageDir /* directory */
// );
// Save a file: path for use with ACTION_VIEW intents
mCurrentPhotoPath = image.getAbsolutePath();
return image;
}
public Intent dispatchTakePictureIntent(Context context) throws IOException {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
// Ensure that there's a camera activity to handle the intent
if (takePictureIntent.resolveActivity(mContext.getPackageManager()) != null) {
// Create the File where the photo should go
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
File newFile = createImageFile();
takePictureIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
Uri photoURI = FileProvider.getUriForFile(context, PickerManager.getInstance().getProviderAuthorities(), newFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
} else {
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(createImageFile()));
}
return takePictureIntent;
}
return null;
}
public String galleryAddPic() {
Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
if (TextUtils.isEmpty(mCurrentPhotoPath)) {
return null;
}
File f = new File(mCurrentPhotoPath);
Uri contentUri = Uri.fromFile(f);
mediaScanIntent.setData(contentUri);
mContext.sendBroadcast(mediaScanIntent);
return mCurrentPhotoPath;
}
public final void notifyMediaStoreScanner(Context mContext, final File file) {
try {
MediaStore.Images.Media.insertImage(mContext.getContentResolver(),
file.getAbsolutePath(), file.getName(), null);
mContext.sendBroadcast(new Intent(
Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(file)));
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
public String getCurrentPhotoPath() {
return mCurrentPhotoPath;
}
public void onSaveInstanceState(Bundle savedInstanceState) {
if (savedInstanceState != null && mCurrentPhotoPath != null) {
savedInstanceState.putString(CAPTURED_PHOTO_PATH_KEY, mCurrentPhotoPath);
}
}
public void onRestoreInstanceState(Bundle savedInstanceState) {
if (savedInstanceState != null && savedInstanceState.containsKey(CAPTURED_PHOTO_PATH_KEY)) {
mCurrentPhotoPath = savedInstanceState.getString(CAPTURED_PHOTO_PATH_KEY);
}
}
}

View File

@@ -0,0 +1,37 @@
package de.beyondsoft.ownchat.filepicker.utils;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
import de.beyondsoft.ownchat.filepicker.cursors.DocScannerTask;
import de.beyondsoft.ownchat.filepicker.cursors.loadercallbacks.FileResultCallback;
import de.beyondsoft.ownchat.filepicker.cursors.loadercallbacks.ImageDirLoaderCallback;
import de.beyondsoft.ownchat.filepicker.models.Document;
import de.beyondsoft.ownchat.filepicker.models.ImageDirectory;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class MediaStoreHelper {
public static void getPhotoDirs(FragmentActivity activity, Bundle args, FileResultCallback<ImageDirectory> resultCallback) {
if(activity.getSupportLoaderManager().getLoader(FilePickerConst.MEDIA_TYPE_IMAGE)!=null) {
activity.getSupportLoaderManager().restartLoader(FilePickerConst.MEDIA_TYPE_IMAGE, args, new ImageDirLoaderCallback(activity, resultCallback));
} else {
activity.getSupportLoaderManager().initLoader(FilePickerConst.MEDIA_TYPE_IMAGE, args, new ImageDirLoaderCallback(activity, resultCallback));
}
}
public static void getVideoDirs(FragmentActivity activity, Bundle args, FileResultCallback<ImageDirectory> resultCallback) {
if(activity.getSupportLoaderManager().getLoader(FilePickerConst.MEDIA_TYPE_VIDEO)!=null) {
activity.getSupportLoaderManager().restartLoader(FilePickerConst.MEDIA_TYPE_VIDEO, args, new ImageDirLoaderCallback(activity, resultCallback));
} else {
activity.getSupportLoaderManager().initLoader(FilePickerConst.MEDIA_TYPE_VIDEO, args, new ImageDirLoaderCallback(activity, resultCallback));
}
}
public static void getDocs(FragmentActivity activity, FileResultCallback<Document> fileResultCallback) {
new DocScannerTask(activity,fileResultCallback).execute();
}
}

View File

@@ -0,0 +1,11 @@
package de.beyondsoft.ownchat.filepicker.utils;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public enum Orientation {
PORTRAIT_ONLY,
LANDSCAPE_ONLY,
UNSPECIFIED
}

View File

@@ -0,0 +1,483 @@
package de.beyondsoft.ownchat.filepicker.utils;
import android.database.DataSetObserver;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.design.widget.TabLayout;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import java.lang.ref.WeakReference;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class TabLayoutHelper {
protected TabLayout mTabLayout;
protected ViewPager mViewPager;
protected TabLayout.OnTabSelectedListener mUserOnTabSelectedListener;
protected TabLayout.OnTabSelectedListener mInternalOnTabSelectedListener;
protected FixedTabLayoutOnPageChangeListener mInternalTabLayoutOnPageChangeListener;
protected ViewPager.OnAdapterChangeListener mInternalOnAdapterChangeListener;
protected DataSetObserver mInternalDataSetObserver;
protected Runnable mAdjustTabModeRunnable;
protected Runnable mSetTabsFromPagerAdapterRunnable;
protected Runnable mUpdateScrollPositionRunnable;
protected boolean mAutoAdjustTabMode = false;
protected boolean mDuringSetTabsFromPagerAdapter;
public TabLayoutHelper(@NonNull TabLayout tabLayout, @NonNull ViewPager viewPager) {
PagerAdapter adapter = viewPager.getAdapter();
if (adapter == null) {
throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
}/**/
mTabLayout = tabLayout;
mViewPager = viewPager;
mInternalDataSetObserver = new DataSetObserver() {
@Override
public void onChanged() {
handleOnDataSetChanged();
}
};
mInternalOnTabSelectedListener = new TabLayout.OnTabSelectedListener() {
@Override
public void onTabSelected(TabLayout.Tab tab) {
handleOnTabSelected(tab);
}
@Override
public void onTabUnselected(TabLayout.Tab tab) {
handleOnTabUnselected(tab);
}
@Override
public void onTabReselected(TabLayout.Tab tab) {
handleOnTabReselected(tab);
}
};
mInternalTabLayoutOnPageChangeListener = new FixedTabLayoutOnPageChangeListener(mTabLayout);
mInternalOnAdapterChangeListener = new ViewPager.OnAdapterChangeListener() {
@Override
public void onAdapterChanged(@NonNull ViewPager viewPager, @Nullable PagerAdapter oldAdapter, @Nullable PagerAdapter newAdapter) {
handleOnAdapterChanged(viewPager, oldAdapter, newAdapter);
}
};
setupWithViewPager(mTabLayout, mViewPager);
}
public TabLayout getTabLayout() {
return mTabLayout;
}
public ViewPager getViewPager() {
return mViewPager;
}
public void setAutoAdjustTabModeEnabled(boolean enabled) {
if (mAutoAdjustTabMode == enabled) {
return;
}
mAutoAdjustTabMode = enabled;
if (mAutoAdjustTabMode) {
adjustTabMode(-1);
} else {
cancelPendingAdjustTabMode();
}
}
public boolean isAutoAdjustTabModeEnabled() {
return mAutoAdjustTabMode;
}
@Deprecated
public void setOnTabSelectedListener(TabLayout.OnTabSelectedListener listener) {
mUserOnTabSelectedListener = listener;
}
public void release() {
cancelPendingAdjustTabMode();
cancelPendingSetTabsFromPagerAdapter();
cancelPendingUpdateScrollPosition();
if (mInternalOnAdapterChangeListener != null) {
mViewPager.removeOnAdapterChangeListener(mInternalOnAdapterChangeListener);
mInternalOnAdapterChangeListener = null;
}
if (mInternalDataSetObserver != null) {
mViewPager.getAdapter().unregisterDataSetObserver(mInternalDataSetObserver);
mInternalDataSetObserver = null;
}
if (mInternalOnTabSelectedListener != null) {
mTabLayout.removeOnTabSelectedListener(mInternalOnTabSelectedListener);
mInternalOnTabSelectedListener = null;
}
if (mInternalTabLayoutOnPageChangeListener != null) {
mViewPager.removeOnPageChangeListener(mInternalTabLayoutOnPageChangeListener);
mInternalTabLayoutOnPageChangeListener = null;
}
mUserOnTabSelectedListener = null;
mViewPager = null;
mTabLayout = null;
}
public void updateAllTabs() {
int count = mTabLayout.getTabCount();
for (int i = 0; i < count; i++) {
updateTab(mTabLayout.getTabAt(i));
}
}
protected TabLayout.Tab onCreateTab(TabLayout tabLayout, PagerAdapter adapter, int position) {
TabLayout.Tab tab = tabLayout.newTab();
tab.setText(adapter.getPageTitle(position));
return tab;
}
private void onUpdateTab(TabLayout.Tab tab) {
if (tab.getCustomView() == null) {
tab.setCustomView(null); // invokes update() method internally.
}
}
private void handleOnDataSetChanged() {
cancelPendingUpdateScrollPosition();
cancelPendingSetTabsFromPagerAdapter();
if (mSetTabsFromPagerAdapterRunnable == null) {
mSetTabsFromPagerAdapterRunnable = new Runnable() {
@Override
public void run() {
setTabsFromPagerAdapter(mTabLayout, mViewPager.getAdapter(), mViewPager.getCurrentItem());
}
};
}
mTabLayout.post(mSetTabsFromPagerAdapterRunnable);
}
private void handleOnTabSelected(TabLayout.Tab tab) {
if (mDuringSetTabsFromPagerAdapter) {
return;
}
mViewPager.setCurrentItem(tab.getPosition());
cancelPendingUpdateScrollPosition();
if (mUserOnTabSelectedListener != null) {
mUserOnTabSelectedListener.onTabSelected(tab);
}
}
private void handleOnTabUnselected(TabLayout.Tab tab) {
if (mDuringSetTabsFromPagerAdapter) {
return;
}
if (mUserOnTabSelectedListener != null) {
mUserOnTabSelectedListener.onTabUnselected(tab);
}
}
private void handleOnTabReselected(TabLayout.Tab tab) {
if (mDuringSetTabsFromPagerAdapter) {
return;
}
if (mUserOnTabSelectedListener != null) {
mUserOnTabSelectedListener.onTabReselected(tab);
}
}
protected void handleOnAdapterChanged(ViewPager viewPager, PagerAdapter oldAdapter, PagerAdapter newAdapter) {
if (mViewPager != viewPager) {
return;
}
if (oldAdapter != null) {
oldAdapter.unregisterDataSetObserver(mInternalDataSetObserver);
}
if (newAdapter != null) {
newAdapter.registerDataSetObserver(mInternalDataSetObserver);
}
setTabsFromPagerAdapter(mTabLayout, newAdapter, mViewPager.getCurrentItem());
}
protected void cancelPendingAdjustTabMode() {
if (mAdjustTabModeRunnable != null) {
mTabLayout.removeCallbacks(mAdjustTabModeRunnable);
mAdjustTabModeRunnable = null;
}
}
protected void cancelPendingSetTabsFromPagerAdapter() {
if (mSetTabsFromPagerAdapterRunnable != null) {
mTabLayout.removeCallbacks(mSetTabsFromPagerAdapterRunnable);
mSetTabsFromPagerAdapterRunnable = null;
}
}
protected void cancelPendingUpdateScrollPosition() {
if (mUpdateScrollPositionRunnable != null) {
mTabLayout.removeCallbacks(mUpdateScrollPositionRunnable);
mUpdateScrollPositionRunnable = null;
}
}
protected void adjustTabMode(int prevScrollX) {
if (mAdjustTabModeRunnable != null) {
return;
}
if (prevScrollX < 0) {
prevScrollX = mTabLayout.getScrollX();
}
if (ViewCompat.isLaidOut(mTabLayout)) {
adjustTabModeInternal(mTabLayout, prevScrollX);
} else {
final int prevScrollX1 = prevScrollX;
mAdjustTabModeRunnable = new Runnable() {
@Override
public void run() {
mAdjustTabModeRunnable = null;
adjustTabModeInternal(mTabLayout, prevScrollX1);
}
};
mTabLayout.post(mAdjustTabModeRunnable);
}
}
protected TabLayout.Tab createNewTab(TabLayout tabLayout, PagerAdapter adapter, int position) {
return onCreateTab(tabLayout, adapter, position);
}
protected void setupWithViewPager(@NonNull TabLayout tabLayout, @NonNull ViewPager viewPager) {
final PagerAdapter adapter = viewPager.getAdapter();
if (adapter == null) {
throw new IllegalArgumentException("ViewPager does not have a PagerAdapter set");
}
setTabsFromPagerAdapter(tabLayout, adapter, viewPager.getCurrentItem());
viewPager.getAdapter().registerDataSetObserver(mInternalDataSetObserver);
viewPager.addOnPageChangeListener(mInternalTabLayoutOnPageChangeListener);
viewPager.addOnAdapterChangeListener(mInternalOnAdapterChangeListener);
tabLayout.addOnTabSelectedListener(mInternalOnTabSelectedListener);
}
protected void setTabsFromPagerAdapter(@NonNull TabLayout tabLayout, @Nullable PagerAdapter adapter, int currentItem) {
try {
mDuringSetTabsFromPagerAdapter = true;
int prevSelectedTab = tabLayout.getSelectedTabPosition();
int prevScrollX = tabLayout.getScrollX();
// remove all tabs
tabLayout.removeAllTabs();
// add tabs
if (adapter != null) {
int count = adapter.getCount();
for (int i = 0; i < count; i++) {
TabLayout.Tab tab = createNewTab(tabLayout, adapter, i);
tabLayout.addTab(tab, false);
updateTab(tab);
}
// select current tab
currentItem = Math.min(currentItem, count - 1);
if (currentItem >= 0) {
tabLayout.getTabAt(currentItem).select();
}
}
// adjust tab mode & gravity
if (mAutoAdjustTabMode) {
adjustTabMode(prevScrollX);
} else {
// restore scroll position if needed
int curTabMode = tabLayout.getTabMode();
if (curTabMode == TabLayout.MODE_SCROLLABLE) {
tabLayout.scrollTo(prevScrollX, 0);
}
}
} finally {
mDuringSetTabsFromPagerAdapter = false;
}
}
protected void updateTab(TabLayout.Tab tab) {
onUpdateTab(tab);
}
protected int determineTabMode(@NonNull TabLayout tabLayout) {
LinearLayout slidingTabStrip = (LinearLayout) tabLayout.getChildAt(0);
int childCount = slidingTabStrip.getChildCount();
// NOTE: slidingTabStrip.getMeasuredWidth() method does not return correct width!
// Need to measure each tabs and calculate the sum of them.
int tabLayoutWidth = tabLayout.getMeasuredWidth() - tabLayout.getPaddingLeft() - tabLayout.getPaddingRight();
int tabLayoutHeight = tabLayout.getMeasuredHeight() - tabLayout.getPaddingTop() - tabLayout.getPaddingBottom();
if (childCount == 0) {
return TabLayout.MODE_FIXED;
}
int stripWidth = 0;
int maxWidthTab = 0;
int tabHeightMeasureSpec = View.MeasureSpec.makeMeasureSpec(tabLayoutHeight, View.MeasureSpec.EXACTLY);
for (int i = 0; i < childCount; i++) {
View tabView = slidingTabStrip.getChildAt(i);
tabView.measure(View.MeasureSpec.UNSPECIFIED, tabHeightMeasureSpec);
int tabWidth = tabView.getMeasuredWidth();
stripWidth += tabWidth;
maxWidthTab = Math.max(maxWidthTab, tabWidth);
}
return ((stripWidth < tabLayoutWidth) && (maxWidthTab < (tabLayoutWidth / childCount)))
? TabLayout.MODE_FIXED : TabLayout.MODE_SCROLLABLE;
}
protected void adjustTabModeInternal(@NonNull TabLayout tabLayout, int prevScrollX) {
int prevTabMode = tabLayout.getTabMode();
tabLayout.setTabMode(TabLayout.MODE_SCROLLABLE);
tabLayout.setTabGravity(TabLayout.GRAVITY_CENTER);
int newTabMode = determineTabMode(tabLayout);
cancelPendingUpdateScrollPosition();
if (newTabMode == TabLayout.MODE_FIXED) {
tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
tabLayout.setTabMode(TabLayout.MODE_FIXED);
} else {
LinearLayout slidingTabStrip = (LinearLayout) tabLayout.getChildAt(0);
slidingTabStrip.setGravity(Gravity.CENTER_HORIZONTAL);
if (prevTabMode == TabLayout.MODE_SCROLLABLE) {
// restore scroll position
tabLayout.scrollTo(prevScrollX, 0);
} else {
// scroll to current selected tab
mUpdateScrollPositionRunnable = new Runnable() {
@Override
public void run() {
mUpdateScrollPositionRunnable = null;
updateScrollPosition();
}
};
mTabLayout.post(mUpdateScrollPositionRunnable);
}
}
}
private void updateScrollPosition() {
mTabLayout.setScrollPosition(mTabLayout.getSelectedTabPosition(), 0, false);
}
protected static class FixedTabLayoutOnPageChangeListener implements ViewPager.OnPageChangeListener {
private final WeakReference<TabLayout> mTabLayoutRef;
private int mPreviousScrollState;
private int mScrollState;
public FixedTabLayoutOnPageChangeListener(TabLayout tabLayout) {
mTabLayoutRef = new WeakReference<>(tabLayout);
}
@Override
public void onPageScrollStateChanged(int state) {
mPreviousScrollState = mScrollState;
mScrollState = state;
}
@Override
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
final TabLayout tabLayout = mTabLayoutRef.get();
if (tabLayout != null) {
if (shouldUpdateScrollPosition()) {
// Update the scroll position, only update the text selection if we're being
// dragged (or we're settling after a drag)
final boolean updateText = (mScrollState == ViewPager.SCROLL_STATE_DRAGGING)
|| (mScrollState == ViewPager.SCROLL_STATE_SETTLING
&& mPreviousScrollState == ViewPager.SCROLL_STATE_DRAGGING);
tabLayout.setScrollPosition(position, positionOffset, updateText);
}
}
}
@Override
public void onPageSelected(int position) {
final TabLayout tabLayout = mTabLayoutRef.get();
if (tabLayout != null && tabLayout.getSelectedTabPosition() != position) {
// Select the tab, only updating the indicator if we're not being dragged/settled
// (since onPageScrolled will handle that).
Internal.selectTab(tabLayout, tabLayout.getTabAt(position),
mScrollState == ViewPager.SCROLL_STATE_IDLE);
}
}
private boolean shouldUpdateScrollPosition() {
return (mScrollState == ViewPager.SCROLL_STATE_DRAGGING) ||
((mScrollState == ViewPager.SCROLL_STATE_SETTLING) && (mPreviousScrollState == ViewPager.SCROLL_STATE_DRAGGING));
}
}
static class Internal {
private static final Method mMethodSelectTab;
static {
mMethodSelectTab = getAccessiblePrivateMethod(TabLayout.class, "selectTab", TabLayout.Tab.class, boolean.class);
}
private static Method getAccessiblePrivateMethod(Class<?> targetClass, String methodName, Class<?>... params) throws RuntimeException {
try {
Method m = targetClass.getDeclaredMethod(methodName, params);
m.setAccessible(true);
return m;
} catch (NoSuchMethodException e) {
throw new IllegalStateException(e);
}
}
public static void selectTab(TabLayout tabLayout, TabLayout.Tab tab, boolean updateIndicator) {
try {
mMethodSelectTab.invoke(tabLayout, tab, updateIndicator);
} catch (IllegalAccessException e) {
new IllegalStateException(e);
} catch (InvocationTargetException e) {
throw handleInvocationTargetException(e);
}
}
private static RuntimeException handleInvocationTargetException(InvocationTargetException e) {
Throwable targetException = e.getTargetException();
if (targetException instanceof RuntimeException) {
throw (RuntimeException) targetException;
} else {
throw new IllegalStateException(targetException);
}
}
}
}

View File

@@ -0,0 +1,81 @@
package de.beyondsoft.ownchat.filepicker.utils;
import android.content.Context;
import android.graphics.Point;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.WindowManager;
import com.android.internal.util.Predicate;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class Utils {
public static <T> Collection<T> filter(Collection<T> target, Predicate<T> predicate) {
Collection<T> result = new ArrayList<T>();
for (T element: target) {
if (predicate.apply(element)) {
result.add(element);
}
}
return result;
}
static String getFileExtension(File file) {
String name = file.getName();
try {
return name.substring(name.lastIndexOf(".") + 1);
} catch (Exception e) {
return "";
}
}
public static boolean contains(String[] types, String path) {
for (String string : types) {
if (path.toLowerCase().endsWith(string)) return true;
}
return false;
}
private static final int WIDTH_INDEX = 0;
private static final int HEIGHT_INDEX = 1;
public static int[] getScreenSize(Context context) {
int[] widthHeight = new int[2];
widthHeight[WIDTH_INDEX] = 0;
widthHeight[HEIGHT_INDEX] = 0;
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
widthHeight[WIDTH_INDEX] = size.x;
widthHeight[HEIGHT_INDEX] = size.y;
if (!isScreenSizeRetrieved(widthHeight)) {
DisplayMetrics metrics = new DisplayMetrics();
display.getMetrics(metrics);
widthHeight[0] = metrics.widthPixels;
widthHeight[1] = metrics.heightPixels;
}
// Last defense. Use deprecated API that was introduced in lower than API 13
if (!isScreenSizeRetrieved(widthHeight)) {
widthHeight[0] = display.getWidth(); // deprecated
widthHeight[1] = display.getHeight(); // deprecated
}
return widthHeight;
}
private static boolean isScreenSizeRetrieved(int[] widthHeight) {
return widthHeight[WIDTH_INDEX] != 0 && widthHeight[HEIGHT_INDEX] != 0;
}
}

View File

@@ -0,0 +1,35 @@
package de.beyondsoft.ownchat.filepicker.views;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.RelativeLayout;
/**
* Created by Lyndon on 26-Oct-2017.
*/
public class SquareRelativeLayout extends RelativeLayout {
public SquareRelativeLayout(Context context) {
super(context);
}
public SquareRelativeLayout(Context context, AttributeSet attrs) {
super(context, attrs);
}
public SquareRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public SquareRelativeLayout(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
super(context, attrs, defStyleAttr, defStyleRes);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, widthMeasureSpec);
}
}

View File

@@ -269,14 +269,10 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha
}
private void selectFile(int requestCode) {
Intent intent;
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
} else {
intent = new Intent(Intent.ACTION_GET_CONTENT);
}
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:duration="300" android:fromXDelta="100.0%p" android:toXDelta="0.0" />
</set>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<set xmlns:android="http://schemas.android.com/apk/res/android">
<translate android:duration="300" android:fromXDelta="0.0" android:toXDelta="-100.0%p" />
</set>

Binary file not shown.

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 128 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 162 KiB

View File

@@ -0,0 +1,14 @@
<?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">
<FrameLayout
android:id="@+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent">
</FrameLayout>
</LinearLayout>

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@android:color/white"
/>
<TextView
android:id="@+id/empty_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:text="@string/no_files_found"
android:textSize="25sp"
android:textStyle="bold"
android:visibility="gone"
/>
</RelativeLayout>

View File

@@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/PickerTabLayout">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tabs"/>
<ProgressBar
android:id="@+id/progress_bar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"/>
</RelativeLayout>

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<TextView
android:id="@+id/empty_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:text="@string/no_files_found"
android:textSize="25sp"
android:textStyle="bold"
android:visibility="gone"
/>
</RelativeLayout>

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@android:color/white">
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<TextView
android:id="@+id/empty_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:gravity="center_horizontal"
android:text="@string/no_files_found"
android:textSize="25sp"
android:textStyle="bold"
android:visibility="gone"
/>
</RelativeLayout>

View File

@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.TabLayout
android:id="@+id/tabs"
android:layout_width="match_parent"
android:layout_height="wrap_content"
style="@style/PickerTabLayout">
</android.support.design.widget.TabLayout>
<android.support.v4.view.ViewPager
android:id="@+id/viewPager"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@+id/tabs"/>
</RelativeLayout>

View File

@@ -1,5 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
<TextView
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/chat_item_date"
android:layout_width="match_parent"

View File

@@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools">
<ImageView
android:id="@+id/file_iv"
android:layout_width="60dp"
android:layout_height="60dp"
android:src="@drawable/document"
android:layout_margin="10dp"
android:contentDescription="@null" />
<TextView
android:id="@+id/file_name_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:text="PPDF_112121_jfioweijf_fiowejfowjfeowf_oifwjefowjifoiwjf_joiwjeofjwiojf0j.pdf"
android:textColor="@android:color/black"
android:textSize="18sp"
android:layout_toEndOf="@+id/file_iv"
android:layout_toStartOf="@+id/checkbox"
android:layout_marginTop="10dp"
android:ellipsize="end"
/>
<TextView
android:id="@+id/file_size_tv"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/file_name_tv"
tools:text="1.2MB"
android:layout_toEndOf="@+id/file_iv"
android:layout_marginStart="5dp"/>
<CheckBox
android:id="@+id/checkbox"
android:layout_width="25dp"
android:layout_height="25dp"
android:layout_alignParentEnd="true"
android:layout_margin="20dp"
/>
</RelativeLayout>

View File

@@ -0,0 +1,68 @@
<?xml version="1.0" encoding="utf-8"?>
<de.beyondsoft.ownchat.filepicker.views.SquareRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical">
<ImageView
android:id="@+id/iv_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@drawable/document"
android:contentDescription="@null"
android:padding="1dp"
android:scaleType="center" />
<View
android:id="@+id/transparent_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent_black"
android:visibility="gone" />
<View
android:id="@+id/bottomOverlay"
android:layout_width="fill_parent"
android:layout_height="70.0dip"
android:layout_alignParentBottom="true"
android:background="@drawable/gallery_album_overlay" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_gravity="bottom"
android:gravity="center_vertical"
android:orientation="horizontal"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:paddingTop="5dp"
android:paddingBottom="5dp"
>
<TextView
android:id="@+id/folder_title"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1.0"
android:ellipsize="marquee"
android:gravity="start"
tools:text="All Photos"
android:singleLine="true"
android:textColor="#ffffffff"
android:textSize="13.0sp" />
<TextView
android:id="@+id/folder_count"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="marquee"
tools:text="123"
android:singleLine="true"
android:textColor="#ffeeeeee"
android:textSize="12sp" />
</LinearLayout>
</de.beyondsoft.ownchat.filepicker.views.SquareRelativeLayout>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<de.beyondsoft.ownchat.filepicker.views.SquareRelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<ImageView
android:id="@+id/iv_photo"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:background="@drawable/document"
android:contentDescription="@null"
android:padding="1dip"
android:scaleType="center" />
<View
android:id="@+id/transparent_bg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/transparent_black"
android:visibility="gone"
/>
<ImageView
android:id="@+id/video_icon"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="@mipmap/ic_play_icon"
android:contentDescription="@null" />
<CheckBox
android:id="@+id/checkbox"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_margin="5dp"
android:layout_alignParentTop="true"
android:layout_alignParentEnd="true"
/>
</de.beyondsoft.ownchat.filepicker.views.SquareRelativeLayout>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto">
<item android:id="@+id/action_done"
android:title="@string/done"
android:orderInCategory="100"
app:showAsAction="always" />
</menu>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 930 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

View File

@@ -19,4 +19,5 @@
<color name="colorSubtitle">#9B9B9B</color>
<color name="colorTimestamp">#636363</color>
<color name="colorLeftChat">#515151</color>
<color name="transparent_black">#94333232</color>
</resources>

View File

@@ -73,5 +73,13 @@
<!-- Impressum -->
<string name="impressum">Impressum</string>
<string name="done">Fertig</string>
<string name="no_files_found">Keine Dateien gefunden</string>
<string name="no_camera_exists">Keine Kamera vorhanden</string>
<string name="images">Bilder</string>
<string name="videos">Videos</string>
<string name="all_videos">Alle Videos</string>
<string name="all_photos">Alle Bilder</string>
<string name="all_files">Alle Dateien</string>
</resources>

View File

@@ -109,4 +109,11 @@
<item name="android:background">@drawable/chat_left_v2</item>
</style>
<!-- File Picker -->
<style name="PickerTabLayout" parent="Widget.Design.TabLayout">
<item name="tabGravity">fill</item>
<item name="tabMaxWidth">0dp</item>
</style>
</resources>

View File

@@ -5,9 +5,9 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.3.3'
classpath 'me.tatarka:gradle-retrolambda:3.3.0'
classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
classpath 'com.android.tools.build:gradle:3.0.0'
//classpath 'me.tatarka:gradle-retrolambda:3.3.0'
//classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2'
classpath 'io.realm:realm-gradle-plugin:2.2.2'
// NOTE: Do not place your application dependencies here; they belong
@@ -19,6 +19,7 @@ buildscript {
allprojects {
repositories {
jcenter()
google()
}
}

View File

@@ -1,6 +1,6 @@
#Mon Mar 06 15:25:21 EET 2017
#Thu Oct 26 10:33:36 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-4.1-all.zip