Bigger thumbnail size
Audio recording
@@ -16,6 +16,8 @@ buildscript {
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'io.fabric'
|
||||
|
||||
|
||||
|
||||
repositories {
|
||||
maven { url 'https://maven.fabric.io/public' }
|
||||
maven { url "https://dl.bintray.com/hani-momanii/maven" }
|
||||
@@ -67,6 +69,10 @@ android {
|
||||
abortOnError false
|
||||
disable 'InvalidPackage'
|
||||
}
|
||||
|
||||
dexOptions {
|
||||
javaMaxHeapSize "12g"
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
|
||||
<application
|
||||
android:name="de.beyondsoft.ownchat.BewoplanerApplication"
|
||||
@@ -22,7 +23,6 @@
|
||||
android:theme="@style/AppTheme.FullBackground">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
@@ -63,7 +63,9 @@
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:screenOrientation="portrait"
|
||||
/>
|
||||
<activity android:name=".filepicker.MediaDetailsActivity"
|
||||
|
||||
<activity
|
||||
android:name=".filepicker.MediaDetailsActivity"
|
||||
android:theme="@style/AppTheme.NoActionBar"
|
||||
android:screenOrientation="portrait"
|
||||
/>
|
||||
|
||||
@@ -41,14 +41,14 @@ public class FilePickerActivity extends BaseFilePickerActivity implements
|
||||
protected void initView() {
|
||||
Intent intent = getIntent();
|
||||
if (intent != null) {
|
||||
if(getSupportActionBar()!=null)
|
||||
if(getSupportActionBar() != null) {
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
}
|
||||
|
||||
ArrayList<String> selectedPaths = intent.getStringArrayListExtra(FilePickerConst.KEY_SELECTED_MEDIA);
|
||||
type = intent.getIntExtra(FilePickerConst.EXTRA_PICKER_TYPE, FilePickerConst.MEDIA_PICKER);
|
||||
|
||||
if(selectedPaths!=null) {
|
||||
|
||||
if (PickerManager.getInstance().getMaxCount() == 1) {
|
||||
selectedPaths.clear();
|
||||
}
|
||||
@@ -59,8 +59,9 @@ public class FilePickerActivity extends BaseFilePickerActivity implements
|
||||
PickerManager.getInstance().add(selectedPaths, FilePickerConst.FILE_TYPE_DOCUMENT);
|
||||
}
|
||||
}
|
||||
else
|
||||
else {
|
||||
selectedPaths = new ArrayList<>();
|
||||
}
|
||||
|
||||
setToolbarTitle(PickerManager.getInstance().getCurrentCount());
|
||||
openSpecificFragment(type, selectedPaths);
|
||||
@@ -72,8 +73,9 @@ public class FilePickerActivity extends BaseFilePickerActivity implements
|
||||
MediaPickerFragment photoFragment = MediaPickerFragment.newInstance();
|
||||
FragmentUtil.addFragment(this, R.id.container, photoFragment);
|
||||
} else {
|
||||
if(PickerManager.getInstance().isDocSupport())
|
||||
if(PickerManager.getInstance().isDocSupport()) {
|
||||
PickerManager.getInstance().addDocTypes();
|
||||
}
|
||||
|
||||
DocPickerFragment photoFragment = DocPickerFragment.newInstance(selectedPaths);
|
||||
FragmentUtil.addFragment(this, R.id.container, photoFragment);
|
||||
@@ -82,14 +84,15 @@ public class FilePickerActivity extends BaseFilePickerActivity implements
|
||||
|
||||
private void setToolbarTitle(int count) {
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if(actionBar!=null) {
|
||||
if (PickerManager.getInstance().getMaxCount() > 1)
|
||||
if(actionBar != null) {
|
||||
if (PickerManager.getInstance().getMaxCount() > 1) {
|
||||
actionBar.setTitle(String.format(getString(R.string.attachments_title_text), count, PickerManager.getInstance().getMaxCount()));
|
||||
else {
|
||||
if (type == FilePickerConst.MEDIA_PICKER)
|
||||
} else {
|
||||
if (type == FilePickerConst.MEDIA_PICKER) {
|
||||
actionBar.setTitle(R.string.select_photo_text);
|
||||
else
|
||||
} else {
|
||||
actionBar.setTitle(R.string.select_doc_text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,43 +109,46 @@ public class FilePickerActivity extends BaseFilePickerActivity implements
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int i = item.getItemId();
|
||||
if (i == R.id.action_done) {
|
||||
if (type == FilePickerConst.MEDIA_PICKER)
|
||||
if (type == FilePickerConst.MEDIA_PICKER) {
|
||||
returnData(PickerManager.getInstance().getSelectedPhotos());
|
||||
else
|
||||
} else {
|
||||
returnData(PickerManager.getInstance().getSelectedFiles());
|
||||
}
|
||||
|
||||
return true;
|
||||
} else if (i == android.R.id.home) {
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
super.onBackPressed();
|
||||
|
||||
setResult(RESULT_CANCELED);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
switch (requestCode)
|
||||
{
|
||||
|
||||
switch (requestCode) {
|
||||
case FilePickerConst.REQUEST_CODE_MEDIA_DETAIL:
|
||||
if(resultCode== Activity.RESULT_OK)
|
||||
{
|
||||
if (type == FilePickerConst.MEDIA_PICKER)
|
||||
if(resultCode== Activity.RESULT_OK) {
|
||||
if (type == FilePickerConst.MEDIA_PICKER) {
|
||||
returnData(PickerManager.getInstance().getSelectedPhotos());
|
||||
else
|
||||
} else {
|
||||
returnData(PickerManager.getInstance().getSelectedFiles());
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
} else {
|
||||
setToolbarTitle(PickerManager.getInstance().getCurrentCount());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -164,7 +170,8 @@ public class FilePickerActivity extends BaseFilePickerActivity implements
|
||||
public void onItemSelected() {
|
||||
setToolbarTitle(PickerManager.getInstance().getCurrentCount());
|
||||
|
||||
if(PickerManager.getInstance().getMaxCount()==1)
|
||||
if(PickerManager.getInstance().getMaxCount() == 1) {
|
||||
returnData(type == FilePickerConst.MEDIA_PICKER ? PickerManager.getInstance().getSelectedPhotos() : PickerManager.getInstance().getSelectedFiles());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -42,7 +42,6 @@ public class MediaDetailsActivity extends BaseFilePickerActivity implements File
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState, R.layout.activity_media_details);
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -66,8 +65,8 @@ public class MediaDetailsActivity extends BaseFilePickerActivity implements File
|
||||
}
|
||||
|
||||
private void setUpView(ImageDirectory photoDirectory) {
|
||||
recyclerView = (RecyclerView) findViewById(R.id.recyclerview);
|
||||
emptyView = (TextView) findViewById(R.id.empty_view);
|
||||
recyclerView = findViewById(R.id.recyclerview);
|
||||
emptyView = findViewById(R.id.empty_view);
|
||||
|
||||
StaggeredGridLayoutManager layoutManager = new StaggeredGridLayoutManager(3, OrientationHelper.VERTICAL);
|
||||
layoutManager.setGapStrategy(StaggeredGridLayoutManager.GAP_HANDLING_MOVE_ITEMS_BETWEEN_SPANS);
|
||||
@@ -77,13 +76,14 @@ public class MediaDetailsActivity extends BaseFilePickerActivity implements File
|
||||
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();
|
||||
@@ -102,13 +102,9 @@ public class MediaDetailsActivity extends BaseFilePickerActivity implements File
|
||||
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));
|
||||
MediaStoreHelper.getPhotoDirs(this, mediaStoreArgs, this::updateList);
|
||||
} else if(fileType==FilePickerConst.MEDIA_TYPE_VIDEO) {
|
||||
MediaStoreHelper.getVideoDirs(this, mediaStoreArgs, this::updateList);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,31 +114,22 @@ public class MediaDetailsActivity extends BaseFilePickerActivity implements File
|
||||
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();
|
||||
}
|
||||
});
|
||||
Collections.sort(medias, (a, b) -> b.getId() - a.getId());
|
||||
|
||||
if(medias.size()>0) {
|
||||
if(medias.size() > 0) {
|
||||
emptyView.setVisibility(View.GONE);
|
||||
recyclerView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
emptyView.setVisibility(View.VISIBLE);
|
||||
recyclerView.setVisibility(View.GONE);
|
||||
return;
|
||||
}
|
||||
|
||||
if(photoGridAdapter!=null)
|
||||
{
|
||||
if(photoGridAdapter!=null) {
|
||||
photoGridAdapter.setData(medias);
|
||||
photoGridAdapter.notifyDataSetChanged();
|
||||
}
|
||||
else
|
||||
{
|
||||
photoGridAdapter = new ImageGridAdapter(this, mGlideRequestManager, (ArrayList<Media>) medias,PickerManager.getInstance().getSelectedPhotos(),false, this);
|
||||
} else {
|
||||
photoGridAdapter = new ImageGridAdapter(this, mGlideRequestManager, medias,PickerManager.getInstance().getSelectedPhotos(),false, this);
|
||||
recyclerView.setAdapter(photoGridAdapter);
|
||||
}
|
||||
|
||||
@@ -175,6 +162,7 @@ public class MediaDetailsActivity extends BaseFilePickerActivity implements File
|
||||
onBackPressed();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
|
||||
@@ -46,20 +46,10 @@ public class FileListAdapter extends SelectableAdapter<FileListAdapter.FileViewH
|
||||
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.itemView.setOnClickListener(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.setOnClickListener(view -> onItemClicked(document,holder));
|
||||
|
||||
holder.checkBox.setChecked(isSelected(document));
|
||||
|
||||
@@ -81,10 +71,11 @@ public class FileListAdapter extends SelectableAdapter<FileListAdapter.FileViewH
|
||||
if(PickerManager.getInstance().getMaxCount()==1)
|
||||
{
|
||||
PickerManager.getInstance().add(document.getPath(), FilePickerConst.FILE_TYPE_DOCUMENT);
|
||||
if(mListener!=null)
|
||||
|
||||
if(mListener != null) {
|
||||
mListener.onItemSelected();
|
||||
}
|
||||
else {
|
||||
}
|
||||
} else {
|
||||
if (holder.checkBox.isChecked()) {
|
||||
PickerManager.getInstance().remove(document.getPath(), FilePickerConst.FILE_TYPE_DOCUMENT);
|
||||
holder.checkBox.setChecked(!holder.checkBox.isChecked());
|
||||
@@ -102,7 +93,7 @@ public class FileListAdapter extends SelectableAdapter<FileListAdapter.FileViewH
|
||||
return getItems().size();
|
||||
}
|
||||
|
||||
public static class FileViewHolder extends RecyclerView.ViewHolder {
|
||||
static class FileViewHolder extends RecyclerView.ViewHolder {
|
||||
CheckBox checkBox;
|
||||
|
||||
ImageView imageView;
|
||||
@@ -111,12 +102,12 @@ public class FileListAdapter extends SelectableAdapter<FileListAdapter.FileViewH
|
||||
|
||||
TextView fileSizeTextView;
|
||||
|
||||
public FileViewHolder(View itemView) {
|
||||
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);
|
||||
checkBox = itemView.findViewById(R.id.checkbox);
|
||||
imageView = itemView.findViewById(R.id.file_iv);
|
||||
fileNameTextView = itemView.findViewById(R.id.file_name_tv);
|
||||
fileSizeTextView = itemView.findViewById(R.id.file_size_tv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ public class FolderGridAdapter extends SelectableAdapter<FolderGridAdapter.Image
|
||||
if(AndroidLifecycleUtils.canLoadImage(holder.imageView.getContext())) {
|
||||
glide.load(new File(photoDirectory.getCoverPath()))
|
||||
.override(imageSize, imageSize)
|
||||
.thumbnail(0.5f)
|
||||
.thumbnail(0.25f)
|
||||
.listener(this)
|
||||
.into(holder.imageView);
|
||||
}
|
||||
@@ -122,7 +122,9 @@ public class FolderGridAdapter extends SelectableAdapter<FolderGridAdapter.Image
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import android.widget.CheckBox;
|
||||
import android.widget.ImageView;
|
||||
|
||||
import com.bumptech.glide.RequestManager;
|
||||
import com.bumptech.glide.load.engine.DiskCacheStrategy;
|
||||
import com.bumptech.glide.load.resource.bitmap.GlideBitmapDrawable;
|
||||
import com.bumptech.glide.load.resource.drawable.GlideDrawable;
|
||||
import com.bumptech.glide.load.resource.gif.GifDrawable;
|
||||
@@ -37,8 +38,8 @@ public class ImageGridAdapter extends SelectableAdapter<ImageGridAdapter.ImageVi
|
||||
private final FileAdapterListener mListener;
|
||||
private int imageSize;
|
||||
|
||||
public final static int ITEM_TYPE_CAMERA = 100;
|
||||
public final static int ITEM_TYPE_PHOTO = 101;
|
||||
private final static int ITEM_TYPE_CAMERA = 100;
|
||||
private 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) {
|
||||
@@ -47,7 +48,7 @@ public class ImageGridAdapter extends SelectableAdapter<ImageGridAdapter.ImageVi
|
||||
this.glide = requestManager;
|
||||
this.showCamera = showCamera;
|
||||
this.mListener = photoGridAdapterListener;
|
||||
setColumnNumber(context,3);
|
||||
setColumnNumber(context,4);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -74,7 +75,7 @@ public class ImageGridAdapter extends SelectableAdapter<ImageGridAdapter.ImageVi
|
||||
if(AndroidLifecycleUtils.canLoadImage(holder.imageView.getContext())) {
|
||||
glide.load(new File(media.getPath()))
|
||||
.override(imageSize, imageSize)
|
||||
.thumbnail(0.5f)
|
||||
.thumbnail(0.25f)
|
||||
.listener(this)
|
||||
.into(holder.imageView);
|
||||
}
|
||||
|
||||
@@ -14,9 +14,9 @@ import de.beyondsoft.ownchat.filepicker.models.BaseFile;
|
||||
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;
|
||||
private List<T> selectedPhotos;
|
||||
|
||||
public SelectableAdapter(List<T> items, List<String> selectedPaths) {
|
||||
SelectableAdapter(List<T> items, List<String> selectedPaths) {
|
||||
this.items = items;
|
||||
selectedPhotos = new ArrayList<>();
|
||||
|
||||
@@ -65,7 +65,7 @@ public abstract class SelectableAdapter<VH extends RecyclerView.ViewHolder, T ex
|
||||
this.items = items;
|
||||
}
|
||||
|
||||
public List<T> getItems()
|
||||
List<T> getItems()
|
||||
{
|
||||
return items;
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import de.beyondsoft.ownchat.di.InjectionHelper;
|
||||
import de.beyondsoft.ownchat.filepicker.FilePickerBuilder;
|
||||
import de.beyondsoft.ownchat.filepicker.FilePickerConst;
|
||||
import de.beyondsoft.ownchat.filepicker.utils.Orientation;
|
||||
import de.beyondsoft.ownchat.utils.ui.TouchableImageView;
|
||||
import de.beyondsoft.ownchat.model.Group;
|
||||
import de.beyondsoft.ownchat.model.Message;
|
||||
import de.beyondsoft.ownchat.page.common.RuntimePermissionActivity;
|
||||
@@ -22,7 +23,6 @@ import de.beyondsoft.ownchat.utils.Constants;
|
||||
import de.beyondsoft.ownchat.utils.EndlessScrollListener;
|
||||
import de.beyondsoft.ownchat.utils.FileUtils;
|
||||
import de.beyondsoft.ownchat.utils.SystemUtils;
|
||||
import de.beyondsoft.ownchat.utils.Utils;
|
||||
import de.beyondsoft.ownchat.utils.ui.EmptyLayout;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
@@ -34,9 +34,11 @@ import android.app.Activity;
|
||||
import android.app.Dialog;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Rect;
|
||||
import android.media.MediaRecorder;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.CountDownTimer;
|
||||
import android.os.Environment;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.annotation.StringRes;
|
||||
@@ -50,15 +52,24 @@ import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.SimpleItemAnimator;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
import android.view.Gravity;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.view.ViewTreeObserver;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
@@ -121,6 +132,10 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha
|
||||
@Named(AppPrefsConstants.USER_ID)
|
||||
LongPreference mUserIdPreference;
|
||||
|
||||
@Inject
|
||||
@Named(AppPrefsConstants.UPLOAD_MAX_SIZE)
|
||||
LongPreference mUploadMaxSize;
|
||||
|
||||
@Inject
|
||||
ChatPresenter mChatPresenter;
|
||||
|
||||
@@ -143,6 +158,7 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha
|
||||
protected EndlessScrollListener mEndlessScrollListener;
|
||||
protected BaseChatAdapter mBaseChatAdapter;
|
||||
private Snackbar mSnackbar;
|
||||
MediaRecorder mMediaRecorder;
|
||||
|
||||
@Inject
|
||||
@Named(AppPrefsConstants.CHAT_OPENED)
|
||||
@@ -308,7 +324,7 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha
|
||||
|
||||
@OnClick(R.id.chat_attachment)
|
||||
void attachmentClicked() {
|
||||
requestAppPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
|
||||
requestAppPermissions(new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO},
|
||||
R.string.permission_storage_explained,
|
||||
STORAGE_REQUEST_CODE,
|
||||
this::selectFile);
|
||||
@@ -330,17 +346,25 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha
|
||||
mSendMessageImageView.setEnabled(!TextUtils.isEmpty(editable.toString()) && editable.toString().trim().length() > 0);
|
||||
}
|
||||
|
||||
private String mAudioFilePath;
|
||||
private void selectFile(int requestCode) {
|
||||
final String[] zipFileTypes = {".zip", ".rar", ".7z"};
|
||||
final String[] pdfFileTypes = {".pdf"};
|
||||
final String[] docFileTypes = {".txt", ".doc", ".xls", ".docx", ".xlsx", ".odt"};
|
||||
|
||||
|
||||
final Dialog dialog = new Dialog(this);
|
||||
dialog.setContentView(R.layout.file_chooser_dialog);
|
||||
dialog.setContentView(R.layout.dialog_file_chooser);
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
WindowManager.LayoutParams layoutParams = window.getAttributes();
|
||||
layoutParams.dimAmount = 0;
|
||||
layoutParams.gravity = Gravity.BOTTOM;
|
||||
window.setAttributes(layoutParams);
|
||||
|
||||
ImageView attachFromGalleryImageView = dialog.findViewById(R.id.attachFromGalleryBtn);
|
||||
ImageView attachDocumentImageView = dialog.findViewById(R.id.attachDocumentBtn);
|
||||
TouchableImageView attachRecordAudioImageView = dialog.findViewById(R.id.attachRecordAudioBtn);
|
||||
TextView limitTextView = dialog.findViewById(R.id.audioRecordingLimitTextView);
|
||||
|
||||
attachDocumentImageView.setOnClickListener(v -> {
|
||||
FilePickerBuilder.getInstance().setMaxCount(1)
|
||||
@@ -367,9 +391,104 @@ abstract class BaseChatActivity extends RuntimePermissionActivity implements Cha
|
||||
dialog.dismiss();
|
||||
});
|
||||
|
||||
final long duration = (mUploadMaxSize.get() / 256000L) * 1000;
|
||||
CountDownTimer countDownTimer = new CountDownTimer(duration, 10) {
|
||||
@Override
|
||||
public void onTick(long millisecondsUntilFinished) {
|
||||
limitTextView.setText(String.format(Locale.getDefault(), "%.2fs", (double) (millisecondsUntilFinished / 1000.0)));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFinish() {
|
||||
attachRecordAudioImageView.setImageResource(R.mipmap.ic_file_dialog_record_audio);
|
||||
limitTextView.setVisibility(View.INVISIBLE);
|
||||
limitTextView.setText("");
|
||||
attachDocumentImageView.setVisibility(View.VISIBLE);
|
||||
attachFromGalleryImageView.setVisibility(View.VISIBLE);
|
||||
|
||||
try {
|
||||
mMediaRecorder.stop();
|
||||
} catch (IllegalStateException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
attachRecordAudioImageView.setOnTouchListener((v, event) -> {
|
||||
try {
|
||||
attachRecordAudioImageView.performClick();
|
||||
|
||||
float prevX = 0f, prevY = 0f;
|
||||
|
||||
switch(event.getAction()) {
|
||||
case MotionEvent.ACTION_DOWN:
|
||||
attachRecordAudioImageView.setImageResource(R.mipmap.ic_file_dialog_record_audio_pressed);
|
||||
limitTextView.setVisibility(View.VISIBLE);
|
||||
attachDocumentImageView.setVisibility(View.INVISIBLE);
|
||||
attachFromGalleryImageView.setVisibility(View.INVISIBLE);
|
||||
|
||||
mAudioFilePath = FileUtils.generateAudioRecordingFileName(this);
|
||||
setupMediaRecorder(mAudioFilePath);
|
||||
|
||||
countDownTimer.start();
|
||||
|
||||
prevX = event.getX();
|
||||
prevY = event.getY();
|
||||
|
||||
Log.d("ON_TOUCH", "" + prevX + "/" + prevY);
|
||||
|
||||
try {
|
||||
mMediaRecorder.setMaxFileSize(mUploadMaxSize.get());
|
||||
mMediaRecorder.prepare();
|
||||
mMediaRecorder.start();
|
||||
} catch (IllegalStateException | IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return true;
|
||||
case MotionEvent.ACTION_UP:
|
||||
attachRecordAudioImageView.setImageResource(R.mipmap.ic_file_dialog_record_audio);
|
||||
|
||||
countDownTimer.cancel();
|
||||
|
||||
mMediaRecorder.stop();
|
||||
|
||||
if (!mChatPresenter.isAttached()) {
|
||||
mChatPresenter.attachView(this);
|
||||
}
|
||||
|
||||
//mCallback.sendFile(Uri.fromFile(new File(mAudioFilePath)), null);
|
||||
|
||||
dialog.dismiss();
|
||||
return true;
|
||||
|
||||
case MotionEvent.ACTION_MOVE:
|
||||
|
||||
Log.d("ON_TOUCH", "" + prevX + "/" + prevY + " vs current position: " + event.getX() + "/" + event.getY());
|
||||
|
||||
return true;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return false;
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
}
|
||||
|
||||
private void setupMediaRecorder(String audioFilePath) {
|
||||
mMediaRecorder = new MediaRecorder();
|
||||
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
|
||||
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
|
||||
mMediaRecorder.setAudioEncodingBitRate(32000);
|
||||
mMediaRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
|
||||
mMediaRecorder.setOutputFile(audioFilePath);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
|
||||
@@ -34,4 +34,6 @@ public interface Constants {
|
||||
String TMP_FILE_DIR = "tmp_files";
|
||||
|
||||
String HAS_OPEN_CHAT = "has_open_chat";
|
||||
|
||||
String AUDIO_RECORDINGS_DIR = "audio_recordings";
|
||||
}
|
||||
@@ -36,9 +36,14 @@ import java.io.File;
|
||||
import java.io.FileFilter;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.text.DateFormat;
|
||||
import java.text.DecimalFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Comparator;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
@@ -1237,4 +1242,31 @@ public class FileUtils {
|
||||
|
||||
return tmpFile;
|
||||
}
|
||||
|
||||
public static String generateAudioRecordingFileName(Context context) {
|
||||
String audioDirectoryPath = context.getExternalFilesDir(null) + File.separator + Constants.AUDIO_RECORDINGS_DIR;
|
||||
|
||||
File audioDir = new File(audioDirectoryPath);
|
||||
if(!audioDir.exists()) {
|
||||
audioDir.mkdir();
|
||||
}
|
||||
|
||||
String fileName = "rec_";
|
||||
String fileSuffix = ".m4a";
|
||||
|
||||
Date today = Calendar.getInstance().getTime();
|
||||
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("YYYYmmddHHMMss", Locale.GERMAN);
|
||||
|
||||
fileName += simpleDateFormat.format(today);
|
||||
|
||||
fileName = audioDirectoryPath + File.separator + fileName;
|
||||
String newFileName = fileName;
|
||||
|
||||
int i = 1;
|
||||
while((new File(newFileName + fileSuffix)).exists()) {
|
||||
newFileName = fileName + "_" + i;
|
||||
}
|
||||
|
||||
return newFileName + fileSuffix;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
package de.beyondsoft.ownchat.utils.ui;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.util.AttributeSet;
|
||||
|
||||
/**
|
||||
* Created by Lyndon on 15-Nov-2017.
|
||||
*/
|
||||
|
||||
public class TouchableImageView extends android.support.v7.widget.AppCompatImageView {
|
||||
public TouchableImageView(Context context) {
|
||||
super(context);
|
||||
}
|
||||
|
||||
public TouchableImageView(Context context, @Nullable AttributeSet attrs) {
|
||||
super(context, attrs);
|
||||
}
|
||||
|
||||
public TouchableImageView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
|
||||
super(context, attrs, defStyleAttr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean performClick() {
|
||||
return super.performClick();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<GridLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:layout_centerHorizontal="false"
|
||||
android:layout_centerInParent="true"
|
||||
android:layout_centerVertical="false"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:background="@android:color/white"
|
||||
android:columnCount="3"
|
||||
android:orientation="horizontal"
|
||||
android:rowCount="1">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/audioRecordingLimitTextView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_column="0"
|
||||
android:layout_columnSpan="2"
|
||||
android:layout_gravity="center_vertical|center_horizontal"
|
||||
android:layout_margin="20dp"
|
||||
android:layout_row="0"
|
||||
android:textAlignment="center"
|
||||
android:textColor="@color/colorBlack"
|
||||
android:visibility="gone"
|
||||
tools:text="3.48s"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/attachFromGalleryBtn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_column="0"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_row="0"
|
||||
android:adjustViewBounds="false"
|
||||
android:contentDescription="@null"
|
||||
android:cropToPadding="false"
|
||||
android:src="@mipmap/ic_file_dialog_gallery"
|
||||
tools:visibility="invisible" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/attachDocumentBtn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_column="1"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_row="0"
|
||||
android:contentDescription="@null"
|
||||
android:src="@mipmap/ic_file_dialog_document"
|
||||
tools:visibility="invisible" />
|
||||
|
||||
<de.beyondsoft.ownchat.utils.ui.TouchableImageView
|
||||
android:id="@+id/attachRecordAudioBtn"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_column="2"
|
||||
android:layout_margin="10dp"
|
||||
android:layout_row="0"
|
||||
android:clickable="true"
|
||||
android:contentDescription="@null"
|
||||
android:focusable="true"
|
||||
android:src="@mipmap/ic_file_dialog_record_audio" />
|
||||
</GridLayout>
|
||||
@@ -1,30 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@android:color/white"
|
||||
android:gravity="center_vertical"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:orientation="horizontal">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/attachFromGalleryBtn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight=".50"
|
||||
android:adjustViewBounds="false"
|
||||
android:contentDescription="@null"
|
||||
android:cropToPadding="false"
|
||||
android:layout_margin="10dp"
|
||||
android:src="@mipmap/ic_file_dialog_gallery" />
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/attachDocumentBtn"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight=".50"
|
||||
android:contentDescription="@null"
|
||||
android:layout_margin="10dp"
|
||||
android:src="@mipmap/ic_file_dialog_document" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -19,7 +19,8 @@
|
||||
android:layout_height="@dimen/profile_avatar"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/avatar" />
|
||||
android:src="@drawable/avatar"
|
||||
tools:src="@drawable/sasha_grey"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/profile_avatar_progress_bar"
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
xmlns:emojicon="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingRight="40dp"
|
||||
android:paddingEnd="40dp"
|
||||
android:layout_marginTop="6dp"
|
||||
android:layout_marginBottom="6dp"
|
||||
>
|
||||
@@ -27,13 +27,13 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/chat_item_file"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="120dp"
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="250dp"
|
||||
android:layout_below="@id/chat_item_time"
|
||||
android:layout_marginTop="4dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="fitCenter"
|
||||
android:scaleType="centerCrop"
|
||||
android:visibility="gone"
|
||||
tools:src="@drawable/document"
|
||||
tools:visibility="visible" />
|
||||
|
||||
@@ -70,14 +70,14 @@
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/chat_item_file"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="120dp"
|
||||
android:layout_width="250dp"
|
||||
android:layout_height="250dp"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_below="@id/chat_item_time"
|
||||
android:layout_marginTop="4dp"
|
||||
android:adjustViewBounds="true"
|
||||
android:contentDescription="@null"
|
||||
android:scaleType="fitCenter"
|
||||
android:scaleType="centerCrop"
|
||||
android:visibility="gone"
|
||||
tools:src="@drawable/document"
|
||||
tools:visibility="visible" />
|
||||
|
||||
|
After Width: | Height: | Size: 3.0 KiB |
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 9.9 KiB |
|
After Width: | Height: | Size: 10 KiB |
@@ -20,4 +20,5 @@
|
||||
<color name="colorTimestamp">#636363</color>
|
||||
<color name="colorLeftChat">#515151</color>
|
||||
<color name="transparent_black">#94333232</color>
|
||||
<color name="transparent">#00000000</color>
|
||||
</resources>
|
||||
|
||||
@@ -116,4 +116,10 @@
|
||||
<item name="tabMaxWidth">0dp</item>
|
||||
</style>
|
||||
|
||||
<style name="Dialog" parent="android:style/Theme.Dialog">
|
||||
<item name="android:windowBackground">@color/transparent</item>
|
||||
<item name="android:windowNoTitle">true</item>
|
||||
<item name="android:windowIsFloating">true</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
|
||||
@@ -15,3 +15,5 @@ org.gradle.jvmargs=-Xmx1536m
|
||||
# This option should only be used with decoupled projects. More details, visit
|
||||
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
|
||||
# org.gradle.parallel=true
|
||||
org.gradle.parallel=true
|
||||
org.gradle.deamon=true
|
||||