From e78f02812a5a1e92fd8c534baa8b6afa0080c388 Mon Sep 17 00:00:00 2001 From: Arjun Date: Sat, 23 Sep 2017 12:19:28 +0530 Subject: [PATCH 01/26] added new seek bar view --- .../audiorecorder/libs/FillSeekBar.java | 166 ++++++++++++++++++ .../playlist/PlayListAdapter.java | 3 +- .../{card_view.xml => record_list_item.xml} | 0 app/src/main/res/values/attrs.xml | 7 + 4 files changed, 174 insertions(+), 2 deletions(-) create mode 100644 app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java rename app/src/main/res/layout/{card_view.xml => record_list_item.xml} (100%) diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java new file mode 100644 index 0000000..e7ee676 --- /dev/null +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -0,0 +1,166 @@ +package in.arjsna.audiorecorder.libs; + +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Paint; +import android.os.Handler; +import android.os.Looper; +import android.os.Parcel; +import android.os.Parcelable; +import android.util.AttributeSet; +import android.view.View; +import android.view.ViewGroup; +import android.widget.FrameLayout; +import android.widget.LinearLayout; +import in.arjsna.audiorecorder.R; +import java.util.Timer; +import java.util.TimerTask; + +public class FillSeekBar extends FrameLayout { + protected static final int LARGE = 1; + protected static final int MIDDLE = 2; + protected static final int LITTLE = 3; + + private int mProgress; + private Solid mSolid; + + private final int DEFAULT_FILL_COLOR = Color.WHITE; + private final int DEFAULT_PROGRESS = 80; + private int mSolidRight; + private long finalValue; + + public FillSeekBar(Context context, AttributeSet attrs) { + super(context, attrs); + //load styled attributes. + final TypedArray attributes = context.getTheme() + .obtainStyledAttributes(attrs, R.styleable.FillSeekBar, R.attr.fillseekbarViewStyle, 0); + int mFillColor = + attributes.getColor(R.styleable.FillSeekBar_fill_color, DEFAULT_FILL_COLOR); + mProgress = attributes.getInt(R.styleable.FillSeekBar_progress, DEFAULT_PROGRESS); + attributes.recycle(); + mSolid = new Solid(context, null); + mSolid.initPaint(mFillColor); + addView(mSolid); + setProgress(0); + setAutoProgress(1000, 1000); + } + + public void setProgress(int progress) { + this.mProgress = progress > 100 ? 100 : progress; + computeProgressRigth(); + } + + @Override public void onWindowFocusChanged(boolean hasWindowFocus) { + super.onWindowFocusChanged(hasWindowFocus); + if (hasWindowFocus) { + computeProgressRigth(); + } + } + + private void computeProgressRigth() { + mSolidRight = (int) (getWidth() * (1f - mProgress / 100f)); + ViewGroup.LayoutParams params = mSolid.getLayoutParams(); + if (params != null) { + ((LayoutParams) params).rightMargin = mSolidRight; + } + mSolid.setLayoutParams(params); + } + + @Override public Parcelable onSaveInstanceState() { + // Force our ancestor class to save its state + Parcelable superState = super.onSaveInstanceState(); + SavedState ss = new SavedState(superState); + ss.progress = mProgress; + return ss; + } + + @Override public void onRestoreInstanceState(Parcelable state) { + SavedState ss = (SavedState) state; + super.onRestoreInstanceState(ss.getSuperState()); + setProgress(ss.progress); + } + + private static class SavedState extends BaseSavedState { + int progress; + + /** + * Constructor called from {@link android.widget.ProgressBar#onSaveInstanceState()} + */ + SavedState(Parcelable superState) { + super(superState); + } + + /** + * Constructor called from {@link #CREATOR} + */ + private SavedState(Parcel in) { + super(in); + progress = in.readInt(); + } + + @Override public void writeToParcel(Parcel out, int flags) { + super.writeToParcel(out, flags); + out.writeInt(progress); + } + + public static final Creator CREATOR = new Creator() { + public SavedState createFromParcel(Parcel in) { + return new SavedState(in); + } + + public SavedState[] newArray(int size) { + return new SavedState[size]; + } + }; + } + + public void setAutoProgress(long offset, long finalVal) { + timer = new Timer(); + this.finalValue = finalVal; + timer.scheduleAtFixedRate(timerTask, 0 , 100); + } + Handler handler = new Handler(Looper.getMainLooper()); + Timer timer; + TimerTask timerTask = new TimerTask() { + @Override public void run() { + handler.post(new Runnable() { + @Override public void run() { + setProgress(mProgress + 1); + } + }); + } + }; + + static class Solid extends View { + + private Paint progressPaint; + + public Solid(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public Solid(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + LinearLayout.LayoutParams params = + new LinearLayout.LayoutParams(LinearLayout.LayoutParams.MATCH_PARENT, + LinearLayout.LayoutParams.WRAP_CONTENT); + params.weight = 1; + setLayoutParams(params); + } + + public void initPaint(int mFillColor) { + progressPaint = new Paint(); + progressPaint.setColor(mFillColor); + progressPaint.setStyle(Paint.Style.FILL); + progressPaint.setAntiAlias(true); + } + + @Override protected void onDraw(Canvas canvas) { + super.onDraw(canvas); + canvas.drawRect(getLeft(), 0, getRight(), getBottom(), progressPaint); + } + } + +} diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index 5e29dd8..1966661 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -8,7 +8,6 @@ import android.view.ViewGroup; import android.widget.TextView; import in.arjsna.audiorecorder.R; -import in.arjsna.audiorecorder.db.RecordItemDataSource; import in.arjsna.audiorecorder.db.RecordingItem; import java.util.ArrayList; import java.util.concurrent.TimeUnit; @@ -56,7 +55,7 @@ public PlayListAdapter(Context context, ArrayList recordingItems) @Override public RecordingsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = inflater. - inflate(R.layout.card_view, parent, false); + inflate(R.layout.record_list_item, parent, false); return new RecordingsViewHolder(itemView); } diff --git a/app/src/main/res/layout/card_view.xml b/app/src/main/res/layout/record_list_item.xml similarity index 100% rename from app/src/main/res/layout/card_view.xml rename to app/src/main/res/layout/record_list_item.xml diff --git a/app/src/main/res/values/attrs.xml b/app/src/main/res/values/attrs.xml index 25ff2ac..cfa162a 100644 --- a/app/src/main/res/values/attrs.xml +++ b/app/src/main/res/values/attrs.xml @@ -25,4 +25,11 @@ + + + + + + + \ No newline at end of file From 128b36d40a93e15f7468bbfe7a9cdb09f91320ea Mon Sep 17 00:00:00 2001 From: Arjun Date: Sat, 23 Sep 2017 12:50:06 +0530 Subject: [PATCH 02/26] part complete fill seek bar --- .../audiorecorder/libs/FillSeekBar.java | 6 +--- .../playback/PlaybackFragment.java | 1 + .../playlist/PlayListAdapter.java | 2 +- app/src/main/res/layout/record_list_item.xml | 30 +++++++++---------- 4 files changed, 18 insertions(+), 21 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index e7ee676..f5b4f33 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -19,10 +19,6 @@ import java.util.TimerTask; public class FillSeekBar extends FrameLayout { - protected static final int LARGE = 1; - protected static final int MIDDLE = 2; - protected static final int LITTLE = 3; - private int mProgress; private Solid mSolid; @@ -133,7 +129,7 @@ public void setAutoProgress(long offset, long finalVal) { } }; - static class Solid extends View { + private static class Solid extends View { private Paint progressPaint; diff --git a/app/src/main/java/in/arjsna/audiorecorder/playback/PlaybackFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playback/PlaybackFragment.java index d8f11da..e29992b 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playback/PlaybackFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playback/PlaybackFragment.java @@ -265,6 +265,7 @@ private void stopPlaying() { if (mMediaPlayer != null) { int mCurrentPosition = mMediaPlayer.getCurrentPosition(); + Log.i("Seekbar", " " + mCurrentPosition); mSeekBar.setProgress(mCurrentPosition); long minutes = TimeUnit.MILLISECONDS.toMinutes(mCurrentPosition); diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index 1966661..c970a49 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -84,7 +84,7 @@ static class RecordingsViewHolder extends RecyclerView.ViewHolder { vName = v.findViewById(R.id.file_name_text); vLength = v.findViewById(R.id.file_length_text); vDateAdded = v.findViewById(R.id.file_date_added_text); - cardView = v.findViewById(R.id.card_view); + cardView = v.findViewById(R.id.record_item_root_view); } } diff --git a/app/src/main/res/layout/record_list_item.xml b/app/src/main/res/layout/record_list_item.xml index 1d8a352..24bc64d 100644 --- a/app/src/main/res/layout/record_list_item.xml +++ b/app/src/main/res/layout/record_list_item.xml @@ -1,20 +1,20 @@ - - - - - \ No newline at end of file + + \ No newline at end of file From 2ce2b696c45c547305fde02a0edbb4850817ad13 Mon Sep 17 00:00:00 2001 From: Arjun Date: Sun, 24 Sep 2017 11:33:54 +0530 Subject: [PATCH 03/26] wroking progress --- .../java/in/arjsna/audiorecorder/libs/FillSeekBar.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index f5b4f33..28b1c55 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -44,7 +44,7 @@ public FillSeekBar(Context context, AttributeSet attrs) { } public void setProgress(int progress) { - this.mProgress = progress > 100 ? 100 : progress; + this.mProgress = progress > 10000 ? 10000 : progress; computeProgressRigth(); } @@ -56,7 +56,7 @@ public void setProgress(int progress) { } private void computeProgressRigth() { - mSolidRight = (int) (getWidth() * (1f - mProgress / 100f)); + mSolidRight = (int) (getWidth() * (1f - mProgress / 10000f)); ViewGroup.LayoutParams params = mSolid.getLayoutParams(); if (params != null) { ((LayoutParams) params).rightMargin = mSolidRight; @@ -115,7 +115,7 @@ public SavedState[] newArray(int size) { public void setAutoProgress(long offset, long finalVal) { timer = new Timer(); this.finalValue = finalVal; - timer.scheduleAtFixedRate(timerTask, 0 , 100); + timer.scheduleAtFixedRate(timerTask, 0 , 10); } Handler handler = new Handler(Looper.getMainLooper()); Timer timer; @@ -123,7 +123,7 @@ public void setAutoProgress(long offset, long finalVal) { @Override public void run() { handler.post(new Runnable() { @Override public void run() { - setProgress(mProgress + 1); + setProgress(mProgress + 10); } }); } From 398501144e524dd28ddfa927617975cfafe4d0fd Mon Sep 17 00:00:00 2001 From: Arjun Date: Mon, 25 Sep 2017 12:01:55 +0530 Subject: [PATCH 04/26] play pause audio player --- .../audiorecorder/mvpbase/IMVPPresenter.java | 3 ++ .../playlist/PlayListFragment.java | 37 +++++++++++++++++-- .../playlist/PlayListMVPView.java | 9 +++++ .../playlist/PlayListPresenter.java | 2 + .../playlist/PlayListPresenterImpl.java | 32 ++++++++++++++++ 5 files changed, 79 insertions(+), 4 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/mvpbase/IMVPPresenter.java b/app/src/main/java/in/arjsna/audiorecorder/mvpbase/IMVPPresenter.java index b920bd4..37a03c8 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/mvpbase/IMVPPresenter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/mvpbase/IMVPPresenter.java @@ -1,6 +1,9 @@ package in.arjsna.audiorecorder.mvpbase; +import in.arjsna.audiorecorder.db.RecordingItem; + public interface IMVPPresenter { void onAttach(V view); + void onDetach(); } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index 3859cd5..4159c07 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -1,6 +1,7 @@ package in.arjsna.audiorecorder.playlist; import android.content.Intent; +import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.FileObserver; @@ -18,11 +19,11 @@ import in.arjsna.audiorecorder.R; import in.arjsna.audiorecorder.db.RecordingItem; import in.arjsna.audiorecorder.di.components.ActivityComponent; -import in.arjsna.audiorecorder.playback.PlaybackFragment; import in.arjsna.audiorecorder.mvpbase.BaseFragment; import in.arjsna.audiorecorder.recordingservice.Constants; import in.arjsna.audiorecorder.theme.ThemeHelper; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import javax.inject.Inject; @@ -38,6 +39,7 @@ public class PlayListFragment extends BaseFragment public PlayListPresenter playListPresenter; private RecyclerView mRecordingsListView; private TextView emptyListLabel; + private MediaPlayer mMediaPlayer; public static PlayListFragment newInstance() { return new PlayListFragment(); @@ -57,6 +59,7 @@ public void onCreate(Bundle savedInstanceState) { Bundle savedInstanceState) { View v = inflater.inflate(R.layout.fragment_file_viewer, container, false); initViews(v); + mMediaPlayer = new MediaPlayer(); return v; } @@ -106,8 +109,8 @@ private void initViews(View v) { } @Override public void onDestroy() { - super.onDestroy(); playListPresenter.onDetach(); + super.onDestroy(); } @Override public void showData(ArrayList recordingItems) { @@ -227,8 +230,34 @@ private void deleteFileDialog(final RecordingItem recordingItem, int position) { } @Override public void onItemClick(int position, RecordingItem recordingItem) { - PlaybackFragment playbackFragment = new PlaybackFragment().newInstance(recordingItem); - playbackFragment.show(getActivity().getSupportFragmentManager(), "dialog_playback"); + //PlaybackFragment playbackFragment = new PlaybackFragment().newInstance(recordingItem); + //playbackFragment.show(getActivity().getSupportFragmentManager(), "dialog_playback"); + playListPresenter.onListItemClicked(position, recordingItem); + } + + @Override public void pauseMediaPlayer(int position) { + mMediaPlayer.pause(); + } + + @Override public void resumeMediaPlayer(int position) { + mMediaPlayer.start(); + } + + @Override public void stopMediaPlayer(int currentPlayingItem) { + if (mMediaPlayer != null) { + mMediaPlayer.stop(); + mMediaPlayer.reset(); + mMediaPlayer.release(); + mMediaPlayer = null; + } + } + + @Override public void startMediaPlayer(int position, RecordingItem recordingItem) + throws IOException { + mMediaPlayer = new MediaPlayer(); + mMediaPlayer.setDataSource(recordingItem.getFilePath()); + mMediaPlayer.prepare(); + mMediaPlayer.setOnPreparedListener(MediaPlayer::start); } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java index 52ff586..d5824e4 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java @@ -2,6 +2,7 @@ import in.arjsna.audiorecorder.db.RecordingItem; import in.arjsna.audiorecorder.mvpbase.IMVPView; +import java.io.IOException; import java.util.ArrayList; public interface PlayListMVPView extends IMVPView { @@ -24,4 +25,12 @@ public interface PlayListMVPView extends IMVPView { void showError(String message); void notifyListItemRemove(Integer position); + + void pauseMediaPlayer(int position); + + void stopMediaPlayer(int currentPlayingItem); + + void startMediaPlayer(int position, RecordingItem recordingItem) throws IOException; + + void resumeMediaPlayer(int position); } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java index af5d7d5..80bda93 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java @@ -9,4 +9,6 @@ public interface PlayListPresenter extends IMVPPresen void renameFile(RecordingItem recordingItem, int position, String value); void deleteFile(RecordingItem recordingItem, int position); + + void onListItemClicked(int position, RecordingItem recordingItem); } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index 89eb14b..2bf3e2d 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -12,6 +12,7 @@ import io.reactivex.disposables.Disposable; import io.reactivex.schedulers.Schedulers; import java.io.File; +import java.io.IOException; import java.util.ArrayList; import javax.inject.Inject; @@ -20,6 +21,10 @@ public class PlayListPresenterImpl extends BasePresen @Inject public RecordItemDataSource recordItemDataSource; + private int currentPlayingItem; + private boolean isAudioPlaying = false; + private boolean isAudioPaused = false; + @Inject public PlayListPresenterImpl(CompositeDisposable compositeDisposable) { super(compositeDisposable); @@ -82,6 +87,32 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, }); } + @Override public void onListItemClicked(int position, RecordingItem recordingItem) { + try { + if (isAudioPlaying) { + if (currentPlayingItem == position) { + if (isAudioPaused) { + isAudioPaused = false; + getAttachedView().resumeMediaPlayer(position); + } else { + isAudioPaused = true; + getAttachedView().pauseMediaPlayer(position); + } + } else { + getAttachedView().stopMediaPlayer(currentPlayingItem); + getAttachedView().startMediaPlayer(position, recordingItem); + currentPlayingItem = position; + } + } else { + isAudioPlaying = true; + getAttachedView().startMediaPlayer(position, recordingItem); + currentPlayingItem = position; + } + } catch (IOException e) { + getAttachedView().showError("Failed to start media Player"); + } + } + private Single removeFile(RecordingItem recordingItem, int position) { return Single.create((SingleOnSubscribe) e -> { File file = new File(recordingItem.getFilePath()); @@ -96,6 +127,7 @@ private Single removeFile(RecordingItem recordingItem, int position) { @Override public void onDetach() { getAttachedView().stopWatchingForFileChanges(); + getAttachedView().stopMediaPlayer(currentPlayingItem); super.onDetach(); } From a735a8dd926d47fc9048acb44d8d913092be75ff Mon Sep 17 00:00:00 2001 From: Arjun Date: Mon, 25 Sep 2017 12:41:02 +0530 Subject: [PATCH 05/26] seek bar progress based on length --- .../audiorecorder/libs/FillSeekBar.java | 24 ++++++++++++++----- .../playlist/PlayListAdapter.java | 5 +++- app/src/main/res/layout/record_list_item.xml | 1 + 3 files changed, 23 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index 28b1c55..918058a 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -10,6 +10,7 @@ import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; +import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; @@ -25,7 +26,7 @@ public class FillSeekBar extends FrameLayout { private final int DEFAULT_FILL_COLOR = Color.WHITE; private final int DEFAULT_PROGRESS = 80; private int mSolidRight; - private long finalValue; + private double mMaxValue = 1.0; public FillSeekBar(Context context, AttributeSet attrs) { super(context, attrs); @@ -40,11 +41,15 @@ public FillSeekBar(Context context, AttributeSet attrs) { mSolid.initPaint(mFillColor); addView(mSolid); setProgress(0); - setAutoProgress(1000, 1000); + } + + public void setMaxVal(double maxVal) { + this.mMaxValue = maxVal; + setAutoProgress(); } public void setProgress(int progress) { - this.mProgress = progress > 10000 ? 10000 : progress; + this.mProgress = progress > mMaxValue ? (int) mMaxValue : progress; computeProgressRigth(); } @@ -56,7 +61,8 @@ public void setProgress(int progress) { } private void computeProgressRigth() { - mSolidRight = (int) (getWidth() * (1f - mProgress / 10000f)); + mSolidRight = (int) (getWidth() * (1f - mProgress / mMaxValue)); + Log.i("Stats " , mSolidRight + " " + mProgress); ViewGroup.LayoutParams params = mSolid.getLayoutParams(); if (params != null) { ((LayoutParams) params).rightMargin = mSolidRight; @@ -112,9 +118,8 @@ public SavedState[] newArray(int size) { }; } - public void setAutoProgress(long offset, long finalVal) { + public void setAutoProgress() { timer = new Timer(); - this.finalValue = finalVal; timer.scheduleAtFixedRate(timerTask, 0 , 10); } Handler handler = new Handler(Looper.getMainLooper()); @@ -159,4 +164,11 @@ public void initPaint(int mFillColor) { } } + @Override protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + if (timer != null) { + timer.cancel(); + timer = null; + } + } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index c970a49..d318cca 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -9,6 +9,7 @@ import android.widget.TextView; import in.arjsna.audiorecorder.R; import in.arjsna.audiorecorder.db.RecordingItem; +import in.arjsna.audiorecorder.libs.FillSeekBar; import java.util.ArrayList; import java.util.concurrent.TimeUnit; @@ -35,7 +36,7 @@ public PlayListAdapter(Context context, ArrayList recordingItems) long minutes = TimeUnit.MILLISECONDS.toMinutes(itemDuration); long seconds = TimeUnit.MILLISECONDS.toSeconds(itemDuration) - TimeUnit.MINUTES.toSeconds(minutes); - + holder.fillSeekBar.setMaxVal(itemDuration); holder.vName.setText(currentRecording.getName()); holder.vLength.setText( String.format(mContext.getString(R.string.play_time_format), minutes, seconds)); @@ -78,6 +79,7 @@ static class RecordingsViewHolder extends RecyclerView.ViewHolder { final TextView vLength; final TextView vDateAdded; final View cardView; + final FillSeekBar fillSeekBar; RecordingsViewHolder(View v) { super(v); @@ -85,6 +87,7 @@ static class RecordingsViewHolder extends RecyclerView.ViewHolder { vLength = v.findViewById(R.id.file_length_text); vDateAdded = v.findViewById(R.id.file_date_added_text); cardView = v.findViewById(R.id.record_item_root_view); + fillSeekBar = v.findViewById(R.id.attached_seek_bar); } } diff --git a/app/src/main/res/layout/record_list_item.xml b/app/src/main/res/layout/record_list_item.xml index 24bc64d..8d0a8b6 100644 --- a/app/src/main/res/layout/record_list_item.xml +++ b/app/src/main/res/layout/record_list_item.xml @@ -11,6 +11,7 @@ app:cardElevation="3dp" > Date: Mon, 25 Sep 2017 12:59:49 +0530 Subject: [PATCH 06/26] ui update for media player complete --- .../audiorecorder/db/RecordingItem.java | 7 ++++ .../audiorecorder/libs/FillSeekBar.java | 35 ++++++++++++++----- .../playlist/PlayListAdapter.java | 14 ++++++++ .../playlist/PlayListFragment.java | 1 + 4 files changed, 48 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java b/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java index 4caf93c..30fe846 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java +++ b/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java @@ -1,6 +1,7 @@ package in.arjsna.audiorecorder.db; import android.arch.persistence.room.Entity; +import android.arch.persistence.room.Ignore; import android.arch.persistence.room.PrimaryKey; import android.os.Parcel; import android.os.Parcelable; @@ -15,6 +16,12 @@ public class RecordingItem implements Parcelable { private long mLength; // length of recording in seconds private long mTime; // date/time of the recording + @Ignore + public boolean isPlaying; + + @Ignore + public boolean isPaused; + public RecordingItem() { } diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index 918058a..912b1f7 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -45,12 +45,15 @@ public FillSeekBar(Context context, AttributeSet attrs) { public void setMaxVal(double maxVal) { this.mMaxValue = maxVal; - setAutoProgress(); } public void setProgress(int progress) { - this.mProgress = progress > mMaxValue ? (int) mMaxValue : progress; - computeProgressRigth(); + if (progress > mMaxValue) { + stopProgress(); + } else { + mProgress = progress; + computeProgressRigth(); + } } @Override public void onWindowFocusChanged(boolean hasWindowFocus) { @@ -118,7 +121,25 @@ public SavedState[] newArray(int size) { }; } - public void setAutoProgress() { + public void pauseProgress() { + if (timer != null) { + timer.cancel(); + } + } + + public void stopProgress() { + if (timer != null) { + timer.cancel(); + } + setProgress(0); + } + + public void resumeProgress() { + timer = new Timer(); + timer.scheduleAtFixedRate(timerTask, 0 , 10); + } + + public void startProgress() { timer = new Timer(); timer.scheduleAtFixedRate(timerTask, 0 , 10); } @@ -126,11 +147,7 @@ public void setAutoProgress() { Timer timer; TimerTask timerTask = new TimerTask() { @Override public void run() { - handler.post(new Runnable() { - @Override public void run() { - setProgress(mProgress + 10); - } - }); + handler.post(() -> setProgress(mProgress + 10)); } }; diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index d318cca..a752f7e 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -52,6 +52,20 @@ public PlayListAdapter(Context context, ArrayList recordingItems) listItemEventsListener.onItemLongClick(position, currentRecording); return false; }); + if (currentRecording.isPlaying) { + if (currentRecording.isPaused) { + holder.fillSeekBar.pauseProgress(); + } else { + holder.fillSeekBar.startProgress(); + } + } else { + holder.fillSeekBar.stopProgress(); + } + } + + public void startProgress(int position) { + recordingItems.get(position).isPlaying = true; + notifyItemChanged(position); } @Override public RecordingsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index 4159c07..cabb328 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -258,6 +258,7 @@ private void deleteFileDialog(final RecordingItem recordingItem, int position) { mMediaPlayer.setDataSource(recordingItem.getFilePath()); mMediaPlayer.prepare(); mMediaPlayer.setOnPreparedListener(MediaPlayer::start); + mPlayListAdapter.startProgress(position); } } From 430e5c75587952241dce1ce242f6b58498fb740a Mon Sep 17 00:00:00 2001 From: Arjun Date: Mon, 25 Sep 2017 13:21:49 +0530 Subject: [PATCH 07/26] more functionalities --- .../audiorecorder/libs/FillSeekBar.java | 21 ++++++++++++------- .../playlist/PlayListAdapter.java | 15 +++++++++++++ .../playlist/PlayListFragment.java | 3 +++ 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index 912b1f7..be1367c 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -130,26 +130,30 @@ public void pauseProgress() { public void stopProgress() { if (timer != null) { timer.cancel(); + setProgress(0); } - setProgress(0); } public void resumeProgress() { timer = new Timer(); - timer.scheduleAtFixedRate(timerTask, 0 , 10); + timer.scheduleAtFixedRate(getNewTask(), 0 , 10); } public void startProgress() { timer = new Timer(); - timer.scheduleAtFixedRate(timerTask, 0 , 10); + timer.scheduleAtFixedRate(getNewTask(), 0 , 10); } + Handler handler = new Handler(Looper.getMainLooper()); Timer timer; - TimerTask timerTask = new TimerTask() { - @Override public void run() { - handler.post(() -> setProgress(mProgress + 10)); - } - }; + + private TimerTask getNewTask() { + return new TimerTask() { + @Override public void run() { + handler.post(() -> setProgress(mProgress + 10)); + } + }; + } private static class Solid extends View { @@ -177,6 +181,7 @@ public void initPaint(int mFillColor) { @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); + Log.i("Statsinneer " , getRight() + " "); canvas.drawRect(getLeft(), 0, getRight(), getBottom(), progressPaint); } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index a752f7e..b30d951 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -68,6 +68,21 @@ public void startProgress(int position) { notifyItemChanged(position); } + public void stopProgress(int currentPlayingItem) { + recordingItems.get(currentPlayingItem).isPlaying = false; + notifyItemChanged(currentPlayingItem); + } + + public void pauseProgress(int currentPlayingItem) { + recordingItems.get(currentPlayingItem).isPaused = true; + notifyItemChanged(currentPlayingItem); + } + + public void resumeProgress(int currentPlayingItem) { + recordingItems.get(currentPlayingItem).isPaused = false; + notifyItemChanged(currentPlayingItem); + } + @Override public RecordingsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = inflater. inflate(R.layout.record_list_item, parent, false); diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index cabb328..d5bf6ee 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -237,10 +237,12 @@ private void deleteFileDialog(final RecordingItem recordingItem, int position) { @Override public void pauseMediaPlayer(int position) { mMediaPlayer.pause(); + mPlayListAdapter.pauseProgress(position); } @Override public void resumeMediaPlayer(int position) { mMediaPlayer.start(); + mPlayListAdapter.resumeProgress(position); } @Override public void stopMediaPlayer(int currentPlayingItem) { @@ -250,6 +252,7 @@ private void deleteFileDialog(final RecordingItem recordingItem, int position) { mMediaPlayer.release(); mMediaPlayer = null; } + mPlayListAdapter.stopProgress(currentPlayingItem); } @Override public void startMediaPlayer(int position, RecordingItem recordingItem) From 7db3efc1a94cd3d2f79bf8ed7afcb37a672f0db3 Mon Sep 17 00:00:00 2001 From: Arjun Date: Tue, 26 Sep 2017 17:28:49 +0530 Subject: [PATCH 08/26] refactored adapter code --- .../di/modules/ActivityModule.java | 8 +- .../playlist/ListItemEventsListener.java | 9 --- .../playlist/PlayListAdapter.java | 80 +++++++++---------- .../playlist/PlayListFragment.java | 56 +++++++------ .../playlist/PlayListMVPView.java | 10 ++- .../playlist/PlayListPresenter.java | 18 ++++- .../playlist/PlayListPresenterImpl.java | 60 ++++++++++---- 7 files changed, 143 insertions(+), 98 deletions(-) delete mode 100644 app/src/main/java/in/arjsna/audiorecorder/playlist/ListItemEventsListener.java diff --git a/app/src/main/java/in/arjsna/audiorecorder/di/modules/ActivityModule.java b/app/src/main/java/in/arjsna/audiorecorder/di/modules/ActivityModule.java index b9a129d..36ac978 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/di/modules/ActivityModule.java +++ b/app/src/main/java/in/arjsna/audiorecorder/di/modules/ActivityModule.java @@ -4,12 +4,12 @@ import android.support.v7.widget.LinearLayoutManager; import dagger.Module; import dagger.Provides; -import in.arjsna.audiorecorder.playlist.PlayListAdapter; import in.arjsna.audiorecorder.audiorecording.AudioRecordMVPView; import in.arjsna.audiorecorder.audiorecording.AudioRecordPresenter; import in.arjsna.audiorecorder.audiorecording.AudioRecordPresenterImpl; import in.arjsna.audiorecorder.di.qualifiers.ActivityContext; import in.arjsna.audiorecorder.di.scopes.ActivityScope; +import in.arjsna.audiorecorder.playlist.PlayListAdapter; import in.arjsna.audiorecorder.playlist.PlayListMVPView; import in.arjsna.audiorecorder.playlist.PlayListPresenter; import in.arjsna.audiorecorder.playlist.PlayListPresenterImpl; @@ -43,12 +43,6 @@ LinearLayoutManager provideLinearLayoutManager(@ActivityContext AppCompatActivit return new LinearLayoutManager(context); } - @Provides - @ActivityScope - PlayListAdapter providesPlayListAdapter(@ActivityContext AppCompatActivity context) { - return new PlayListAdapter(context, new ArrayList<>()); - } - @Provides @ActivityScope AudioRecordPresenter provideAudioRecordPresenter( diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/ListItemEventsListener.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/ListItemEventsListener.java deleted file mode 100644 index f2b04c2..0000000 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/ListItemEventsListener.java +++ /dev/null @@ -1,9 +0,0 @@ -package in.arjsna.audiorecorder.playlist; - -import in.arjsna.audiorecorder.db.RecordingItem; - -interface ListItemEventsListener { - void onItemLongClick(int position, RecordingItem recordingItem); - - void onItemClick(int position, RecordingItem recordingItem); -} diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index b30d951..2033f91 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -1,6 +1,7 @@ package in.arjsna.audiorecorder.playlist; import android.content.Context; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.RecyclerView; import android.text.format.DateUtils; import android.view.LayoutInflater; @@ -9,9 +10,10 @@ import android.widget.TextView; import in.arjsna.audiorecorder.R; import in.arjsna.audiorecorder.db.RecordingItem; +import in.arjsna.audiorecorder.di.qualifiers.ActivityContext; import in.arjsna.audiorecorder.libs.FillSeekBar; -import java.util.ArrayList; import java.util.concurrent.TimeUnit; +import javax.inject.Inject; public class PlayListAdapter extends RecyclerView.Adapter { @@ -20,18 +22,21 @@ public class PlayListAdapter extends RecyclerView.Adapter recordingItems; - private PlayListFragment listItemEventsListener; + private final PlayListPresenter playListPresenter; + //private final ArrayList recordingItems; - public PlayListAdapter(Context context, ArrayList recordingItems) { + @Inject + public PlayListAdapter(@ActivityContext AppCompatActivity context, + PlayListPresenter playListPresenter) { mContext = context; - this.recordingItems = recordingItems; + //this.recordingItems = recordingItems; + this.playListPresenter = playListPresenter; inflater = LayoutInflater.from(mContext); } @Override public void onBindViewHolder(final RecordingsViewHolder holder, int position) { - RecordingItem currentRecording = recordingItems.get(position); + RecordingItem currentRecording = playListPresenter.getListItemAt(position); long itemDuration = currentRecording.getLength(); long minutes = TimeUnit.MILLISECONDS.toMinutes(itemDuration); long seconds = @@ -46,12 +51,13 @@ public PlayListAdapter(Context context, ArrayList recordingItems) | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR)); - holder.cardView.setOnClickListener(view -> listItemEventsListener.onItemClick(position, currentRecording)); + holder.cardView.setOnClickListener(view -> playListPresenter.onListItemClick(position)); holder.cardView.setOnLongClickListener(v -> { - listItemEventsListener.onItemLongClick(position, currentRecording); + playListPresenter.onListItemLongClick(position); return false; }); + if (currentRecording.isPlaying) { if (currentRecording.isPaused) { holder.fillSeekBar.pauseProgress(); @@ -63,25 +69,25 @@ public PlayListAdapter(Context context, ArrayList recordingItems) } } - public void startProgress(int position) { - recordingItems.get(position).isPlaying = true; - notifyItemChanged(position); - } - - public void stopProgress(int currentPlayingItem) { - recordingItems.get(currentPlayingItem).isPlaying = false; - notifyItemChanged(currentPlayingItem); - } - - public void pauseProgress(int currentPlayingItem) { - recordingItems.get(currentPlayingItem).isPaused = true; - notifyItemChanged(currentPlayingItem); - } - - public void resumeProgress(int currentPlayingItem) { - recordingItems.get(currentPlayingItem).isPaused = false; - notifyItemChanged(currentPlayingItem); - } + //public void startProgress(int position) { + // recordingItems.get(position).isPlaying = true; + // notifyItemChanged(position); + //} + // + //public void stopProgress(int currentPlayingItem) { + // recordingItems.get(currentPlayingItem).isPlaying = false; + // notifyItemChanged(currentPlayingItem); + //} + // + //public void pauseProgress(int currentPlayingItem) { + // recordingItems.get(currentPlayingItem).isPaused = true; + // notifyItemChanged(currentPlayingItem); + //} + // + //public void resumeProgress(int currentPlayingItem) { + // recordingItems.get(currentPlayingItem).isPaused = false; + // notifyItemChanged(currentPlayingItem); + //} @Override public RecordingsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { View itemView = inflater. @@ -89,19 +95,11 @@ public void resumeProgress(int currentPlayingItem) { return new RecordingsViewHolder(itemView); } - void addAllAndNotify(ArrayList recordingItems) { - this.recordingItems.addAll(recordingItems); - notifyDataSetChanged(); - } - - void setListItemEventsListener(PlayListFragment listItemEventsListener) { - this.listItemEventsListener = listItemEventsListener; - } - - void removeItemAndNotify(int position) { - recordingItems.remove(position); - notifyItemRemoved(position); - } + // + //void removeItemAndNotify(int position) { + // recordingItems.remove(position); + // notifyItemRemoved(position); + //} static class RecordingsViewHolder extends RecyclerView.ViewHolder { final TextView vName; @@ -121,7 +119,7 @@ static class RecordingsViewHolder extends RecyclerView.ViewHolder { } @Override public int getItemCount() { - return recordingItems.size(); + return playListPresenter.getListItemCount(); } //TODO diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index d5bf6ee..ba9e170 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -1,11 +1,13 @@ package in.arjsna.audiorecorder.playlist; +import android.content.Context; import android.content.Intent; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.FileObserver; import android.support.v7.app.AlertDialog; +import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -19,6 +21,7 @@ import in.arjsna.audiorecorder.R; import in.arjsna.audiorecorder.db.RecordingItem; import in.arjsna.audiorecorder.di.components.ActivityComponent; +import in.arjsna.audiorecorder.di.qualifiers.ActivityContext; import in.arjsna.audiorecorder.mvpbase.BaseFragment; import in.arjsna.audiorecorder.recordingservice.Constants; import in.arjsna.audiorecorder.theme.ThemeHelper; @@ -28,7 +31,7 @@ import javax.inject.Inject; public class PlayListFragment extends BaseFragment - implements PlayListMVPView, ListItemEventsListener { + implements PlayListMVPView{ private static final String LOG_TAG = "PlayListFragment"; @Inject @@ -37,6 +40,9 @@ public class PlayListFragment extends BaseFragment public LinearLayoutManager llm; @Inject public PlayListPresenter playListPresenter; + @Inject + public PlayListPresenter playListPresenter2; + private RecyclerView mRecordingsListView; private TextView emptyListLabel; private MediaPlayer mMediaPlayer; @@ -76,7 +82,6 @@ private void initViews(View v) { mRecordingsListView.setLayoutManager(llm); mRecordingsListView.setItemAnimator(new DefaultItemAnimator()); mRecordingsListView.setAdapter(mPlayListAdapter); - mPlayListAdapter.setListItemEventsListener(this); playListPresenter.onViewInitialised(); } @@ -113,8 +118,8 @@ private void initViews(View v) { super.onDestroy(); } - @Override public void showData(ArrayList recordingItems) { - mPlayListAdapter.addAllAndNotify(recordingItems); + @Override public void notifyListAdapter() { + mPlayListAdapter.notifyDataSetChanged(); } @Override public void setRecordingListVisible() { @@ -150,10 +155,10 @@ private void initViews(View v) { } @Override public void notifyListItemRemove(Integer position) { - mPlayListAdapter.removeItemAndNotify(position); + mPlayListAdapter.notifyItemRemoved(position); } - @Override public void onItemLongClick(int position, RecordingItem recordingItem) { + @Override public void showFileOptionDialog(int position, RecordingItem recordingItem) { ArrayList fileOptions = new ArrayList<>(); fileOptions.add(getString(R.string.dialog_file_share)); fileOptions.add(getString(R.string.dialog_file_rename)); @@ -167,13 +172,13 @@ private void initViews(View v) { builder.setItems(items, (dialog, listItem) -> { switch (listItem) { case 0: - shareFileDialog(recordingItem); + playListPresenter.shareFileClicked(position); break; case 1: - renameFileDialog(recordingItem, position); + playListPresenter.renameFileClicked(position); break; case 2: - deleteFileDialog(recordingItem, position); + playListPresenter.deleteFileClicked(position); break; } }); @@ -185,16 +190,18 @@ private void initViews(View v) { alert.show(); } - private void shareFileDialog(RecordingItem recordingItem) { + @Override + public void shareFileDialog(String filePath) { Intent shareIntent = new Intent(); shareIntent.setAction(Intent.ACTION_SEND); shareIntent.putExtra(Intent.EXTRA_STREAM, - Uri.fromFile(new File(recordingItem.getFilePath()))); + Uri.fromFile(new File(filePath))); shareIntent.setType("audio/mp4"); getActivity().startActivity(Intent.createChooser(shareIntent, getText(R.string.send_to))); } - private void renameFileDialog(final RecordingItem recordingItem, int position) { + @Override + public void showRenameFileDialog(int position) { AlertDialog.Builder renameFileBuilder = new AlertDialog.Builder(getActivity()); View view = LayoutInflater.from(getActivity()).inflate(R.layout.dialog_rename_file, null); final EditText input = view.findViewById(R.id.new_name); @@ -203,7 +210,7 @@ private void renameFileDialog(final RecordingItem recordingItem, int position) { renameFileBuilder.setPositiveButton(getString(R.string.dialog_action_ok), (dialog, id) -> { String value = input.getText().toString().trim() + Constants.AUDIO_RECORDER_FILE_EXT_WAV; - playListPresenter.renameFile(recordingItem, position, value); + playListPresenter.renameFile(position, value); dialog.cancel(); }); renameFileBuilder.setNegativeButton(getActivity().getString(R.string.dialog_action_cancel), @@ -213,14 +220,15 @@ private void renameFileDialog(final RecordingItem recordingItem, int position) { alert.show(); } - private void deleteFileDialog(final RecordingItem recordingItem, int position) { + @Override + public void showDeleteFileDialog(int position) { AlertDialog.Builder confirmDelete = new AlertDialog.Builder(getActivity()); confirmDelete.setTitle(getString(R.string.dialog_title_delete)); confirmDelete.setMessage(getString(R.string.dialog_text_delete)); confirmDelete.setCancelable(true); confirmDelete.setPositiveButton(getString(R.string.dialog_action_yes), (dialog, id) -> { - playListPresenter.deleteFile(recordingItem, position); + playListPresenter.deleteFile(position); dialog.cancel(); }); confirmDelete.setNegativeButton(getString(R.string.dialog_action_no), @@ -229,20 +237,20 @@ private void deleteFileDialog(final RecordingItem recordingItem, int position) { alert.show(); } - @Override public void onItemClick(int position, RecordingItem recordingItem) { - //PlaybackFragment playbackFragment = new PlaybackFragment().newInstance(recordingItem); - //playbackFragment.show(getActivity().getSupportFragmentManager(), "dialog_playback"); - playListPresenter.onListItemClicked(position, recordingItem); - } + //@Override public void onItemClick(int position, RecordingItem recordingItem) { + // //PlaybackFragment playbackFragment = new PlaybackFragment().newInstance(recordingItem); + // //playbackFragment.show(getActivity().getSupportFragmentManager(), "dialog_playback"); + // playListPresenter.onListItemClicked(position, recordingItem); + //} @Override public void pauseMediaPlayer(int position) { mMediaPlayer.pause(); - mPlayListAdapter.pauseProgress(position); + //mPlayListAdapter.pauseProgress(position); } @Override public void resumeMediaPlayer(int position) { mMediaPlayer.start(); - mPlayListAdapter.resumeProgress(position); + //mPlayListAdapter.resumeProgress(position); } @Override public void stopMediaPlayer(int currentPlayingItem) { @@ -252,7 +260,7 @@ private void deleteFileDialog(final RecordingItem recordingItem, int position) { mMediaPlayer.release(); mMediaPlayer = null; } - mPlayListAdapter.stopProgress(currentPlayingItem); + //mPlayListAdapter.stopProgress(currentPlayingItem); } @Override public void startMediaPlayer(int position, RecordingItem recordingItem) @@ -261,7 +269,7 @@ private void deleteFileDialog(final RecordingItem recordingItem, int position) { mMediaPlayer.setDataSource(recordingItem.getFilePath()); mMediaPlayer.prepare(); mMediaPlayer.setOnPreparedListener(MediaPlayer::start); - mPlayListAdapter.startProgress(position); + //mPlayListAdapter.startProgress(position); } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java index d5824e4..dcda0ed 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java @@ -6,7 +6,7 @@ import java.util.ArrayList; public interface PlayListMVPView extends IMVPView { - void showData(ArrayList recordingItems); + void notifyListAdapter(); void setRecordingListVisible(); @@ -33,4 +33,12 @@ public interface PlayListMVPView extends IMVPView { void startMediaPlayer(int position, RecordingItem recordingItem) throws IOException; void resumeMediaPlayer(int position); + + void showFileOptionDialog(int position, RecordingItem recordingItem); + + void shareFileDialog(String filePath); + + void showRenameFileDialog(int position); + + void showDeleteFileDialog(int position); } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java index 80bda93..79bc08c 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java @@ -6,9 +6,23 @@ public interface PlayListPresenter extends IMVPPresenter { void onViewInitialised(); - void renameFile(RecordingItem recordingItem, int position, String value); + void renameFile(int position, String value); - void deleteFile(RecordingItem recordingItem, int position); + void deleteFile(int position); void onListItemClicked(int position, RecordingItem recordingItem); + + RecordingItem getListItemAt(int position); + + void onListItemClick(int position); + + void onListItemLongClick(int position); + + int getListItemCount(); + + void shareFileClicked(int position); + + void renameFileClicked(int position); + + void deleteFileClicked(int position); } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index 2bf3e2d..f736210 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -14,6 +14,7 @@ import java.io.File; import java.io.IOException; import java.util.ArrayList; +import java.util.List; import javax.inject.Inject; public class PlayListPresenterImpl extends BasePresenter @@ -24,6 +25,7 @@ public class PlayListPresenterImpl extends BasePresen private int currentPlayingItem; private boolean isAudioPlaying = false; private boolean isAudioPaused = false; + private List recordingItems = new ArrayList<>(); @Inject public PlayListPresenterImpl(CompositeDisposable compositeDisposable) { @@ -35,20 +37,21 @@ public PlayListPresenterImpl(CompositeDisposable compositeDisposable) { getAttachedView().startWatchingForFileChanges(); } - @Override public void renameFile(RecordingItem recordingItem, int adapterPosition, String value) { - rename(recordingItem, adapterPosition, value).subscribe(new SingleObserver() { - @Override public void onSubscribe(Disposable d) { + @Override public void renameFile(int adapterPosition, String value) { + rename(recordingItems.get(adapterPosition), adapterPosition, value).subscribe( + new SingleObserver() { + @Override public void onSubscribe(Disposable d) { - } + } - @Override public void onSuccess(Integer position) { - getAttachedView().notifyListItemChange(position); - } + @Override public void onSuccess(Integer position) { + getAttachedView().notifyListItemChange(position); + } - @Override public void onError(Throwable e) { - getAttachedView().showError(e.getMessage()); - } - }); + @Override public void onError(Throwable e) { + getAttachedView().showError(e.getMessage()); + } + }); } private Single rename(RecordingItem recordingItem, int adapterPosition, String name) { @@ -71,8 +74,8 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, }).subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()); } - @Override public void deleteFile(RecordingItem recordingItem, int position) { - removeFile(recordingItem, position).subscribe(new SingleObserver() { + @Override public void deleteFile(int position) { + removeFile(recordingItems.get(position), position).subscribe(new SingleObserver() { @Override public void onSubscribe(Disposable d) { } @@ -113,6 +116,34 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, } } + @Override public RecordingItem getListItemAt(int position) { + return recordingItems.get(position); + } + + @Override public void onListItemClick(int position) { + + } + + @Override public void onListItemLongClick(int position) { + getAttachedView().showFileOptionDialog(position, recordingItems.get(position)); + } + + @Override public int getListItemCount() { + return recordingItems.size(); + } + + @Override public void shareFileClicked(int position) { + getAttachedView().shareFileDialog(recordingItems.get(position).getFilePath()); + } + + @Override public void renameFileClicked(int position) { + getAttachedView().showRenameFileDialog(position); + } + + @Override public void deleteFileClicked(int position) { + getAttachedView().showDeleteFileDialog(position); + } + private Single removeFile(RecordingItem recordingItem, int position) { return Single.create((SingleOnSubscribe) e -> { File file = new File(recordingItem.getFilePath()); @@ -137,7 +168,8 @@ private void fillAdapter() { .observeOn(AndroidSchedulers.mainThread()) .subscribe((recordingItems) -> { if (recordingItems.size() > 0) { - getAttachedView().showData((ArrayList) recordingItems); + this.recordingItems.addAll(recordingItems); + getAttachedView().notifyListAdapter(); } else { getAttachedView().setRecordingListInVisible(); getAttachedView().setEmptyLabelVisible(); From 5ee9c7e723f9bcd3d9d8f424ae71dd09c93c9482 Mon Sep 17 00:00:00 2001 From: Arjun Date: Tue, 26 Sep 2017 17:45:07 +0530 Subject: [PATCH 09/26] bug fixes --- .../arjsna/audiorecorder/playlist/PlayListAdapter.java | 10 +++++----- .../audiorecorder/playlist/PlayListPresenterImpl.java | 1 + 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index 2033f91..bc19eb5 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -51,10 +51,11 @@ public PlayListAdapter(@ActivityContext AppCompatActivity context, | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR)); - holder.cardView.setOnClickListener(view -> playListPresenter.onListItemClick(position)); + holder.cardView.setOnClickListener( + view -> playListPresenter.onListItemClick(holder.getAdapterPosition())); holder.cardView.setOnLongClickListener(v -> { - playListPresenter.onListItemLongClick(position); + playListPresenter.onListItemLongClick(holder.getAdapterPosition()); return false; }); @@ -90,9 +91,8 @@ public PlayListAdapter(@ActivityContext AppCompatActivity context, //} @Override public RecordingsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { - View itemView = inflater. - inflate(R.layout.record_list_item, parent, false); - return new RecordingsViewHolder(itemView); + return new RecordingsViewHolder(inflater. + inflate(R.layout.record_list_item, parent, false)); } // diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index f736210..115d1ca 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -149,6 +149,7 @@ private Single removeFile(RecordingItem recordingItem, int position) { File file = new File(recordingItem.getFilePath()); if (file.delete()) { recordItemDataSource.deleteRecordItem(recordingItem); + recordingItems.remove(position); e.onSuccess(position); } else { e.onError(new Exception("File deletion failed")); From 2cee28cb63604b773d59d4bd183333a8cb81a557 Mon Sep 17 00:00:00 2001 From: Arjun Date: Tue, 26 Sep 2017 19:17:02 +0530 Subject: [PATCH 10/26] player functionalities added --- .../playlist/PlayListFragment.java | 12 +---- .../playlist/PlayListPresenter.java | 2 + .../playlist/PlayListPresenterImpl.java | 49 ++++++++++++++++++- 3 files changed, 52 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index ba9e170..412b5da 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -1,13 +1,11 @@ package in.arjsna.audiorecorder.playlist; -import android.content.Context; import android.content.Intent; import android.media.MediaPlayer; import android.net.Uri; import android.os.Bundle; import android.os.FileObserver; import android.support.v7.app.AlertDialog; -import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -21,7 +19,6 @@ import in.arjsna.audiorecorder.R; import in.arjsna.audiorecorder.db.RecordingItem; import in.arjsna.audiorecorder.di.components.ActivityComponent; -import in.arjsna.audiorecorder.di.qualifiers.ActivityContext; import in.arjsna.audiorecorder.mvpbase.BaseFragment; import in.arjsna.audiorecorder.recordingservice.Constants; import in.arjsna.audiorecorder.theme.ThemeHelper; @@ -31,7 +28,7 @@ import javax.inject.Inject; public class PlayListFragment extends BaseFragment - implements PlayListMVPView{ + implements PlayListMVPView { private static final String LOG_TAG = "PlayListFragment"; @Inject @@ -40,8 +37,6 @@ public class PlayListFragment extends BaseFragment public LinearLayoutManager llm; @Inject public PlayListPresenter playListPresenter; - @Inject - public PlayListPresenter playListPresenter2; private RecyclerView mRecordingsListView; private TextView emptyListLabel; @@ -245,12 +240,10 @@ public void showDeleteFileDialog(int position) { @Override public void pauseMediaPlayer(int position) { mMediaPlayer.pause(); - //mPlayListAdapter.pauseProgress(position); } @Override public void resumeMediaPlayer(int position) { mMediaPlayer.start(); - //mPlayListAdapter.resumeProgress(position); } @Override public void stopMediaPlayer(int currentPlayingItem) { @@ -260,7 +253,6 @@ public void showDeleteFileDialog(int position) { mMediaPlayer.release(); mMediaPlayer = null; } - //mPlayListAdapter.stopProgress(currentPlayingItem); } @Override public void startMediaPlayer(int position, RecordingItem recordingItem) @@ -269,7 +261,7 @@ public void showDeleteFileDialog(int position) { mMediaPlayer.setDataSource(recordingItem.getFilePath()); mMediaPlayer.prepare(); mMediaPlayer.setOnPreparedListener(MediaPlayer::start); - //mPlayListAdapter.startProgress(position); + mMediaPlayer.setOnCompletionListener(mp -> playListPresenter.mediaPlayerStopped()); } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java index 79bc08c..e0225f0 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java @@ -25,4 +25,6 @@ public interface PlayListPresenter extends IMVPPresen void renameFileClicked(int position); void deleteFileClicked(int position); + + void mediaPlayerStopped(); } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index 115d1ca..f615dcd 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -4,17 +4,20 @@ import in.arjsna.audiorecorder.db.RecordItemDataSource; import in.arjsna.audiorecorder.db.RecordingItem; import in.arjsna.audiorecorder.mvpbase.BasePresenter; +import io.reactivex.Observable; import io.reactivex.Single; import io.reactivex.SingleObserver; import io.reactivex.SingleOnSubscribe; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; +import io.reactivex.observers.DisposableObserver; import io.reactivex.schedulers.Schedulers; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.List; +import java.util.concurrent.TimeUnit; import javax.inject.Inject; public class PlayListPresenterImpl extends BasePresenter @@ -120,8 +123,35 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, return recordingItems.get(position); } - @Override public void onListItemClick(int position) { + @Override public void mediaPlayerStopped() { + isAudioPlaying = false; + isAudioPaused = false; + } + @Override public void onListItemClick(int position) { + try { + if (isAudioPlaying) { + if (currentPlayingItem == position) { + if (isAudioPaused) { + isAudioPaused = false; + getAttachedView().resumeMediaPlayer(position); + } else { + isAudioPaused = true; + getAttachedView().pauseMediaPlayer(position); + } + } else { + getAttachedView().stopMediaPlayer(currentPlayingItem); + getAttachedView().startMediaPlayer(position, recordingItems.get(position)); + currentPlayingItem = position; + } + } else { + isAudioPlaying = true; + getAttachedView().startMediaPlayer(position, recordingItems.get(position)); + currentPlayingItem = position; + } + } catch (IOException e) { + getAttachedView().showError("Failed to start media Player"); + } } @Override public void onListItemLongClick(int position) { @@ -144,6 +174,23 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, getAttachedView().showDeleteFileDialog(position); } + private void startProgress() { + Observable.interval(10, TimeUnit.MILLISECONDS) + .subscribeWith(new DisposableObserver() { + @Override public void onNext(Long aLong) { + + } + + @Override public void onError(Throwable e) { + + } + + @Override public void onComplete() { + + } + }); + } + private Single removeFile(RecordingItem recordingItem, int position) { return Single.create((SingleOnSubscribe) e -> { File file = new File(recordingItem.getFilePath()); From 694a5477a93af840f84c8c0cc03d0f58dae13f6b Mon Sep 17 00:00:00 2001 From: Arjun Date: Tue, 26 Sep 2017 19:52:58 +0530 Subject: [PATCH 11/26] play progress added --- .../audiorecorder/db/RecordingItem.java | 2 + .../audiorecorder/libs/FillSeekBar.java | 50 +++++++++---------- .../playlist/PlayListAdapter.java | 19 +++---- .../playlist/PlayListFragment.java | 8 +-- .../playlist/PlayListPresenterImpl.java | 39 +++++++++++---- 5 files changed, 66 insertions(+), 52 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java b/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java index 30fe846..3a650b4 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java +++ b/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java @@ -21,6 +21,8 @@ public class RecordingItem implements Parcelable { @Ignore public boolean isPaused; + @Ignore + public long playProgress; public RecordingItem() { } diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index be1367c..bd62bb9 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -20,7 +20,7 @@ import java.util.TimerTask; public class FillSeekBar extends FrameLayout { - private int mProgress; + private long mProgress; private Solid mSolid; private final int DEFAULT_FILL_COLOR = Color.WHITE; @@ -47,25 +47,21 @@ public void setMaxVal(double maxVal) { this.mMaxValue = maxVal; } - public void setProgress(int progress) { - if (progress > mMaxValue) { - stopProgress(); - } else { - mProgress = progress; - computeProgressRigth(); - } + public void setProgress(long progress) { + mProgress = progress > mMaxValue ? (long) mMaxValue : progress; + computeProgressRight(); } @Override public void onWindowFocusChanged(boolean hasWindowFocus) { super.onWindowFocusChanged(hasWindowFocus); if (hasWindowFocus) { - computeProgressRigth(); + computeProgressRight(); } } - private void computeProgressRigth() { + private void computeProgressRight() { mSolidRight = (int) (getWidth() * (1f - mProgress / mMaxValue)); - Log.i("Stats " , mSolidRight + " " + mProgress); + Log.i("Stats ", mSolidRight + " " + mProgress); ViewGroup.LayoutParams params = mSolid.getLayoutParams(); if (params != null) { ((LayoutParams) params).rightMargin = mSolidRight; @@ -73,19 +69,19 @@ private void computeProgressRigth() { mSolid.setLayoutParams(params); } - @Override public Parcelable onSaveInstanceState() { - // Force our ancestor class to save its state - Parcelable superState = super.onSaveInstanceState(); - SavedState ss = new SavedState(superState); - ss.progress = mProgress; - return ss; - } - - @Override public void onRestoreInstanceState(Parcelable state) { - SavedState ss = (SavedState) state; - super.onRestoreInstanceState(ss.getSuperState()); - setProgress(ss.progress); - } + //@Override public Parcelable onSaveInstanceState() { + // // Force our ancestor class to save its state + // Parcelable superState = super.onSaveInstanceState(); + // SavedState ss = new SavedState(superState); + // ss.progress = mProgress; + // return ss; + //} + // + //@Override public void onRestoreInstanceState(Parcelable state) { + // SavedState ss = (SavedState) state; + // super.onRestoreInstanceState(ss.getSuperState()); + // setProgress(ss.progress); + //} private static class SavedState extends BaseSavedState { int progress; @@ -136,12 +132,12 @@ public void stopProgress() { public void resumeProgress() { timer = new Timer(); - timer.scheduleAtFixedRate(getNewTask(), 0 , 10); + timer.scheduleAtFixedRate(getNewTask(), 0, 10); } public void startProgress() { timer = new Timer(); - timer.scheduleAtFixedRate(getNewTask(), 0 , 10); + timer.scheduleAtFixedRate(getNewTask(), 0, 10); } Handler handler = new Handler(Looper.getMainLooper()); @@ -181,7 +177,7 @@ public void initPaint(int mFillColor) { @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - Log.i("Statsinneer " , getRight() + " "); + Log.i("Statsinneer ", getRight() + " "); canvas.drawRect(getLeft(), 0, getRight(), getBottom(), progressPaint); } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index bc19eb5..9c8d272 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -59,15 +59,16 @@ public PlayListAdapter(@ActivityContext AppCompatActivity context, return false; }); - if (currentRecording.isPlaying) { - if (currentRecording.isPaused) { - holder.fillSeekBar.pauseProgress(); - } else { - holder.fillSeekBar.startProgress(); - } - } else { - holder.fillSeekBar.stopProgress(); - } + holder.fillSeekBar.setProgress(currentRecording.playProgress); + //if (currentRecording.isPlaying) { + // if (currentRecording.isPaused) { + // holder.fillSeekBar.pauseProgress(); + // } else { + // holder.fillSeekBar.startProgress(); + // } + //} else { + // holder.fillSeekBar.stopProgress(); + //} } //public void startProgress(int position) { diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index 412b5da..4ec860f 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -75,7 +75,7 @@ private void initViews(View v) { llm.setStackFromEnd(true); mRecordingsListView.setLayoutManager(llm); - mRecordingsListView.setItemAnimator(new DefaultItemAnimator()); + //mRecordingsListView.setItemAnimator(new DefaultItemAnimator()); mRecordingsListView.setAdapter(mPlayListAdapter); playListPresenter.onViewInitialised(); } @@ -232,12 +232,6 @@ public void showDeleteFileDialog(int position) { alert.show(); } - //@Override public void onItemClick(int position, RecordingItem recordingItem) { - // //PlaybackFragment playbackFragment = new PlaybackFragment().newInstance(recordingItem); - // //playbackFragment.show(getActivity().getSupportFragmentManager(), "dialog_playback"); - // playListPresenter.onListItemClicked(position, recordingItem); - //} - @Override public void pauseMediaPlayer(int position) { mMediaPlayer.pause(); } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index f615dcd..2fbd923 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -4,6 +4,8 @@ import in.arjsna.audiorecorder.db.RecordItemDataSource; import in.arjsna.audiorecorder.db.RecordingItem; import in.arjsna.audiorecorder.mvpbase.BasePresenter; +import io.reactivex.BackpressureStrategy; +import io.reactivex.Flowable; import io.reactivex.Observable; import io.reactivex.Single; import io.reactivex.SingleObserver; @@ -13,6 +15,7 @@ import io.reactivex.disposables.Disposable; import io.reactivex.observers.DisposableObserver; import io.reactivex.schedulers.Schedulers; +import io.reactivex.subscribers.DisposableSubscriber; import java.io.File; import java.io.IOException; import java.util.ArrayList; @@ -126,6 +129,12 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, @Override public void mediaPlayerStopped() { isAudioPlaying = false; isAudioPaused = false; + if (playProgressDisposable != null) { + playProgressDisposable.dispose(); + } + currentProgress = 0; + recordingItems.get(currentPlayingItem).playProgress = 0; + getAttachedView().notifyListItemChange(currentPlayingItem); } @Override public void onListItemClick(int position) { @@ -141,19 +150,25 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, } } else { getAttachedView().stopMediaPlayer(currentPlayingItem); - getAttachedView().startMediaPlayer(position, recordingItems.get(position)); - currentPlayingItem = position; + startPlayer(position); } } else { isAudioPlaying = true; - getAttachedView().startMediaPlayer(position, recordingItems.get(position)); - currentPlayingItem = position; + startPlayer(position); } } catch (IOException e) { getAttachedView().showError("Failed to start media Player"); } } + private long currentProgress = 0; + private void startPlayer(int position) throws IOException { + currentProgress = 0; + getAttachedView().startMediaPlayer(position, recordingItems.get(position)); + currentPlayingItem = position; + updateProgress(position); + } + @Override public void onListItemLongClick(int position) { getAttachedView().showFileOptionDialog(position, recordingItems.get(position)); } @@ -174,14 +189,19 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, getAttachedView().showDeleteFileDialog(position); } - private void startProgress() { - Observable.interval(10, TimeUnit.MILLISECONDS) - .subscribeWith(new DisposableObserver() { + private DisposableSubscriber playProgressDisposable; + private void updateProgress(int position) { + playProgressDisposable = Flowable.interval(50, TimeUnit.MILLISECONDS) + .onBackpressureDrop() + .subscribeOn(AndroidSchedulers.mainThread()) + .subscribeWith(new DisposableSubscriber() { @Override public void onNext(Long aLong) { - + currentProgress += 50; + recordingItems.get(position).playProgress = currentProgress; + getAttachedView().notifyListItemChange(position); } - @Override public void onError(Throwable e) { + @Override public void onError(Throwable t) { } @@ -189,6 +209,7 @@ private void startProgress() { } }); + getCompositeDisposable().add(playProgressDisposable); } private Single removeFile(RecordingItem recordingItem, int position) { From 4d3f3c84d95ed8490a58f5ad0da5b8e640a843f8 Mon Sep 17 00:00:00 2001 From: Arjun Date: Tue, 26 Sep 2017 20:13:31 +0530 Subject: [PATCH 12/26] switch play items --- .../arjsna/audiorecorder/libs/FillSeekBar.java | 4 ++-- .../playlist/PlayListFragment.java | 6 +++++- .../playlist/PlayListPresenterImpl.java | 18 +++++++++++++++--- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index bd62bb9..d72d237 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -61,7 +61,7 @@ public void setProgress(long progress) { private void computeProgressRight() { mSolidRight = (int) (getWidth() * (1f - mProgress / mMaxValue)); - Log.i("Stats ", mSolidRight + " " + mProgress); + //Log.i("Stats ", mSolidRight + " " + mProgress); ViewGroup.LayoutParams params = mSolid.getLayoutParams(); if (params != null) { ((LayoutParams) params).rightMargin = mSolidRight; @@ -177,7 +177,7 @@ public void initPaint(int mFillColor) { @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - Log.i("Statsinneer ", getRight() + " "); + //Log.i("Statsinneer ", getRight() + " "); canvas.drawRect(getLeft(), 0, getRight(), getBottom(), progressPaint); } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index 4ec860f..0703966 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -142,7 +142,9 @@ private void initViews(View v) { } @Override public void notifyListItemChange(Integer position) { - mPlayListAdapter.notifyItemChanged(position); + if (!mRecordingsListView.isComputingLayout()) { + mPlayListAdapter.notifyItemChanged(position); + } } @Override public void showError(String message) { @@ -242,6 +244,7 @@ public void showDeleteFileDialog(int position) { @Override public void stopMediaPlayer(int currentPlayingItem) { if (mMediaPlayer != null) { + Log.i("Debug ", "Stopping"); mMediaPlayer.stop(); mMediaPlayer.reset(); mMediaPlayer.release(); @@ -256,6 +259,7 @@ public void showDeleteFileDialog(int position) { mMediaPlayer.prepare(); mMediaPlayer.setOnPreparedListener(MediaPlayer::start); mMediaPlayer.setOnCompletionListener(mp -> playListPresenter.mediaPlayerStopped()); + Log.i("Debug ", "Started"); } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index 2fbd923..98ca404 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -1,6 +1,7 @@ package in.arjsna.audiorecorder.playlist; import android.os.Environment; +import android.util.Log; import in.arjsna.audiorecorder.db.RecordItemDataSource; import in.arjsna.audiorecorder.db.RecordingItem; import in.arjsna.audiorecorder.mvpbase.BasePresenter; @@ -25,6 +26,7 @@ public class PlayListPresenterImpl extends BasePresenter implements PlayListPresenter { + private static final int INVALID_ITEM = -1; @Inject public RecordItemDataSource recordItemDataSource; @@ -127,14 +129,21 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, } @Override public void mediaPlayerStopped() { - isAudioPlaying = false; - isAudioPaused = false; + Log.i("Debug ", "Stopping called"); + + updateStateToStop(); + } + + private void updateStateToStop() { if (playProgressDisposable != null) { playProgressDisposable.dispose(); } + isAudioPlaying = false; + isAudioPaused = false; currentProgress = 0; recordingItems.get(currentPlayingItem).playProgress = 0; getAttachedView().notifyListItemChange(currentPlayingItem); + currentPlayingItem = INVALID_ITEM; } @Override public void onListItemClick(int position) { @@ -144,16 +153,18 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, if (isAudioPaused) { isAudioPaused = false; getAttachedView().resumeMediaPlayer(position); + updateProgress(position); } else { isAudioPaused = true; getAttachedView().pauseMediaPlayer(position); + playProgressDisposable.dispose(); } } else { getAttachedView().stopMediaPlayer(currentPlayingItem); + updateStateToStop(); startPlayer(position); } } else { - isAudioPlaying = true; startPlayer(position); } } catch (IOException e) { @@ -163,6 +174,7 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, private long currentProgress = 0; private void startPlayer(int position) throws IOException { + isAudioPlaying = true; currentProgress = 0; getAttachedView().startMediaPlayer(position, recordingItems.get(position)); currentPlayingItem = position; From 15998ee490b2dc2f43652cb77f59601e35b8d374 Mon Sep 17 00:00:00 2001 From: Arjun Date: Tue, 26 Sep 2017 20:38:44 +0530 Subject: [PATCH 13/26] remove unused code --- .../activities/PlayListActivity.java | 2 +- .../activities/SettingsActivity.java | 2 +- .../audiorecording/RecordFragment.java | 2 +- .../di/components/ActivityComponent.java | 4 +- .../di/components/ApplicationComponent.java | 2 +- .../di/components/ServiceComponent.java | 2 +- .../di/modules/ActivityModule.java | 2 - .../audiorecorder/libs/FillSeekBar.java | 53 +------------------ .../audiorecorder/mvpbase/IMVPPresenter.java | 2 - .../playlist/PlayListAdapter.java | 37 ------------- .../playlist/PlayListFragment.java | 7 ++- .../playlist/PlayListMVPView.java | 1 - .../playlist/PlayListPresenter.java | 2 - .../playlist/PlayListPresenterImpl.java | 34 ++---------- 14 files changed, 15 insertions(+), 137 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/activities/PlayListActivity.java b/app/src/main/java/in/arjsna/audiorecorder/activities/PlayListActivity.java index c463557..cf6adf5 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/activities/PlayListActivity.java +++ b/app/src/main/java/in/arjsna/audiorecorder/activities/PlayListActivity.java @@ -4,8 +4,8 @@ import android.support.v7.app.ActionBar; import android.support.v7.widget.Toolbar; import in.arjsna.audiorecorder.R; -import in.arjsna.audiorecorder.playlist.PlayListFragment; import in.arjsna.audiorecorder.mvpbase.BaseActivity; +import in.arjsna.audiorecorder.playlist.PlayListFragment; public class PlayListActivity extends BaseActivity { diff --git a/app/src/main/java/in/arjsna/audiorecorder/activities/SettingsActivity.java b/app/src/main/java/in/arjsna/audiorecorder/activities/SettingsActivity.java index b7145bc..c445f66 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/activities/SettingsActivity.java +++ b/app/src/main/java/in/arjsna/audiorecorder/activities/SettingsActivity.java @@ -5,8 +5,8 @@ import android.support.v7.app.ActionBar; import android.support.v7.widget.Toolbar; import in.arjsna.audiorecorder.R; -import in.arjsna.audiorecorder.settings.SettingsFragment; import in.arjsna.audiorecorder.mvpbase.BaseActivity; +import in.arjsna.audiorecorder.settings.SettingsFragment; public class SettingsActivity extends BaseActivity { @Override public void onCreate(@Nullable Bundle savedInstanceState) { diff --git a/app/src/main/java/in/arjsna/audiorecorder/audiorecording/RecordFragment.java b/app/src/main/java/in/arjsna/audiorecorder/audiorecording/RecordFragment.java index 0679908..5b31ecc 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/audiorecording/RecordFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/audiorecording/RecordFragment.java @@ -27,8 +27,8 @@ import in.arjsna.audiorecorder.activities.PlayListActivity; import in.arjsna.audiorecorder.activities.SettingsActivity; import in.arjsna.audiorecorder.audiovisualization.GLAudioVisualizationView; -import in.arjsna.audiorecorder.di.qualifiers.ActivityContext; import in.arjsna.audiorecorder.di.components.ActivityComponent; +import in.arjsna.audiorecorder.di.qualifiers.ActivityContext; import in.arjsna.audiorecorder.mvpbase.BaseFragment; import in.arjsna.audiorecorder.recordingservice.AudioRecordService; import in.arjsna.audiorecorder.recordingservice.AudioRecorder; diff --git a/app/src/main/java/in/arjsna/audiorecorder/di/components/ActivityComponent.java b/app/src/main/java/in/arjsna/audiorecorder/di/components/ActivityComponent.java index 46f753e..c019982 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/di/components/ActivityComponent.java +++ b/app/src/main/java/in/arjsna/audiorecorder/di/components/ActivityComponent.java @@ -4,9 +4,9 @@ import in.arjsna.audiorecorder.activities.MainActivity; import in.arjsna.audiorecorder.activities.PlayListActivity; import in.arjsna.audiorecorder.activities.SettingsActivity; -import in.arjsna.audiorecorder.di.scopes.ActivityScope; -import in.arjsna.audiorecorder.di.modules.ActivityModule; import in.arjsna.audiorecorder.audiorecording.RecordFragment; +import in.arjsna.audiorecorder.di.modules.ActivityModule; +import in.arjsna.audiorecorder.di.scopes.ActivityScope; import in.arjsna.audiorecorder.playlist.PlayListFragment; @ActivityScope diff --git a/app/src/main/java/in/arjsna/audiorecorder/di/components/ApplicationComponent.java b/app/src/main/java/in/arjsna/audiorecorder/di/components/ApplicationComponent.java index 6dada40..a4922d7 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/di/components/ApplicationComponent.java +++ b/app/src/main/java/in/arjsna/audiorecorder/di/components/ApplicationComponent.java @@ -4,8 +4,8 @@ import dagger.Component; import in.arjsna.audiorecorder.AudioRecorderApp; import in.arjsna.audiorecorder.db.RecordItemDataSource; -import in.arjsna.audiorecorder.di.qualifiers.ApplicationContext; import in.arjsna.audiorecorder.di.modules.ApplicationModule; +import in.arjsna.audiorecorder.di.qualifiers.ApplicationContext; import javax.inject.Singleton; @Singleton diff --git a/app/src/main/java/in/arjsna/audiorecorder/di/components/ServiceComponent.java b/app/src/main/java/in/arjsna/audiorecorder/di/components/ServiceComponent.java index 90eb9c4..15f3bda 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/di/components/ServiceComponent.java +++ b/app/src/main/java/in/arjsna/audiorecorder/di/components/ServiceComponent.java @@ -1,8 +1,8 @@ package in.arjsna.audiorecorder.di.components; import dagger.Component; -import in.arjsna.audiorecorder.di.scopes.ServiceScope; import in.arjsna.audiorecorder.di.modules.ServiceModule; +import in.arjsna.audiorecorder.di.scopes.ServiceScope; import in.arjsna.audiorecorder.recordingservice.AudioRecordService; @ServiceScope diff --git a/app/src/main/java/in/arjsna/audiorecorder/di/modules/ActivityModule.java b/app/src/main/java/in/arjsna/audiorecorder/di/modules/ActivityModule.java index 36ac978..af55d9c 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/di/modules/ActivityModule.java +++ b/app/src/main/java/in/arjsna/audiorecorder/di/modules/ActivityModule.java @@ -9,12 +9,10 @@ import in.arjsna.audiorecorder.audiorecording.AudioRecordPresenterImpl; import in.arjsna.audiorecorder.di.qualifiers.ActivityContext; import in.arjsna.audiorecorder.di.scopes.ActivityScope; -import in.arjsna.audiorecorder.playlist.PlayListAdapter; import in.arjsna.audiorecorder.playlist.PlayListMVPView; import in.arjsna.audiorecorder.playlist.PlayListPresenter; import in.arjsna.audiorecorder.playlist.PlayListPresenterImpl; import io.reactivex.disposables.CompositeDisposable; -import java.util.ArrayList; @Module public class ActivityModule { diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index d72d237..a2d5030 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -5,27 +5,20 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; -import android.os.Handler; -import android.os.Looper; import android.os.Parcel; import android.os.Parcelable; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.LinearLayout; import in.arjsna.audiorecorder.R; -import java.util.Timer; -import java.util.TimerTask; public class FillSeekBar extends FrameLayout { private long mProgress; private Solid mSolid; private final int DEFAULT_FILL_COLOR = Color.WHITE; - private final int DEFAULT_PROGRESS = 80; - private int mSolidRight; private double mMaxValue = 1.0; public FillSeekBar(Context context, AttributeSet attrs) { @@ -35,7 +28,7 @@ public FillSeekBar(Context context, AttributeSet attrs) { .obtainStyledAttributes(attrs, R.styleable.FillSeekBar, R.attr.fillseekbarViewStyle, 0); int mFillColor = attributes.getColor(R.styleable.FillSeekBar_fill_color, DEFAULT_FILL_COLOR); - mProgress = attributes.getInt(R.styleable.FillSeekBar_progress, DEFAULT_PROGRESS); + mProgress = attributes.getInt(R.styleable.FillSeekBar_progress, 0); attributes.recycle(); mSolid = new Solid(context, null); mSolid.initPaint(mFillColor); @@ -60,7 +53,7 @@ public void setProgress(long progress) { } private void computeProgressRight() { - mSolidRight = (int) (getWidth() * (1f - mProgress / mMaxValue)); + int mSolidRight = (int) (getWidth() * (1f - mProgress / mMaxValue)); //Log.i("Stats ", mSolidRight + " " + mProgress); ViewGroup.LayoutParams params = mSolid.getLayoutParams(); if (params != null) { @@ -117,40 +110,6 @@ public SavedState[] newArray(int size) { }; } - public void pauseProgress() { - if (timer != null) { - timer.cancel(); - } - } - - public void stopProgress() { - if (timer != null) { - timer.cancel(); - setProgress(0); - } - } - - public void resumeProgress() { - timer = new Timer(); - timer.scheduleAtFixedRate(getNewTask(), 0, 10); - } - - public void startProgress() { - timer = new Timer(); - timer.scheduleAtFixedRate(getNewTask(), 0, 10); - } - - Handler handler = new Handler(Looper.getMainLooper()); - Timer timer; - - private TimerTask getNewTask() { - return new TimerTask() { - @Override public void run() { - handler.post(() -> setProgress(mProgress + 10)); - } - }; - } - private static class Solid extends View { private Paint progressPaint; @@ -181,12 +140,4 @@ public void initPaint(int mFillColor) { canvas.drawRect(getLeft(), 0, getRight(), getBottom(), progressPaint); } } - - @Override protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - if (timer != null) { - timer.cancel(); - timer = null; - } - } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/mvpbase/IMVPPresenter.java b/app/src/main/java/in/arjsna/audiorecorder/mvpbase/IMVPPresenter.java index 37a03c8..2495aff 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/mvpbase/IMVPPresenter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/mvpbase/IMVPPresenter.java @@ -1,7 +1,5 @@ package in.arjsna.audiorecorder.mvpbase; -import in.arjsna.audiorecorder.db.RecordingItem; - public interface IMVPPresenter { void onAttach(V view); diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index 9c8d272..833c0f1 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -23,13 +23,11 @@ public class PlayListAdapter extends RecyclerView.Adapter playListPresenter; - //private final ArrayList recordingItems; @Inject public PlayListAdapter(@ActivityContext AppCompatActivity context, PlayListPresenter playListPresenter) { mContext = context; - //this.recordingItems = recordingItems; this.playListPresenter = playListPresenter; inflater = LayoutInflater.from(mContext); } @@ -60,48 +58,13 @@ public PlayListAdapter(@ActivityContext AppCompatActivity context, }); holder.fillSeekBar.setProgress(currentRecording.playProgress); - //if (currentRecording.isPlaying) { - // if (currentRecording.isPaused) { - // holder.fillSeekBar.pauseProgress(); - // } else { - // holder.fillSeekBar.startProgress(); - // } - //} else { - // holder.fillSeekBar.stopProgress(); - //} } - //public void startProgress(int position) { - // recordingItems.get(position).isPlaying = true; - // notifyItemChanged(position); - //} - // - //public void stopProgress(int currentPlayingItem) { - // recordingItems.get(currentPlayingItem).isPlaying = false; - // notifyItemChanged(currentPlayingItem); - //} - // - //public void pauseProgress(int currentPlayingItem) { - // recordingItems.get(currentPlayingItem).isPaused = true; - // notifyItemChanged(currentPlayingItem); - //} - // - //public void resumeProgress(int currentPlayingItem) { - // recordingItems.get(currentPlayingItem).isPaused = false; - // notifyItemChanged(currentPlayingItem); - //} - @Override public RecordingsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new RecordingsViewHolder(inflater. inflate(R.layout.record_list_item, parent, false)); } - // - //void removeItemAndNotify(int position) { - // recordingItems.remove(position); - // notifyItemRemoved(position); - //} - static class RecordingsViewHolder extends RecyclerView.ViewHolder { final TextView vName; final TextView vLength; diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index 0703966..082a104 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -5,8 +5,8 @@ import android.net.Uri; import android.os.Bundle; import android.os.FileObserver; +import android.os.Handler; import android.support.v7.app.AlertDialog; -import android.support.v7.widget.DefaultItemAnimator; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; import android.util.Log; @@ -141,10 +141,9 @@ private void initViews(View v) { observer.stopWatching(); } + Handler handler = new Handler(); @Override public void notifyListItemChange(Integer position) { - if (!mRecordingsListView.isComputingLayout()) { - mPlayListAdapter.notifyItemChanged(position); - } + handler.post(() -> mPlayListAdapter.notifyItemChanged(position)); } @Override public void showError(String message) { diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java index dcda0ed..2ea608b 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java @@ -3,7 +3,6 @@ import in.arjsna.audiorecorder.db.RecordingItem; import in.arjsna.audiorecorder.mvpbase.IMVPView; import java.io.IOException; -import java.util.ArrayList; public interface PlayListMVPView extends IMVPView { void notifyListAdapter(); diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java index e0225f0..96f24bf 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenter.java @@ -10,8 +10,6 @@ public interface PlayListPresenter extends IMVPPresen void deleteFile(int position); - void onListItemClicked(int position, RecordingItem recordingItem); - RecordingItem getListItemAt(int position); void onListItemClick(int position); diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index 98ca404..945d3eb 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -5,16 +5,13 @@ import in.arjsna.audiorecorder.db.RecordItemDataSource; import in.arjsna.audiorecorder.db.RecordingItem; import in.arjsna.audiorecorder.mvpbase.BasePresenter; -import io.reactivex.BackpressureStrategy; import io.reactivex.Flowable; -import io.reactivex.Observable; import io.reactivex.Single; import io.reactivex.SingleObserver; import io.reactivex.SingleOnSubscribe; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; -import io.reactivex.observers.DisposableObserver; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.DisposableSubscriber; import java.io.File; @@ -27,6 +24,7 @@ public class PlayListPresenterImpl extends BasePresenter implements PlayListPresenter { private static final int INVALID_ITEM = -1; + private static final int PROGRESS_OFFSET = 50; @Inject public RecordItemDataSource recordItemDataSource; @@ -98,32 +96,6 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, }); } - @Override public void onListItemClicked(int position, RecordingItem recordingItem) { - try { - if (isAudioPlaying) { - if (currentPlayingItem == position) { - if (isAudioPaused) { - isAudioPaused = false; - getAttachedView().resumeMediaPlayer(position); - } else { - isAudioPaused = true; - getAttachedView().pauseMediaPlayer(position); - } - } else { - getAttachedView().stopMediaPlayer(currentPlayingItem); - getAttachedView().startMediaPlayer(position, recordingItem); - currentPlayingItem = position; - } - } else { - isAudioPlaying = true; - getAttachedView().startMediaPlayer(position, recordingItem); - currentPlayingItem = position; - } - } catch (IOException e) { - getAttachedView().showError("Failed to start media Player"); - } - } - @Override public RecordingItem getListItemAt(int position) { return recordingItems.get(position); } @@ -203,12 +175,12 @@ private void startPlayer(int position) throws IOException { private DisposableSubscriber playProgressDisposable; private void updateProgress(int position) { - playProgressDisposable = Flowable.interval(50, TimeUnit.MILLISECONDS) + playProgressDisposable = Flowable.interval(PROGRESS_OFFSET, TimeUnit.MILLISECONDS) .onBackpressureDrop() .subscribeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableSubscriber() { @Override public void onNext(Long aLong) { - currentProgress += 50; + currentProgress += PROGRESS_OFFSET; recordingItems.get(position).playProgress = currentProgress; getAttachedView().notifyListItemChange(position); } From 961245280c453168b2d09042d24a41fa2cb2cbcf Mon Sep 17 00:00:00 2001 From: Arjun Date: Wed, 27 Sep 2017 09:43:09 +0530 Subject: [PATCH 14/26] optimisation --- .../playlist/PlayListAdapter.java | 30 ++++++++++++------- .../playlist/PlayListPresenterImpl.java | 2 +- 2 files changed, 20 insertions(+), 12 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index 833c0f1..87bd152 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -48,21 +48,12 @@ public PlayListAdapter(@ActivityContext AppCompatActivity context, | DateUtils.FORMAT_NUMERIC_DATE | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR)); - - holder.cardView.setOnClickListener( - view -> playListPresenter.onListItemClick(holder.getAdapterPosition())); - - holder.cardView.setOnLongClickListener(v -> { - playListPresenter.onListItemLongClick(holder.getAdapterPosition()); - return false; - }); - holder.fillSeekBar.setProgress(currentRecording.playProgress); } @Override public RecordingsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { return new RecordingsViewHolder(inflater. - inflate(R.layout.record_list_item, parent, false)); + inflate(R.layout.record_list_item, parent, false), playListPresenter); } static class RecordingsViewHolder extends RecyclerView.ViewHolder { @@ -71,14 +62,31 @@ static class RecordingsViewHolder extends RecyclerView.ViewHolder { final TextView vDateAdded; final View cardView; final FillSeekBar fillSeekBar; + private final PlayListPresenter playListPresenter; - RecordingsViewHolder(View v) { + RecordingsViewHolder(View v, PlayListPresenter playListPresenter) { super(v); + this.playListPresenter = playListPresenter; vName = v.findViewById(R.id.file_name_text); vLength = v.findViewById(R.id.file_length_text); vDateAdded = v.findViewById(R.id.file_date_added_text); cardView = v.findViewById(R.id.record_item_root_view); fillSeekBar = v.findViewById(R.id.attached_seek_bar); + bindEvents(); + } + + private void bindEvents() { + cardView.setOnClickListener( + view -> playListPresenter.onListItemClick(this, getAdapterPosition())); + + cardView.setOnLongClickListener(v -> { + playListPresenter.onListItemLongClick(getAdapterPosition()); + return false; + }); + } + + public void setProgress(long p) { + fillSeekBar.setProgress(p); } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index 945d3eb..a082e28 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -24,7 +24,7 @@ public class PlayListPresenterImpl extends BasePresenter implements PlayListPresenter { private static final int INVALID_ITEM = -1; - private static final int PROGRESS_OFFSET = 50; + private static final int PROGRESS_OFFSET = 100; @Inject public RecordItemDataSource recordItemDataSource; From 0b70c1f8570cda5a4d25db751ae60fda0663c408 Mon Sep 17 00:00:00 2001 From: Arjun Date: Wed, 27 Sep 2017 10:23:44 +0530 Subject: [PATCH 15/26] update view for showing progress --- .../playlist/PlayListAdapter.java | 6 +++--- .../playlist/PlayListFragment.java | 19 ++++++++++++++++--- .../playlist/PlayListMVPView.java | 2 ++ .../playlist/PlayListPresenterImpl.java | 6 +++--- 4 files changed, 24 insertions(+), 9 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index 87bd152..2122570 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -77,7 +77,7 @@ static class RecordingsViewHolder extends RecyclerView.ViewHolder { private void bindEvents() { cardView.setOnClickListener( - view -> playListPresenter.onListItemClick(this, getAdapterPosition())); + view -> playListPresenter.onListItemClick(getAdapterPosition())); cardView.setOnLongClickListener(v -> { playListPresenter.onListItemLongClick(getAdapterPosition()); @@ -85,8 +85,8 @@ private void bindEvents() { }); } - public void setProgress(long p) { - fillSeekBar.setProgress(p); + public void updateProgressInSeekBar(Integer position) { + fillSeekBar.setProgress(playListPresenter.getListItemAt(position).playProgress); } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index 082a104..ff24986 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -5,7 +5,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.FileObserver; -import android.os.Handler; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -141,9 +140,23 @@ private void initViews(View v) { observer.stopWatching(); } - Handler handler = new Handler(); + private int positionOfCurrentViewHolder = -1; + private PlayListAdapter.RecordingsViewHolder recordingsViewHolder; + + @Override public void updateProgressInListItem(Integer position) { + if (position != positionOfCurrentViewHolder || recordingsViewHolder == null) { + positionOfCurrentViewHolder = position; + recordingsViewHolder = + (PlayListAdapter.RecordingsViewHolder) mRecordingsListView.findViewHolderForAdapterPosition( + position); + } + if (recordingsViewHolder != null) { + recordingsViewHolder.updateProgressInSeekBar(position); + } + } + @Override public void notifyListItemChange(Integer position) { - handler.post(() -> mPlayListAdapter.notifyItemChanged(position)); + mPlayListAdapter.notifyItemChanged(position); } @Override public void showError(String message) { diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java index 2ea608b..51e5a76 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java @@ -40,4 +40,6 @@ public interface PlayListMVPView extends IMVPView { void showRenameFileDialog(int position); void showDeleteFileDialog(int position); + + void updateProgressInListItem(Integer position); } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index a082e28..d1018ef 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -24,7 +24,7 @@ public class PlayListPresenterImpl extends BasePresenter implements PlayListPresenter { private static final int INVALID_ITEM = -1; - private static final int PROGRESS_OFFSET = 100; + private static final int PROGRESS_OFFSET = 25; @Inject public RecordItemDataSource recordItemDataSource; @@ -177,12 +177,12 @@ private void startPlayer(int position) throws IOException { private void updateProgress(int position) { playProgressDisposable = Flowable.interval(PROGRESS_OFFSET, TimeUnit.MILLISECONDS) .onBackpressureDrop() - .subscribeOn(AndroidSchedulers.mainThread()) + .observeOn(AndroidSchedulers.mainThread()) .subscribeWith(new DisposableSubscriber() { @Override public void onNext(Long aLong) { currentProgress += PROGRESS_OFFSET; recordingItems.get(position).playProgress = currentProgress; - getAttachedView().notifyListItemChange(position); + getAttachedView().updateProgressInListItem(position); } @Override public void onError(Throwable t) { From c87857aaebf133a7cc22c6903d97a78776028e58 Mon Sep 17 00:00:00 2001 From: Arjun Date: Wed, 27 Sep 2017 14:20:17 +0530 Subject: [PATCH 16/26] bug fix in progress update --- .../in/arjsna/audiorecorder/playlist/PlayListFragment.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index ff24986..e89fa5c 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -150,8 +150,11 @@ private void initViews(View v) { (PlayListAdapter.RecordingsViewHolder) mRecordingsListView.findViewHolderForAdapterPosition( position); } - if (recordingsViewHolder != null) { + if (recordingsViewHolder != null && recordingsViewHolder.getAdapterPosition() == position) { recordingsViewHolder.updateProgressInSeekBar(position); + } else { + positionOfCurrentViewHolder = -1; + recordingsViewHolder = null; } } From b7ebdea4ef648979a0995bf243863fca9f47cbad Mon Sep 17 00:00:00 2001 From: Arjun Date: Wed, 27 Sep 2017 15:13:12 +0530 Subject: [PATCH 17/26] progress color based on selected theme --- .../audiorecorder/libs/FillSeekBar.java | 77 +++---------------- app/src/main/res/layout/record_list_item.xml | 1 - 2 files changed, 11 insertions(+), 67 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index a2d5030..8008712 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -5,17 +5,18 @@ import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; -import android.os.Parcel; -import android.os.Parcelable; import android.util.AttributeSet; +import android.util.Log; import android.view.View; import android.view.ViewGroup; import android.widget.FrameLayout; import android.widget.LinearLayout; import in.arjsna.audiorecorder.R; +import in.arjsna.audiorecorder.theme.ThemedActivity; public class FillSeekBar extends FrameLayout { - private long mProgress; + private final int mFillColor; + private long mProgress = 0; private Solid mSolid; private final int DEFAULT_FILL_COLOR = Color.WHITE; @@ -26,14 +27,13 @@ public FillSeekBar(Context context, AttributeSet attrs) { //load styled attributes. final TypedArray attributes = context.getTheme() .obtainStyledAttributes(attrs, R.styleable.FillSeekBar, R.attr.fillseekbarViewStyle, 0); - int mFillColor = - attributes.getColor(R.styleable.FillSeekBar_fill_color, DEFAULT_FILL_COLOR); + mFillColor = + ((ThemedActivity) context).getPrimaryColor(); mProgress = attributes.getInt(R.styleable.FillSeekBar_progress, 0); attributes.recycle(); mSolid = new Solid(context, null); mSolid.initPaint(mFillColor); - addView(mSolid); - setProgress(0); + addView(mSolid, 0, LayoutParams.MATCH_PARENT); } public void setMaxVal(double maxVal) { @@ -45,71 +45,16 @@ public void setProgress(long progress) { computeProgressRight(); } - @Override public void onWindowFocusChanged(boolean hasWindowFocus) { - super.onWindowFocusChanged(hasWindowFocus); - if (hasWindowFocus) { - computeProgressRight(); - } - } - private void computeProgressRight() { int mSolidRight = (int) (getWidth() * (1f - mProgress / mMaxValue)); - //Log.i("Stats ", mSolidRight + " " + mProgress); + Log.i("Stats ", mSolidRight + " " + mProgress); ViewGroup.LayoutParams params = mSolid.getLayoutParams(); if (params != null) { - ((LayoutParams) params).rightMargin = mSolidRight; + ((LayoutParams) params).width = getWidth() - mSolidRight; } mSolid.setLayoutParams(params); } - //@Override public Parcelable onSaveInstanceState() { - // // Force our ancestor class to save its state - // Parcelable superState = super.onSaveInstanceState(); - // SavedState ss = new SavedState(superState); - // ss.progress = mProgress; - // return ss; - //} - // - //@Override public void onRestoreInstanceState(Parcelable state) { - // SavedState ss = (SavedState) state; - // super.onRestoreInstanceState(ss.getSuperState()); - // setProgress(ss.progress); - //} - - private static class SavedState extends BaseSavedState { - int progress; - - /** - * Constructor called from {@link android.widget.ProgressBar#onSaveInstanceState()} - */ - SavedState(Parcelable superState) { - super(superState); - } - - /** - * Constructor called from {@link #CREATOR} - */ - private SavedState(Parcel in) { - super(in); - progress = in.readInt(); - } - - @Override public void writeToParcel(Parcel out, int flags) { - super.writeToParcel(out, flags); - out.writeInt(progress); - } - - public static final Creator CREATOR = new Creator() { - public SavedState createFromParcel(Parcel in) { - return new SavedState(in); - } - - public SavedState[] newArray(int size) { - return new SavedState[size]; - } - }; - } - private static class Solid extends View { private Paint progressPaint; @@ -136,8 +81,8 @@ public void initPaint(int mFillColor) { @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - //Log.i("Statsinneer ", getRight() + " "); - canvas.drawRect(getLeft(), 0, getRight(), getBottom(), progressPaint); + Log.i("Statsinneer ", getRight() + " "); + canvas.drawRect(getLeft(), 0, getWidth(), getBottom(), progressPaint); } } } diff --git a/app/src/main/res/layout/record_list_item.xml b/app/src/main/res/layout/record_list_item.xml index 8d0a8b6..7bd400c 100644 --- a/app/src/main/res/layout/record_list_item.xml +++ b/app/src/main/res/layout/record_list_item.xml @@ -14,7 +14,6 @@ android:id="@+id/attached_seek_bar" android:layout_width="match_parent" android:layout_height="match_parent" - android:background="#303F9F" app:fill_color="@color/primary_light" > From b1a61298f1e37c115fac81ec9322bd3f6db50d85 Mon Sep 17 00:00:00 2001 From: Arjun Date: Wed, 27 Sep 2017 18:11:16 +0530 Subject: [PATCH 18/26] event posting moved to handler --- .../in/arjsna/audiorecorder/playlist/PlayListFragment.java | 5 ++++- .../arjsna/audiorecorder/playlist/PlayListPresenterImpl.java | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index e89fa5c..d37857b 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -5,6 +5,7 @@ import android.net.Uri; import android.os.Bundle; import android.os.FileObserver; +import android.os.Handler; import android.support.v7.app.AlertDialog; import android.support.v7.widget.LinearLayoutManager; import android.support.v7.widget.RecyclerView; @@ -143,6 +144,8 @@ private void initViews(View v) { private int positionOfCurrentViewHolder = -1; private PlayListAdapter.RecordingsViewHolder recordingsViewHolder; + Handler uiThreadHandler = new Handler(); + @Override public void updateProgressInListItem(Integer position) { if (position != positionOfCurrentViewHolder || recordingsViewHolder == null) { positionOfCurrentViewHolder = position; @@ -151,7 +154,7 @@ private void initViews(View v) { position); } if (recordingsViewHolder != null && recordingsViewHolder.getAdapterPosition() == position) { - recordingsViewHolder.updateProgressInSeekBar(position); + uiThreadHandler.post(() -> recordingsViewHolder.updateProgressInSeekBar(position)); } else { positionOfCurrentViewHolder = -1; recordingsViewHolder = null; diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index d1018ef..c95e135 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -24,7 +24,7 @@ public class PlayListPresenterImpl extends BasePresenter implements PlayListPresenter { private static final int INVALID_ITEM = -1; - private static final int PROGRESS_OFFSET = 25; + private static final int PROGRESS_OFFSET = 10; @Inject public RecordItemDataSource recordItemDataSource; From fce1d96e47f62c7e40197655bc623db250ca0ae9 Mon Sep 17 00:00:00 2001 From: Arjun Date: Wed, 27 Sep 2017 18:28:36 +0530 Subject: [PATCH 19/26] set alpha for fill color --- app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java | 1 + 1 file changed, 1 insertion(+) diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index 8008712..a0d77b1 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -75,6 +75,7 @@ public Solid(Context context, AttributeSet attrs, int defStyleAttr) { public void initPaint(int mFillColor) { progressPaint = new Paint(); progressPaint.setColor(mFillColor); + progressPaint.setAlpha(125); progressPaint.setStyle(Paint.Style.FILL); progressPaint.setAntiAlias(true); } From 74ac8f98c5b9273522956787c0ccd7baa6f57c7c Mon Sep 17 00:00:00 2001 From: Arjun Date: Wed, 27 Sep 2017 18:34:17 +0530 Subject: [PATCH 20/26] view location updated --- app/src/main/res/layout/record_list_item.xml | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/app/src/main/res/layout/record_list_item.xml b/app/src/main/res/layout/record_list_item.xml index 7bd400c..ba583f9 100644 --- a/app/src/main/res/layout/record_list_item.xml +++ b/app/src/main/res/layout/record_list_item.xml @@ -21,6 +21,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="horizontal" + android:paddingLeft="10dp" + android:paddingRight="10dp" > + app:layout_constraintBottom_toBottomOf="parent"/> Date: Wed, 27 Sep 2017 23:28:56 +0530 Subject: [PATCH 21/26] show play progress timer --- .../audiorecorder/libs/FillSeekBar.java | 4 ++-- .../playlist/PlayListAdapter.java | 19 ++++++++++++++++++- .../playlist/PlayListFragment.java | 6 ++++++ .../playlist/PlayListMVPView.java | 2 ++ .../playlist/PlayListPresenterImpl.java | 15 +++++++++++---- app/src/main/res/layout/record_list_item.xml | 15 +++++++++++++++ 6 files changed, 54 insertions(+), 7 deletions(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java index a0d77b1..82ee68c 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java +++ b/app/src/main/java/in/arjsna/audiorecorder/libs/FillSeekBar.java @@ -47,7 +47,7 @@ public void setProgress(long progress) { private void computeProgressRight() { int mSolidRight = (int) (getWidth() * (1f - mProgress / mMaxValue)); - Log.i("Stats ", mSolidRight + " " + mProgress); + //Log.i("Stats ", mSolidRight + " " + mProgress); ViewGroup.LayoutParams params = mSolid.getLayoutParams(); if (params != null) { ((LayoutParams) params).width = getWidth() - mSolidRight; @@ -82,7 +82,7 @@ public void initPaint(int mFillColor) { @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); - Log.i("Statsinneer ", getRight() + " "); + //Log.i("Statsinneer ", getRight() + " "); canvas.drawRect(getLeft(), 0, getWidth(), getBottom(), progressPaint); } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index 2122570..e376360 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -58,6 +58,7 @@ public PlayListAdapter(@ActivityContext AppCompatActivity context, static class RecordingsViewHolder extends RecyclerView.ViewHolder { final TextView vName; + final TextView playProgress; final TextView vLength; final TextView vDateAdded; final View cardView; @@ -68,6 +69,7 @@ static class RecordingsViewHolder extends RecyclerView.ViewHolder { super(v); this.playListPresenter = playListPresenter; vName = v.findViewById(R.id.file_name_text); + playProgress = v.findViewById(R.id.play_progress_text); vLength = v.findViewById(R.id.file_length_text); vDateAdded = v.findViewById(R.id.file_date_added_text); cardView = v.findViewById(R.id.record_item_root_view); @@ -86,7 +88,22 @@ private void bindEvents() { } public void updateProgressInSeekBar(Integer position) { - fillSeekBar.setProgress(playListPresenter.getListItemAt(position).playProgress); + RecordingItem currentItem = playListPresenter.getListItemAt(position); + fillSeekBar.setProgress(currentItem.playProgress); + } + + public void updatePlayTimer(int position) { + RecordingItem currentItem = playListPresenter.getListItemAt(position); + if (currentItem.playProgress > 0) { + playProgress.setVisibility(View.VISIBLE); + long minutes = TimeUnit.MILLISECONDS.toMinutes(currentItem.playProgress); + long seconds = + TimeUnit.MILLISECONDS.toSeconds(currentItem.playProgress) - TimeUnit.MINUTES.toSeconds( + minutes); + playProgress.setText(String.format("%02d:%02d", minutes, seconds)); + } else { + playProgress.setVisibility(View.GONE); + } } } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java index d37857b..00b2543 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListFragment.java @@ -161,6 +161,12 @@ private void initViews(View v) { } } + @Override public void updateTimerInListItem(int position) { + if (recordingsViewHolder != null) { + uiThreadHandler.post(() -> recordingsViewHolder.updatePlayTimer(position)); + } + } + @Override public void notifyListItemChange(Integer position) { mPlayListAdapter.notifyItemChanged(position); } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java index 51e5a76..6cd24ed 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListMVPView.java @@ -42,4 +42,6 @@ public interface PlayListMVPView extends IMVPView { void showDeleteFileDialog(int position); void updateProgressInListItem(Integer position); + + void updateTimerInListItem(int position); } diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index c95e135..1968c17 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -12,6 +12,7 @@ import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; import io.reactivex.disposables.Disposable; +import io.reactivex.functions.Function; import io.reactivex.schedulers.Schedulers; import io.reactivex.subscribers.DisposableSubscriber; import java.io.File; @@ -114,7 +115,8 @@ private void updateStateToStop() { isAudioPaused = false; currentProgress = 0; recordingItems.get(currentPlayingItem).playProgress = 0; - getAttachedView().notifyListItemChange(currentPlayingItem); + getAttachedView().updateProgressInListItem(currentPlayingItem); + getAttachedView().updateTimerInListItem(currentPlayingItem); currentPlayingItem = INVALID_ITEM; } @@ -178,11 +180,16 @@ private void updateProgress(int position) { playProgressDisposable = Flowable.interval(PROGRESS_OFFSET, TimeUnit.MILLISECONDS) .onBackpressureDrop() .observeOn(AndroidSchedulers.mainThread()) + .map(aLong -> { + currentProgress += PROGRESS_OFFSET; + recordingItems.get(position).playProgress = currentProgress; + getAttachedView().updateProgressInListItem(position); + return currentProgress / 1000; + }) + .distinctUntilChanged() .subscribeWith(new DisposableSubscriber() { @Override public void onNext(Long aLong) { - currentProgress += PROGRESS_OFFSET; - recordingItems.get(position).playProgress = currentProgress; - getAttachedView().updateProgressInListItem(position); + getAttachedView().updateTimerInListItem(position); } @Override public void onError(Throwable t) { diff --git a/app/src/main/res/layout/record_list_item.xml b/app/src/main/res/layout/record_list_item.xml index ba583f9..493bd98 100644 --- a/app/src/main/res/layout/record_list_item.xml +++ b/app/src/main/res/layout/record_list_item.xml @@ -48,6 +48,21 @@ android:layout_marginStart="10dp" /> + + Date: Thu, 28 Sep 2017 00:15:08 +0530 Subject: [PATCH 22/26] integrated leak canary --- app/build.gradle | 2 ++ .../main/java/in/arjsna/audiorecorder/AudioRecorderApp.java | 5 +++++ .../arjsna/audiorecorder/playlist/PlayListPresenterImpl.java | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/build.gradle b/app/build.gradle index 04e129b..53ecf90 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -59,4 +59,6 @@ dependencies { annotationProcessor 'com.google.dagger:dagger-compiler:2.11' provided 'javax.annotation:jsr250-api:1.0' compile 'javax.inject:javax.inject:1' + + debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4' } diff --git a/app/src/main/java/in/arjsna/audiorecorder/AudioRecorderApp.java b/app/src/main/java/in/arjsna/audiorecorder/AudioRecorderApp.java index 7bdbb85..f9aa92d 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/AudioRecorderApp.java +++ b/app/src/main/java/in/arjsna/audiorecorder/AudioRecorderApp.java @@ -2,6 +2,7 @@ import android.app.Application; import com.orhanobut.hawk.Hawk; +import com.squareup.leakcanary.LeakCanary; import in.arjsna.audiorecorder.di.components.ApplicationComponent; import in.arjsna.audiorecorder.di.components.DaggerApplicationComponent; import in.arjsna.audiorecorder.di.modules.ApplicationModule; @@ -11,6 +12,10 @@ public class AudioRecorderApp extends Application { @Override public void onCreate() { super.onCreate(); + if (LeakCanary.isInAnalyzerProcess(this)) { + return; + } + LeakCanary.install(this); Hawk.init(getApplicationContext()).build(); applicationComponent = DaggerApplicationComponent.builder().applicationModule(new ApplicationModule(this)).build(); diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index 1968c17..35981a8 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -25,7 +25,7 @@ public class PlayListPresenterImpl extends BasePresenter implements PlayListPresenter { private static final int INVALID_ITEM = -1; - private static final int PROGRESS_OFFSET = 10; + private static final int PROGRESS_OFFSET = 20; @Inject public RecordItemDataSource recordItemDataSource; From da43eb39b6ba558400a420d2901d087615f957cf Mon Sep 17 00:00:00 2001 From: Arjun Date: Fri, 29 Sep 2017 13:12:07 +0530 Subject: [PATCH 23/26] execution thread changed --- .../in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index 35981a8..5ade451 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -179,7 +179,6 @@ private void startPlayer(int position) throws IOException { private void updateProgress(int position) { playProgressDisposable = Flowable.interval(PROGRESS_OFFSET, TimeUnit.MILLISECONDS) .onBackpressureDrop() - .observeOn(AndroidSchedulers.mainThread()) .map(aLong -> { currentProgress += PROGRESS_OFFSET; recordingItems.get(position).playProgress = currentProgress; @@ -187,6 +186,7 @@ private void updateProgress(int position) { return currentProgress / 1000; }) .distinctUntilChanged() + .subscribeOn(Schedulers.computation()) .subscribeWith(new DisposableSubscriber() { @Override public void onNext(Long aLong) { getAttachedView().updateTimerInListItem(position); From 329bc011ec27131b79f9ea923b87190a9e9ff895 Mon Sep 17 00:00:00 2001 From: Arjun Date: Fri, 29 Sep 2017 13:38:18 +0530 Subject: [PATCH 24/26] dependencies updated --- app/build.gradle | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 53ecf90..17c9dd6 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -39,10 +39,10 @@ dependencies { androidTestImplementation 'com.android.support.test:runner:1.0.1' androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' - compile 'com.android.support:appcompat-v7:26.0.2' - compile 'com.android.support:cardview-v7:26.0.2' - compile 'com.android.support:recyclerview-v7:26.0.2' - compile 'com.android.support:design:26.0.2' + compile 'com.android.support:appcompat-v7:26.1.0' + compile 'com.android.support:cardview-v7:26.1.0' + compile 'com.android.support:recyclerview-v7:26.1.0' + compile 'com.android.support:design:26.1.0' compile 'io.reactivex.rxjava2:rxjava:2.1.3' compile 'io.reactivex.rxjava2:rxandroid:2.0.1' From 15ae5636d47da64b5e6dc07941ca217f0710a85f Mon Sep 17 00:00:00 2001 From: Arjun Date: Fri, 29 Sep 2017 13:38:37 +0530 Subject: [PATCH 25/26] play pause icon updated --- app/build.gradle | 1 + app/src/main/AndroidManifest.xml | 1 + .../in/arjsna/audiorecorder/db/RecordingItem.java | 2 +- .../audiorecorder/playlist/PlayListAdapter.java | 5 +++++ .../playlist/PlayListPresenterImpl.java | 13 ++++++++----- app/src/main/res/drawable-v21/ic_pause_grey.xml | 4 ++++ app/src/main/res/drawable/ic_pause_grey.xml | 4 ++++ app/src/main/res/drawable/ic_play_arrow_grey.xml | 4 ++++ app/src/main/res/layout/record_list_item.xml | 2 +- 9 files changed, 29 insertions(+), 7 deletions(-) create mode 100644 app/src/main/res/drawable-v21/ic_pause_grey.xml create mode 100644 app/src/main/res/drawable/ic_pause_grey.xml create mode 100644 app/src/main/res/drawable/ic_play_arrow_grey.xml diff --git a/app/build.gradle b/app/build.gradle index 17c9dd6..767f2d3 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -61,4 +61,5 @@ dependencies { compile 'javax.inject:javax.inject:1' debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5.4' + releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5.4' } diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 23a9415..8d612d4 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -16,6 +16,7 @@ android:theme="@style/Theme.AppCompat.Light.NoActionBar"> diff --git a/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java b/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java index 3a650b4..beb6cde 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java +++ b/app/src/main/java/in/arjsna/audiorecorder/db/RecordingItem.java @@ -17,7 +17,7 @@ public class RecordingItem implements Parcelable { private long mTime; // date/time of the recording @Ignore - public boolean isPlaying; + public boolean isPlaying = false; @Ignore public boolean isPaused; diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java index e376360..2698f24 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListAdapter.java @@ -7,6 +7,7 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; +import android.widget.ImageView; import android.widget.TextView; import in.arjsna.audiorecorder.R; import in.arjsna.audiorecorder.db.RecordingItem; @@ -49,6 +50,8 @@ public PlayListAdapter(@ActivityContext AppCompatActivity context, | DateUtils.FORMAT_SHOW_TIME | DateUtils.FORMAT_SHOW_YEAR)); holder.fillSeekBar.setProgress(currentRecording.playProgress); + holder.playStateImage.setImageResource( + currentRecording.isPlaying ? R.drawable.ic_pause_grey : R.drawable.ic_play_arrow_grey); } @Override public RecordingsViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { @@ -57,6 +60,7 @@ public PlayListAdapter(@ActivityContext AppCompatActivity context, } static class RecordingsViewHolder extends RecyclerView.ViewHolder { + final ImageView playStateImage; final TextView vName; final TextView playProgress; final TextView vLength; @@ -68,6 +72,7 @@ static class RecordingsViewHolder extends RecyclerView.ViewHolder { RecordingsViewHolder(View v, PlayListPresenter playListPresenter) { super(v); this.playListPresenter = playListPresenter; + playStateImage = v.findViewById(R.id.record_list_image); vName = v.findViewById(R.id.file_name_text); playProgress = v.findViewById(R.id.play_progress_text); vLength = v.findViewById(R.id.file_length_text); diff --git a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java index 5ade451..e44e4b4 100644 --- a/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java +++ b/app/src/main/java/in/arjsna/audiorecorder/playlist/PlayListPresenterImpl.java @@ -102,8 +102,6 @@ private Single rename(RecordingItem recordingItem, int adapterPosition, } @Override public void mediaPlayerStopped() { - Log.i("Debug ", "Stopping called"); - updateStateToStop(); } @@ -114,9 +112,10 @@ private void updateStateToStop() { isAudioPlaying = false; isAudioPaused = false; currentProgress = 0; - recordingItems.get(currentPlayingItem).playProgress = 0; - getAttachedView().updateProgressInListItem(currentPlayingItem); - getAttachedView().updateTimerInListItem(currentPlayingItem); + RecordingItem currentItem = recordingItems.get(currentPlayingItem); + currentItem.isPlaying = false; + currentItem.playProgress = 0; + getAttachedView().notifyListItemChange(currentPlayingItem); currentPlayingItem = INVALID_ITEM; } @@ -127,10 +126,12 @@ private void updateStateToStop() { if (isAudioPaused) { isAudioPaused = false; getAttachedView().resumeMediaPlayer(position); + recordingItems.get(position).isPlaying = true; updateProgress(position); } else { isAudioPaused = true; getAttachedView().pauseMediaPlayer(position); + recordingItems.get(position).isPlaying = false; playProgressDisposable.dispose(); } } else { @@ -141,6 +142,7 @@ private void updateStateToStop() { } else { startPlayer(position); } + getAttachedView().notifyListItemChange(position); } catch (IOException e) { getAttachedView().showError("Failed to start media Player"); } @@ -150,6 +152,7 @@ private void updateStateToStop() { private void startPlayer(int position) throws IOException { isAudioPlaying = true; currentProgress = 0; + recordingItems.get(position).isPlaying = true; getAttachedView().startMediaPlayer(position, recordingItems.get(position)); currentPlayingItem = position; updateProgress(position); diff --git a/app/src/main/res/drawable-v21/ic_pause_grey.xml b/app/src/main/res/drawable-v21/ic_pause_grey.xml new file mode 100644 index 0000000..b4497a1 --- /dev/null +++ b/app/src/main/res/drawable-v21/ic_pause_grey.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/drawable/ic_pause_grey.xml b/app/src/main/res/drawable/ic_pause_grey.xml new file mode 100644 index 0000000..b4497a1 --- /dev/null +++ b/app/src/main/res/drawable/ic_pause_grey.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/drawable/ic_play_arrow_grey.xml b/app/src/main/res/drawable/ic_play_arrow_grey.xml new file mode 100644 index 0000000..12ae226 --- /dev/null +++ b/app/src/main/res/drawable/ic_play_arrow_grey.xml @@ -0,0 +1,4 @@ + + + + diff --git a/app/src/main/res/layout/record_list_item.xml b/app/src/main/res/layout/record_list_item.xml index 493bd98..e21a5c2 100644 --- a/app/src/main/res/layout/record_list_item.xml +++ b/app/src/main/res/layout/record_list_item.xml @@ -29,7 +29,7 @@ android:id="@+id/record_list_image" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:src="@drawable/ic_audiotrack_grey" + android:src="@drawable/ic_play_arrow_grey" app:layout_constraintLeft_toLeftOf="parent" app:layout_constraintTop_toTopOf="parent" app:layout_constraintBottom_toBottomOf="parent"/> From f3d751460f077538a677defbc3b32cc2d21ba743 Mon Sep 17 00:00:00 2001 From: Arjun Date: Fri, 29 Sep 2017 13:55:59 +0530 Subject: [PATCH 26/26] version bump --- app/build.gradle | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 767f2d3..afa06da 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -7,8 +7,8 @@ android { applicationId "in.arjsna.audiorecorder" minSdkVersion 16 targetSdkVersion 26 - versionCode 3 - versionName "3.0" + versionCode 4 + versionName "3.1" testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" }