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.history.HistoryListFragment;
import org.linphone.mediastream.Log; import org.linphone.mediastream.Log;
import org.linphone.purchase.InAppPurchaseActivity; import org.linphone.purchase.InAppPurchaseActivity;
import org.linphone.recording.RecordingListFragment; import org.linphone.recording.RecordingsFragment;
import org.linphone.settings.AccountPreferencesFragment; import org.linphone.settings.AccountPreferencesFragment;
import org.linphone.settings.LinphonePreferences; import org.linphone.settings.LinphonePreferences;
import org.linphone.settings.SettingsFragment; import org.linphone.settings.SettingsFragment;
@ -465,7 +465,7 @@ public class LinphoneActivity extends LinphoneGenericActivity
fragment = new DevicesFragment(); fragment = new DevicesFragment();
break; break;
case RECORDING_LIST: case RECORDING_LIST:
fragment = new RecordingListFragment(); fragment = new RecordingsFragment();
break; break;
default: default:
break; break;
@ -992,6 +992,9 @@ public class LinphoneActivity extends LinphoneGenericActivity
hideTabBar(hideBottomBar); hideTabBar(hideBottomBar);
chat_selected.setVisibility(View.VISIBLE); chat_selected.setVisibility(View.VISIBLE);
break; 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 class Recording implements PlayerListener, Comparable<Recording> {
public static final Pattern RECORD_PATTERN = public static final Pattern RECORD_PATTERN =
Pattern.compile(".*/(.*)_(\\d{2}-\\d{2}-\\d{4}-\\d{2}-\\d{2}-\\d{2})\\..*"); Pattern.compile(".*/(.*)_(\\d{2}-\\d{2}-\\d{4}-\\d{2}-\\d{2}-\\d{2})\\..*");
private String recordPath, name; private String mRecordPath, mName;
private Date recordDate; private Date mRecordDate;
private Player player; private Player mPlayer;
private RecordingListener listener; private RecordingListener mListener;
private Handler handler; private Handler mHandler;
private Runnable updateCurrentPositionTimer; private Runnable mUpdateCurrentPositionTimer;
@SuppressLint("SimpleDateFormat") @SuppressLint("SimpleDateFormat")
public Recording(Context context, String recordPath) { public Recording(Context context, String recordPath) {
this.recordPath = recordPath; this.mRecordPath = recordPath;
Matcher m = RECORD_PATTERN.matcher(recordPath); Matcher m = RECORD_PATTERN.matcher(recordPath);
if (m.matches()) { if (m.matches()) {
name = m.group(1); mName = m.group(1);
try { 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) { } catch (ParseException e) {
Log.e(e); Log.e(e);
} }
} }
handler = new Handler(context.getMainLooper()); mHandler = new Handler(context.getMainLooper());
updateCurrentPositionTimer = mUpdateCurrentPositionTimer =
new Runnable() { new Runnable() {
@Override @Override
public void run() { public void run() {
if (listener != null) listener.currentPositionChanged(getCurrentPosition()); if (mListener != null) mListener.currentPositionChanged(getCurrentPosition());
if (isPlaying()) handler.postDelayed(updateCurrentPositionTimer, 20); if (isPlaying()) mHandler.postDelayed(mUpdateCurrentPositionTimer, 20);
} }
}; };
player = LinphoneManager.getLc().createLocalPlayer(null, null, null); mPlayer = LinphoneManager.getLc().createLocalPlayer(null, null, null);
player.setListener(this); mPlayer.setListener(this);
} }
public String getRecordPath() { public String getRecordPath() {
return recordPath; return mRecordPath;
} }
public String getName() { public String getName() {
return name; return mName;
} }
public Date getRecordDate() { public Date getRecordDate() {
return recordDate; return mRecordDate;
} }
public boolean isClosed() { public boolean isClosed() {
return player.getState() == Player.State.Closed; return mPlayer.getState() == Player.State.Closed;
} }
public void play() { public void play() {
if (isClosed()) { if (isClosed()) {
player.open(recordPath); mPlayer.open(mRecordPath);
} }
player.start(); mPlayer.start();
handler.post(updateCurrentPositionTimer); mHandler.post(mUpdateCurrentPositionTimer);
} }
public boolean isPlaying() { public boolean isPlaying() {
return player.getState() == Player.State.Playing; return mPlayer.getState() == Player.State.Playing;
} }
public void pause() { public void pause() {
if (!isClosed()) { if (!isClosed()) {
player.pause(); mPlayer.pause();
} }
} }
public boolean isPaused() { public boolean isPaused() {
return player.getState() == Player.State.Paused; return mPlayer.getState() == Player.State.Paused;
} }
public void seek(int i) { public void seek(int i) {
if (!isClosed()) player.seek(i); if (!isClosed()) mPlayer.seek(i);
} }
public int getCurrentPosition() { public int getCurrentPosition() {
if (isClosed()) { if (isClosed()) {
player.open(recordPath); mPlayer.open(mRecordPath);
} }
return player.getCurrentPosition(); return mPlayer.getCurrentPosition();
} }
public int getDuration() { public int getDuration() {
if (isClosed()) { if (isClosed()) {
player.open(recordPath); mPlayer.open(mRecordPath);
} }
return player.getDuration(); return mPlayer.getDuration();
} }
public void close() { public void close() {
player.close(); mPlayer.close();
} }
public void setRecordingListener(RecordingListener listener) { public void setRecordingListener(RecordingListener listener) {
this.listener = listener; this.mListener = listener;
} }
@Override @Override
public void onEofReached(Player player) { public void onEofReached(Player player) {
if (listener != null) listener.endOfRecordReached(); if (mListener != null) mListener.endOfRecordReached();
} }
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof Recording) { if (o instanceof Recording) {
Recording r = (Recording) o; Recording r = (Recording) o;
return recordPath.equals(r.getRecordPath()); return mRecordPath.equals(r.getRecordPath());
} }
return false; return false;
} }
@Override @Override
public int compareTo(@NonNull Recording o) { 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 CheckBox select;
public LinearLayout separator; public LinearLayout separator;
public TextView separatorText; public TextView separatorText;
private RecordingViewHolder.ClickListener listener;
private RecordingViewHolder.ClickListener mListener;
public RecordingViewHolder(View view, RecordingViewHolder.ClickListener listener) { public RecordingViewHolder(View view, RecordingViewHolder.ClickListener listener) {
super(view); super(view);
@ -51,22 +52,22 @@ public class RecordingViewHolder extends RecyclerView.ViewHolder
separator = view.findViewById(R.id.separator); separator = view.findViewById(R.id.separator);
separatorText = view.findViewById(R.id.separator_text); separatorText = view.findViewById(R.id.separator_text);
this.listener = listener; mListener = listener;
view.setOnClickListener(this); view.setOnClickListener(this);
view.setOnLongClickListener(this); view.setOnLongClickListener(this);
} }
@Override @Override
public void onClick(View view) { public void onClick(View view) {
if (listener != null) { if (mListener != null) {
listener.onItemClicked(getAdapterPosition()); mListener.onItemClicked(getAdapterPosition());
} }
} }
@Override @Override
public boolean onLongClick(View view) { public boolean onLongClick(View view) {
if (listener != null) { if (mListener != null) {
return listener.onItemLongClicked(getAdapterPosition()); return mListener.onItemLongClicked(getAdapterPosition());
} }
return false; return false;
} }

View file

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

View file

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

View file

@ -12,10 +12,20 @@
android:background="@color/colorF" android:background="@color/colorF"
android:orientation="horizontal"> 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 <View
android:layout_width="0dp" android:layout_width="0dp"
android:layout_height="match_parent" android:layout_height="match_parent"
android:layout_weight="0.8" /> android:layout_weight="0.6" />
<ImageView <ImageView
android:id="@+id/edit" android:id="@+id/edit"