9 Commits
Author SHA1 Message Date
Electric1447 ee7e75b5e8 Update README.md 2022-09-29 22:22:41 +03:00
Electric1447 b939674a62 Add missing airpods pro 2 text in supported devices list 2022-09-29 22:21:44 +03:00
Electric1447 ade3d0a481 Update localizations 2022-09-29 22:20:06 +03:00
Electric1447 70a05a1848 Add Airpods Pro Gen 2 support 2022-09-29 22:17:32 +03:00
Electric1447 6803ef0691 refactor pod models folders 2022-09-29 22:14:18 +03:00
Electric1447 71f08a4098 renamed ``data` to `types`` 2022-09-29 22:07:56 +03:00
Electric1447 17afa55203 Android 13 support 2022-09-29 22:06:36 +03:00
Electric1447 96ffaf1d90 Update localizations 2022-09-29 22:06:22 +03:00
Electric1447 047b9b373c Update build tools 2022-09-29 22:05:54 +03:00
30 changed files with 167 additions and 95 deletions
+1
View File
@@ -47,6 +47,7 @@
* Apple AirPods 2nd gen
* Apple AirPods 3rd gen
* Apple AirPods Pro
* Apple AirPods Pro 2
* Apple AirPods Max
* Beats X
* Beats Flex
+13 -9
View File
@@ -1,15 +1,17 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 31
buildToolsVersion '32.0.0'
namespace 'com.dosse.airpods'
compileSdkVersion 33
buildToolsVersion '33.0.0'
defaultConfig {
applicationId "com.dosse.airpods"
minSdkVersion 23
targetSdkVersion 31
versionCode 20
versionName '1.8'
targetSdkVersion 33
versionCode 21
versionName '1.9'
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@@ -22,17 +24,19 @@ android {
}
}
lintOptions {
abortOnError false
}
compileOptions {
sourceCompatibility = 11
targetCompatibility = 11
}
lint {
abortOnError false
}
}
dependencies {
implementation 'androidx.appcompat:appcompat:1.4.1'
//noinspection GradleDependency 1.5.0/1.5.1 is broken
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'androidx.preference:preference:1.2.0'
}
+8 -7
View File
@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.dosse.airpods">
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
@@ -8,7 +8,10 @@
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="s" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
@@ -23,7 +26,8 @@
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
android:theme="@style/AppTheme"
tools:ignore="DataExtractionRules">
<activity
android:name=".ui.MainActivity"
@@ -47,13 +51,10 @@
android:launchMode="singleTop"
android:parentActivityName=".ui.MainActivity" />
<activity
android:name=".ui.NoBTActivity"
android:label="@string/app_name" />
<activity android:name=".ui.NoBTActivity" />
<activity
android:name=".ui.IntroActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar" />
<receiver
@@ -8,9 +8,9 @@ import androidx.core.app.NotificationCompat;
import com.dosse.airpods.R;
import com.dosse.airpods.pods.PodsStatus;
import com.dosse.airpods.pods.data.IPods;
import com.dosse.airpods.pods.data.RegularPods;
import com.dosse.airpods.pods.data.SinglePods;
import com.dosse.airpods.pods.models.IPods;
import com.dosse.airpods.pods.models.RegularPods;
import com.dosse.airpods.pods.models.SinglePods;
public class NotificationBuilder {
public static final String TAG = "AirPods";
@@ -1,4 +1,4 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods;
import android.view.View;
@@ -1,5 +1,6 @@
package com.dosse.airpods.pods;
import android.annotation.SuppressLint;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -59,6 +60,7 @@ public class PodsService extends Service {
*
* After decoding a beacon, the status is written to PodsStatus so that the NotificationThread can use the information
*/
@SuppressLint("MissingPermission")
private void startAirPodsScanner () {
try {
Logger.debug("START SCANNER");
@@ -71,7 +73,6 @@ public class PodsService extends Service {
return;
}
//if (batterySaver && btScanner != null && scanCallback != null) {
if (btScanner != null && scanCallback != null) {
btScanner.stopScan(scanCallback);
scanCallback = null;
@@ -102,6 +103,7 @@ public class PodsService extends Service {
}
}
@SuppressLint("MissingPermission")
private void stopAirPodsScanner () {
try {
if (btScanner != null && scanCallback != null) {
@@ -233,6 +235,7 @@ public class PodsService extends Service {
}
}
@SuppressLint("MissingPermission")
private static boolean checkUUID (BluetoothDevice bluetoothDevice) {
ParcelUuid[] AIRPODS_UUIDS = {
ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a"),
@@ -1,19 +1,19 @@
package com.dosse.airpods.pods;
import com.dosse.airpods.pods.data.AirPods1;
import com.dosse.airpods.pods.data.AirPods2;
import com.dosse.airpods.pods.data.AirPods3;
import com.dosse.airpods.pods.data.AirPodsMax;
import com.dosse.airpods.pods.data.AirPodsPro;
import com.dosse.airpods.pods.data.BeatsFlex;
import com.dosse.airpods.pods.data.BeatsSolo3;
import com.dosse.airpods.pods.data.BeatsStudio3;
import com.dosse.airpods.pods.data.BeatsX;
import com.dosse.airpods.pods.data.IPods;
import com.dosse.airpods.pods.data.Pod;
import com.dosse.airpods.pods.data.Powerbeats3;
import com.dosse.airpods.pods.data.PowerbeatsPro;
import com.dosse.airpods.pods.data.RegularPods;
import com.dosse.airpods.pods.models.AirPods1;
import com.dosse.airpods.pods.models.AirPods2;
import com.dosse.airpods.pods.models.AirPods3;
import com.dosse.airpods.pods.models.AirPodsMax;
import com.dosse.airpods.pods.models.AirPodsPro;
import com.dosse.airpods.pods.models.AirPodsPro2;
import com.dosse.airpods.pods.models.BeatsFlex;
import com.dosse.airpods.pods.models.BeatsSolo3;
import com.dosse.airpods.pods.models.BeatsStudio3;
import com.dosse.airpods.pods.models.BeatsX;
import com.dosse.airpods.pods.models.IPods;
import com.dosse.airpods.pods.models.Powerbeats3;
import com.dosse.airpods.pods.models.PowerbeatsPro;
import com.dosse.airpods.pods.models.RegularPods;
/**
* Decoding the beacon:
@@ -81,6 +81,8 @@ public class PodsStatus {
pods = new AirPods3(leftPod, rightPod, casePod); // Airpods 3rd gen
} else if ("0E20".equals(idFull)) {
pods = new AirPodsPro(leftPod, rightPod, casePod); // Airpods Pro
} else if ("1420".equals(idFull)) {
pods = new AirPodsPro2(leftPod, rightPod, casePod); // Airpods Pro 2
} else if ('A' == idSingle) {
pods = new AirPodsMax(singlePod); // Airpods Max
} else if ('B' == idSingle) {
@@ -1,27 +0,0 @@
package com.dosse.airpods.pods.data;
public interface IPods {
String MODEL_AIRPODS_GEN1 = "airpods1";
String MODEL_AIRPODS_GEN2 = "airpods2";
String MODEL_AIRPODS_GEN3 = "airpods3";
String MODEL_AIRPODS_PRO = "airpodspro";
String MODEL_AIRPODS_MAX = "airpodsmax";
String MODEL_BEATS_X = "beatsx";
String MODEL_BEATS_FLEX = "beatsflex";
String MODEL_BEATS_SOLO_3 = "beatssolo3";
String MODEL_BEATS_STUDIO_3 = "beatsstudio3";
String MODEL_POWERBEATS_3 = "powerbeats3";
String MODEL_POWERBEATS_PRO = "powerbeatspro";
String MODEL_UNKNOWN = "unknown";
String getModel ();
boolean isSingle ();
boolean isDisconnected ();
String parseStatusForLogger ();
}
@@ -1,4 +1,6 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.pods.Pod;
public class AirPods1 extends RegularPods {
@@ -8,7 +10,7 @@ public class AirPods1 extends RegularPods {
@Override
public String getModel () {
return MODEL_AIRPODS_GEN1;
return Constants.MODEL_AIRPODS_GEN1;
}
}
@@ -1,4 +1,6 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.pods.Pod;
public class AirPods2 extends RegularPods {
@@ -8,7 +10,7 @@ public class AirPods2 extends RegularPods {
@Override
public String getModel () {
return MODEL_AIRPODS_GEN2;
return Constants.MODEL_AIRPODS_GEN2;
}
}
@@ -1,4 +1,6 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.pods.Pod;
public class AirPods3 extends RegularPods {
@@ -8,7 +10,7 @@ public class AirPods3 extends RegularPods {
@Override
public String getModel () {
return MODEL_AIRPODS_GEN3;
return Constants.MODEL_AIRPODS_GEN3;
}
}
@@ -1,6 +1,7 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class AirPodsMax extends SinglePods {
@@ -15,7 +16,7 @@ public class AirPodsMax extends SinglePods {
@Override
public String getModel () {
return MODEL_AIRPODS_MAX;
return Constants.MODEL_AIRPODS_MAX;
}
}
@@ -1,6 +1,7 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class AirPodsPro extends RegularPods {
@@ -25,7 +26,7 @@ public class AirPodsPro extends RegularPods {
@Override
public String getModel () {
return MODEL_AIRPODS_PRO;
return Constants.MODEL_AIRPODS_PRO;
}
}
@@ -0,0 +1,32 @@
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) {
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 () {
return Constants.MODEL_AIRPODS_PRO_2;
}
}
@@ -1,6 +1,7 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class BeatsFlex extends SinglePods {
@@ -15,7 +16,7 @@ public class BeatsFlex extends SinglePods {
@Override
public String getModel () {
return MODEL_BEATS_FLEX;
return Constants.MODEL_BEATS_FLEX;
}
}
@@ -1,6 +1,7 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class BeatsSolo3 extends SinglePods {
@@ -15,7 +16,7 @@ public class BeatsSolo3 extends SinglePods {
@Override
public String getModel () {
return MODEL_BEATS_SOLO_3;
return Constants.MODEL_BEATS_SOLO_3;
}
}
@@ -1,6 +1,7 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class BeatsStudio3 extends SinglePods {
@@ -15,7 +16,7 @@ public class BeatsStudio3 extends SinglePods {
@Override
public String getModel () {
return MODEL_BEATS_STUDIO_3;
return Constants.MODEL_BEATS_STUDIO_3;
}
}
@@ -1,6 +1,7 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class BeatsX extends SinglePods {
@@ -15,7 +16,7 @@ public class BeatsX extends SinglePods {
@Override
public String getModel () {
return MODEL_BEATS_X;
return Constants.MODEL_BEATS_X;
}
}
@@ -0,0 +1,17 @@
package com.dosse.airpods.pods.models;
public final class Constants {
static final String MODEL_AIRPODS_GEN1 = "airpods1";
static final String MODEL_AIRPODS_GEN2 = "airpods2";
static final String MODEL_AIRPODS_GEN3 = "airpods3";
static final String MODEL_AIRPODS_PRO = "airpodspro";
static final String MODEL_AIRPODS_PRO_2 = "airpodspro2";
static final String MODEL_AIRPODS_MAX = "airpodsmax";
static final String MODEL_BEATS_X = "beatsx";
static final String MODEL_BEATS_FLEX = "beatsflex";
static final String MODEL_BEATS_SOLO_3 = "beatssolo3";
static final String MODEL_BEATS_STUDIO_3 = "beatsstudio3";
static final String MODEL_POWERBEATS_3 = "powerbeats3";
static final String MODEL_POWERBEATS_PRO = "powerbeatspro";
static final String MODEL_UNKNOWN = "unknown";
}
@@ -0,0 +1,13 @@
package com.dosse.airpods.pods.models;
public interface IPods {
String getModel ();
boolean isSingle ();
boolean isDisconnected ();
String parseStatusForLogger ();
}
@@ -1,6 +1,7 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class Powerbeats3 extends SinglePods {
@@ -15,7 +16,7 @@ public class Powerbeats3 extends SinglePods {
@Override
public String getModel () {
return MODEL_POWERBEATS_3;
return Constants.MODEL_POWERBEATS_3;
}
}
@@ -1,6 +1,7 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
public class PowerbeatsPro extends RegularPods {
@@ -25,7 +26,7 @@ public class PowerbeatsPro extends RegularPods {
@Override
public String getModel () {
return MODEL_POWERBEATS_PRO;
return Constants.MODEL_POWERBEATS_PRO;
}
}
@@ -1,6 +1,7 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.R;
import com.dosse.airpods.pods.Pod;
import java.util.Locale;
@@ -48,7 +49,7 @@ public class RegularPods implements IPods {
@Override
public String getModel () {
return MODEL_UNKNOWN;
return Constants.MODEL_UNKNOWN;
}
@Override
@@ -1,4 +1,6 @@
package com.dosse.airpods.pods.data;
package com.dosse.airpods.pods.models;
import com.dosse.airpods.pods.Pod;
import java.util.Locale;
@@ -94,6 +94,11 @@
android:layout_height="wrap_content"
android:text="@string/airpodsmax" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/airpodspro2" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -55,6 +55,11 @@
android:layout_height="wrap_content"
android:text="@string/airpodspro" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/airpodspro2" />
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -8,7 +8,9 @@
<string name="supportedDevicesTitle"><u>מכשירים נתמכים</u></string>
<string name="airpods1">• אפל איירפודס דור ראשון</string>
<string name="airpods2">• אפל איירפודס דור שני</string>
<string name="airpods3">• אפל איירפודס דור שלישי</string>
<string name="airpodspro">• אפל איירפודס פרו</string>
<string name="airpodspro2">• אפל איירפודס פרו 2</string>
<string name="airpodsmax">• אפל איירפודס מקס</string>
<string name="beatsx">• ביטס אקס</string>
<string name="beatsflex">• ביטס פלקס</string>
+2 -1
View File
@@ -22,8 +22,9 @@
<string name="supportedDevicesTitle"><u>Supported devices:</u></string>
<string name="airpods1">&#8226; Apple AirPods 1st gen</string>
<string name="airpods2">&#8226; Apple AirPods 2nd gen</string>
<string name="airpods3">&#8226; Apple AirPods 3rd gen</string>
<string name="airpods3" tools:ignore="MissingTranslation">&#8226; Apple AirPods 3rd gen</string>
<string name="airpodspro">&#8226; Apple AirPods Pro</string>
<string name="airpodspro2" tools:ignore="MissingTranslation">&#8226; Apple AirPods Pro 2</string>
<string name="airpodsmax">&#8226; Apple AirPods Max</string>
<string name="beatsx">&#8226; Beats X</string>
<string name="beatsflex">&#8226; Beats Flex</string>
+1 -5
View File
@@ -7,10 +7,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'com.android.tools.build:gradle:7.3.0'
}
}
@@ -18,7 +15,6 @@ allprojects {
repositories {
google()
mavenCentral()
}
}
+2 -2
View File
@@ -1,6 +1,6 @@
#Wed May 18 00:26:39 IDT 2022
#Thu Sep 29 21:38:30 IDT 2022
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME