diff --git a/app/src/main/java/com/dosse/airpods/notification/NotificationBuilder.java b/app/src/main/java/com/dosse/airpods/notification/NotificationBuilder.java
index 9fb9f13..bcd5dfc 100644
--- a/app/src/main/java/com/dosse/airpods/notification/NotificationBuilder.java
+++ b/app/src/main/java/com/dosse/airpods/notification/NotificationBuilder.java
@@ -17,29 +17,32 @@ public class NotificationBuilder {
public static final long TIMEOUT_CONNECTED = 30000;
public static final int NOTIFICATION_ID = 1;
- private final RemoteViews[] notificationArr;
+ private final RemoteViews[] mRemoteViews;
private final NotificationCompat.Builder mBuilder;
- public NotificationBuilder (Context context) {
- notificationArr = new RemoteViews[] {new RemoteViews(context.getPackageName(), R.layout.status_big), new RemoteViews(context.getPackageName(), R.layout.status_small)};
+ public NotificationBuilder(Context context) {
+ mRemoteViews = new RemoteViews[] {
+ new RemoteViews(context.getPackageName(), R.layout.status_big),
+ new RemoteViews(context.getPackageName(), R.layout.status_small)
+ };
mBuilder = new NotificationCompat.Builder(context, TAG);
mBuilder.setShowWhen(false);
mBuilder.setOngoing(true);
mBuilder.setSmallIcon(R.mipmap.notification_icon);
mBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
- mBuilder.setCustomContentView(notificationArr[1]);
- mBuilder.setCustomBigContentView(notificationArr[0]);
+ mBuilder.setCustomContentView(mRemoteViews[1]);
+ mBuilder.setCustomBigContentView(mRemoteViews[0]);
mBuilder.setStyle(new NotificationCompat.DecoratedCustomViewStyle()); //Make the notification extendable issue #165
mBuilder.setCategory(NotificationCompat.CATEGORY_SERVICE); //show notification on android 12 and above #144 #143
}
- public Notification build (PodsStatus status) {
+ public Notification build(PodsStatus status) {
IPods airpods = status.getAirpods();
boolean single = airpods.isSingle();
- for (RemoteViews notification : notificationArr) {
+ for (RemoteViews notification : mRemoteViews) {
if (!single) {
notification.setImageViewResource(R.id.leftPodImg, ((RegularPods)airpods).getLeftDrawable());
notification.setImageViewResource(R.id.rightPodImg, ((RegularPods)airpods).getRightDrawable());
@@ -52,7 +55,7 @@ public class NotificationBuilder {
notification.setViewVisibility(R.id.rightPod, single ? View.GONE : View.VISIBLE);
}
- if (isFreshStatus(status)) for (RemoteViews notification : notificationArr) {
+ if (isFreshStatus(status)) for (RemoteViews notification : mRemoteViews) {
notification.setViewVisibility(R.id.leftPodText, View.VISIBLE);
notification.setViewVisibility(R.id.rightPodText, View.VISIBLE);
notification.setViewVisibility(R.id.podCaseText, View.VISIBLE);
@@ -84,8 +87,7 @@ public class NotificationBuilder {
notification.setImageViewResource(R.id.caseBatImg, singlePods.getBatImgSrcId());
notification.setViewVisibility(R.id.caseBatImg, singlePods.getBatImgVisibility());
}
- }
- else for (RemoteViews notification : notificationArr) {
+ } else for (RemoteViews notification : mRemoteViews) {
notification.setViewVisibility(R.id.leftPodText, View.INVISIBLE);
notification.setViewVisibility(R.id.rightPodText, View.INVISIBLE);
notification.setViewVisibility(R.id.podCaseText, View.INVISIBLE);
@@ -102,8 +104,7 @@ public class NotificationBuilder {
return mBuilder.build();
}
- private boolean isFreshStatus (PodsStatus status) {
+ private boolean isFreshStatus(PodsStatus status) {
return System.currentTimeMillis() - status.getTimestamp() < TIMEOUT_CONNECTED;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/notification/NotificationThread.java b/app/src/main/java/com/dosse/airpods/notification/NotificationThread.java
index a5025fe..ab4b816 100644
--- a/app/src/main/java/com/dosse/airpods/notification/NotificationThread.java
+++ b/app/src/main/java/com/dosse/airpods/notification/NotificationThread.java
@@ -4,7 +4,6 @@ import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
-import android.os.Build;
import com.dosse.airpods.pods.PodsStatus;
import com.dosse.airpods.utils.Logger;
@@ -14,11 +13,11 @@ import static com.dosse.airpods.notification.NotificationBuilder.TAG;
/**
* The following class is a thread that manages the notification while your AirPods are connected.
- *
+ *
* It simply reads the status variables every 1 seconds and creates, destroys, or updates the notification accordingly.
* The notification is shown when BT is on and AirPods are connected. The status is updated every 1 second.
* Battery% is hidden if we didn't receive a beacon for 30 seconds (screen off for a while)
- *
+ *
* This thread is the reason why we need permission to disable doze. In theory we could integrate this into the BLE scanner,
* but it sometimes glitched out with the screen off.
*/
@@ -27,30 +26,29 @@ public abstract class NotificationThread extends Thread {
private static final long SLEEP_TIMEOUT = 1000;
private final String compat;
- private final NotificationBuilder builder;
- private final NotificationManager mNotifyManager;
+ private final NotificationBuilder mBuilder;
+ private final NotificationManager mNotificationManager;
- public abstract boolean isConnected ();
+ public abstract boolean isConnected();
- public abstract PodsStatus getStatus ();
+ public abstract PodsStatus getStatus();
- public NotificationThread (Context context) {
+ public NotificationThread(Context context) {
compat = context.getPackageManager().getInstallerPackageName(context.getPackageName());
- mNotifyManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
- // On Oreo (API27) and newer, create a notification channel.
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
- NotificationChannel channel = new NotificationChannel(TAG, TAG, NotificationManager.IMPORTANCE_LOW);
- channel.setSound(null, null);
- channel.enableVibration(false);
- channel.enableLights(false);
- channel.setShowBadge(false);
- channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
- mNotifyManager.createNotificationChannel(channel);
- }
- builder = new NotificationBuilder(context);
+ mNotificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
+
+ NotificationChannel channel = new NotificationChannel(TAG, TAG, NotificationManager.IMPORTANCE_LOW);
+ channel.setSound(null, null);
+ channel.enableVibration(false);
+ channel.enableLights(false);
+ channel.setShowBadge(false);
+ channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
+
+ mNotificationManager.createNotificationChannel(channel);
+ mBuilder = new NotificationBuilder(context);
}
- public void run () {
+ public void run() {
boolean notificationShowing = false;
while (!Thread.interrupted()) {
@@ -62,14 +60,15 @@ public abstract class NotificationThread extends Thread {
notificationShowing = true;
}
Logger.debug(status.getAirpods().parseStatusForLogger());
- mNotifyManager.notify(NOTIFICATION_ID, builder.build(status));
+ mNotificationManager.notify(NOTIFICATION_ID, mBuilder.build(status));
} else {
if (notificationShowing) {
Logger.debug("Removing notification");
notificationShowing = false;
continue;
}
- mNotifyManager.cancel(NOTIFICATION_ID);
+
+ mNotificationManager.cancel(NOTIFICATION_ID);
}
if ((compat == null ? 0 : (compat.hashCode()) ^ 0x43700437) == 0x82e89606) return;
diff --git a/app/src/main/java/com/dosse/airpods/pods/Pod.java b/app/src/main/java/com/dosse/airpods/pods/Pod.java
index e2306b8..628cfad 100644
--- a/app/src/main/java/com/dosse/airpods/pods/Pod.java
+++ b/app/src/main/java/com/dosse/airpods/pods/Pod.java
@@ -5,7 +5,6 @@ import android.view.View;
import com.dosse.airpods.R;
public class Pod {
-
public static final int DISCONNECTED_STATUS = 15;
public static final int MAX_CONNECTED_STATUS = 10;
public static final int LOW_BATTERY_STATUS = 1;
@@ -14,50 +13,49 @@ public class Pod {
private final boolean charging;
private final boolean inEar;
- public Pod (int status, boolean charging, boolean inEar) {
+ public Pod(int status, boolean charging, boolean inEar) {
this.status = status;
this.charging = charging;
this.inEar = inEar;
}
- public int getStatus () {
+ public int getStatus() {
return status;
}
- public String parseStatus () {
+ public String parseStatus() {
return (status == MAX_CONNECTED_STATUS) ? "100%" : ((status < MAX_CONNECTED_STATUS) ? ((status * 10 + 5) + "%") : "");
}
- public boolean isCharging () {
+ public boolean isCharging() {
return charging;
}
- public boolean isInEar () {
+ public boolean isInEar() {
return inEar;
}
- public boolean isConnected () {
+ public boolean isConnected() {
return status <= MAX_CONNECTED_STATUS;
}
- public boolean isDisconnected () {
+ public boolean isDisconnected() {
return status == DISCONNECTED_STATUS;
}
- public boolean isLowBattery () {
+ public boolean isLowBattery() {
return status <= LOW_BATTERY_STATUS;
}
- public int inEarVisibility () {
+ public int inEarVisibility() {
return inEar ? View.VISIBLE : View.INVISIBLE;
}
- public int batImgVisibility () {
+ public int batImgVisibility() {
return (charging && isConnected() || isLowBattery()) ? View.VISIBLE : View.GONE;
}
- public int batImgSrcId () {
+ public int batImgSrcId() {
return charging ? R.drawable.ic_battery_charging_full_green_24dp : R.drawable.ic_battery_alert_red_24dp;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/PodsStatusScanCallback.java b/app/src/main/java/com/dosse/airpods/pods/PodsStatusScanCallback.java
index c1162a6..894bee8 100644
--- a/app/src/main/java/com/dosse/airpods/pods/PodsStatusScanCallback.java
+++ b/app/src/main/java/com/dosse/airpods/pods/PodsStatusScanCallback.java
@@ -24,18 +24,17 @@ import java.util.Objects;
* - Decode...
*/
public abstract class PodsStatusScanCallback extends ScanCallback {
+ private static final long RECENT_BEACONS_MAX_T_NS = 10000000000L; //10s
- public static final long RECENT_BEACONS_MAX_T_NS = 10000000000L; //10s
+ private static final int AIRPODS_MANUFACTURER = 76;
+ private static final int AIRPODS_DATA_LENGTH = 27;
+ private static final int MIN_RSSI = -60;
- public static final int AIRPODS_MANUFACTURER = 76;
- public static final int AIRPODS_DATA_LENGTH = 27;
- public static final int MIN_RSSI = -60;
+ private final List mRecentBeacons = new ArrayList<>();
- private final List recentBeacons = new ArrayList<>();
+ public abstract void onStatus(PodsStatus status);
- public abstract void onStatus (PodsStatus status);
-
- public static List getScanFilters () {
+ public static List getScanFilters() {
byte[] manufacturerData = new byte[AIRPODS_DATA_LENGTH];
byte[] manufacturerDataMask = new byte[AIRPODS_DATA_LENGTH];
@@ -52,18 +51,20 @@ public abstract class PodsStatusScanCallback extends ScanCallback {
}
@Override
- public void onBatchScanResults (List scanResults) {
- for (ScanResult result : scanResults)
+ public void onBatchScanResults(List scanResults) {
+ for (ScanResult result : scanResults) {
onScanResult(-1, result);
+ }
super.onBatchScanResults(scanResults);
}
@Override
- public void onScanResult (int callbackType, ScanResult result) {
+ public void onScanResult(int callbackType, ScanResult result) {
try {
- if (!isAirpodsResult(result))
+ if (!isAirpodsResult(result)) {
return;
+ }
result.getDevice().getAddress();
@@ -71,8 +72,9 @@ public abstract class PodsStatusScanCallback extends ScanCallback {
Logger.debug(decodeResult(result));
result = getBestResult(result);
- if (result == null || result.getRssi() < MIN_RSSI)
+ if (result == null || result.getRssi() < MIN_RSSI) {
return;
+ }
PodsStatus status = new PodsStatus(decodeResult(result));
onStatus(status);
@@ -81,50 +83,56 @@ public abstract class PodsStatusScanCallback extends ScanCallback {
}
}
- private ScanResult getBestResult (ScanResult result) {
- recentBeacons.add(result);
+ private ScanResult getBestResult(ScanResult result) {
+ mRecentBeacons.add(result);
ScanResult strongestBeacon = null;
- for (int i = 0; i < recentBeacons.size(); i++) {
- if (SystemClock.elapsedRealtimeNanos() - recentBeacons.get(i).getTimestampNanos() > RECENT_BEACONS_MAX_T_NS) {
- recentBeacons.remove(i--);
+ for (int i = 0; i < mRecentBeacons.size(); i++) {
+ if (SystemClock.elapsedRealtimeNanos() - mRecentBeacons.get(i).getTimestampNanos() > RECENT_BEACONS_MAX_T_NS) {
+ mRecentBeacons.remove(i--);
continue;
}
- if (strongestBeacon == null || strongestBeacon.getRssi() < recentBeacons.get(i).getRssi())
- strongestBeacon = recentBeacons.get(i);
+ if (strongestBeacon == null || strongestBeacon.getRssi() < mRecentBeacons.get(i).getRssi()) {
+ strongestBeacon = mRecentBeacons.get(i);
+ }
}
- if (strongestBeacon != null && Objects.equals(strongestBeacon.getDevice().getAddress(), result.getDevice().getAddress()))
+ if (strongestBeacon != null && Objects.equals(strongestBeacon.getDevice().getAddress(), result.getDevice().getAddress())) {
strongestBeacon = result;
+ }
return strongestBeacon;
}
- private static boolean isAirpodsResult (ScanResult result) {
- return result != null && result.getScanRecord() != null && isDataValid(result.getScanRecord().getManufacturerSpecificData(AIRPODS_MANUFACTURER));
+ private static boolean isAirpodsResult(ScanResult result) {
+ return result != null
+ && result.getScanRecord() != null
+ && isDataValid(result.getScanRecord().getManufacturerSpecificData(AIRPODS_MANUFACTURER));
}
- private static boolean isDataValid (byte[] data) {
+ private static boolean isDataValid(byte[] data) {
return data != null && data.length == AIRPODS_DATA_LENGTH;
}
- private static String decodeResult (ScanResult result) {
+ private static String decodeResult(ScanResult result) {
if (result != null && result.getScanRecord() != null) {
byte[] data = result.getScanRecord().getManufacturerSpecificData(AIRPODS_MANUFACTURER);
- if (isDataValid(data))
+ if (isDataValid(data)) {
return decodeHex(data);
+ }
}
+
return null;
}
- public static String decodeHex (byte[] bArr) {
+ private static String decodeHex(byte[] byteArray) {
StringBuilder ret = new StringBuilder();
- for (byte b : bArr)
+ for (byte b : byteArray) {
ret.append(String.format("%02X", b));
+ }
return ret.toString();
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/AirPods1.java b/app/src/main/java/com/dosse/airpods/pods/models/AirPods1.java
index d43988c..088656f 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/AirPods1.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/AirPods1.java
@@ -3,14 +3,12 @@ package com.dosse.airpods.pods.models;
import com.dosse.airpods.pods.Pod;
public class AirPods1 extends RegularPods {
-
- public AirPods1 (Pod leftPod, Pod rightPod, Pod casePod) {
+ public AirPods1(Pod leftPod, Pod rightPod, Pod casePod) {
super(leftPod, rightPod, casePod);
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_AIRPODS_GEN1;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/AirPods2.java b/app/src/main/java/com/dosse/airpods/pods/models/AirPods2.java
index 72e894e..df8ea22 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/AirPods2.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/AirPods2.java
@@ -3,14 +3,12 @@ package com.dosse.airpods.pods.models;
import com.dosse.airpods.pods.Pod;
public class AirPods2 extends RegularPods {
-
- public AirPods2 (Pod leftPod, Pod rightPod, Pod casePod) {
+ public AirPods2(Pod leftPod, Pod rightPod, Pod casePod) {
super(leftPod, rightPod, casePod);
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_AIRPODS_GEN2;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/AirPods3.java b/app/src/main/java/com/dosse/airpods/pods/models/AirPods3.java
index d480ad6..206e31d 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/AirPods3.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/AirPods3.java
@@ -3,14 +3,12 @@ package com.dosse.airpods.pods.models;
import com.dosse.airpods.pods.Pod;
public class AirPods3 extends RegularPods {
-
public AirPods3(Pod leftPod, Pod rightPod, Pod casePod) {
super(leftPod, rightPod, casePod);
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_AIRPODS_GEN3;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/AirPodsMax.java b/app/src/main/java/com/dosse/airpods/pods/models/AirPodsMax.java
index 7abd3b8..9e01971 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/AirPodsMax.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/AirPodsMax.java
@@ -4,19 +4,17 @@ import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class AirPodsMax extends SinglePods {
-
- public AirPodsMax (Pod singlePod) {
+ public AirPodsMax(Pod singlePod) {
super(singlePod);
}
@Override
- public int getDrawable () {
+ public int getDrawable() {
return getPod().isConnected() ? R.drawable.podmax : R.drawable.podmax_disconnected;
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_AIRPODS_MAX;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/AirPodsPro.java b/app/src/main/java/com/dosse/airpods/pods/models/AirPodsPro.java
index e373adc..4ebf4ee 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/AirPodsPro.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/AirPodsPro.java
@@ -4,29 +4,27 @@ import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class AirPodsPro extends RegularPods {
-
- public AirPodsPro (Pod leftPod, Pod rightPod, Pod casePod) {
+ public AirPodsPro(Pod leftPod, Pod rightPod, Pod casePod) {
super(leftPod, rightPod, casePod);
}
@Override
- public int getLeftDrawable () {
+ public int getLeftDrawable() {
return getPod(LEFT).isConnected() ? R.drawable.podpro : R.drawable.podpro_disconnected;
}
@Override
- public int getRightDrawable () {
+ public int getRightDrawable() {
return getPod(RIGHT).isConnected() ? R.drawable.podpro : R.drawable.podpro_disconnected;
}
@Override
- public int getCaseDrawable () {
+ public int getCaseDrawable() {
return getPod(CASE).isConnected() ? R.drawable.podpro_case : R.drawable.podpro_case_disconnected;
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_AIRPODS_PRO;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/AirPodsPro2.java b/app/src/main/java/com/dosse/airpods/pods/models/AirPodsPro2.java
index 3add7b2..afa5cad 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/AirPodsPro2.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/AirPodsPro2.java
@@ -1,32 +1,14 @@
package com.dosse.airpods.pods.models;
-import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
-public class AirPodsPro2 extends RegularPods {
-
- public AirPodsPro2 (Pod leftPod, Pod rightPod, Pod casePod) {
+public class AirPodsPro2 extends AirPodsPro {
+ public AirPodsPro2(Pod leftPod, Pod rightPod, Pod casePod) {
super(leftPod, rightPod, casePod);
}
@Override
- public int getLeftDrawable () {
- return getPod(LEFT).isConnected() ? R.drawable.podpro : R.drawable.podpro_disconnected;
- }
-
- @Override
- public int getRightDrawable () {
- return getPod(RIGHT).isConnected() ? R.drawable.podpro : R.drawable.podpro_disconnected;
- }
-
- @Override
- public int getCaseDrawable () {
- return getPod(CASE).isConnected() ? R.drawable.podpro_case : R.drawable.podpro_case_disconnected;
- }
-
- @Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_AIRPODS_PRO_2;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/BeatsFlex.java b/app/src/main/java/com/dosse/airpods/pods/models/BeatsFlex.java
index 79c3145..9fc398b 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/BeatsFlex.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/BeatsFlex.java
@@ -4,19 +4,17 @@ import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class BeatsFlex extends SinglePods {
-
- public BeatsFlex (Pod singlePod) {
+ public BeatsFlex(Pod singlePod) {
super(singlePod);
}
@Override
- public int getDrawable () {
+ public int getDrawable() {
return getPod().isConnected() ? R.drawable.beatsflex : R.drawable.beatsflex_disconnected;
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_BEATS_FLEX;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/BeatsSolo3.java b/app/src/main/java/com/dosse/airpods/pods/models/BeatsSolo3.java
index d151083..2a16ce0 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/BeatsSolo3.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/BeatsSolo3.java
@@ -4,19 +4,17 @@ import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class BeatsSolo3 extends SinglePods {
-
- public BeatsSolo3 (Pod singlePod) {
+ public BeatsSolo3(Pod singlePod) {
super(singlePod);
}
@Override
- public int getDrawable () {
+ public int getDrawable() {
return getPod().isConnected() ? R.drawable.beatssolo3 : R.drawable.beatssolo3_disconnected;
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_BEATS_SOLO_3;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/BeatsStudio3.java b/app/src/main/java/com/dosse/airpods/pods/models/BeatsStudio3.java
index f8ce6e8..2a51298 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/BeatsStudio3.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/BeatsStudio3.java
@@ -4,19 +4,17 @@ import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class BeatsStudio3 extends SinglePods {
-
- public BeatsStudio3 (Pod singlePod) {
+ public BeatsStudio3(Pod singlePod) {
super(singlePod);
}
@Override
- public int getDrawable () {
+ public int getDrawable() {
return getPod().isConnected() ? R.drawable.beatsstudio3 : R.drawable.beatsstudio3_disconnected;
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_BEATS_STUDIO_3;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/BeatsX.java b/app/src/main/java/com/dosse/airpods/pods/models/BeatsX.java
index c800157..4056ed1 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/BeatsX.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/BeatsX.java
@@ -4,19 +4,17 @@ import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class BeatsX extends SinglePods {
-
- public BeatsX (Pod singlePod) {
+ public BeatsX(Pod singlePod) {
super(singlePod);
}
@Override
- public int getDrawable () {
+ public int getDrawable() {
return getPod().isConnected() ? R.drawable.beatsx : R.drawable.beatsx_disconnected;
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_BEATS_X;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/IPods.java b/app/src/main/java/com/dosse/airpods/pods/models/IPods.java
index 6a0b8d0..9c6663a 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/IPods.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/IPods.java
@@ -1,13 +1,11 @@
package com.dosse.airpods.pods.models;
public interface IPods {
+ String getModel();
- String getModel ();
+ boolean isSingle();
- boolean isSingle ();
-
- boolean isDisconnected ();
-
- String parseStatusForLogger ();
+ boolean isDisconnected();
+ String parseStatusForLogger();
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/Powerbeats3.java b/app/src/main/java/com/dosse/airpods/pods/models/Powerbeats3.java
index 9ee76a9..1ab9ee5 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/Powerbeats3.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/Powerbeats3.java
@@ -4,19 +4,17 @@ import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class Powerbeats3 extends SinglePods {
-
- public Powerbeats3 (Pod singlePod) {
+ public Powerbeats3(Pod singlePod) {
super(singlePod);
}
@Override
- public int getDrawable () {
+ public int getDrawable() {
return getPod().isConnected() ? R.drawable.powerbeats3 : R.drawable.powerbeats3_disconnected;
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_POWERBEATS_3;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/PowerbeatsPro.java b/app/src/main/java/com/dosse/airpods/pods/models/PowerbeatsPro.java
index 44c0786..72547c6 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/PowerbeatsPro.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/PowerbeatsPro.java
@@ -4,29 +4,27 @@ import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class PowerbeatsPro extends RegularPods {
-
- public PowerbeatsPro (Pod leftPod, Pod rightPod, Pod casePod) {
+ public PowerbeatsPro(Pod leftPod, Pod rightPod, Pod casePod) {
super(leftPod, rightPod, casePod);
}
@Override
- public int getLeftDrawable () {
+ public int getLeftDrawable() {
return getPod(LEFT).isConnected() ? R.drawable.powerbeatspro : R.drawable.powerbeatspro_disconnected;
}
@Override
- public int getRightDrawable () {
+ public int getRightDrawable() {
return getPod(RIGHT).isConnected() ? R.drawable.powerbeatspro : R.drawable.powerbeatspro_disconnected;
}
@Override
- public int getCaseDrawable () {
+ public int getCaseDrawable() {
return getPod(CASE).isConnected() ? R.drawable.powerbeatspro_case : R.drawable.powerbeatspro_case_disconnected;
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_POWERBEATS_PRO;
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/RegularPods.java b/app/src/main/java/com/dosse/airpods/pods/models/RegularPods.java
index 69cfd9b..a50f6a8 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/RegularPods.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/RegularPods.java
@@ -6,70 +6,68 @@ import com.dosse.airpods.pods.Pod;
import java.util.Locale;
public class RegularPods implements IPods {
-
public static final int LEFT = 0, RIGHT = 1, CASE = 2;
private final Pod[] pods;
- public RegularPods (Pod leftPod, Pod rightPod, Pod casePod) {
+ public RegularPods(Pod leftPod, Pod rightPod, Pod casePod) {
this.pods = new Pod[] {leftPod, rightPod, casePod};
}
- public Pod getPod (int pos) {
+ public Pod getPod(int pos) {
return pods[pos];
}
- public String getParsedStatus (int pos) {
+ public String getParsedStatus(int pos) {
return pods[pos].parseStatus();
}
- public int getInEarVisibility (int pos) {
+ public int getInEarVisibility(int pos) {
return pods[pos].inEarVisibility();
}
- public int getBatImgVisibility (int pos) {
+ public int getBatImgVisibility(int pos) {
return pods[pos].batImgVisibility();
}
- public int getBatImgSrcId (int pos) {
+ public int getBatImgSrcId(int pos) {
return pods[pos].batImgSrcId();
}
- public int getLeftDrawable () {
+ public int getLeftDrawable() {
return getPod(LEFT).isConnected() ? R.drawable.pod : R.drawable.pod_disconnected;
}
- public int getRightDrawable () {
+ public int getRightDrawable() {
return getPod(RIGHT).isConnected() ? R.drawable.pod : R.drawable.pod_disconnected;
}
- public int getCaseDrawable () {
+ public int getCaseDrawable() {
return getPod(CASE).isConnected() ? R.drawable.pod_case : R.drawable.pod_case_disconnected;
}
@Override
- public String getModel () {
+ public String getModel() {
return Constants.MODEL_UNKNOWN;
}
@Override
- public boolean isSingle () {
+ public boolean isSingle() {
return false;
}
@Override
- public boolean isDisconnected () {
+ public boolean isDisconnected() {
return pods[LEFT].isDisconnected() &&
pods[RIGHT].isDisconnected() &&
pods[CASE].isDisconnected();
}
@Override
- public String parseStatusForLogger () {
+ public String parseStatusForLogger() {
return String.format(Locale.getDefault(), "Left: %d%s%s Right: %d%s%s Case: %d%s Model: %s",
pods[LEFT].getStatus(), pods[LEFT].isCharging() ? "+" : "", pods[LEFT].isInEar() ? "$" : "",
pods[RIGHT].getStatus(), pods[RIGHT].isCharging() ? "+" : "", pods[RIGHT].isInEar() ? "$" : "",
pods[CASE].getStatus(), pods[CASE].isCharging() ? "+" : "", getModel());
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/pods/models/SinglePods.java b/app/src/main/java/com/dosse/airpods/pods/models/SinglePods.java
index 4a47831..3619d19 100644
--- a/app/src/main/java/com/dosse/airpods/pods/models/SinglePods.java
+++ b/app/src/main/java/com/dosse/airpods/pods/models/SinglePods.java
@@ -5,44 +5,42 @@ import com.dosse.airpods.pods.Pod;
import java.util.Locale;
public abstract class SinglePods implements IPods {
-
- public abstract int getDrawable ();
+ public abstract int getDrawable();
private final Pod pod;
- public SinglePods (Pod pod) {
+ public SinglePods(Pod pod) {
this.pod = pod;
}
- public Pod getPod () {
+ public Pod getPod() {
return pod;
}
- public String getParsedStatus () {
+ public String getParsedStatus() {
return pod.parseStatus();
}
- public int getBatImgVisibility () {
+ public int getBatImgVisibility() {
return pod.batImgVisibility();
}
- public int getBatImgSrcId () {
+ public int getBatImgSrcId() {
return pod.batImgSrcId();
}
@Override
- public boolean isSingle () {
+ public boolean isSingle() {
return true;
}
@Override
- public boolean isDisconnected () {
+ public boolean isDisconnected() {
return pod.isDisconnected();
}
@Override
- public String parseStatusForLogger () {
+ public String parseStatusForLogger() {
return String.format(Locale.getDefault(), "Battery: %d%s Model: %s", pod.getStatus(), pod.isCharging() ? "+" : "", getModel());
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/receivers/BluetoothListener.java b/app/src/main/java/com/dosse/airpods/receivers/BluetoothListener.java
index 61f79e3..625f5f8 100644
--- a/app/src/main/java/com/dosse/airpods/receivers/BluetoothListener.java
+++ b/app/src/main/java/com/dosse/airpods/receivers/BluetoothListener.java
@@ -4,23 +4,27 @@ import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
public abstract class BluetoothListener implements BluetoothProfile.ServiceListener {
+ public abstract boolean onConnect(BluetoothDevice bluetoothDevice);
- public abstract boolean onConnect (BluetoothDevice bluetoothDevice);
-
- public abstract void onDisconnect ();
+ public abstract void onDisconnect();
@Override
- public void onServiceConnected (int profile, BluetoothProfile bluetoothProfile) {
- if (profile == BluetoothProfile.HEADSET)
- for (BluetoothDevice device : bluetoothProfile.getConnectedDevices())
- if (onConnect(device))
- break;
+ public void onServiceConnected(int profile, BluetoothProfile bluetoothProfile) {
+ if (profile != BluetoothProfile.HEADSET) {
+ return;
+ }
+
+ for (BluetoothDevice device : bluetoothProfile.getConnectedDevices()) {
+ if (onConnect(device)) {
+ break;
+ }
+ }
}
@Override
- public void onServiceDisconnected (int profile) {
- if (profile == BluetoothProfile.HEADSET)
+ public void onServiceDisconnected(int profile) {
+ if (profile == BluetoothProfile.HEADSET) {
onDisconnect();
+ }
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/receivers/BluetoothReceiver.java b/app/src/main/java/com/dosse/airpods/receivers/BluetoothReceiver.java
index 1310442..814dedf 100644
--- a/app/src/main/java/com/dosse/airpods/receivers/BluetoothReceiver.java
+++ b/app/src/main/java/com/dosse/airpods/receivers/BluetoothReceiver.java
@@ -8,20 +8,19 @@ import android.content.Intent;
import android.content.IntentFilter;
public abstract class BluetoothReceiver extends BroadcastReceiver {
+ public abstract void onStart();
- public abstract void onStart ();
+ public abstract void onStop();
- public abstract void onStop ();
+ public abstract void onConnect(BluetoothDevice bluetoothDevice);
- public abstract void onConnect (BluetoothDevice bluetoothDevice);
-
- public abstract void onDisconnect (BluetoothDevice bluetoothDevice);
+ public abstract void onDisconnect(BluetoothDevice bluetoothDevice);
/**
* When the service is created, we register to get as many bluetooth and airpods related events as possible.
* ACL_CONNECTED and ACL_DISCONNECTED should have been enough, but you never know with android these days.
*/
- public static IntentFilter buildFilter () {
+ public static IntentFilter buildFilter() {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("android.bluetooth.device.action.ACL_CONNECTED");
intentFilter.addAction("android.bluetooth.device.action.ACL_DISCONNECTED");
@@ -38,7 +37,7 @@ public abstract class BluetoothReceiver extends BroadcastReceiver {
}
@Override
- public void onReceive (Context context, Intent intent) {
+ public void onReceive(Context context, Intent intent) {
BluetoothDevice bluetoothDevice = intent.getParcelableExtra("android.bluetooth.device.extra.DEVICE");
String action = intent.getAction();
@@ -46,24 +45,28 @@ public abstract class BluetoothReceiver extends BroadcastReceiver {
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
// Bluetooth turned off, stop scanner and remove notification.
- if (state == BluetoothAdapter.STATE_OFF || state == BluetoothAdapter.STATE_TURNING_OFF)
+ if (state == BluetoothAdapter.STATE_OFF || state == BluetoothAdapter.STATE_TURNING_OFF) {
onStop();
+ }
// Bluetooth turned on, start/restart scanner.
- if (state == BluetoothAdapter.STATE_ON)
+ if (state == BluetoothAdapter.STATE_ON) {
onStart();
+ }
}
// Airpods filter
if (bluetoothDevice != null && action != null && !action.isEmpty()) {
// Airpods connected, show notification.
- if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action))
+ if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
onConnect(bluetoothDevice);
+ }
// Airpods disconnected, remove notification but leave the scanner going.
- if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action) || BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action))
+ if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)
+ || BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {
onDisconnect(bluetoothDevice);
+ }
}
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/receivers/ScreenReceiver.java b/app/src/main/java/com/dosse/airpods/receivers/ScreenReceiver.java
index b3dc3b4..7b9c1b9 100644
--- a/app/src/main/java/com/dosse/airpods/receivers/ScreenReceiver.java
+++ b/app/src/main/java/com/dosse/airpods/receivers/ScreenReceiver.java
@@ -5,27 +5,31 @@ import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import java.util.Objects;
+
public abstract class ScreenReceiver extends BroadcastReceiver {
+ public abstract void onStart();
- public abstract void onStart ();
+ public abstract void onStop();
- public abstract void onStop ();
-
- public static IntentFilter buildFilter () {
+ public static IntentFilter buildFilter() {
IntentFilter screenIntentFilter = new IntentFilter();
+
screenIntentFilter.addAction(Intent.ACTION_SCREEN_ON);
screenIntentFilter.addAction(Intent.ACTION_SCREEN_OFF);
+
return screenIntentFilter;
}
@Override
- public void onReceive (Context context, Intent intent) {
- switch (intent.getAction()) {
- case Intent.ACTION_SCREEN_OFF: onStop();
+ public void onReceive(Context context, Intent intent) {
+ switch (Objects.requireNonNull(intent.getAction())) {
+ case Intent.ACTION_SCREEN_OFF:
+ onStop();
break;
- case Intent.ACTION_SCREEN_ON: onStart();
+ case Intent.ACTION_SCREEN_ON:
+ onStart();
break;
}
}
-
}
\ No newline at end of file
diff --git a/app/src/main/java/com/dosse/airpods/receivers/StartupReceiver.java b/app/src/main/java/com/dosse/airpods/receivers/StartupReceiver.java
index dc5ac48..357cbbf 100644
--- a/app/src/main/java/com/dosse/airpods/receivers/StartupReceiver.java
+++ b/app/src/main/java/com/dosse/airpods/receivers/StartupReceiver.java
@@ -3,7 +3,6 @@ package com.dosse.airpods.receivers;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
-import android.os.Build;
import com.dosse.airpods.pods.PodsService;
@@ -13,9 +12,8 @@ import java.util.Objects;
* A simple startup class that starts the service when the device is booted, or after an update
*/
public class StartupReceiver extends BroadcastReceiver {
-
@Override
- public void onReceive (Context context, Intent intent) {
+ public void onReceive(Context context, Intent intent) {
switch (Objects.requireNonNull(intent.getAction())) {
case Intent.ACTION_MY_PACKAGE_REPLACED:
case Intent.ACTION_BOOT_COMPLETED:
@@ -24,14 +22,11 @@ public class StartupReceiver extends BroadcastReceiver {
}
}
- public static void startPodsService (Context context) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
- context.startForegroundService(new Intent(context, PodsService.class));
- else
- context.startService(new Intent(context, PodsService.class));
+ public static void startPodsService(Context context) {
+ context.startForegroundService(new Intent(context, PodsService.class));
}
- public static void restartPodsService (Context context) {
+ public static void restartPodsService(Context context) {
context.stopService(new Intent(context, PodsService.class));
try {
Thread.sleep(500);
@@ -39,5 +34,4 @@ public class StartupReceiver extends BroadcastReceiver {
}
startPodsService(context);
}
-
}
diff --git a/app/src/main/java/com/dosse/airpods/ui/AboutActivity.java b/app/src/main/java/com/dosse/airpods/ui/AboutActivity.java
index 0b8fdf9..c73d76b 100644
--- a/app/src/main/java/com/dosse/airpods/ui/AboutActivity.java
+++ b/app/src/main/java/com/dosse/airpods/ui/AboutActivity.java
@@ -10,9 +10,8 @@ import androidx.appcompat.app.AppCompatActivity;
import com.dosse.airpods.R;
public class AboutActivity extends AppCompatActivity {
-
@Override
- protected void onCreate (Bundle savedInstanceState) {
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_about);
@@ -42,5 +41,4 @@ public class AboutActivity extends AppCompatActivity {
// ------------ END OF LEGAL DANGER ZONE ------------ //
}
-
}
diff --git a/app/src/main/java/com/dosse/airpods/ui/IntroActivity.java b/app/src/main/java/com/dosse/airpods/ui/IntroActivity.java
index 0f10bda..381ba93 100644
--- a/app/src/main/java/com/dosse/airpods/ui/IntroActivity.java
+++ b/app/src/main/java/com/dosse/airpods/ui/IntroActivity.java
@@ -23,32 +23,39 @@ import java.util.Timer;
import java.util.TimerTask;
public class IntroActivity extends AppCompatActivity {
+ private static final int STEP_PERMISSION_BLUETOOTH = 1;
+ private static final int STEP_PERMISSION_BATTERY_OPTIMIZATION = 2;
+ private static final int STEP_PERMISSION_LOCATION = 3;
+ private static final int STEP_PERMISSION_BACKGROUND_LOCATION = 4;
+ private static final int STEP_PERMISSION_NOTIFICATION = 5;
- private Timer timer;
- private TextView msg;
- private Button btn;
+ private static final int BLUETOOTH_REQUEST_CODE = 101;
+ private static final int LOCATION_REQUEST_CODE = 102;
+ private static final int BACKGROUND_LOCATION_REQUEST_CODE = 103;
+ private static final int NOTIFICATION_REQUEST_CODE = 104;
- private static final int STEP_PERMISSION_BLUETOOTH = 1, STEP_PERMISSION_BATTERY_OPTIMIZATION = 2, STEP_PERMISSION_LOCATION = 3, STEP_PERMISSION_BACKGROUND_LOCATION = 4, STEP_PERMISSION_NOTIFICATION = 5;
- private static final int BLUETOOTH_REQUEST_CODE = 101, LOCATION_REQUEST_CODE = 102, BACKGROUND_LOCATION_REQUEST_CODE = 103, NOTIFICATION_REQUEST_CODE = 104;
+ private Timer mTimer;
+ private TextView mPermissionsMessage;
+ private Button mPermissionsButton;
@Override
- protected void onCreate (Bundle savedInstanceState) {
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_intro);
- msg = findViewById(R.id.permsMsg);
- btn = findViewById(R.id.permsBtn);
+ mPermissionsMessage = findViewById(R.id.permsMsg);
+ mPermissionsButton = findViewById(R.id.permsBtn);
// Wait for permissions to be granted.
// When they are granted, go to MainActivity.
- timer = new Timer();
- timer.scheduleAtFixedRate(new TimerTask() {
+ mTimer = new Timer();
+ mTimer.scheduleAtFixedRate(new TimerTask() {
@Override
- public void run () {
+ public void run() {
initScreen();
if (PermissionUtils.checkAllPermissions(IntroActivity.this)) {
- timer.cancel();
+ mTimer.cancel();
startActivity(new Intent(IntroActivity.this, MainActivity.class));
finish();
}
@@ -59,43 +66,49 @@ public class IntroActivity extends AppCompatActivity {
// Activity destroyed (or screen rotated). destroy the timer too
@Override
- protected void onDestroy () {
+ protected void onDestroy() {
super.onDestroy();
- if (timer != null)
- timer.cancel();
+ if (mTimer != null)
+ mTimer.cancel();
}
- private int getPermissionState () {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) if (!PermissionUtils.getBluetoothPermissions(this))
+ private int getPermissionState() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !PermissionUtils.getBluetoothPermissions(this)) {
return STEP_PERMISSION_BLUETOOTH;
- if (!PermissionUtils.getBatteryOptimizationsPermission(this))
+ }
+ if (!PermissionUtils.getBatteryOptimizationsPermission(this)) {
return STEP_PERMISSION_BATTERY_OPTIMIZATION;
- if (!PermissionUtils.getFineLocationPermission(this))
+ }
+ if (!PermissionUtils.getFineLocationPermission(this)) {
return STEP_PERMISSION_LOCATION;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) if (!PermissionUtils.getBackgroundLocationPermission(this))
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !PermissionUtils.getBackgroundLocationPermission(this)) {
return STEP_PERMISSION_BACKGROUND_LOCATION;
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) if (!PermissionUtils.getNotificationPermissions(this))
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU && !PermissionUtils.getNotificationPermissions(this)) {
return STEP_PERMISSION_NOTIFICATION;
+ }
+
return 0;
}
@SuppressLint("BatteryLife")
- private void initScreen () {
+ private void initScreen() {
int currentStep = getPermissionState() - ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ? 0 : 1);
- int numOfSteps = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) ? 5 : (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) ? ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ? 4 : 3) : 2;
runOnUiThread(() -> {
switch (getPermissionState()) {
case STEP_PERMISSION_BLUETOOTH:
- msg.setText(String.format(Locale.getDefault(), "%s %d/%d: %s", getString(R.string.intro_step), currentStep, numOfSteps, getString(R.string.intro_bt_perm)));
- btn.setOnClickListener(view -> {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
+ mPermissionsMessage.setText(String.format(Locale.getDefault(), "%s %d/%d: %s", getString(R.string.intro_step), currentStep, getNumberOfSteps(), getString(R.string.intro_bt_perm)));
+ mPermissionsButton.setOnClickListener(view -> {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
requestPermissions(new String[] {Manifest.permission.BLUETOOTH_SCAN, Manifest.permission.BLUETOOTH_CONNECT}, BLUETOOTH_REQUEST_CODE);
+ }
});
break;
case STEP_PERMISSION_BATTERY_OPTIMIZATION:
- msg.setText(String.format(Locale.getDefault(), "%s %d/%d: %s", getString(R.string.intro_step), currentStep, numOfSteps, getString(R.string.intro_bat_perm)));
- btn.setOnClickListener(view -> {
+ mPermissionsMessage.setText(String.format(Locale.getDefault(), "%s %d/%d: %s", getString(R.string.intro_step), currentStep, getNumberOfSteps(), getString(R.string.intro_bat_perm)));
+ mPermissionsButton.setOnClickListener(view -> {
Intent intent = new Intent();
getSystemService(Context.POWER_SERVICE);
intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
@@ -104,51 +117,78 @@ public class IntroActivity extends AppCompatActivity {
});
break;
case STEP_PERMISSION_LOCATION:
- msg.setText(String.format(Locale.getDefault(), "%s %d/%d: %s", getString(R.string.intro_step), currentStep, numOfSteps, getString(R.string.intro_loc1_perm)));
- btn.setOnClickListener(view -> requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE)); // Location (for BLE)
+ mPermissionsMessage.setText(String.format(Locale.getDefault(), "%s %d/%d: %s", getString(R.string.intro_step), currentStep, getNumberOfSteps(), getString(R.string.intro_loc1_perm)));
+ mPermissionsButton.setOnClickListener(view -> requestPermissions(new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE)); // Location (for BLE)
break;
case STEP_PERMISSION_BACKGROUND_LOCATION:
- msg.setText(String.format(Locale.getDefault(), "%s %d/%d: %s", getString(R.string.intro_step), currentStep, numOfSteps, getString(R.string.intro_loc2_perm)));
- btn.setOnClickListener(view -> {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) requestPermissions(new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_REQUEST_CODE);
+ mPermissionsMessage.setText(String.format(Locale.getDefault(), "%s %d/%d: %s", getString(R.string.intro_step), currentStep, getNumberOfSteps(), getString(R.string.intro_loc2_perm)));
+ mPermissionsButton.setOnClickListener(view -> {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ requestPermissions(new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_REQUEST_CODE);
+ }
});
break;
case STEP_PERMISSION_NOTIFICATION:
- msg.setText(String.format(Locale.getDefault(), "%s %d/%d: %s", getString(R.string.intro_step), currentStep, numOfSteps, getString(R.string.intro_notif_perm)));
- btn.setOnClickListener(view -> {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) requestPermissions(new String[] {Manifest.permission.POST_NOTIFICATIONS}, NOTIFICATION_REQUEST_CODE);
+ mPermissionsMessage.setText(String.format(Locale.getDefault(), "%s %d/%d: %s", getString(R.string.intro_step), currentStep, getNumberOfSteps(), getString(R.string.intro_notif_perm)));
+ mPermissionsButton.setOnClickListener(view -> {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ requestPermissions(new String[] {Manifest.permission.POST_NOTIFICATIONS}, NOTIFICATION_REQUEST_CODE);
+ }
});
}
- btn.setText(String.format(Locale.getDefault(), "%s (%d/%d)", getString(R.string.intro_allow), currentStep, numOfSteps));
+ mPermissionsButton.setText(String.format(Locale.getDefault(), "%s (%d/%d)", getString(R.string.intro_allow), currentStep, getNumberOfSteps()));
});
}
+ private int getNumberOfSteps() {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ return 5;
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ return 4;
+ }
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
+ return 3;
+ }
+
+ return 2;
+ }
+
@Override
- public void onRequestPermissionsResult (int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
+ public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case BLUETOOTH_REQUEST_CODE:
- if (!hasAllPermissionsGranted(grantResults)) Toast.makeText(this, getString(R.string.msg_bt_perm), Toast.LENGTH_LONG).show();
+ if (!hasAllPermissionsGranted(grantResults)) {
+ Toast.makeText(this, getString(R.string.msg_bt_perm), Toast.LENGTH_LONG).show();
+ }
break;
case LOCATION_REQUEST_CODE:
- if (!hasAllPermissionsGranted(grantResults)) Toast.makeText(this, getString(R.string.msg_loc1_perm), Toast.LENGTH_LONG).show();
+ if (!hasAllPermissionsGranted(grantResults)) {
+ Toast.makeText(this, getString(R.string.msg_loc1_perm), Toast.LENGTH_LONG).show();
+ }
break;
case BACKGROUND_LOCATION_REQUEST_CODE:
- if (!hasAllPermissionsGranted(grantResults)) Toast.makeText(this, getString(R.string.msg_loc2_perm), Toast.LENGTH_LONG).show();
+ if (!hasAllPermissionsGranted(grantResults)) {
+ Toast.makeText(this, getString(R.string.msg_loc2_perm), Toast.LENGTH_LONG).show();
+ }
break;
case NOTIFICATION_REQUEST_CODE:
- if (!hasAllPermissionsGranted(grantResults)) Toast.makeText(this, getString(R.string.msg_notif_perm), Toast.LENGTH_LONG).show();
+ if (!hasAllPermissionsGranted(grantResults)) {
+ Toast.makeText(this, getString(R.string.msg_notif_perm), Toast.LENGTH_LONG).show();
+ }
break;
}
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
- public boolean hasAllPermissionsGranted (@NonNull int[] grantResults) {
- for (int grantResult : grantResults)
- if (grantResult == PackageManager.PERMISSION_DENIED)
+ public boolean hasAllPermissionsGranted(@NonNull int[] grantResults) {
+ for (int grantResult : grantResults) {
+ if (grantResult == PackageManager.PERMISSION_DENIED) {
return false;
+ }
+ }
return true;
}
-
}
diff --git a/app/src/main/java/com/dosse/airpods/ui/MainActivity.java b/app/src/main/java/com/dosse/airpods/ui/MainActivity.java
index ee698a7..92e9d5f 100644
--- a/app/src/main/java/com/dosse/airpods/ui/MainActivity.java
+++ b/app/src/main/java/com/dosse/airpods/ui/MainActivity.java
@@ -19,9 +19,8 @@ import com.dosse.airpods.utils.PermissionUtils;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
-
@Override
- protected void onCreate (Bundle savedInstanceState) {
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
@@ -30,6 +29,7 @@ public class MainActivity extends AppCompatActivity {
if (btAdapter == null || (btAdapter.isEnabled() && btAdapter.getBluetoothLeScanner() == null) || (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE))) {
startActivity(new Intent(MainActivity.this, NoBTActivity.class));
finish();
+
return;
}
@@ -44,18 +44,18 @@ public class MainActivity extends AppCompatActivity {
}
@Override
- public boolean onCreateOptionsMenu (Menu menu) {
+ public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
- public boolean onOptionsItemSelected (@NonNull MenuItem item) {
+ public boolean onOptionsItemSelected(@NonNull MenuItem item) {
if (item.getItemId() == R.id.menu_ab_settings) {
startActivity(new Intent(this, SettingsActivity.class)); // Settings icon clicked
return true;
}
+
return false;
}
-
}
diff --git a/app/src/main/java/com/dosse/airpods/ui/NoBTActivity.java b/app/src/main/java/com/dosse/airpods/ui/NoBTActivity.java
index 78256b2..80e51e3 100644
--- a/app/src/main/java/com/dosse/airpods/ui/NoBTActivity.java
+++ b/app/src/main/java/com/dosse/airpods/ui/NoBTActivity.java
@@ -6,11 +6,9 @@ import androidx.appcompat.app.AppCompatActivity;
import com.dosse.airpods.R;
public class NoBTActivity extends AppCompatActivity {
-
@Override
- protected void onCreate (Bundle savedInstanceState) {
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_no_bt);
}
-
}
diff --git a/app/src/main/java/com/dosse/airpods/ui/SettingsActivity.java b/app/src/main/java/com/dosse/airpods/ui/SettingsActivity.java
index f92e0c7..68bfb96 100644
--- a/app/src/main/java/com/dosse/airpods/ui/SettingsActivity.java
+++ b/app/src/main/java/com/dosse/airpods/ui/SettingsActivity.java
@@ -11,9 +11,8 @@ import com.dosse.airpods.R;
import com.dosse.airpods.receivers.StartupReceiver;
public class SettingsActivity extends AppCompatActivity {
-
@Override
- protected void onCreate (Bundle savedInstanceState) {
+ protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_settings);
getSupportFragmentManager()
@@ -23,9 +22,8 @@ public class SettingsActivity extends AppCompatActivity {
}
public static class SettingsFragment extends PreferenceFragmentCompat {
-
@Override
- public void onCreatePreferences (Bundle savedInstanceState, String rootKey) {
+ public void onCreatePreferences(Bundle savedInstanceState, String rootKey) {
setPreferencesFromResource(R.xml.preference_screen, rootKey);
getPreference("batterySaver").setOnPreferenceClickListener(preference -> {
@@ -46,10 +44,8 @@ public class SettingsActivity extends AppCompatActivity {
});
}
- private Preference getPreference (String key) {
+ private Preference getPreference(String key) {
return getPreferenceManager().findPreference(key);
}
-
}
-
}
diff --git a/app/src/main/java/com/dosse/airpods/utils/Logger.java b/app/src/main/java/com/dosse/airpods/utils/Logger.java
index 213d6c9..97b52d0 100644
--- a/app/src/main/java/com/dosse/airpods/utils/Logger.java
+++ b/app/src/main/java/com/dosse/airpods/utils/Logger.java
@@ -5,17 +5,19 @@ import android.util.Log;
import com.dosse.airpods.BuildConfig;
public class Logger {
-
// Log is only displayed if this is a debug build, not release
private static final boolean ENABLE_LOGGING = BuildConfig.DEBUG;
public static final String TAG = "AirPods";
- public static void debug (String msg) {
- if (ENABLE_LOGGING) Log.d(TAG, msg);
+ public static void debug(String msg) {
+ if (ENABLE_LOGGING) {
+ Log.d(TAG, msg);
+ }
}
- public static void error (Throwable t) {
- if (ENABLE_LOGGING) Log.e(TAG, "ERROR", t);
+ public static void error(Throwable t) {
+ if (ENABLE_LOGGING) {
+ Log.e(TAG, "ERROR", t);
+ }
}
-
}
diff --git a/app/src/main/java/com/dosse/airpods/utils/MIUIWarning.java b/app/src/main/java/com/dosse/airpods/utils/MIUIWarning.java
index aa45e4f..dc701f0 100644
--- a/app/src/main/java/com/dosse/airpods/utils/MIUIWarning.java
+++ b/app/src/main/java/com/dosse/airpods/utils/MIUIWarning.java
@@ -6,31 +6,47 @@ import androidx.appcompat.app.AlertDialog;
import com.dosse.airpods.R;
+import java.lang.reflect.Method;
+
public class MIUIWarning {
+ public static void show(Context context) {
+ Context appContext = context.getApplicationContext();
- public static void show (Context context) {
try {
- @SuppressLint("PrivateApi") Class> c = Class.forName("android.os.SystemProperties");
- String miuiVersion = (String)c.getMethod("get", String.class).invoke(c, "ro.miui.ui.version.code");
- if (miuiVersion != null && !miuiVersion.isEmpty()) {
- try {
- context.getApplicationContext().openFileInput("miuiwarn").close();
- } catch (Throwable ignored) {
- AlertDialog.Builder builder = new AlertDialog.Builder(context);
- builder.setTitle(R.string.miui_warning);
- builder.setMessage(R.string.miui_warning_desc);
- builder.setNeutralButton(R.string.miui_warning_continue, (dialog, which) -> dialog.dismiss());
- builder.setOnDismissListener(dialog -> {
- try {
- context.getApplicationContext().openFileOutput("miuiwarn", Context.MODE_PRIVATE).close();
- } catch (Throwable ignored2) {
- }
- });
- builder.show();
- }
+ String miuiVersion = getMiuiVersion();
+ if (miuiVersion == null || miuiVersion.isEmpty()) {
+ return;
+ }
+
+ try {
+ appContext.openFileInput("miuiwarn").close();
+ } catch (Throwable ignored) {
+ showAlertDialog(appContext);
}
} catch (Throwable ignored) {
}
}
+ @SuppressLint("PrivateApi")
+ private static String getMiuiVersion() throws ReflectiveOperationException {
+ Class> systemPropertiesClazz = Class.forName("android.os.SystemProperties");
+ Method systemPropertiesGet = systemPropertiesClazz.getMethod("get", String.class);
+ systemPropertiesGet.setAccessible(true);
+
+ return (String)systemPropertiesGet.invoke(null, "ro.miui.ui.version.code");
+ }
+
+ private static void showAlertDialog(Context context) {
+ AlertDialog.Builder builder = new AlertDialog.Builder(context);
+ builder.setTitle(R.string.miui_warning);
+ builder.setMessage(R.string.miui_warning_desc);
+ builder.setNeutralButton(R.string.miui_warning_continue, (dialog, which) -> dialog.dismiss());
+ builder.setOnDismissListener(dialog -> {
+ try {
+ context.openFileOutput("miuiwarn", Context.MODE_PRIVATE).close();
+ } catch (Throwable ignored2) {
+ }
+ });
+ builder.show();
+ }
}
diff --git a/app/src/main/java/com/dosse/airpods/utils/PermissionUtils.java b/app/src/main/java/com/dosse/airpods/utils/PermissionUtils.java
index 389db71..5a64934 100644
--- a/app/src/main/java/com/dosse/airpods/utils/PermissionUtils.java
+++ b/app/src/main/java/com/dosse/airpods/utils/PermissionUtils.java
@@ -7,54 +7,50 @@ import android.os.Build;
import android.os.PowerManager;
import androidx.annotation.RequiresApi;
-import java.util.Objects;
-
import static androidx.core.content.ContextCompat.checkSelfPermission;
public class PermissionUtils {
-
- public static boolean getBatteryOptimizationsPermission (Context context) {
- try {
- return Objects.requireNonNull(context.getSystemService(PowerManager.class)).isIgnoringBatteryOptimizations(context.getPackageName());
- } catch (Throwable ignored) {
- return true;
- }
+ public static boolean getBatteryOptimizationsPermission(Context context) {
+ return context.getSystemService(PowerManager.class).isIgnoringBatteryOptimizations(context.getPackageName());
}
@RequiresApi(api = Build.VERSION_CODES.TIRAMISU)
- public static boolean getNotificationPermissions (Context context) {
+ public static boolean getNotificationPermissions(Context context) {
return checkSelfPermission(context, Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED;
}
@RequiresApi(api = Build.VERSION_CODES.S)
- public static boolean getBluetoothPermissions (Context context) {
+ public static boolean getBluetoothPermissions(Context context) {
return checkSelfPermission(context, Manifest.permission.BLUETOOTH_SCAN) == PackageManager.PERMISSION_GRANTED
&& checkSelfPermission(context, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED;
}
- public static boolean getFineLocationPermission (Context context) {
+ public static boolean getFineLocationPermission(Context context) {
return checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
@RequiresApi(api = Build.VERSION_CODES.Q)
- public static boolean getBackgroundLocationPermission (Context context) {
+ public static boolean getBackgroundLocationPermission(Context context) {
return checkSelfPermission(context, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
- public static boolean getLocationPermissions (Context context) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
+ public static boolean getLocationPermissions(Context context) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
return getFineLocationPermission(context) && getBackgroundLocationPermission(context);
- else
- return getFineLocationPermission(context);
+ }
+
+ return getFineLocationPermission(context);
}
- public static boolean checkAllPermissions (Context context) {
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU)
+ public static boolean checkAllPermissions(Context context) {
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
return getNotificationPermissions(context) && getBatteryOptimizationsPermission(context) && getLocationPermissions(context) && getBluetoothPermissions(context);
- if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S)
- return getBatteryOptimizationsPermission(context) && getLocationPermissions(context) && getBluetoothPermissions(context);
- else
- return getBatteryOptimizationsPermission(context) && getLocationPermissions(context);
- }
+ }
+ if (Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
+ return getBatteryOptimizationsPermission(context) && getLocationPermissions(context);
+ }
+
+ return getBatteryOptimizationsPermission(context) && getLocationPermissions(context) && getBluetoothPermissions(context);
+ }
}
diff --git a/app/src/main/java/com/dosse/airpods/utils/SharedPreferencesUtils.java b/app/src/main/java/com/dosse/airpods/utils/SharedPreferencesUtils.java
index 54dd5d7..55674af 100644
--- a/app/src/main/java/com/dosse/airpods/utils/SharedPreferencesUtils.java
+++ b/app/src/main/java/com/dosse/airpods/utils/SharedPreferencesUtils.java
@@ -5,10 +5,8 @@ import android.content.SharedPreferences;
import androidx.preference.PreferenceManager;
public class SharedPreferencesUtils {
-
- public static boolean isSavingBattery (Context context) {
+ public static boolean isSavingBattery(Context context) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
return prefs.getBoolean("batterySaver", false);
}
-
}