Hide bottom bar and added back button while on recordings view

This commit is contained in:
Sylvain Berfini 2018-11-30 10:47:39 +01:00
parent ebf69f01ee
commit f0f9e1302b
6 changed files with 130 additions and 98 deletions

View file

@ -111,7 +111,7 @@ import org.linphone.history.HistoryDetailFragment;
import org.linphone.history.HistoryListFragment;
import org.linphone.mediastream.Log;
import org.linphone.purchase.InAppPurchaseActivity;
import org.linphone.recording.RecordingListFragment;
import org.linphone.recording.RecordingsFragment;
import org.linphone.settings.AccountPreferencesFragment;
import org.linphone.settings.LinphonePreferences;
import org.linphone.settings.SettingsFragment;
@ -465,7 +465,7 @@ public class LinphoneActivity extends LinphoneGenericActivity
fragment = new DevicesFragment();
break;
case RECORDING_LIST:
fragment = new RecordingListFragment();
fragment = new RecordingsFragment();
break;
default:
break;
@ -992,6 +992,9 @@ public class LinphoneActivity extends LinphoneGenericActivity
hideTabBar(hideBottomBar);
chat_selected.setVisibility(View.VISIBLE);
break;
case RECORDING_LIST:
hideTabBar(hideBottomBar);
break;
}
}

View file

@ -36,125 +36,125 @@ import org.linphone.mediastream.Log;
public class Recording implements PlayerListener, Comparable<Recording> {
public static final Pattern RECORD_PATTERN =
Pattern.compile(".*/(.*)_(\\d{2}-\\d{2}-\\d{4}-\\d{2}-\\d{2}-\\d{2})\\..*");
private String recordPath, name;
private Date recordDate;
private Player player;
private RecordingListener listener;
private Handler handler;
private Runnable updateCurrentPositionTimer;
private String mRecordPath, mName;
private Date mRecordDate;
private Player mPlayer;
private RecordingListener mListener;
private Handler mHandler;
private Runnable mUpdateCurrentPositionTimer;
@SuppressLint("SimpleDateFormat")
public Recording(Context context, String recordPath) {
this.recordPath = recordPath;
this.mRecordPath = recordPath;
Matcher m = RECORD_PATTERN.matcher(recordPath);
if (m.matches()) {
name = m.group(1);
mName = m.group(1);
try {
recordDate = new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss").parse(m.group(2));
mRecordDate = new SimpleDateFormat("dd-MM-yyyy-HH-mm-ss").parse(m.group(2));
} catch (ParseException e) {
Log.e(e);
}
}
handler = new Handler(context.getMainLooper());
updateCurrentPositionTimer =
mHandler = new Handler(context.getMainLooper());
mUpdateCurrentPositionTimer =
new Runnable() {
@Override
public void run() {
if (listener != null) listener.currentPositionChanged(getCurrentPosition());
if (isPlaying()) handler.postDelayed(updateCurrentPositionTimer, 20);
if (mListener != null) mListener.currentPositionChanged(getCurrentPosition());
if (isPlaying()) mHandler.postDelayed(mUpdateCurrentPositionTimer, 20);
}
};
player = LinphoneManager.getLc().createLocalPlayer(null, null, null);
player.setListener(this);
mPlayer = LinphoneManager.getLc().createLocalPlayer(null, null, null);
mPlayer.setListener(this);
}
public String getRecordPath() {
return recordPath;
return mRecordPath;
}
public String getName() {
return name;
return mName;
}
public Date getRecordDate() {
return recordDate;
return mRecordDate;
}
public boolean isClosed() {
return player.getState() == Player.State.Closed;
return mPlayer.getState() == Player.State.Closed;
}
public void play() {
if (isClosed()) {
player.open(recordPath);
mPlayer.open(mRecordPath);
}
player.start();
handler.post(updateCurrentPositionTimer);
mPlayer.start();
mHandler.post(mUpdateCurrentPositionTimer);
}
public boolean isPlaying() {
return player.getState() == Player.State.Playing;
return mPlayer.getState() == Player.State.Playing;
}
public void pause() {
if (!isClosed()) {
player.pause();
mPlayer.pause();
}
}
public boolean isPaused() {
return player.getState() == Player.State.Paused;
return mPlayer.getState() == Player.State.Paused;
}
public void seek(int i) {
if (!isClosed()) player.seek(i);
if (!isClosed()) mPlayer.seek(i);
}
public int getCurrentPosition() {
if (isClosed()) {
player.open(recordPath);
mPlayer.open(mRecordPath);
}
return player.getCurrentPosition();
return mPlayer.getCurrentPosition();
}
public int getDuration() {
if (isClosed()) {
player.open(recordPath);
mPlayer.open(mRecordPath);
}
return player.getDuration();
return mPlayer.getDuration();
}
public void close() {
player.close();
mPlayer.close();
}
public void setRecordingListener(RecordingListener listener) {
this.listener = listener;
this.mListener = listener;
}
@Override
public void onEofReached(Player player) {
if (listener != null) listener.endOfRecordReached();
if (mListener != null) mListener.endOfRecordReached();
}
@Override
public boolean equals(Object o) {
if (o instanceof Recording) {
Recording r = (Recording) o;
return recordPath.equals(r.getRecordPath());
return mRecordPath.equals(r.getRecordPath());
}
return false;
}
@Override
public int compareTo(@NonNull Recording o) {
return -recordDate.compareTo(o.getRecordDate());
return -mRecordDate.compareTo(o.getRecordDate());
}
}

View file

@ -36,7 +36,8 @@ public class RecordingViewHolder extends RecyclerView.ViewHolder
public CheckBox select;
public LinearLayout separator;
public TextView separatorText;
private RecordingViewHolder.ClickListener listener;
private RecordingViewHolder.ClickListener mListener;
public RecordingViewHolder(View view, RecordingViewHolder.ClickListener listener) {
super(view);
@ -51,22 +52,22 @@ public class RecordingViewHolder extends RecyclerView.ViewHolder
separator = view.findViewById(R.id.separator);
separatorText = view.findViewById(R.id.separator_text);
this.listener = listener;
mListener = listener;
view.setOnClickListener(this);
view.setOnLongClickListener(this);
}
@Override
public void onClick(View view) {
if (listener != null) {
listener.onItemClicked(getAdapterPosition());
if (mListener != null) {
mListener.onItemClicked(getAdapterPosition());
}
}
@Override
public boolean onLongClick(View view) {
if (listener != null) {
return listener.onItemLongClicked(getAdapterPosition());
if (mListener != null) {
return mListener.onItemLongClicked(getAdapterPosition());
}
return false;
}

View file

@ -1,7 +1,7 @@
package org.linphone.recording;
/*
RecordingAdapter.java
RecordingsAdapter.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
@ -35,12 +35,12 @@ import org.linphone.R;
import org.linphone.utils.SelectableAdapter;
import org.linphone.utils.SelectableHelper;
public class RecordingAdapter extends SelectableAdapter<RecordingViewHolder> {
public class RecordingsAdapter extends SelectableAdapter<RecordingViewHolder> {
private List<Recording> recordings;
private Context context;
private RecordingViewHolder.ClickListener clickListener;
public RecordingAdapter(
public RecordingsAdapter(
Context context,
List<Recording> recordings,
RecordingViewHolder.ClickListener listener,

View file

@ -1,7 +1,7 @@
package org.linphone.recording;
/*
RecordingListFragment.java
RecordingsFragment.java
Copyright (C) 2018 Belledonne Communications, Grenoble, France
This program is free software; you can redistribute it and/or
@ -26,6 +26,7 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.recyclerview.widget.DividerItemDecoration;
import androidx.recyclerview.widget.LinearLayoutManager;
@ -41,62 +42,76 @@ import org.linphone.fragments.FragmentsAvailable;
import org.linphone.utils.FileUtils;
import org.linphone.utils.SelectableHelper;
public class RecordingListFragment extends Fragment
public class RecordingsFragment extends Fragment
implements AdapterView.OnItemClickListener,
RecordingViewHolder.ClickListener,
SelectableHelper.DeleteListener {
private RecyclerView recordingList;
private List<Recording> recordings;
private TextView noRecordings;
private RecordingAdapter recordingAdapter;
private LinearLayoutManager layoutManager;
private Context context;
private SelectableHelper selectableHelper;
private RecyclerView mRecordingList;
private List<Recording> mRecordings;
private TextView mNoRecordings;
private RecordingsAdapter mRecordingsAdapter;
private LinearLayoutManager mLayoutManager;
private Context mContext;
private SelectableHelper mSelectableHelper;
private ImageView mBackButton;
@Override
public View onCreateView(
LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.recordings_list, container, false);
context = getActivity().getApplicationContext();
selectableHelper = new SelectableHelper(view, this);
mContext = getActivity().getApplicationContext();
mSelectableHelper = new SelectableHelper(view, this);
recordingList = view.findViewById(R.id.recording_list);
noRecordings = view.findViewById(R.id.no_recordings);
mRecordingList = view.findViewById(R.id.recording_list);
mNoRecordings = view.findViewById(R.id.no_recordings);
layoutManager = new LinearLayoutManager(context);
recordingList.setLayoutManager(layoutManager);
mBackButton = view.findViewById(R.id.back);
if (getResources().getBoolean(R.bool.isTablet)) {
mBackButton.setVisibility(View.INVISIBLE);
} else {
mBackButton.setOnClickListener(
new View.OnClickListener() {
@Override
public void onClick(View view) {
LinphoneActivity.instance().popBackStack();
}
});
}
mLayoutManager = new LinearLayoutManager(mContext);
mRecordingList.setLayoutManager(mLayoutManager);
// Divider between items
DividerItemDecoration dividerItemDecoration =
new DividerItemDecoration(
recordingList.getContext(), layoutManager.getOrientation());
dividerItemDecoration.setDrawable(context.getResources().getDrawable(R.drawable.divider));
recordingList.addItemDecoration(dividerItemDecoration);
mRecordingList.getContext(), mLayoutManager.getOrientation());
dividerItemDecoration.setDrawable(mContext.getResources().getDrawable(R.drawable.divider));
mRecordingList.addItemDecoration(dividerItemDecoration);
recordings = new ArrayList<>();
mRecordings = new ArrayList<>();
return view;
}
private void hideRecordingListAndDisplayMessageIfEmpty() {
if (recordings == null || recordings.isEmpty()) {
noRecordings.setVisibility(View.VISIBLE);
recordingList.setVisibility(View.GONE);
if (mRecordings == null || mRecordings.isEmpty()) {
mNoRecordings.setVisibility(View.VISIBLE);
mRecordingList.setVisibility(View.GONE);
} else {
noRecordings.setVisibility(View.GONE);
recordingList.setVisibility(View.VISIBLE);
mNoRecordings.setVisibility(View.GONE);
mRecordingList.setVisibility(View.VISIBLE);
}
}
public void removeDeletedRecordings() {
String recordingsDirectory = FileUtils.getRecordingsDirectory(context);
String recordingsDirectory = FileUtils.getRecordingsDirectory(mContext);
File directory = new File(recordingsDirectory);
if (directory.exists() && directory.isDirectory()) {
File[] existingRecordings = directory.listFiles();
for (Recording r : recordings) {
for (Recording r : mRecordings) {
boolean exists = false;
for (File f : existingRecordings) {
if (f.getPath().equals(r.getRecordPath())) {
@ -105,15 +120,15 @@ public class RecordingListFragment extends Fragment
}
}
if (!exists) recordings.remove(r);
if (!exists) mRecordings.remove(r);
}
Collections.sort(recordings);
Collections.sort(mRecordings);
}
}
public void searchForRecordings() {
String recordingsDirectory = FileUtils.getRecordingsDirectory(context);
String recordingsDirectory = FileUtils.getRecordingsDirectory(mContext);
File directory = new File(recordingsDirectory);
if (directory.exists() && directory.isDirectory()) {
@ -121,7 +136,7 @@ public class RecordingListFragment extends Fragment
for (File f : existingRecordings) {
boolean exists = false;
for (Recording r : recordings) {
for (Recording r : mRecordings) {
if (r.getRecordPath().equals(f.getPath())) {
exists = true;
break;
@ -130,12 +145,12 @@ public class RecordingListFragment extends Fragment
if (!exists) {
if (Recording.RECORD_PATTERN.matcher(f.getPath()).matches()) {
recordings.add(new Recording(context, f.getPath()));
mRecordings.add(new Recording(mContext, f.getPath()));
}
}
}
Collections.sort(recordings);
Collections.sort(mRecordings);
}
}
@ -143,7 +158,7 @@ public class RecordingListFragment extends Fragment
public void onResume() {
super.onResume();
// This is necessary, without it you won't be able to remove recordings as you won't be
// This is necessary, without it you won't be able to remove mRecordings as you won't be
// allowed to.
LinphoneActivity.instance().checkAndRequestExternalStoragePermission();
@ -158,12 +173,15 @@ public class RecordingListFragment extends Fragment
searchForRecordings();
hideRecordingListAndDisplayMessageIfEmpty();
recordingAdapter =
new RecordingAdapter(
getActivity().getApplicationContext(), recordings, this, selectableHelper);
recordingList.setAdapter(recordingAdapter);
selectableHelper.setAdapter(recordingAdapter);
selectableHelper.setDialogMessage(R.string.recordings_delete_dialog);
mRecordingsAdapter =
new RecordingsAdapter(
getActivity().getApplicationContext(),
mRecordings,
this,
mSelectableHelper);
mRecordingList.setAdapter(mRecordingsAdapter);
mSelectableHelper.setAdapter(mRecordingsAdapter);
mSelectableHelper.setDialogMessage(R.string.recordings_delete_dialog);
}
@Override
@ -172,8 +190,8 @@ public class RecordingListFragment extends Fragment
LinphoneManager.getInstance().routeAudioToReceiver();
// Close all opened recordings
for (Recording r : recordings) {
// Close all opened mRecordings
for (Recording r : mRecordings) {
if (!r.isClosed()) {
if (r.isPlaying()) r.pause();
r.close();
@ -183,38 +201,38 @@ public class RecordingListFragment extends Fragment
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
if (recordingAdapter.isEditionEnabled()) {
Recording record = recordings.get(position);
if (mRecordingsAdapter.isEditionEnabled()) {
Recording record = mRecordings.get(position);
if (record.isPlaying()) record.pause();
record.close();
File recordingFile = new File(record.getRecordPath());
if (recordingFile.delete()) {
recordings.remove(record);
mRecordings.remove(record);
}
}
}
@Override
public void onItemClicked(int position) {
if (recordingAdapter.isEditionEnabled()) {
recordingAdapter.toggleSelection(position);
if (mRecordingsAdapter.isEditionEnabled()) {
mRecordingsAdapter.toggleSelection(position);
}
}
@Override
public boolean onItemLongClicked(int position) {
if (!recordingAdapter.isEditionEnabled()) {
selectableHelper.enterEditionMode();
if (!mRecordingsAdapter.isEditionEnabled()) {
mSelectableHelper.enterEditionMode();
}
recordingAdapter.toggleSelection(position);
mRecordingsAdapter.toggleSelection(position);
return true;
}
@Override
public void onDeleteSelection(Object[] objectsToDelete) {
int size = recordingAdapter.getSelectedItemCount();
int size = mRecordingsAdapter.getSelectedItemCount();
for (int i = 0; i < size; i++) {
Recording record = (Recording) objectsToDelete[i];
@ -223,7 +241,7 @@ public class RecordingListFragment extends Fragment
File recordingFile = new File(record.getRecordPath());
if (recordingFile.delete()) {
recordings.remove(record);
mRecordings.remove(record);
}
}
}

View file

@ -12,10 +12,20 @@
android:background="@color/colorF"
android:orientation="horizontal">
<ImageView
android:id="@+id/back"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.2"
android:background="@drawable/toolbar_button"
android:contentDescription="@string/content_description_back"
android:padding="18dp"
android:src="@drawable/back" />
<View
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="0.8" />
android:layout_weight="0.6" />
<ImageView
android:id="@+id/edit"