aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorChristian Schneppe <christian@pix-art.de>2018-08-30 22:10:21 +0200
committerChristian Schneppe <christian@pix-art.de>2018-08-30 22:10:21 +0200
commitecad9ad9294e951f9350635ace661e5ab981a39b (patch)
tree5945c84d328e228afaac047a39d318683a4fed5c /src
parent86bf53d3e3519784f9497ccabf797883f4ed60ca (diff)
switch between earphone and speaker while playing sounds
Diffstat (limited to 'src')
-rw-r--r--src/main/java/de/pixart/messenger/services/AudioPlayer.java106
-rw-r--r--src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java10
2 files changed, 110 insertions, 6 deletions
diff --git a/src/main/java/de/pixart/messenger/services/AudioPlayer.java b/src/main/java/de/pixart/messenger/services/AudioPlayer.java
index e1f97ef1a..120a810e1 100644
--- a/src/main/java/de/pixart/messenger/services/AudioPlayer.java
+++ b/src/main/java/de/pixart/messenger/services/AudioPlayer.java
@@ -1,13 +1,20 @@
package de.pixart.messenger.services;
import android.Manifest;
+import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
+import android.hardware.Sensor;
+import android.hardware.SensorEvent;
+import android.hardware.SensorEventListener;
+import android.hardware.SensorManager;
+import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Build;
import android.os.Handler;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
+import android.util.Log;
import android.view.View;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
@@ -17,6 +24,7 @@ import android.widget.TextView;
import java.lang.ref.WeakReference;
import java.util.Locale;
+import de.pixart.messenger.Config;
import de.pixart.messenger.R;
import de.pixart.messenger.entities.Message;
import de.pixart.messenger.ui.ConversationsActivity;
@@ -24,14 +32,16 @@ import de.pixart.messenger.ui.adapter.MessageAdapter;
import de.pixart.messenger.ui.util.PendingItem;
import de.pixart.messenger.utils.WeakReferenceSet;
-public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompletionListener, SeekBar.OnSeekBarChangeListener, Runnable {
+public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompletionListener, SeekBar.OnSeekBarChangeListener, Runnable, SensorEventListener {
private static final int REFRESH_INTERVAL = 250;
private static final Object LOCK = new Object();
- public static MediaPlayer player = null;
+ private static MediaPlayerWrapper player = null;
private static Message currentlyPlayingMessage = null;
private final MessageAdapter messageAdapter;
private final WeakReferenceSet<RelativeLayout> audioPlayerLayouts = new WeakReferenceSet<>();
+ private final SensorManager sensorManager;
+ private final Sensor proximitySensor;
private final PendingItem<WeakReference<ImageButton>> pendingOnClickView = new PendingItem<>();
@@ -39,6 +49,8 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
public AudioPlayer(MessageAdapter adapter) {
this.messageAdapter = adapter;
+ this.sensorManager = (SensorManager) adapter.getActivity().getSystemService(Context.SENSOR_SERVICE);
+ this.proximitySensor = sensorManager != null ? sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY) : null;
synchronized (AudioPlayer.LOCK) {
if (AudioPlayer.player != null) {
AudioPlayer.player.setOnCompletionListener(this);
@@ -91,6 +103,7 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
viewHolder.progress.setProgress(0);
viewHolder.progress.setEnabled(false);
messageAdapter.flagScreenOff();
+ messageAdapter.flagEnableInputs();
return false;
}
}
@@ -126,6 +139,7 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
viewHolder.progress.setEnabled(false);
player.pause();
messageAdapter.flagScreenOff();
+ messageAdapter.flagEnableInputs();
viewHolder.playPause.setImageResource(viewHolder.darkBackground ? R.drawable.ic_play_arrow_white_36dp : R.drawable.ic_play_arrow_black_36dp);
} else {
viewHolder.progress.setEnabled(true);
@@ -137,21 +151,36 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
return false;
}
- private boolean play(ViewHolder viewHolder, Message message) {
- AudioPlayer.player = new MediaPlayer();
+ private void play(ViewHolder viewHolder, Message message, boolean earpiece, double progress) {
+ if (play(viewHolder, message, earpiece)) {
+ AudioPlayer.player.seekTo((int) (AudioPlayer.player.getDuration() * progress));
+ }
+ }
+
+ private boolean play(ViewHolder viewHolder, Message message, boolean earpiece) {
+ AudioPlayer.player = new MediaPlayerWrapper();
try {
AudioPlayer.currentlyPlayingMessage = message;
+ AudioPlayer.player.setAudioStreamType(earpiece ? AudioManager.STREAM_VOICE_CALL : AudioManager.STREAM_MUSIC);
AudioPlayer.player.setDataSource(messageAdapter.getFileBackend().getFile(message).getAbsolutePath());
AudioPlayer.player.setOnCompletionListener(this);
AudioPlayer.player.prepare();
AudioPlayer.player.start();
messageAdapter.flagScreenOn();
+ if (earpiece) {
+ messageAdapter.flagDisableInputs();
+ } else {
+ messageAdapter.flagEnableInputs();
+ }
viewHolder.progress.setEnabled(true);
viewHolder.playPause.setImageResource(viewHolder.darkBackground ? R.drawable.ic_pause_white_36dp : R.drawable.ic_pause_black_36dp);
+ sensorManager.registerListener(this, proximitySensor, SensorManager.SENSOR_DELAY_NORMAL);
return true;
} catch (Exception e) {
messageAdapter.flagScreenOff();
+ messageAdapter.flagEnableInputs();
AudioPlayer.currentlyPlayingMessage = null;
+ sensorManager.unregisterListener(this);
return false;
}
}
@@ -173,7 +202,7 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
if (AudioPlayer.player != null) {
stopCurrent();
}
- return play(viewHolder, message);
+ return play(viewHolder, message, false);
}
private void stopCurrent() {
@@ -182,8 +211,10 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
}
AudioPlayer.player.release();
messageAdapter.flagScreenOff();
+ messageAdapter.flagEnableInputs();
AudioPlayer.player = null;
resetPlayerUi();
+ sensorManager.unregisterListener(this);
}
private void resetPlayerUi() {
@@ -216,7 +247,9 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
}
mediaPlayer.release();
messageAdapter.flagScreenOff();
+ messageAdapter.flagEnableInputs();
resetPlayerUi();
+ sensorManager.unregisterListener(this);
}
}
@@ -288,6 +321,55 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
return true;
}
+ @Override
+ public void onSensorChanged(SensorEvent event) {
+ if (event.sensor.getType() != Sensor.TYPE_PROXIMITY) {
+ return;
+ }
+ if (AudioPlayer.player == null || !AudioPlayer.player.isPlaying()) {
+ return;
+ }
+ int streamType;
+ if (event.values[0] < 5f && event.values[0] != proximitySensor.getMaximumRange()) {
+ streamType = AudioManager.STREAM_VOICE_CALL;
+ } else {
+ streamType = AudioManager.STREAM_MUSIC;
+ }
+ double position = AudioPlayer.player.getCurrentPosition();
+ double duration = AudioPlayer.player.getDuration();
+ double progress = position / duration;
+ if (AudioPlayer.player.getAudioStreamType() != streamType) {
+ synchronized (AudioPlayer.LOCK) {
+ AudioPlayer.player.stop();
+ AudioPlayer.player.release();
+ AudioPlayer.player = null;
+ try {
+ ViewHolder currentViewHolder = getCurrentViewHolder();
+ if (currentViewHolder != null) {
+ Log.d(Config.LOGTAG, "AudioPlayer start playing - progress: " + progress);
+ play(currentViewHolder, currentlyPlayingMessage, streamType == AudioManager.STREAM_VOICE_CALL, progress);
+ }
+ } catch (Exception e) {
+ Log.w(Config.LOGTAG, "AudioPlayer Exception: " + e);
+ }
+ }
+ }
+ }
+
+ @Override
+ public void onAccuracyChanged(Sensor sensor, int i) {
+ }
+
+ private ViewHolder getCurrentViewHolder() {
+ for (WeakReference<RelativeLayout> audioPlayer : audioPlayerLayouts) {
+ final Message message = (Message) audioPlayer.get().getTag();
+ if (message == currentlyPlayingMessage) {
+ return ViewHolder.get(audioPlayer.get());
+ }
+ }
+ return null;
+ }
+
public static class ViewHolder {
private TextView runtime;
private SeekBar progress;
@@ -310,4 +392,18 @@ public class AudioPlayer implements View.OnClickListener, MediaPlayer.OnCompleti
this.darkBackground = darkBackground;
}
}
+
+ private static class MediaPlayerWrapper extends MediaPlayer {
+ private int streamType;
+
+ private int getAudioStreamType() {
+ return streamType;
+ }
+
+ @Override
+ public void setAudioStreamType(int streamType) {
+ this.streamType = streamType;
+ super.setAudioStreamType(streamType);
+ }
+ }
} \ No newline at end of file
diff --git a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
index 519b01c1a..f3b04ff8a 100644
--- a/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
+++ b/src/main/java/de/pixart/messenger/ui/adapter/MessageAdapter.java
@@ -112,8 +112,8 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
public MessageAdapter(XmppActivity activity, List<Message> messages) {
super(activity, 0, messages);
- this.audioPlayer = new AudioPlayer(this);
this.activity = activity;
+ this.audioPlayer = new AudioPlayer(this);
metrics = getContext().getResources().getDisplayMetrics();
updatePreferences();
}
@@ -149,6 +149,14 @@ public class MessageAdapter extends ArrayAdapter<Message> implements CopyTextVie
}
}
+ public void flagDisableInputs() {
+ activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+ }
+
+ public void flagEnableInputs() {
+ activity.getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
+ }
+
public void flagScreenOn() {
activity.getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}