|
21 | 21 | import android.net.Uri;
|
22 | 22 | import android.os.Build;
|
23 | 23 | import android.os.Bundle;
|
24 |
| -import android.os.SystemClock; |
25 | 24 | import android.text.Spannable;
|
26 | 25 | import android.text.SpannableString;
|
27 | 26 | import android.text.Spanned;
|
@@ -1004,25 +1003,25 @@ static class ViewHolder extends RecyclerView.ViewHolder {
|
1004 | 1003 | mGestureDetector = new GestureDetector(itemView.getContext(),
|
1005 | 1004 | new GestureDetector.SimpleOnGestureListener() {
|
1006 | 1005 | @Override
|
1007 |
| - public void onLongPress(MotionEvent ev) { |
| 1006 | + public void onLongPress(@NonNull MotionEvent ev) { |
1008 | 1007 | itemView.performLongClick();
|
1009 | 1008 | }
|
1010 | 1009 |
|
1011 | 1010 | @Override
|
1012 |
| - public boolean onSingleTapConfirmed(MotionEvent ev) { |
| 1011 | + public boolean onSingleTapConfirmed(@NonNull MotionEvent ev) { |
1013 | 1012 | itemView.performClick();
|
1014 | 1013 | return super.onSingleTapConfirmed(ev);
|
1015 | 1014 | }
|
1016 | 1015 |
|
1017 | 1016 | @Override
|
1018 |
| - public void onShowPress(MotionEvent ev) { |
| 1017 | + public void onShowPress(@NonNull MotionEvent ev) { |
1019 | 1018 | if (mRippleOverlay != null) {
|
1020 | 1019 | mRippleOverlay.setPressed(true);
|
1021 | 1020 | mRippleOverlay.postDelayed(() -> mRippleOverlay.setPressed(false), 250);
|
1022 | 1021 | }
|
1023 | 1022 | }
|
1024 | 1023 | @Override
|
1025 |
| - public boolean onDown(MotionEvent ev) { |
| 1024 | + public boolean onDown(@NonNull MotionEvent ev) { |
1026 | 1025 | // Convert click coordinates in itemView to TexView.
|
1027 | 1026 | int[] item = new int[2];
|
1028 | 1027 | int[] text = new int[2];
|
@@ -1151,13 +1150,15 @@ private boolean clickAudio(Map<String, Object> data, Object params) {
|
1151 | 1150 | try {
|
1152 | 1151 | FullFormatter.AudioClickAction aca = (FullFormatter.AudioClickAction) params;
|
1153 | 1152 | if (aca.action == FullFormatter.AudioClickAction.Action.PLAY) {
|
1154 |
| - mMediaControl.ensurePlayerReady(mSeqId, data, aca.control); |
1155 |
| - mMediaControl.playWhenReady(); |
| 1153 | + if (mMediaControl.ensurePlayerReady(mSeqId, data, aca.control)) { |
| 1154 | + mMediaControl.playWhenReady(); |
| 1155 | + } |
1156 | 1156 | } else if (aca.action == FullFormatter.AudioClickAction.Action.PAUSE) {
|
1157 | 1157 | mMediaControl.pause();
|
1158 | 1158 | } else if (aca.seekTo != null) {
|
1159 |
| - mMediaControl.ensurePlayerReady(mSeqId, data, aca.control); |
1160 |
| - mMediaControl.seekToWhenReady(aca.seekTo); |
| 1159 | + if (mMediaControl.ensurePlayerReady(mSeqId, data, aca.control)) { |
| 1160 | + mMediaControl.seekToWhenReady(aca.seekTo); |
| 1161 | + } |
1161 | 1162 | }
|
1162 | 1163 | } catch (IOException | ClassCastException ignored) {
|
1163 | 1164 | Toast.makeText(mActivity, R.string.unable_to_play_audio, Toast.LENGTH_SHORT).show();
|
@@ -1305,11 +1306,11 @@ private class MediaControl {
|
1305 | 1306 | // Playback fraction to seek to when the player is ready.
|
1306 | 1307 | private float mSeekTo = -1f;
|
1307 | 1308 |
|
1308 |
| - synchronized void ensurePlayerReady(int seq, Map<String, Object> data, |
| 1309 | + synchronized boolean ensurePlayerReady(int seq, Map<String, Object> data, |
1309 | 1310 | FullFormatter.AudioControlCallback control) throws IOException {
|
1310 | 1311 | if (mAudioPlayer != null && mPlayingAudioSeq == seq) {
|
1311 | 1312 | mAudioControlCallback = control;
|
1312 |
| - return; |
| 1313 | + return true; |
1313 | 1314 | }
|
1314 | 1315 |
|
1315 | 1316 | if (mPlayingAudioSeq > 0 && mAudioControlCallback != null) {
|
@@ -1383,15 +1384,24 @@ synchronized void ensurePlayerReady(int seq, Map<String, Object> data,
|
1383 | 1384 | .build();
|
1384 | 1385 | mAudioPlayer.setDataSource(mActivity, uri);
|
1385 | 1386 | }
|
| 1387 | + } else { |
| 1388 | + mAudioControlCallback.reset(); |
| 1389 | + Log.w(TAG, "Invalid ref URL " + val); |
| 1390 | + Toast.makeText(mActivity, R.string.unable_to_play_audio, Toast.LENGTH_SHORT).show(); |
| 1391 | + return false; |
1386 | 1392 | }
|
1387 | 1393 | } else if ((val = data.get("val")) instanceof String) {
|
1388 | 1394 | byte[] source = Base64.decode((String) val, Base64.DEFAULT);
|
1389 | 1395 | mAudioPlayer.setDataSource(new MemoryAudioSource(source));
|
1390 | 1396 | } else {
|
| 1397 | + mAudioControlCallback.reset(); |
1391 | 1398 | Log.w(TAG, "Unable to play audio: missing data");
|
| 1399 | + Toast.makeText(mActivity, R.string.unable_to_play_audio, Toast.LENGTH_SHORT).show(); |
| 1400 | + return false; |
1392 | 1401 | }
|
1393 | 1402 |
|
1394 | 1403 | mAudioPlayer.prepareAsync();
|
| 1404 | + return true; |
1395 | 1405 | }
|
1396 | 1406 |
|
1397 | 1407 | synchronized void releasePlayer(int seq) {
|
|
0 commit comments