Skip to content

Commit ebbdf86

Browse files
committed
FloatingVolume: VoiceCall seekbar improvements and code cleanup
* Don't hardcode ringer mode drawables * Adjust about app section * Remove some redundant code * Properly handle voice call seekbar show/hide event (Needs READ_PHONE_STATE permission) * Manage new permission Signed-off-by: Adam Myczkowski <mycaxd511@gmail.com>
1 parent 1d5b68e commit ebbdf86

File tree

17 files changed

+170
-43
lines changed

17 files changed

+170
-43
lines changed
0 Bytes
Binary file not shown.

app/build.gradle

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,8 @@ android {
4848
applicationId "com.android.mycax.floatingvolume"
4949
minSdkVersion min_sdk_version
5050
targetSdkVersion compile_sdk_version
51-
versionCode 8
52-
versionName "1.0.7 beta"
51+
versionCode 9
52+
versionName "1.0.8 beta"
5353
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
5454
}
5555
buildTypes {
@@ -72,4 +72,5 @@ dependencies {
7272
implementation 'com.github.BaselHorany:DualButton:1.1.1'
7373
implementation 'com.github.recruit-lifestyle:FloatingView:2.3.1'
7474
implementation 'com.github.jrvansuita:MaterialAbout:0.2.3'
75+
implementation 'com.karumi:dexter:4.2.0'
7576
}

app/lint.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,6 @@
55
<ignore path="src/main/res/mipmap-hdpi/ic_launcher.png" />
66
<ignore path="src/main/res/mipmap-mdpi/ic_launcher.png" />
77
<ignore path="src/main/res/mipmap-xhdpi/ic_launcher.png" />
8+
<ignore path="src/main/res/mipmap-xhdpi/ic_launcher.png" />
89
</issue>
910
</lint>

app/src/main/AndroidManifest.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
<!-- Permission required to draw floating widget over other apps -->
77
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
88
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
9+
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
910

1011
<application
1112
android:allowBackup="true"

app/src/main/java/com/android/musicfx/SeekBarRotator.java

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
package com.android.musicfx;
1717
import android.content.Context;
1818
import android.util.AttributeSet;
19-
import android.util.Log;
2019
import android.view.View;
2120
import android.view.ViewGroup;
2221
/*
@@ -36,6 +35,7 @@ public SeekBarRotator(Context context, AttributeSet attrs, int defStyleAttr,
3635
int defStyleRes) {
3736
super(context, attrs, defStyleAttr, defStyleRes);
3837
}
38+
@SuppressWarnings("SuspiciousNameCombination")
3939
@Override
4040
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
4141
final View child = getChildAt(0);
@@ -62,9 +62,7 @@ protected void onLayout(boolean changed, int l, int t, int r, int b) {
6262
// place the child below this view, so it rotates into view
6363
int mywidth = r - l;
6464
int myheight = b - t;
65-
int childwidth = myheight;
66-
int childheight = mywidth;
67-
child.layout(0, myheight, childwidth, myheight + childheight);
65+
child.layout(0, myheight, myheight, myheight + mywidth);
6866
}
6967
}
7068
}

app/src/main/java/com/android/mycax/floatingvolume/AboutActivity.java

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -33,19 +33,19 @@ private void loadAbout() {
3333
.setName(R.string.dev_name)
3434
.setSubTitle(R.string.dev_sub)
3535
.setLinksColumnsCount(3)
36-
.addFacebookLink("mycax6")
37-
.addTwitterLink("Adam_Myczkowski")
38-
.addInstagramLink("mycax6")
39-
.addGooglePlusLink("112043897899708921734")
40-
.addYoutubeChannelLink("UCxQZUuxF0N7Aj0SNlLcEpgw")
41-
.addEmailLink("mycaxd511@gmail.com")
42-
.addGitHubLink("MyczkowskiAdam")
43-
.addWebsiteLink("https://myczkowskiadam.github.io/FloatingVolume/")
44-
.addLink(R.mipmap.github, R.string.git_project, "https://github.com/MyczkowskiAdam/FloatingVolume")
36+
.addFacebookLink(R.string.name_fb_ig)
37+
.addTwitterLink(R.string.name_twitter)
38+
.addInstagramLink(R.string.name_fb_ig)
39+
.addGooglePlusLink(R.string.name_googleplus)
40+
.addYoutubeChannelLink(R.string.name_youtube)
41+
.addEmailLink(R.string.name_email)
42+
.addGitHubLink(R.string.name_github)
43+
.addWebsiteLink(R.string.url_fv_website)
44+
.addLink(R.mipmap.github, R.string.git_project, getString(R.string.url_fv_repo))
4545
.setVersionNameAsAppSubTitle()
46-
.addShareAction(R.string.app_name)
46+
.addShareAction(R.string.app_name, R.string.url_xdalabs_link)
4747
.setActionsColumnsCount(2)
48-
.addFeedbackAction("mycaxd511@gmail.com")
48+
.addFeedbackAction(R.string.name_email)
4949
.setWrapScrollView(true)
5050
.setShowAsCard(true);
5151

app/src/main/java/com/android/mycax/floatingvolume/MainActivity.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package com.android.mycax.floatingvolume;
22

3+
import android.Manifest;
4+
import android.annotation.SuppressLint;
35
import android.annotation.TargetApi;
46
import android.app.NotificationManager;
57
import android.content.Context;
@@ -17,9 +19,16 @@
1719
import com.android.mycax.floatingvolume.utils.AppUtils;
1820
import com.android.mycax.floatingvolume.utils.Constants;
1921
import com.basel.DualButton.DualButton;
22+
import com.karumi.dexter.Dexter;
23+
import com.karumi.dexter.PermissionToken;
24+
import com.karumi.dexter.listener.PermissionDeniedResponse;
25+
import com.karumi.dexter.listener.PermissionGrantedResponse;
26+
import com.karumi.dexter.listener.PermissionRequest;
27+
import com.karumi.dexter.listener.single.PermissionListener;
2028

2129
import java.util.Objects;
2230

31+
@SuppressLint("ExportedPreferenceActivity")
2332
@SuppressWarnings("deprecation")
2433
public class MainActivity extends AppCompatPreferenceActivity implements SwitchPreference.OnPreferenceChangeListener, Preference.OnPreferenceClickListener, DualButton.OnDualClickListener {
2534
private DualButton FloatingService;
@@ -107,6 +116,18 @@ private void checkPermissions() {
107116
startActivityForResult(intent, Constants.NOTIFICATION_POLICY_PERMISSION_REQUEST);
108117
}
109118
}
119+
120+
Dexter.withActivity(this)
121+
.withPermission(Manifest.permission.READ_PHONE_STATE)
122+
.withListener(new PermissionListener() {
123+
@Override public void onPermissionGranted(PermissionGrantedResponse response) {/* ... */}
124+
@Override public void onPermissionDenied(PermissionDeniedResponse response) {
125+
Toast.makeText(getApplicationContext(), R.string.app_permission_denied, Toast.LENGTH_SHORT).show();
126+
}
127+
@Override public void onPermissionRationaleShouldBeShown(PermissionRequest permission, PermissionToken token) {
128+
token.continuePermissionRequest();
129+
}
130+
}).check();
110131
}
111132

112133
@TargetApi(Build.VERSION_CODES.M)
@@ -116,7 +137,7 @@ protected void onActivityResult(int requestCode, int resultCode, Intent data) {
116137
if (Settings.canDrawOverlays(this) && Objects.requireNonNull(notificationManager).isNotificationPolicyAccessGranted()) {
117138
initializeView();
118139
} else {
119-
Toast.makeText(this, R.string.app_permission_denied, Toast.LENGTH_SHORT).show();
140+
Toast.makeText(this, R.string.app_permission_denied, Toast.LENGTH_LONG).show();
120141
}
121142
}
122143
}

app/src/main/java/com/android/mycax/floatingvolume/audio/AudioVolumeContentObserver.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ class AudioVolumeContentObserver extends ContentObserver {
1414
private int mLastVolume;
1515
private final AudioVolumeObserver audioVolumeObserver;
1616

17-
public AudioVolumeContentObserver(
17+
AudioVolumeContentObserver(
1818
@NonNull Handler handler,
1919
@NonNull AudioManager audioManager,
2020
int audioStreamType,

app/src/main/java/com/android/mycax/floatingvolume/services/FloatingVolumeService.java

Lines changed: 73 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package com.android.mycax.floatingvolume.services;
22

3+
import android.Manifest;
4+
import android.animation.LayoutTransition;
35
import android.annotation.SuppressLint;
46
import android.app.Service;
57
import android.content.BroadcastReceiver;
68
import android.content.Context;
79
import android.content.Intent;
810
import android.content.IntentFilter;
911
import android.content.SharedPreferences;
12+
import android.content.pm.PackageManager;
1013
import android.content.res.Configuration;
14+
import android.content.res.TypedArray;
1115
import android.graphics.PixelFormat;
1216
import android.graphics.Point;
1317
import android.media.AudioManager;
@@ -16,16 +20,20 @@
1620
import android.os.IBinder;
1721
import android.preference.PreferenceManager;
1822
import android.support.annotation.Nullable;
23+
import android.support.v4.content.ContextCompat;
24+
import android.telephony.TelephonyManager;
1925
import android.util.DisplayMetrics;
2026
import android.view.Gravity;
2127
import android.view.LayoutInflater;
2228
import android.view.MotionEvent;
2329
import android.view.View;
30+
import android.view.ViewGroup;
2431
import android.view.WindowManager;
2532
import android.view.animation.Animation;
2633
import android.view.animation.AnimationUtils;
2734
import android.widget.ImageView;
2835
import android.widget.SeekBar;
36+
import android.widget.TextView;
2937

3038
import com.android.mycax.floatingvolume.R;
3139
import com.android.mycax.floatingvolume.audio.AudioVolumeObserver;
@@ -46,13 +54,15 @@ public class FloatingVolumeService extends Service implements FloatingViewListen
4654
private FloatingViewManager mFloatingViewManager;
4755
private AudioVolumeObserver mAudioVolumeObserverMedia, mAudioVolumeObserverVoiceCall, mAudioVolumeObserverRinger, mAudioVolumeObserverAlarm;
4856
private SeekBar mediaControl, ringerControl, alarmControl, voiceCallControl;
49-
private BroadcastReceiver RingerModeReceiver;
50-
private boolean isDarkThemeEnabled, isDisableStaticUiEnabled, isUseLastPosition, isBounceEnabled;
57+
private BroadcastReceiver RingerModeReceiver, InCallModeReceiver;
58+
private TelephonyManager telephonyManager;
59+
private boolean isDisableStaticUiEnabled, isUseLastPosition, isBounceEnabled, isVoiceCallRecieverRegistered;
5160
private int x_init_cord, y_init_cord, x_init_margin, y_init_margin, style;
5261
private final Point szWindow = new Point();
5362
private SharedPreferences.Editor editor;
5463
private SharedPreferences sharedPref;
5564
private Set<String> seekbarSelections;
65+
private Animation fab_open_0_to_1, fab_close_1_to_0;
5666
private static int OVERLAY_TYPE;
5767

5868
static {
@@ -85,6 +95,8 @@ public int onStartCommand(Intent intent, int flags, int startId) {
8595
return START_STICKY;
8696
}
8797

98+
fab_open_0_to_1 = AnimationUtils.loadAnimation(this, R.anim.fab_open_0_to_1);
99+
fab_close_1_to_0 = AnimationUtils.loadAnimation(this, R.anim.fab_close_1_to_0);
88100
sharedPref = PreferenceManager.getDefaultSharedPreferences(this);
89101
final DisplayMetrics metrics = new DisplayMetrics();
90102
final WindowManager windowManager = (WindowManager) getSystemService(Context.WINDOW_SERVICE);
@@ -110,8 +122,9 @@ public void onClick(View v) {
110122
private void expandView(LayoutInflater inflater, DisplayMetrics displayMetrics) {
111123
mWindowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
112124
audioManager = (AudioManager) getSystemService(Context.AUDIO_SERVICE);
125+
telephonyManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
113126

114-
isDarkThemeEnabled = sharedPref.getBoolean(Constants.PREF_ENABLE_DARK_MODE, false);
127+
boolean isDarkThemeEnabled = sharedPref.getBoolean(Constants.PREF_ENABLE_DARK_MODE, false);
115128
isDisableStaticUiEnabled = sharedPref.getBoolean(Constants.PREF_DISABLE_FIXED_UI, false);
116129
isUseLastPosition = sharedPref.getBoolean(Constants.PREF_SAVE_LAST_POSITION, false);
117130
isBounceEnabled = sharedPref.getBoolean(Constants.PREF_ENABLE_BOUNCE, false);
@@ -132,6 +145,8 @@ private void expandView(LayoutInflater inflater, DisplayMetrics displayMetrics)
132145
private void addFloatingWidgetView(LayoutInflater inflater, DisplayMetrics displayMetrics) {
133146
getWindowManagerDefaultDisplay();
134147
mFloatingWidgetView = inflater.inflate(getDialogLayout(), null, false);
148+
((ViewGroup) mFloatingWidgetView.findViewById(R.id.root_container)).getLayoutTransition()
149+
.enableTransitionType(LayoutTransition.CHANGING);
135150

136151
final WindowManager.LayoutParams params = new WindowManager.LayoutParams(
137152
WindowManager.LayoutParams.WRAP_CONTENT,
@@ -181,17 +196,57 @@ private void implementVolumeFeatures() {
181196
R.id.SeekBarVoiceCallRotator, R.id.ImageVoiceCall, R.id.linearLayoutVoiceCall);
182197

183198
change_ringer_mode = mFloatingWidgetView.findViewById(R.id.imageViewModeSwitch);
184-
final Animation fab_open = AnimationUtils.loadAnimation(this, R.anim.fab_open_0_to_1);
199+
185200
RingerModeReceiver = new BroadcastReceiver() {
186201
@Override
187202
public void onReceive(Context context, Intent intent) {
188203
change_ringer_mode.setImageResource(getCurrentRingerModeDrawable());
189-
change_ringer_mode.startAnimation(fab_open);
204+
change_ringer_mode.startAnimation(fab_open_0_to_1);
190205
}
191206
};
192-
IntentFilter filter = new IntentFilter(
207+
final IntentFilter filterRingerChanged = new IntentFilter(
193208
AudioManager.RINGER_MODE_CHANGED_ACTION);
194-
registerReceiver(RingerModeReceiver, filter);
209+
registerReceiver(RingerModeReceiver, filterRingerChanged);
210+
211+
InCallModeReceiver = new BroadcastReceiver() {
212+
@Override
213+
public void onReceive(Context context, Intent intent) {
214+
assert telephonyManager != null;
215+
TextView textViewVoiceCall = mFloatingWidgetView.findViewById(R.id.textViewVoiceCall);
216+
if (seekbarSelections.contains(Constants.SEEKBAR_VOICE_CALL) && telephonyManager.getCallState() == TelephonyManager.CALL_STATE_OFFHOOK) {
217+
textViewVoiceCall.setVisibility(View.VISIBLE);
218+
textViewVoiceCall.startAnimation(fab_open_0_to_1);
219+
if (style == 3) {
220+
mFloatingWidgetView.findViewById(R.id.SeekBarVoiceCallRotator).setVisibility(View.VISIBLE);
221+
mFloatingWidgetView.findViewById(R.id.SeekBarVoiceCallRotator).startAnimation(fab_open_0_to_1);
222+
mFloatingWidgetView.findViewById(R.id.ImageVoiceCall).setVisibility(View.VISIBLE);
223+
mFloatingWidgetView.findViewById(R.id.ImageVoiceCall).startAnimation(fab_open_0_to_1);
224+
} else {
225+
mFloatingWidgetView.findViewById(R.id.linearLayoutVoiceCall).setVisibility(View.VISIBLE);
226+
mFloatingWidgetView.findViewById(R.id.linearLayoutVoiceCall).startAnimation(fab_open_0_to_1);
227+
}
228+
} else {
229+
textViewVoiceCall.setVisibility(View.GONE);
230+
textViewVoiceCall.startAnimation(fab_close_1_to_0);
231+
if (style == 3) {
232+
mFloatingWidgetView.findViewById(R.id.SeekBarVoiceCallRotator).setVisibility(View.GONE);
233+
mFloatingWidgetView.findViewById(R.id.SeekBarVoiceCallRotator).startAnimation(fab_close_1_to_0);
234+
mFloatingWidgetView.findViewById(R.id.ImageVoiceCall).setVisibility(View.GONE);
235+
mFloatingWidgetView.findViewById(R.id.ImageVoiceCall).startAnimation(fab_close_1_to_0);
236+
} else {
237+
mFloatingWidgetView.findViewById(R.id.linearLayoutVoiceCall).setVisibility(View.GONE);
238+
mFloatingWidgetView.findViewById(R.id.linearLayoutVoiceCall).startAnimation(fab_close_1_to_0);
239+
}
240+
}
241+
}
242+
};
243+
final IntentFilter filterPhoneStateChanged = new IntentFilter(
244+
TelephonyManager.ACTION_PHONE_STATE_CHANGED);
245+
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_PHONE_STATE) == PackageManager.PERMISSION_GRANTED) {
246+
registerReceiver(InCallModeReceiver, filterPhoneStateChanged);
247+
isVoiceCallRecieverRegistered = true;
248+
} else isVoiceCallRecieverRegistered = false;
249+
195250
change_ringer_mode.setOnClickListener(this);
196251
}
197252

@@ -288,35 +343,32 @@ public void onProgressChanged(SeekBar arg0, int arg1, boolean arg2) {
288343
}
289344

290345
private int getCurrentRingerModeDrawable() {
346+
TypedArray attrs;
291347
switch (audioManager.getRingerMode()) {
292348
case AudioManager.RINGER_MODE_NORMAL:
293-
return isDarkThemeEnabled ? R.drawable.ic_volume_up_white_24dp : R.drawable.ic_volume_up_black_24dp;
349+
attrs = getTheme().obtainStyledAttributes(new int[]{R.attr.ringer_normal});
350+
return attrs.getResourceId(0, 0);
294351
case AudioManager.RINGER_MODE_VIBRATE:
295-
return isDarkThemeEnabled ? R.drawable.ic_vibration_white_24dp : R.drawable.ic_vibration_black_24dp;
352+
attrs = getTheme().obtainStyledAttributes(new int[]{R.attr.ringer_vibrate});
353+
return attrs.getResourceId(0, 0);
296354
case AudioManager.RINGER_MODE_SILENT:
297-
return isDarkThemeEnabled ? R.drawable.ic_do_not_disturb_on_white_24dp : R.drawable.ic_do_not_disturb_on_black_24dp;
355+
attrs = getTheme().obtainStyledAttributes(new int[]{R.attr.ringer_silent});
356+
return attrs.getResourceId(0, 0);
298357
}
299358
return -1;
300359
}
301360

302361
private void setNewRingerMode() {
303362
int ringerMode = audioManager.getRingerMode();
304-
Animation fab_open = AnimationUtils.loadAnimation(this, R.anim.fab_open_0_to_1);
305363
switch (ringerMode) {
306364
case AudioManager.RINGER_MODE_NORMAL:
307365
audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
308-
change_ringer_mode.setImageResource(isDarkThemeEnabled ? R.drawable.ic_vibration_white_24dp : R.drawable.ic_vibration_black_24dp);
309-
change_ringer_mode.startAnimation(fab_open);
310366
break;
311367
case AudioManager.RINGER_MODE_VIBRATE:
312368
audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
313-
change_ringer_mode.setImageResource(isDarkThemeEnabled ? R.drawable.ic_do_not_disturb_on_white_24dp : R.drawable.ic_do_not_disturb_on_black_24dp);
314-
change_ringer_mode.startAnimation(fab_open);
315369
break;
316370
case AudioManager.RINGER_MODE_SILENT:
317371
audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
318-
change_ringer_mode.setImageResource(isDarkThemeEnabled ? R.drawable.ic_volume_up_white_24dp : R.drawable.ic_volume_up_black_24dp);
319-
change_ringer_mode.startAnimation(fab_open);
320372
break;
321373
}
322374
}
@@ -340,6 +392,10 @@ public void onClick(View v) {
340392
mAudioVolumeObserverVoiceCall.unregister();
341393
}
342394
unregisterReceiver(RingerModeReceiver);
395+
if (isVoiceCallRecieverRegistered) {
396+
unregisterReceiver(InCallModeReceiver);
397+
isVoiceCallRecieverRegistered = false;
398+
}
343399
break;
344400
case R.id.imageViewModeSwitch:
345401
setNewRingerMode();
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<set xmlns:android="http://schemas.android.com/apk/res/android"
3+
android:fillAfter="true">
4+
<scale
5+
android:duration="300"
6+
android:fromXScale="1.0"
7+
android:fromYScale="1.0"
8+
android:interpolator="@android:anim/linear_interpolator"
9+
android:pivotX="50%"
10+
android:pivotY="50%"
11+
android:toXScale="0.0"
12+
android:toYScale="0.0" />
13+
<alpha
14+
android:duration="300"
15+
android:fromAlpha="1.0"
16+
android:interpolator="@android:anim/accelerate_interpolator"
17+
android:toAlpha="0.0" />
18+
</set>

0 commit comments

Comments
 (0)