diff --git a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessageListFragment.java b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessageListFragment.java index e13f503f2..8df69c252 100644 --- a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessageListFragment.java +++ b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessageListFragment.java @@ -413,7 +413,6 @@ public void onPause() try { View child; - Log.i(TAG, "onPause:getChildCount=" + listingsView.getChildCount()); for (int i = 0; i < listingsView.getChildCount(); i++) { child = listingsView.getChildAt(i); diff --git a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessageListHolder_file_incoming_state_cancel.java b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessageListHolder_file_incoming_state_cancel.java index c94bc9fe8..a07454c39 100644 --- a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessageListHolder_file_incoming_state_cancel.java +++ b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessageListHolder_file_incoming_state_cancel.java @@ -827,6 +827,17 @@ public void onClick(View v) // Log.i(TAG, "onClick"); } + void DetachedFromWindow(boolean release) + { + /* + ft_audio_player.onPause(); + if (release) + { + ft_audio_player.onStop(); + } + */ + } + @Override public boolean onLongClick(final View v) { diff --git a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessagelistAdapter.java b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessagelistAdapter.java index 88749b0be..ee8a445ce 100644 --- a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessagelistAdapter.java +++ b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/GroupMessagelistAdapter.java @@ -67,7 +67,13 @@ public void onViewDetachedFromWindow(@NonNull RecyclerView.ViewHolder holder) { } catch(Exception e) { - Log.i(TAG, "onViewDetachedFromWindow:G:activity_stop()"); + } + try + { + ((GroupMessageListHolder_file_incoming_state_cancel) holder).DetachedFromWindow(false); + } + catch(Exception e) + { } super.onViewDetachedFromWindow(holder); } diff --git a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessageListFragment.java b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessageListFragment.java index 0d5321d52..adf53003a 100644 --- a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessageListFragment.java +++ b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessageListFragment.java @@ -456,7 +456,6 @@ public void onPause() try { View child; - Log.i(TAG, "onPause:getChildCount=" + listingsView.getChildCount()); for (int i = 0; i < listingsView.getChildCount(); i++) { child = listingsView.getChildAt(i); @@ -468,6 +467,14 @@ public void onPause() catch(Exception e1) { } + try + { + RecyclerView.ViewHolder vh = listingsView.getChildViewHolder(child); + ((MessageListHolder_file_incoming_state_cancel) vh).DetachedFromWindow(true); + } + catch(Exception e1) + { + } } } catch(Exception e2) diff --git a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessageListHolder_file_incoming_state_cancel.java b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessageListHolder_file_incoming_state_cancel.java index 1f3be308e..9e3afaf1a 100644 --- a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessageListHolder_file_incoming_state_cancel.java +++ b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessageListHolder_file_incoming_state_cancel.java @@ -98,6 +98,7 @@ public class MessageListHolder_file_incoming_state_cancel extends RecyclerView.V boolean is_selected = false; TextView message_text_date_string; ViewGroup message_text_date; + me.jagar.chatvoiceplayerlibrary.vVoicePlayerView ft_audio_player; public MessageListHolder_file_incoming_state_cancel(View itemView, Context c) { @@ -124,6 +125,7 @@ public MessageListHolder_file_incoming_state_cancel(View itemView, Context c) ft_export_button_container = (ViewGroup) itemView.findViewById(R.id.ft_export_button_container); ft_export_button = (ImageButton) itemView.findViewById(R.id.ft_export_button); ft_share_button = (ImageButton) itemView.findViewById(R.id.ft_share_button); + ft_audio_player = itemView.findViewById(R.id.ft_audio_player); } @SuppressLint("ClickableViewAccessibility") @@ -140,6 +142,9 @@ public void bindMessageList(Message m) message_ = m; + ft_audio_player.setVisibility(View.GONE); + ft_preview_image.getLayoutParams().height = (int)dp2px(150); + int drawable_id = R.drawable.rounded_orange_bg_with_border; try { @@ -282,6 +287,7 @@ public void bindMessageList(Message m) boolean is_image = false; boolean is_video = false; + boolean is_audio = false; try { String mimeType = URLConnection.guessContentTypeFromName(message.filename_fullpath.toLowerCase()); @@ -304,6 +310,11 @@ public void bindMessageList(Message m) { is_video = true; } + + if (mimeType.startsWith("audio/")) + { + is_audio = true; + } } catch (Exception e) { @@ -439,6 +450,33 @@ else if (is_video) // ---- a video ---- e.printStackTrace(); } } + else if (is_audio) // ---- an audio file ---- + { + if (PREF__compact_chatlist) + { + textView.setVisibility(View.GONE); + imageView.setVisibility(View.GONE); + } + + ft_progressbar.setVisibility(View.GONE); + ft_buttons_container.setVisibility(View.GONE); + button_ok.setVisibility(View.GONE); + button_cancel.setVisibility(View.GONE); + + ft_preview_container.setVisibility(View.VISIBLE); + ft_preview_image.setVisibility(View.GONE); + + ft_audio_player.setVisibility(View.VISIBLE); + + resize_viewgroup(ft_preview_container, 55); + resize_view(ft_preview_image, 1); + + if (VFS_ENCRYPT) + { + ft_audio_player.refreshPlayer(message2.filename_fullpath); + ft_audio_player.refreshVisualizer(); + } + } else // ---- not an image or a video ---- { final Drawable d3 = new IconicsDrawable(this.context). @@ -676,6 +714,15 @@ public void onClick(View v) // Log.i(TAG, "onClick"); } + void DetachedFromWindow(boolean release) + { + ft_audio_player.onPause(); + if (release) + { + ft_audio_player.onStop(); + } + } + @Override public boolean onLongClick(final View v) { diff --git a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessagelistAdapter.java b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessagelistAdapter.java index d38f4a944..093ed39a3 100644 --- a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessagelistAdapter.java +++ b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/MessagelistAdapter.java @@ -327,14 +327,20 @@ else if (my_msg.direction == 0) @Override public void onViewDetachedFromWindow(RecyclerView.ViewHolder holder) { - Log.i(TAG, "onViewDetachedFromWindow:M"); try { ((MessageListHolder_file_outgoing_state_cancel) holder).DetachedFromWindow(false); } catch(Exception e) { - Log.i(TAG, "onViewDetachedFromWindow:M:activity_stop()"); + } + + try + { + ((MessageListHolder_file_incoming_state_cancel) holder).DetachedFromWindow(false); + } + catch(Exception e1) + { } /* diff --git a/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/VFileMediaDataSource.java b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/VFileMediaDataSource.java new file mode 100644 index 000000000..80de42167 --- /dev/null +++ b/android-refimpl-app/app/src/main/java/com/zoffcc/applications/trifa/VFileMediaDataSource.java @@ -0,0 +1,72 @@ +package com.zoffcc.applications.trifa; + +import android.media.MediaDataSource; +import android.os.Build; + +import java.io.IOException; + +import androidx.annotation.RequiresApi; + +@RequiresApi(api = Build.VERSION_CODES.M) +public class VFileMediaDataSource extends MediaDataSource +{ + private info.guardianproject.iocipher.RandomAccessFile f; + private long streamLength = -1, lastReadEndPosition; + + public VFileMediaDataSource(info.guardianproject.iocipher.RandomAccessFile f) + { + this.f = f; + try + { + this.streamLength = f.length(); + } + catch (Exception e) + { + throw new RuntimeException(e); + } + if (streamLength <= 0) + { + throw new RuntimeException(); + } + } + + @Override + public synchronized void close() + { + } + + @Override + public synchronized int readAt(long position, byte[] buffer, int offset, int size) + { + if (position >= streamLength) + { + return -1; + } + + if (position + size > streamLength) + { + size -= (position + size) - streamLength; + } + + if (position < 0) + { + position = 0; + } + + try + { + this.f.seek(position); + return this.f.read(buffer, offset, size); + } + catch(Exception e) + { + return -1; + } + } + + @Override + public synchronized long getSize() + { + return streamLength; + } +} diff --git a/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/FileUtils.java b/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/FileUtils.java index 7050e45c9..ec2fc984f 100644 --- a/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/FileUtils.java +++ b/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/FileUtils.java @@ -38,6 +38,29 @@ public void run() }.execute(); } + public static void vupdateVisualizer(final Context context, final info.guardianproject.iocipher.File vfile, final PlayerVisualizerSeekbar playerVisualizerSeekbar){ + new AsyncTask() + { + @Override + protected byte[] doInBackground(Void... voids) { + return vfileToBytes(vfile); + } + + @Override + protected void onPostExecute(final byte[] bytes) { + super.onPostExecute(bytes); + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() + { + playerVisualizerSeekbar.setBytes(bytes); + playerVisualizerSeekbar.invalidate(); + } + }); + } + }.execute(); + } + public static byte[] fileToBytes(File file) { if (file.length() > MAX_FILE_SIZE_BYTES) @@ -60,4 +83,27 @@ public static byte[] fileToBytes(File file) } return bytes; } + + public static byte[] vfileToBytes(info.guardianproject.iocipher.File vfile) + { + if (vfile.length() > MAX_FILE_SIZE_BYTES) + { + return null; + } + byte[] bytes = null; + try + { + int size = (int) vfile.length(); + bytes = new byte[size]; + BufferedInputStream buf = new BufferedInputStream(new info.guardianproject.iocipher.FileInputStream(vfile)); + buf.read(bytes, 0, bytes.length); + buf.close(); + } + catch (Exception e) + { + e.printStackTrace(); + return null; + } + return bytes; + } } diff --git a/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/PlayerVisualizerSeekbar.java b/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/PlayerVisualizerSeekbar.java index 5055abc53..f0cc6b622 100644 --- a/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/PlayerVisualizerSeekbar.java +++ b/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/PlayerVisualizerSeekbar.java @@ -77,6 +77,11 @@ public void updateVisualizer(File file) { FileUtils.updateVisualizer(getContext(), file, this); } + public void vupdateVisualizer(info.guardianproject.iocipher.File vfile) { + + FileUtils.vupdateVisualizer(getContext(), vfile, this); + } + public void setBytes(byte[] bytes){ this.bytes = bytes; } diff --git a/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/VoicePlayerView.java b/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/VoicePlayerView.java index de1d73b09..96f57f8c4 100644 --- a/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/VoicePlayerView.java +++ b/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/VoicePlayerView.java @@ -35,7 +35,7 @@ import java.net.URLConnection; - public class VoicePlayerView extends LinearLayout { +public class VoicePlayerView extends LinearLayout { private int playPaueseBackgroundColor, shareBackgroundColor, viewBackgroundColor, seekBarProgressColor, seekBarThumbColor, progressTimeColor, timingBackgroundColor, diff --git a/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/vVoicePlayerView.java b/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/vVoicePlayerView.java new file mode 100644 index 000000000..001f6fd0f --- /dev/null +++ b/android-refimpl-app/app/src/main/java/me/jagar/chatvoiceplayerlibrary/vVoicePlayerView.java @@ -0,0 +1,934 @@ + /* + This class is a part of Chat Voice Player View Android Library + Developed by: Jagar Yousef + Date: 2019 + */ + +package me.jagar.chatvoiceplayerlibrary; +import android.app.Activity; +import android.content.Context; +import android.content.res.TypedArray; +import android.graphics.Color; +import android.graphics.PorterDuff; +import android.graphics.drawable.GradientDrawable; +import android.media.AudioManager; +import android.media.MediaPlayer; +import android.net.Uri; +import android.os.Build; +import android.os.Handler; +import android.util.AttributeSet; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.ProgressBar; +import android.widget.SeekBar; +import android.widget.TextView; + +import com.zoffcc.applications.trifa.R; +import com.zoffcc.applications.trifa.VFileMediaDataSource; + +import java.io.IOException; + +import info.guardianproject.iocipher.File; +import info.guardianproject.iocipher.RandomAccessFile; + + + public class vVoicePlayerView extends LinearLayout { + + private int playPaueseBackgroundColor, shareBackgroundColor, viewBackgroundColor, + seekBarProgressColor, seekBarThumbColor, progressTimeColor, timingBackgroundColor, + visualizationPlayedColor, visualizationNotPlayedColor, playProgressbarColor; + private float viewCornerRadius, playPauseCornerRadius, shareCornerRadius; + private boolean showShareButton, showTiming, enableVirtualizer; + private GradientDrawable playPauseShape, shareShape, viewShape; + private Context context; + private String vaudiopath; + private String shareTitle = "Share Voice"; + + private LinearLayout main_layout, padded_layout, container_layout; + private ImageView imgPlay, imgPause, imgShare; + private SeekBar seekBar; + private ProgressBar progressBar; + private TextView txtProcess; + private MediaPlayer mediaPlayer; + private ProgressBar pb_play; + + private PlayerVisualizerSeekbar seekbarV; + private Uri contentUri = null; + + public vVoicePlayerView(Context context) { + super(context); + LayoutInflater.from(context).inflate(R.layout.voiceplayerview_main_view, this); + this.context = context; + } + + public vVoicePlayerView(Context context, AttributeSet attrs) { + super(context, attrs); + initViews(context, attrs); + this.context = context; + } + + public vVoicePlayerView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + initViews(context, attrs); + this.context = context; + } + + private void initViews(Context context, AttributeSet attrs) { + + TypedArray typedArray = context.getTheme().obtainStyledAttributes(attrs, + R.styleable.VoicePlayerView, 0, 0); + + viewShape = new GradientDrawable(); + playPauseShape = new GradientDrawable(); + shareShape = new GradientDrawable(); + + try{ + showShareButton = typedArray.getBoolean(R.styleable.VoicePlayerView_showShareButton, true); + showTiming = typedArray.getBoolean(R.styleable.VoicePlayerView_showTiming, true); + viewCornerRadius = typedArray.getFloat(R.styleable.VoicePlayerView_viewCornerRadius, 0); + playPauseCornerRadius = typedArray.getFloat(R.styleable.VoicePlayerView_playPauseCornerRadius, 0); + shareCornerRadius = typedArray.getFloat(R.styleable.VoicePlayerView_shareCornerRadius, 0); + playPaueseBackgroundColor = typedArray.getColor(R.styleable.VoicePlayerView_playPauseBackgroundColor, getResources().getColor(R.color.md_pink_100)); + shareBackgroundColor = typedArray.getColor(R.styleable.VoicePlayerView_shareBackgroundColor, getResources().getColor(R.color.md_pink_500)); + viewBackgroundColor = typedArray.getColor(R.styleable.VoicePlayerView_viewBackground, getResources().getColor(R.color.md_white_1000)); + seekBarProgressColor = typedArray.getColor(R.styleable.VoicePlayerView_seekBarProgressColor, getResources().getColor(R.color.md_pink_500)); + seekBarThumbColor = typedArray.getColor(R.styleable.VoicePlayerView_seekBarThumbColor, getResources().getColor(R.color.md_pink_500)); + progressTimeColor = typedArray.getColor(R.styleable.VoicePlayerView_progressTimeColor, Color.GRAY); + shareTitle = typedArray.getString(R.styleable.VoicePlayerView_shareText); + enableVirtualizer = typedArray.getBoolean(R.styleable.VoicePlayerView_enableVisualizer, false); + timingBackgroundColor = typedArray.getColor(R.styleable.VoicePlayerView_timingBackgroundColor, getResources().getColor(android.R.color.transparent)); + visualizationNotPlayedColor = typedArray.getColor(R.styleable.VoicePlayerView_visualizationNotPlayedColor, getResources().getColor(R.color.gray)); + visualizationPlayedColor = typedArray.getColor(R.styleable.VoicePlayerView_visualizationPlayedColor, getResources().getColor(R.color.md_pink_500)); + playProgressbarColor= typedArray.getColor(R.styleable.VoicePlayerView_playProgressbarColor, getResources().getColor(R.color.md_pink_500)); + + + + }finally { + typedArray.recycle(); + } + + + LayoutInflater.from(context).inflate(R.layout.voiceplayerview_main_view, this); + main_layout = this.findViewById(R.id.collectorLinearLayout); + padded_layout = this.findViewById(R.id.paddedLinearLayout); + container_layout = this.findViewById(R.id.containerLinearLayout); + imgPlay = this.findViewById(R.id.imgPlay); + imgPause = this.findViewById(R.id.imgPause); + imgShare = this.findViewById(R.id.imgShare); + seekBar = this.findViewById(R.id.seekBar); + progressBar = this.findViewById(R.id.progressBar); + txtProcess = this.findViewById(R.id.txtTime); + seekbarV = this.findViewById(R.id.seekBarV); + pb_play = this.findViewById(R.id.pb_play); + + + viewShape.setColor(viewBackgroundColor); + viewShape.setCornerRadius(viewCornerRadius); + playPauseShape.setColor(playPaueseBackgroundColor); + playPauseShape.setCornerRadius(playPauseCornerRadius); + shareShape.setColor(shareBackgroundColor); + shareShape.setCornerRadius(shareCornerRadius); + + imgPlay.setBackground(playPauseShape); + imgPause.setBackground(playPauseShape); + imgShare.setBackground(shareShape); + main_layout.setBackground(viewShape); + seekBar.getProgressDrawable().setColorFilter(seekBarProgressColor, PorterDuff.Mode.SRC_IN); + seekBar.getThumb().setColorFilter(seekBarThumbColor, PorterDuff.Mode.SRC_IN); + + GradientDrawable timingBackground = new GradientDrawable(); + timingBackground.setColor(timingBackgroundColor); + timingBackground.setCornerRadius(25); + txtProcess.setBackground(timingBackground); + txtProcess.setPadding(16, 0, 16, 0); + txtProcess.setTextColor(progressTimeColor); + + + pb_play.getIndeterminateDrawable().setColorFilter( + playProgressbarColor, + PorterDuff.Mode.SRC_IN); + + + + if (!showShareButton) + imgShare.setVisibility(GONE); + if (!showTiming) + txtProcess.setVisibility(INVISIBLE); + + if (enableVirtualizer){ + seekbarV.setVisibility(VISIBLE); + seekBar.setVisibility(GONE); + seekbarV.getProgressDrawable().setColorFilter(getResources().getColor(android.R.color.transparent), PorterDuff.Mode.SRC_IN); + seekbarV.getThumb().setColorFilter(getResources().getColor(android.R.color.transparent), PorterDuff.Mode.SRC_IN); + seekbarV.setColors(visualizationPlayedColor, visualizationNotPlayedColor); + } + + } + + + //Set the audio source and prepare mediaplayer + + public void setAudio(String vpath){ + vaudiopath = vpath; + mediaPlayer = new MediaPlayer(); + Log.i("vVoicePlayerView", "vVoicePlayerView:setAudio:new MediaPlayer()"); + if (vaudiopath != null) { + try { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + { + mediaPlayer.setDataSource(new VFileMediaDataSource(new info.guardianproject.iocipher.RandomAccessFile(vpath, "r"))); + } + mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + mediaPlayer.prepare(); + mediaPlayer.setVolume(10, 10); + //START and PAUSE are in other listeners + mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(MediaPlayer mp) { + seekBar.setMax(mp.getDuration()); + if (seekbarV.getVisibility() == VISIBLE){ + seekbarV.setMax(mp.getDuration()); + } + txtProcess.setText("00:00:00/"+convertSecondsToHMmSs(mp.getDuration() / 1000)); + } + }); + mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(MediaPlayer mp) { + imgPause.setVisibility(View.GONE); + imgPlay.setVisibility(View.VISIBLE); + } + }); + + } catch (IOException e) { + e.printStackTrace(); + } + } + + seekBar.setOnSeekBarChangeListener(seekBarListener); + imgPlay.setOnClickListener(imgPlayClickListener); + imgPause.setOnClickListener(imgPauseClickListener); + imgShare.setOnClickListener(imgShareClickListener); + if (seekbarV.getVisibility() == VISIBLE){ + seekbarV.vupdateVisualizer(new info.guardianproject.iocipher.File(vpath)); + } + + seekbarV.setOnSeekBarChangeListener(seekBarListener); + // seekbarV.vupdateVisualizer(new File(path)); + } + + + + //Components' listeners + + OnClickListener imgPlayClickListener = new OnClickListener() { + @Override + public void onClick(View v) { + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + imgPause.setVisibility(View.VISIBLE); + imgPlay.setVisibility(View.GONE); + } + }); + + try{ + if (mediaPlayer != null){ + mediaPlayer.start(); + } + update(mediaPlayer, txtProcess, seekBar, context); + }catch (Exception e){ + e.printStackTrace(); + } + + } + }; + + + + private SeekBar.OnSeekBarChangeListener seekBarListener = new SeekBar.OnSeekBarChangeListener() { + @Override + public void onProgressChanged(final SeekBar seekBar, final int progress, boolean fromUser) { + if (fromUser) { + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + try + { + mediaPlayer.seekTo(progress); + update(mediaPlayer, txtProcess, seekBar, context); + if (seekbarV.getVisibility() == VISIBLE) + { + seekbarV.updatePlayerPercent((float) mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration()); + } + } + catch(Exception e) + { + e.printStackTrace(); + } + } + }); + } + } + + @Override + public void onStartTrackingTouch(SeekBar seekBar) { + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + imgPause.setVisibility(View.GONE); + imgPlay.setVisibility(View.VISIBLE); + } + }); + } + + @Override + public void onStopTrackingTouch(SeekBar seekBar) { + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + imgPlay.setVisibility(View.GONE); + imgPause.setVisibility(View.VISIBLE); + try{ + mediaPlayer.start(); + }catch (Exception e){ + e.printStackTrace(); + } + } + }); + + } + }; + + OnClickListener imgPauseClickListener = new OnClickListener() { + @Override + public void onClick(View v) { + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + imgPause.setVisibility(View.GONE); + imgPlay.setVisibility(View.VISIBLE); + try{ + mediaPlayer.pause(); + }catch (Exception e){ + e.printStackTrace(); + } + } + }); + + } + }; + + OnClickListener imgShareClickListener = new OnClickListener() { + @Override + public void onClick(View view) { + } + }; + + //Updating seekBar in realtime + private void update(final MediaPlayer mediaPlayer, final TextView time, final SeekBar seekBar, final Context context) { + ((Activity)context).runOnUiThread(new Runnable() { + @Override + public void run() { + try + { + seekBar.setProgress(mediaPlayer.getCurrentPosition()); + } + catch(Exception e) + { + Log.i("vVoicePlayerView", "vVoicePlayerView:update:EE01:" + e.getMessage() + " mediaPlayer=" + mediaPlayer); + } + if (seekbarV.getVisibility() == VISIBLE){ + seekbarV.setProgress(mediaPlayer.getCurrentPosition()); + seekbarV.updatePlayerPercent((float) mediaPlayer.getCurrentPosition() / mediaPlayer.getDuration()); + } + + + + if (mediaPlayer.getDuration() - mediaPlayer.getCurrentPosition() > 100) { + time.setText(convertSecondsToHMmSs(mediaPlayer.getCurrentPosition() / 1000) + " / " + convertSecondsToHMmSs(mediaPlayer.getDuration() / 1000)); + } + else { + time.setText(convertSecondsToHMmSs(mediaPlayer.getDuration() / 1000)); + seekBar.setProgress(0); + if (seekbarV.getVisibility() == VISIBLE){ + seekbarV.updatePlayerPercent(0); + seekbarV.setProgress(0); + } + } + Handler handler = new Handler(); + try{ + Runnable runnable = new Runnable() { + @Override + public void run() { + try{ + if (mediaPlayer.getCurrentPosition() > -1) { + try { + update(mediaPlayer, time, seekBar, context); + } catch (Exception e) { + // e.printStackTrace(); + } + } + }catch (Exception e){ + // e.printStackTrace(); + } + } + }; + handler.postDelayed(runnable, 500); + }catch (Exception e){ + e.printStackTrace(); + } + + } + }); + } + + //Convert long milli seconds to a formatted String to display it + + private static String convertSecondsToHMmSs(long seconds) { + long s = seconds % 60; + long m = (seconds / 60) % 60; + long h = (seconds / (60 * 60)) % 24; + return String.format("%02d:%02d:%02d", h,m,s); + } + + //These both functions to avoid mediaplayer errors + + public void onStop() + { + try + { + mediaPlayer.stop(); + } + catch (Exception e) + { + e.printStackTrace(); + Log.i("vVoicePlayerView", "vVoicePlayerView:onStop:EE01:" + e.getMessage()); + } + + try + { + mediaPlayer.reset(); + } + catch (Exception e) + { + e.printStackTrace(); + Log.i("vVoicePlayerView", "vVoicePlayerView:onStop:EE02:" + e.getMessage()); + } + + try + { + mediaPlayer.release(); + Log.i("vVoicePlayerView", "vVoicePlayerView:mediaPlayer.release()"); + } + catch (Exception e) + { + e.printStackTrace(); + Log.i("vVoicePlayerView", "vVoicePlayerView:onStop:EE03:" + e.getMessage()); + } + + mediaPlayer = null; + } + + public void onPause(){ + Log.i("vVoicePlayerView", "vVoicePlayerView:onPause():mediaPlayer=" + mediaPlayer); + try{ + if (mediaPlayer != null) + { + Log.i("vVoicePlayerView", "vVoicePlayerView:onPause():mediaPlayer.isPlaying()=" + mediaPlayer.isPlaying()); + if (mediaPlayer.isPlaying()) + { + mediaPlayer.pause(); + Log.i("vVoicePlayerView", "vVoicePlayerView:onPause():DONE ***"); + mediaPlayer.stop(); + } + } + } + catch (Exception e) + { + e.printStackTrace(); + Log.i("vVoicePlayerView", "vVoicePlayerView:onPause:EE01:" + e.getMessage()); + } + + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + imgPause.setVisibility(View.GONE); + imgPlay.setVisibility(View.VISIBLE); + } + }); + } + + + // Programmatically functions + + public void setViewBackgroundShape(int color, float radius){ + GradientDrawable shape = new GradientDrawable(); + shape.setColor(getResources().getColor(color)); + shape.setCornerRadius(radius); + main_layout.setBackground(shape); + } + public void setShareBackgroundShape(int color, float radius){ + GradientDrawable shape = new GradientDrawable(); + shape.setColor(getResources().getColor(color)); + shape.setCornerRadius(radius); + imgShare.setBackground(shape); + } + public void setPlayPaueseBackgroundShape(int color, float radius){ + GradientDrawable shape = new GradientDrawable(); + shape.setColor(getResources().getColor(color)); + shape.setCornerRadius(radius); + imgPause.setBackground(shape); + imgPlay.setBackground(shape); + } + public void setSeekBarStyle(int progressColor, int thumbColor){ + seekBar.getProgressDrawable().setColorFilter(getResources().getColor(progressColor), PorterDuff.Mode.SRC_IN); + seekBar.getThumb().setColorFilter(getResources().getColor(thumbColor), PorterDuff.Mode.SRC_IN); + } + public void setTimingVisibility(boolean visibility){ + if (!visibility) + txtProcess.setVisibility(INVISIBLE); + else + txtProcess.setVisibility(VISIBLE); + } + public void setShareButtonVisibility(boolean visibility){ + if (!visibility) + imgShare.setVisibility(GONE); + else + imgShare.setVisibility(VISIBLE); + } + public void setShareText(String shareText){ + shareTitle = shareText; + } + + public void showPlayProgressbar(){ + imgPlay.setVisibility(GONE); + pb_play.setVisibility(VISIBLE); + } + + public void hidePlayProgresbar(){ + pb_play.setVisibility(GONE); + imgPlay.setVisibility(VISIBLE); + } + + public void refreshPlayer(String vpath){ + vaudiopath = vpath; + if (mediaPlayer != null){ + try{ + if (mediaPlayer.isPlaying()){ + mediaPlayer.stop(); + } + // mediaPlayer.release(); + }catch (Exception e){ + e.printStackTrace(); + } + } + if (mediaPlayer == null) + { + // mediaPlayer = null; + mediaPlayer = new MediaPlayer(); + } + mediaPlayer.reset(); + Log.i("vVoicePlayerView", "vVoicePlayerView:refreshPlayer:new MediaPlayer()"); + if (vpath != null) { + try { + Log.i("vVoicePlayerView", "vVoicePlayerView:refreshPlayer:setDataSource"); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) + { + mediaPlayer.setDataSource(new VFileMediaDataSource(new RandomAccessFile(vpath, "r"))); + } + mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); + mediaPlayer.prepare(); + mediaPlayer.setVolume(10, 10); + //START and PAUSE are in other listeners + mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { + @Override + public void onPrepared(final MediaPlayer mp) { + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + seekBar.setMax(mp.getDuration()); + seekBar.setProgress(0); + if (seekbarV.getVisibility() == VISIBLE){ + seekbarV.setMax(mp.getDuration()); + seekbarV.setProgress(0); + } + + if (imgPause.getVisibility() == View.VISIBLE){ + imgPause.setVisibility(View.GONE); + imgPlay.setVisibility(View.VISIBLE); + } + Log.i("vVoicePlayerView", "vVoicePlayerView:refreshPlayer:setOnPreparedListener"); + txtProcess.setText("00:00:00/"+convertSecondsToHMmSs(mp.getDuration() / 1000)); + } + }); + } + }); + mediaPlayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { + @Override + public void onCompletion(MediaPlayer mp) { + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + imgPause.setVisibility(View.GONE); + imgPlay.setVisibility(View.VISIBLE); + } + }); + } + }); + + } catch (IOException e) { + e.printStackTrace(); + Log.i("vVoicePlayerView", "vVoicePlayerView:refreshPlayer:EE01:" + e.getMessage()); + } + } + + + ((Activity) context).runOnUiThread(new Runnable() { + @Override + public void run() { + seekBar.setOnSeekBarChangeListener(seekBarListener); + imgPlay.setOnClickListener(imgPlayClickListener); + imgPause.setOnClickListener(imgPauseClickListener); + imgShare.setOnClickListener(imgShareClickListener); + if (seekbarV.getVisibility() == VISIBLE){ + // seekbarV.vupdateVisualizer(new File(path)); + seekbarV.setOnSeekBarChangeListener(seekBarListener); + if (vpath != null) + { + seekbarV.vupdateVisualizer(new File(vpath)); + } + Log.i("vVoicePlayerView", "vVoicePlayerView:refreshPlayer:vupdateVisualizer"); + } + } + }); + + seekBar.invalidate(); + seekbarV.invalidate(); + this.invalidate(); + } + + + public void refreshVisualizer() { + if (seekbarV.getVisibility() == VISIBLE){ + seekbarV.vupdateVisualizer(new info.guardianproject.iocipher.File(vaudiopath)); + } + } + + public ProgressBar getPlayProgressbar(){ + return pb_play; + } + + public int getPlayPaueseBackgroundColor() { + return playPaueseBackgroundColor; + } + + public void setPlayPaueseBackgroundColor(int playPaueseBackgroundColor) { + this.playPaueseBackgroundColor = playPaueseBackgroundColor; + } + + public int getShareBackgroundColor() { + return shareBackgroundColor; + } + + public void setShareBackgroundColor(int shareBackgroundColor) { + this.shareBackgroundColor = shareBackgroundColor; + } + + public int getViewBackgroundColor() { + return viewBackgroundColor; + } + + public void setViewBackgroundColor(int viewBackgroundColor) { + this.viewBackgroundColor = viewBackgroundColor; + } + + public int getSeekBarProgressColor() { + return seekBarProgressColor; + } + + public void setSeekBarProgressColor(int seekBarProgressColor) { + this.seekBarProgressColor = seekBarProgressColor; + } + + public int getSeekBarThumbColor() { + return seekBarThumbColor; + } + + public void setSeekBarThumbColor(int seekBarThumbColor) { + this.seekBarThumbColor = seekBarThumbColor; + } + + public int getProgressTimeColor() { + return progressTimeColor; + } + + public void setProgressTimeColor(int progressTimeColor) { + this.progressTimeColor = progressTimeColor; + } + + public int getTimingBackgroundColor() { + return timingBackgroundColor; + } + + public void setTimingBackgroundColor(int timingBackgroundColor) { + this.timingBackgroundColor = timingBackgroundColor; + } + + public int getVisualizationPlayedColor() { + return visualizationPlayedColor; + } + + public void setVisualizationPlayedColor(int visualizationPlayedColor) { + this.visualizationPlayedColor = visualizationPlayedColor; + } + + public int getVisualizationNotPlayedColor() { + return visualizationNotPlayedColor; + } + + public void setVisualizationNotPlayedColor(int visualizationNotPlayedColor) { + this.visualizationNotPlayedColor = visualizationNotPlayedColor; + } + + public int getPlayProgressbarColor() { + return playProgressbarColor; + } + + public void setPlayProgressbarColor(int playProgressbarColor) { + this.playProgressbarColor = playProgressbarColor; + } + + public float getViewCornerRadius() { + return viewCornerRadius; + } + + public void setViewCornerRadius(float viewCornerRadius) { + this.viewCornerRadius = viewCornerRadius; + } + + public float getPlayPauseCornerRadius() { + return playPauseCornerRadius; + } + + public void setPlayPauseCornerRadius(float playPauseCornerRadius) { + this.playPauseCornerRadius = playPauseCornerRadius; + } + + public float getShareCornerRadius() { + return shareCornerRadius; + } + + public void setShareCornerRadius(float shareCornerRadius) { + this.shareCornerRadius = shareCornerRadius; + } + + public boolean isShowShareButton() { + return showShareButton; + } + + public void setShowShareButton(boolean showShareButton) { + this.showShareButton = showShareButton; + } + + public boolean isShowTiming() { + return showTiming; + } + + public void setShowTiming(boolean showTiming) { + this.showTiming = showTiming; + } + + public boolean isEnableVirtualizer() { + return enableVirtualizer; + } + + public void setEnableVirtualizer(boolean enableVirtualizer) { + this.enableVirtualizer = enableVirtualizer; + } + + public GradientDrawable getPlayPauseShape() { + return playPauseShape; + } + + public void setPlayPauseShape(GradientDrawable playPauseShape) { + this.playPauseShape = playPauseShape; + } + + public GradientDrawable getShareShape() { + return shareShape; + } + + public void setShareShape(GradientDrawable shareShape) { + this.shareShape = shareShape; + } + + public GradientDrawable getViewShape() { + return viewShape; + } + + public void setViewShape(GradientDrawable viewShape) { + this.viewShape = viewShape; + } + + public void setContext(Context context) { + this.context = context; + } + + public String getPath() { + return vaudiopath; + } + + public void setPath(String vpath) { + this.vaudiopath = vpath; + } + + public String getShareTitle() { + return shareTitle; + } + + public void setShareTitle(String shareTitle) { + this.shareTitle = shareTitle; + } + + public LinearLayout getMain_layout() { + return main_layout; + } + + public void setMain_layout(LinearLayout main_layout) { + this.main_layout = main_layout; + } + + public LinearLayout getPadded_layout() { + return padded_layout; + } + + public void setPadded_layout(LinearLayout padded_layout) { + this.padded_layout = padded_layout; + } + + public LinearLayout getContainer_layout() { + return container_layout; + } + + public void setContainer_layout(LinearLayout container_layout) { + this.container_layout = container_layout; + } + + public ImageView getImgPlay() { + return imgPlay; + } + + public void setImgPlay(ImageView imgPlay) { + this.imgPlay = imgPlay; + } + + public ImageView getImgPause() { + return imgPause; + } + + public void setImgPause(ImageView imgPause) { + this.imgPause = imgPause; + } + + public ImageView getImgShare() { + return imgShare; + } + + public void setImgShare(ImageView imgShare) { + this.imgShare = imgShare; + } + + public SeekBar getSeekBar() { + return seekBar; + } + + public void setSeekBar(SeekBar seekBar) { + this.seekBar = seekBar; + } + + public ProgressBar getProgressBar() { + return progressBar; + } + + public void setProgressBar(ProgressBar progressBar) { + this.progressBar = progressBar; + } + + public TextView getTxtProcess() { + return txtProcess; + } + + public void setTxtProcess(TextView txtProcess) { + this.txtProcess = txtProcess; + } + + public MediaPlayer getMediaPlayer() { + return mediaPlayer; + } + + public void setMediaPlayer(MediaPlayer mediaPlayer) { + this.mediaPlayer = mediaPlayer; + } + + public ProgressBar getPb_play() { + return pb_play; + } + + public void setPb_play(ProgressBar pb_play) { + this.pb_play = pb_play; + } + + public PlayerVisualizerSeekbar getSeekbarV() { + return seekbarV; + } + + public void setSeekbarV(PlayerVisualizerSeekbar seekbarV) { + this.seekbarV = seekbarV; + } + + public OnClickListener getImgPlayClickListener() { + return imgPlayClickListener; + } + + public void setImgPlayClickListener(OnClickListener imgPlayClickListener) { + this.imgPlayClickListener = imgPlayClickListener; + } + + public SeekBar.OnSeekBarChangeListener getSeekBarListener() { + return seekBarListener; + } + + public void setSeekBarListener(SeekBar.OnSeekBarChangeListener seekBarListener) { + this.seekBarListener = seekBarListener; + } + + public OnClickListener getImgPauseClickListener() { + return imgPauseClickListener; + } + + public void setImgPauseClickListener(OnClickListener imgPauseClickListener) { + this.imgPauseClickListener = imgPauseClickListener; + } + + public OnClickListener getImgShareClickListener() { + return imgShareClickListener; + } + + public void setImgShareClickListener(OnClickListener imgShareClickListener) { + this.imgShareClickListener = imgShareClickListener; + } + + public Uri getContentUri() { + return contentUri; + } + + public void setContentUri(Uri contentUri) { + this.contentUri = contentUri; + } + } + + diff --git a/android-refimpl-app/app/src/main/res/layout/message_list_ft_incoming.xml b/android-refimpl-app/app/src/main/res/layout/message_list_ft_incoming.xml index 378976440..0b9851ce9 100644 --- a/android-refimpl-app/app/src/main/res/layout/message_list_ft_incoming.xml +++ b/android-refimpl-app/app/src/main/res/layout/message_list_ft_incoming.xml @@ -91,8 +91,6 @@ android:layout_marginRight="0dp" android:orientation="horizontal"> - // style="?android:attr/progressBarStyleHorizontal" - - // style="?android:attr/progressBarStyleHorizontal" - + +