Signed-off-by: Mario Danic <mario@lovelyhq.com>
This commit is contained in:
Mario Danic 2018-01-17 23:24:38 +01:00
parent 586e6ca9a3
commit 58c2b1ba74
3 changed files with 189 additions and 37 deletions

View File

@ -26,6 +26,7 @@
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.BATTERY_STATS"/>
<uses-permission <uses-permission
android:name="android.permission.USE_CREDENTIALS" android:name="android.permission.USE_CREDENTIALS"
android:maxSdkVersion="22"/> android:maxSdkVersion="22"/>

View File

@ -27,6 +27,7 @@ package com.nextcloud.talk.activities;
import android.Manifest; import android.Manifest;
import android.animation.Animator; import android.animation.Animator;
import android.animation.AnimatorListenerAdapter; import android.animation.AnimatorListenerAdapter;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver; import android.content.BroadcastReceiver;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
@ -40,6 +41,7 @@ import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity; import android.support.v7.app.AppCompatActivity;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.MotionEvent;
import android.view.View; import android.view.View;
import android.view.Window; import android.view.Window;
import android.view.WindowManager; import android.view.WindowManager;
@ -73,6 +75,7 @@ import com.nextcloud.talk.events.MediaStreamEvent;
import com.nextcloud.talk.events.PeerConnectionEvent; import com.nextcloud.talk.events.PeerConnectionEvent;
import com.nextcloud.talk.events.SessionDescriptionSendEvent; import com.nextcloud.talk.events.SessionDescriptionSendEvent;
import com.nextcloud.talk.persistence.entities.UserEntity; import com.nextcloud.talk.persistence.entities.UserEntity;
import com.nextcloud.talk.utils.animations.PulseAnimation;
import com.nextcloud.talk.utils.database.user.UserUtils; import com.nextcloud.talk.utils.database.user.UserUtils;
import com.nextcloud.talk.webrtc.MagicAudioManager; import com.nextcloud.talk.webrtc.MagicAudioManager;
import com.nextcloud.talk.webrtc.MagicPeerConnectionWrapper; import com.nextcloud.talk.webrtc.MagicPeerConnectionWrapper;
@ -120,6 +123,7 @@ import autodagger.AutoInjector;
import butterknife.BindView; import butterknife.BindView;
import butterknife.ButterKnife; import butterknife.ButterKnife;
import butterknife.OnClick; import butterknife.OnClick;
import butterknife.OnLongClick;
import io.reactivex.Observer; import io.reactivex.Observer;
import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.disposables.Disposable; import io.reactivex.disposables.Disposable;
@ -204,12 +208,16 @@ public class CallActivity extends AppCompatActivity {
private Handler handler = new Handler(); private Handler handler = new Handler();
private boolean isPTTActive = false;
private PulseAnimation pulseAnimation;
private static int getSystemUiVisibility() { private static int getSystemUiVisibility() {
int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN; int flags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY; flags |= View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
return flags; return flags;
} }
@SuppressLint("ClickableViewAccessibility")
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -225,6 +233,12 @@ public class CallActivity extends AppCompatActivity {
setContentView(R.layout.activity_call); setContentView(R.layout.activity_call);
ButterKnife.bind(this); ButterKnife.bind(this);
microphoneControlButton.setOnTouchListener(new microphoneButtonTouchListener());
pulseAnimation = PulseAnimation.create().with(microphoneControlButton)
.setDuration(310)
.setRepeatCount(PulseAnimation.INFINITE)
.setRepeatMode(PulseAnimation.REVERSE);
roomToken = getIntent().getExtras().getString("roomToken", ""); roomToken = getIntent().getExtras().getString("roomToken", "");
userEntity = Parcels.unwrap(getIntent().getExtras().getParcelable("userEntity")); userEntity = Parcels.unwrap(getIntent().getExtras().getParcelable("userEntity"));
callSession = "0"; callSession = "0";
@ -380,9 +394,22 @@ public class CallActivity extends AppCompatActivity {
} }
} }
@OnLongClick(R.id.call_control_microphone)
public boolean onMicrophoneLongClick() {
if (!audioOn) {
handler.removeCallbacksAndMessages(null);
isPTTActive = true;
callControls.setVisibility(View.VISIBLE);
}
onMicrophoneClick();
return true;
}
@OnClick(R.id.call_control_microphone) @OnClick(R.id.call_control_microphone)
public void onMicrophoneClick() { public void onMicrophoneClick() {
if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_MICROPHONE)) { if (EffortlessPermissions.hasPermissions(this, PERMISSIONS_MICROPHONE)) {
if (!isPTTActive) {
audioOn = !audioOn; audioOn = !audioOn;
if (audioOn) { if (audioOn) {
@ -392,6 +419,12 @@ public class CallActivity extends AppCompatActivity {
} }
toggleMedia(audioOn, false); toggleMedia(audioOn, false);
} else {
microphoneControlButton.setImageResource(R.drawable.ic_mic_white_24px);
pulseAnimation.start();
toggleMedia(true, false);
}
} else if (EffortlessPermissions.somePermissionPermanentlyDenied(this, PERMISSIONS_MICROPHONE)) { } else if (EffortlessPermissions.somePermissionPermanentlyDenied(this, PERMISSIONS_MICROPHONE)) {
// Microphone permission is permanently denied so we cannot request it normally. // Microphone permission is permanently denied so we cannot request it normally.
OpenAppDetailsDialogFragment.show( OpenAppDetailsDialogFragment.show(
@ -658,7 +691,9 @@ public class CallActivity extends AppCompatActivity {
private void startCall() { private void startCall() {
inCall = true; inCall = true;
if (!isPTTActive) {
animateCallControls(false, 7500); animateCallControls(false, 7500);
}
startPullingSignalingMessages(false); startPullingSignalingMessages(false);
//registerNetworkReceiver(); //registerNetworkReceiver();
} }
@ -1367,6 +1402,7 @@ public class CallActivity extends AppCompatActivity {
} }
private void animateCallControls(boolean show, long startDelay) { private void animateCallControls(boolean show, long startDelay) {
if (!isPTTActive) {
float alpha; float alpha;
long duration; long duration;
@ -1386,6 +1422,7 @@ public class CallActivity extends AppCompatActivity {
duration = 1000; duration = 1000;
} }
callControls.setEnabled(false);
callControls.animate() callControls.animate()
.translationY(0) .translationY(0)
.alpha(alpha) .alpha(alpha)
@ -1399,15 +1436,42 @@ public class CallActivity extends AppCompatActivity {
if (!show) { if (!show) {
callControls.setVisibility(View.INVISIBLE); callControls.setVisibility(View.INVISIBLE);
} else { } else {
handler.postDelayed(() -> animateCallControls(false, 0), 5000); handler.postDelayed(new Runnable() {
@Override
public void run() {
if (!isPTTActive) {
animateCallControls(false, 0);
} }
} }
}, 7500);
}
callControls.setEnabled(true);
}
} }
}); });
} }
}
@Override @Override
public void onBackPressed() { public void onBackPressed() {
hangup(false); hangup(false);
} }
private class microphoneButtonTouchListener implements View.OnTouchListener {
@SuppressLint("ClickableViewAccessibility")
@Override
public boolean onTouch(View v, MotionEvent event) {
v.onTouchEvent(event);
if (event.getAction() == MotionEvent.ACTION_UP && isPTTActive) {
isPTTActive = false;
microphoneControlButton.setImageResource(R.drawable.ic_mic_off_white_24px);
pulseAnimation.stop();
toggleMedia(false, false);
animateCallControls(false, 5000);
}
return true;
}
}
} }

View File

@ -0,0 +1,87 @@
/*
* Nextcloud Talk application
*
* @author Mario Danic
* Copyright (C) 2017 Mario Danic <mario@lovelyhq.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
* Original code taken from https://github.com/thunderrise/android-TNRAnimationHelper under MIT licence
* and modified by yours truly to fit the needs of this awesome app.
*/
package com.nextcloud.talk.utils.animations;
import android.animation.ObjectAnimator;
import android.animation.PropertyValuesHolder;
import android.animation.ValueAnimator;
import android.support.annotation.NonNull;
import android.view.View;
public class PulseAnimation {
public static final int RESTART = 1;
public static final int REVERSE = 2;
public static final int INFINITE = -1;
private ObjectAnimator scaleDown;
private int duration = 310;
private View view;
private int repeatMode = ValueAnimator.RESTART;
private int repeatCount = INFINITE;
public static PulseAnimation create() {
return new PulseAnimation();
}
public PulseAnimation with(@NonNull View view) {
this.view = view;
return this;
}
public void start() {
if (view == null) throw new NullPointerException("View cant be null!");
scaleDown = ObjectAnimator.ofPropertyValuesHolder(view, PropertyValuesHolder.ofFloat("scaleX", 1.2f), PropertyValuesHolder.ofFloat("scaleY", 1.2f));
scaleDown.setDuration(duration);
scaleDown.setRepeatMode(repeatMode);
scaleDown.setRepeatCount(repeatCount);
scaleDown.setAutoCancel(true);
scaleDown.start();
}
public void stop() {
if (scaleDown != null && view != null) {
scaleDown.end();
scaleDown.cancel();
view.setScaleX(1.0f);
view.setScaleY(1.0f);
}
}
public PulseAnimation setDuration(int duration) {
this.duration = duration;
return this;
}
public PulseAnimation setRepeatMode(int repeatMode) {
this.repeatMode = repeatMode;
return this;
}
public PulseAnimation setRepeatCount(int repeatCount) {
this.repeatCount = repeatCount;
return this;
}
}