Add AirPods Max support

This commit is contained in:
Electric1447
2021-08-24 21:32:08 +03:00
parent 4f7586909a
commit 3b497cc526
20 changed files with 139 additions and 58 deletions
+9
View File
@@ -5,6 +5,15 @@
<configuration PROFILE_NAME="Debug" CONFIG_NAME="Debug" />
</configurations>
</component>
<component name="DesignSurface">
<option name="filePathToZoomLevelMap">
<map>
<entry key="..\:/Users/Electric/Desktop/OpenPods/OpenPods/app/src/main/res/layout-land/activity_main.xml" value="0.25" />
<entry key="..\:/Users/Electric/Desktop/OpenPods/OpenPods/app/src/main/res/layout/activity_main.xml" value="0.36666666666666664" />
<entry key="..\:/Users/Electric/Desktop/OpenPods/OpenPods/app/src/main/res/layout/status_big.xml" value="0.36666666666666664" />
</map>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_11" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
@@ -16,6 +16,8 @@ import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.dosse.airpods.utils.PermissionUtils;
import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
@@ -14,6 +14,8 @@ import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import com.dosse.airpods.utils.PermissionUtils;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
@@ -1,5 +1,7 @@
package com.dosse.airpods;
import static com.dosse.airpods.utils.ScannerUtils.isMax;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
@@ -34,9 +36,14 @@ import androidx.annotation.RequiresApi;
import androidx.core.app.NotificationCompat;
import androidx.preference.PreferenceManager;
import com.dosse.airpods.utils.NotificationUtils;
import com.dosse.airpods.utils.PermissionUtils;
import com.dosse.airpods.utils.ScannerUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
/**
@@ -51,11 +58,11 @@ public class PodsService extends Service {
}
private static BluetoothLeScanner btScanner;
private static int leftStatus = 15, rightStatus = 15, caseStatus = 15;
private static int leftStatus = 15, rightStatus = 15, caseStatus = 15, maxStatus = 15;
private static boolean chargeL = false, chargeR = false, chargeCase = false;
private static boolean inEarL = false, inEarR = false;
private static final String MODEL_AIRPODS_NORMAL = "airpods12", MODEL_AIRPODS_PRO = "airpodspro";
private static String model = MODEL_AIRPODS_NORMAL;
public static final String MODEL_AIRPODS_NORMAL = "airpods12", MODEL_AIRPODS_PRO = "airpodspro", MODEL_AIRPODS_MAX = "airpodsmax";
public static String model = MODEL_AIRPODS_NORMAL;
/**
* The following method (startAirPodsScanner) creates a bluetooth LE scanner.
@@ -83,7 +90,7 @@ public class PodsService extends Service {
* - The 11th character in the string represents the in-ear detection status. Bit 1 is the left pod; Bit 3 is the right pod.
* - The 7th character in the string represents the AirPods model (E=AirPods pro)
* <p>
* After decoding a beacon, the status is written to leftStatus, rightStatus, caseStatus, chargeL, chargeR, chargeCase, inEarL, inEarR so that the NotificationThread can use the information
* After decoding a beacon, the status is written to leftStatus, rightStatus, caseStatus, maxStatus, chargeL, chargeR, chargeCase, inEarL, inEarR so that the NotificationThread can use the information
* <p>
* Notes:
* 1) - isFlipped set by bit 1 of 10th character in the string; seems to be related to in-ear detection;
@@ -139,8 +146,8 @@ public class PodsService extends Service {
recentBeacons.add(result);
OpenPodsDebugLog("" + result.getRssi() + "db");
OpenPodsDebugLog(decodeHex(data));
OpenPodsDebugLog(String.format(Locale.getDefault(), "%ddb", result.getRssi()));
OpenPodsDebugLog(ScannerUtils.decodeHex(data));
ScanResult strongestBeacon = null;
for (int i = 0; i < recentBeacons.size(); i++) {
@@ -160,12 +167,13 @@ public class PodsService extends Service {
if (result.getRssi() < -60)
return;
String a = decodeHex(Objects.requireNonNull(Objects.requireNonNull(result.getScanRecord()).getManufacturerSpecificData(76)));
boolean flip = isFlipped(a);
String a = ScannerUtils.decodeHex(Objects.requireNonNull(Objects.requireNonNull(result.getScanRecord()).getManufacturerSpecificData(76)));
boolean flip = ScannerUtils.isFlipped(a);
leftStatus = Integer.parseInt("" + a.charAt(flip ? 12 : 13), 16); // Left airpod (0-10 batt; 15=disconnected)
rightStatus = Integer.parseInt("" + a.charAt(flip ? 13 : 12), 16); // Right airpod (0-10 batt; 15=disconnected)
caseStatus = Integer.parseInt("" + a.charAt(15), 16); // Case (0-10 batt; 15=disconnected)
maxStatus = Integer.parseInt("" + a.charAt(13), 16); // Airpods max (0-10 batt; 15=disconnected)
int chargeStatus = Integer.parseInt("" + a.charAt(14), 16); // Charge status (bit 0=left; bit 1=right; bit 2=case)
@@ -178,7 +186,11 @@ public class PodsService extends Service {
inEarL = (inEarStatus & (flip ? 0b00001000 : 0b00000010)) != 0;
inEarR = (inEarStatus & (flip ? 0b00000010 : 0b00001000)) != 0;
model = (a.charAt(7) == 'E') ? MODEL_AIRPODS_PRO : MODEL_AIRPODS_NORMAL; // Detect if these are AirPods Pro or regular ones
switch (a.charAt(7)) { // Detect if these are AirPods Pro/Max or regular ones
case 'E': model = MODEL_AIRPODS_PRO; break;
case 'A': model = MODEL_AIRPODS_MAX; break;
default: model = MODEL_AIRPODS_NORMAL;
}
lastSeenConnected = System.currentTimeMillis();
} catch (Throwable t) {
@@ -221,23 +233,11 @@ public class PodsService extends Service {
leftStatus = 15;
rightStatus = 15;
caseStatus = 15;
maxStatus = 15;
} catch (Throwable ignored) {
}
}
private String decodeHex (byte[] bArr) {
StringBuilder ret = new StringBuilder();
for (byte b : bArr)
ret.append(String.format("%02X", b));
return ret.toString();
}
private boolean isFlipped (String str) {
return (Integer.parseInt("" + str.charAt(10), 16) & 0x02) == 0;
}
/**
* The following class is a thread that manages the notification while your AirPods are connected.
* <p>
@@ -285,7 +285,7 @@ public class PodsService extends Service {
RemoteViews[] notificationArr = new RemoteViews[] {new RemoteViews(getPackageName(), R.layout.status_big), new RemoteViews(getPackageName(), R.layout.status_small)};
RemoteViews[] notificationLocation = new RemoteViews[] {new RemoteViews(getPackageName(), R.layout.location_disabled_big), new RemoteViews(getPackageName(), R.layout.location_disabled_small)};
if (maybeConnected && !(leftStatus == 15 && rightStatus == 15 && caseStatus == 15)) {
if (maybeConnected && !(leftStatus == 15 && rightStatus == 15 && caseStatus == 15 && maxStatus == 15)) {
if (!notificationShowing) {
OpenPodsDebugLog("Creating notification");
notificationShowing = true;
@@ -310,17 +310,36 @@ public class PodsService extends Service {
}
if (notificationShowing) {
OpenPodsDebugLog("Left: " + leftStatus + (chargeL ? "+" : "") + (inEarL ? "$" : "") + " Right: " + rightStatus + (chargeR ? "+" : "") + (inEarR ? "$" : "") + " Case: " + caseStatus + (chargeCase ? "+" : "") + " Model: " + model);
OpenPodsDebugLog(isMax() ? String.format(Locale.getDefault(), "Battery: %d Model: %s", maxStatus, model) :
String.format(Locale.getDefault(), "Left: %d%s%s Right: %d%s%s Case: %d%s Model: %s",
leftStatus, chargeL ? "+" : "", inEarL ? "$" : "",
rightStatus, chargeR ? "+" : "", inEarR ? "$" : "",
caseStatus, chargeCase ? "+" : "", model)
);
if (model.equals(MODEL_AIRPODS_NORMAL)) for (RemoteViews notification : notificationArr) {
notification.setImageViewResource(R.id.leftPodImg, leftStatus <= 10 ? R.drawable.pod : R.drawable.pod_disconnected);
notification.setImageViewResource(R.id.rightPodImg, rightStatus <= 10 ? R.drawable.pod : R.drawable.pod_disconnected);
notification.setImageViewResource(R.id.podCaseImg, caseStatus <= 10 ? R.drawable.pod_case : R.drawable.pod_case_disconnected);
switch (model) {
case MODEL_AIRPODS_NORMAL:
for (RemoteViews notification : notificationArr) {
notification.setImageViewResource(R.id.leftPodImg, leftStatus <= 10 ? R.drawable.pod : R.drawable.pod_disconnected);
notification.setImageViewResource(R.id.rightPodImg, rightStatus <= 10 ? R.drawable.pod : R.drawable.pod_disconnected);
notification.setImageViewResource(R.id.podCaseImg, caseStatus <= 10 ? R.drawable.pod_case : R.drawable.pod_case_disconnected);
}
break;
case MODEL_AIRPODS_PRO:
for (RemoteViews notification : notificationArr) {
notification.setImageViewResource(R.id.leftPodImg, leftStatus <= 10 ? R.drawable.podpro : R.drawable.podpro_disconnected);
notification.setImageViewResource(R.id.rightPodImg, rightStatus <= 10 ? R.drawable.podpro : R.drawable.podpro_disconnected);
notification.setImageViewResource(R.id.podCaseImg, caseStatus <= 10 ? R.drawable.podpro_case : R.drawable.podpro_case_disconnected);
}
break;
case MODEL_AIRPODS_MAX:
for (RemoteViews notification : notificationArr)
notification.setImageViewResource(R.id.leftPodImg, maxStatus <= 10 ? R.drawable.podmax : R.drawable.podmax_disconnected);
}
else if (model.equals(MODEL_AIRPODS_PRO)) for (RemoteViews notification : notificationArr) {
notification.setImageViewResource(R.id.leftPodImg, leftStatus <= 10 ? R.drawable.podpro : R.drawable.podpro_disconnected);
notification.setImageViewResource(R.id.rightPodImg, rightStatus <= 10 ? R.drawable.podpro : R.drawable.podpro_disconnected);
notification.setImageViewResource(R.id.podCaseImg, caseStatus <= 10 ? R.drawable.podpro_case : R.drawable.podpro_case_disconnected);
for (RemoteViews notification : notificationArr) {
notification.setViewVisibility(R.id.rightPod, isMax() ? View.GONE : View.VISIBLE);
notification.setViewVisibility(R.id.podCase, isMax() ? View.GONE : View.VISIBLE);
}
if (System.currentTimeMillis() - lastSeenConnected < TIMEOUT_CONNECTED) for (RemoteViews notification : notificationArr) {
@@ -331,23 +350,19 @@ public class PodsService extends Service {
notification.setViewVisibility(R.id.rightPodUpdating, View.INVISIBLE);
notification.setViewVisibility(R.id.podCaseUpdating, View.INVISIBLE);
String podText_Left = (leftStatus == 10) ? "100%" : ((leftStatus < 10) ? ((leftStatus * 10 + 5) + "%") : "");
String podText_Right = (rightStatus == 10) ? "100%" : ((rightStatus < 10) ? ((rightStatus * 10 + 5) + "%") : "");
String podText_Case = (caseStatus == 10) ? "100%" : ((caseStatus < 10) ? ((caseStatus * 10 + 5) + "%") : "");
notification.setTextViewText(R.id.leftPodText, NotificationUtils.statusToString(isMax() ? maxStatus : leftStatus));
notification.setTextViewText(R.id.rightPodText, NotificationUtils.statusToString(rightStatus));
notification.setTextViewText(R.id.podCaseText, NotificationUtils.statusToString(caseStatus));
notification.setTextViewText(R.id.leftPodText, podText_Left);
notification.setTextViewText(R.id.rightPodText, podText_Right);
notification.setTextViewText(R.id.podCaseText, podText_Case);
notification.setImageViewResource(R.id.leftBatImg, NotificationUtils.batImgSrcId(chargeL));
notification.setImageViewResource(R.id.rightBatImg, NotificationUtils.batImgSrcId(chargeR));
notification.setImageViewResource(R.id.caseBatImg, NotificationUtils.batImgSrcId(chargeCase));
notification.setImageViewResource(R.id.leftBatImg, chargeL ? R.drawable.ic_battery_charging_full_green_24dp : R.drawable.ic_battery_alert_red_24dp);
notification.setImageViewResource(R.id.rightBatImg, chargeR ? R.drawable.ic_battery_charging_full_green_24dp : R.drawable.ic_battery_alert_red_24dp);
notification.setImageViewResource(R.id.caseBatImg, chargeCase ? R.drawable.ic_battery_charging_full_green_24dp : R.drawable.ic_battery_alert_red_24dp);
notification.setViewVisibility(R.id.leftBatImg, NotificationUtils.batImgVisibility(chargeL, leftStatus));
notification.setViewVisibility(R.id.rightBatImg, NotificationUtils.batImgVisibility(chargeR, rightStatus));
notification.setViewVisibility(R.id.caseBatImg, NotificationUtils.batImgVisibility(chargeCase, caseStatus));
notification.setViewVisibility(R.id.leftBatImg, ((chargeL && leftStatus <= 10) || (leftStatus <= 1) ? View.VISIBLE : View.GONE));
notification.setViewVisibility(R.id.rightBatImg, ((chargeR && rightStatus <= 10) || (rightStatus <= 1) ? View.VISIBLE : View.GONE));
notification.setViewVisibility(R.id.caseBatImg, ((chargeCase && caseStatus <= 10) || (caseStatus <= 1) ? View.VISIBLE : View.GONE));
notification.setViewVisibility(R.id.leftInEarImg, inEarL ? View.VISIBLE : View.INVISIBLE);
notification.setViewVisibility(R.id.leftInEarImg, inEarL && !isMax() ? View.VISIBLE : View.INVISIBLE);
notification.setViewVisibility(R.id.rightInEarImg, inEarR ? View.VISIBLE : View.INVISIBLE);
}
else for (RemoteViews notification : notificationArr) {
@@ -0,0 +1,23 @@
package com.dosse.airpods.utils;
import static com.dosse.airpods.utils.ScannerUtils.isMax;
import android.view.View;
import com.dosse.airpods.R;
public class NotificationUtils {
public static String statusToString (int status) {
return (status == 10) ? "100%" : ((status < 10) ? ((status * 10 + 5) + "%") : "");
}
public static int batImgSrcId (boolean charge) {
return charge ? R.drawable.ic_battery_charging_full_green_24dp : R.drawable.ic_battery_alert_red_24dp;
}
public static int batImgVisibility (boolean charge, int status) {
return ((charge && status <= 10 && !isMax()) || status <= 1) ? View.VISIBLE : View.GONE;
}
}
@@ -1,4 +1,4 @@
package com.dosse.airpods;
package com.dosse.airpods.utils;
import static androidx.core.content.ContextCompat.checkSelfPermission;
@@ -0,0 +1,30 @@
package com.dosse.airpods.utils;
import com.dosse.airpods.PodsService;
public class ScannerUtils {
/*
* Decodes the byte array to a hexadecimal string
*/
public static String decodeHex (byte[] bArr) {
StringBuilder ret = new StringBuilder();
for (byte b : bArr)
ret.append(String.format("%02X", b));
return ret.toString();
}
public static boolean isFlipped (String str) {
return (Integer.parseInt("" + str.charAt(10), 16) & 0x02) == 0;
}
/*
* Check if model is airpods max
*/
public static boolean isMax () {
return PodsService.model.equals(PodsService.MODEL_AIRPODS_MAX);
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 551 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 KiB

@@ -14,7 +14,7 @@
<string name="noBtText">Es sieht so aus, als hätte dieses Gerät kein Bluetooth LE</string>
<string name="locationDisabledText">Du musst Standortinformationen aktivieren, damit OpenPods den Status deiner AirPods auslesen kann</string>
<string name="supportedDevicesTitle"><u>Unterstützte Geräte:</u></string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1st gen\n&#8226; Apple AirPods 2nd gen\n&#8226; Apple AirPods Pro</string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1st gen\n&#8226; Apple AirPods 2nd gen\n&#8226; Apple AirPods Pro\n&#8226; Apple AirPods Max</string>
<string name="batterySaver">Stromsparmodus (nicht empfohlen)</string>
<string name="batterySaver_desc">Aktiviere diesen Modus, wenn Bluetooth zu viel Batterieleistung erfordert</string>
@@ -14,7 +14,7 @@
<string name="noBtText">Parece que éste dispositivo no tiene Bluetooth LE.</string>
<string name="locationDisabledText">Necesitas activar la Localización para permitir que OpenPods lea el estado.</string>
<string name="supportedDevicesTitle"><u>Dispositivos compatibles:</u></string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1ª generación\n&#8226; Apple AirPods 2ª generación\n&#8226; Apple AirPods Pro</string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1ª generación\n&#8226; Apple AirPods 2ª generación\n&#8226; Apple AirPods Pro\n&#8226; Apple AirPods Max</string>
<string name="batterySaver">Ahorro de energía (no recomendado)</string>
<string name="batterySaver_desc">Activa ésta opción si el Bluetooth consume mucha batería.</string>
@@ -14,7 +14,7 @@
<string name="noBtText">Il semble que cet appareil ne dispose pas de Bluetooth LE.</string>
<string name="locationDisabledText">Vous devez activer la localisation pour permettre aux OpenPod de lire l\'état de vos AirPods.</string>
<string name="supportedDevicesTitle"><u>Appareils pris en charge :</u></string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1re génération\n&#8226; Apple AirPods 2e génération\n&#8226; Apple AirPods Pro</string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1re génération\n&#8226; Apple AirPods 2e génération\n&#8226; Apple AirPods Pro\n&#8226; Apple AirPods Max</string>
<string name="batterySaver">Économiseur de batterie (non recommandé)</string>
<string name="batterySaver_desc">Activez cette option si Bluetooth utilise beaucoup de batterie</string>
@@ -15,7 +15,7 @@
<string name="noBtText">Questo dispositivo non supporta Bluetooth LE</string>
<string name="locationDisabledText">Attiva la posizione per permttere a OpenPods di leggere lo stato</string>
<string name="supportedDevicesTitle"><u>Dispositivi supportati:</u></string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1st gen\n&#8226; Apple AirPods 2nd gen\n&#8226; Apple AirPods Pro</string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1st gen\n&#8226; Apple AirPods 2nd gen\n&#8226; Apple AirPods Pro\n&#8226; Apple AirPods Max</string>
<string name="batterySaver">Risparmio batteria (sconsigliato)</string>
<string name="batterySaver_desc">Attiva se il Bluetooth usa molta batteria</string>
@@ -15,7 +15,7 @@
<string name="noBtText">נראה כי מכשיר זה אינו תומך ב-Bluetooth LE</string>
<string name="locationDisabledText">אתה צריך להפעיל שיתוף מיקום בכדי לאפשר ל-OpenPods לקרוא את סטטוס האוזניות</string>
<string name="supportedDevicesTitle"><u>מכשירים נתמכים</u></string>
<string name="supportedDevicesItems">&#8226; אפל איירפודס דור ראשון \n&#8226; אפל איירפודס דור שני \n&#8226; אפל איירפודס פרו </string>
<string name="supportedDevicesItems"> אפל איירפודס דור ראשון\n אפל איירפודס דור שני\n אפל איירפודס פרו\n• אפל איירפודס מקס</string>
<string name="batterySaver">חיסכון בסוללה (לא מומלץ)</string>
<string name="batterySaver_desc">הפעל אם Bluetooth משתמש בהרבה סוללה</string>
@@ -15,7 +15,7 @@
<string name="noBtText">이 장치에는 Bluetooth LE가 없는 것 같습니다.</string>
<string name="locationDisabledText">OpenPod에서 상태를 읽을 수 있도록 하려면 위치를 허용해야 합니다.</string>
<string name="supportedDevicesTitle"><u>지원하는 기기:</u></string>
<string name="supportedDevicesItems">&#8226; 애플 에어팟 1세대\n&#8226; 애플 에어팟 2세대\n&#8226; 애플 에어팟 프로</string>
<string name="supportedDevicesItems">&#8226; 애플 에어팟 1세대\n&#8226; 애플 에어팟 2세대\n&#8226; 애플 에어팟 프로\n&#8226; 애플 에어팟 최대</string>
<string name="batterySaver">배터리 관리모드 (추천하지 않음)</string>
<string name="batterySaver_desc">Bluetooth에서 배터리를 많이 사용하는 경우 이 옵션을 활성화하세요.</string>
@@ -14,7 +14,7 @@
<string name="noBtText">Het lijkt erop dat dit apparaat niet beschikt over Bluetooth LE</string>
<string name="locationDisabledText">Schakel je locatie in zodat OpenPods de status kan uitlezen</string>
<string name="supportedDevicesTitle"><u>Ondersteunde apparaten:</u></string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1e gen\n&#8226; Apple AirPods 2e gen\n&#8226; Apple AirPods Pro</string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1e gen\n&#8226; Apple AirPods 2e gen\n&#8226; Apple AirPods Pro\n&#8226; Apple AirPods Max</string>
<string name="batterySaver">Accu-optimalisatie (niet aanbevolen)</string>
<string name="batterySaver_desc">Schakel dit in als je merkt dat het accuverbruik hoger is door Bluetooth</string>
@@ -14,7 +14,7 @@
<string name="noBtText">Похоже, что Bluetooth LE не поддерживается на Вашем устройстве</string>
<string name="locationDisabledText">Вам нужно включить местоположение, чтобы разрешить OpenPods читать статус</string>
<string name="supportedDevicesTitle"><u>Поддерживаемые устройства:</u></string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1st gen\n&#8226; Apple AirPods 2nd gen\n&#8226; Apple AirPods Pro</string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1st gen\n&#8226; Apple AirPods 2nd gen\n&#8226; Apple AirPods Pro\n&#8226; Apple AirPods Max</string>
<string name="batterySaver">Режим энергосбережения (Не рекомендуется)</string>
<string name="batterySaver_desc">Включите, если Bluetooth использует слишком много ресурсов</string>
@@ -14,7 +14,7 @@
<string name="noBtText">Схоже, що цей пристрій не підтримує Bluetooth LE</string>
<string name="locationDisabledText">Вам потрібно ввімкнути місцезнаходження, для того, щоб дозволити OpenPods читати статус</string>
<string name="supportedDevicesTitle"><u>Supported devices:</u></string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1st gen\n&#8226; Apple AirPods 2nd gen\n&#8226; Apple AirPods Pro</string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1st gen\n&#8226; Apple AirPods 2nd gen\n&#8226; Apple AirPods Pro\n&#8226; Apple AirPods Max</string>
<string name="batterySaver">Режим збереження енергії (Не рекомендовано)</string>
<string name="batterySaver_desc">Увімкніть, якщо Bluetooth використовує багато ресурсів</string>
@@ -10,7 +10,7 @@
<string name="noBtText">看起来您的设备并不支持蓝牙</string>
<string name="locationDisabledText">您需要开启定位来让 OpenPods 读取状态</string>
<string name="supportedDevicesTitle"><u>支持的设备:</u></string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 一代\n&#8226; Apple AirPods 二代\n&#8226; Apple AirPods Pro</string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 一代\n&#8226; Apple AirPods 二代\n&#8226; Apple AirPods Pro\n&#8226; Apple AirPods Max</string>
<string name="batterySaver">省电模式 (不推荐)</string>
<string name="batterySaver_desc">可在蓝牙消耗过多电量时开启</string>
+1 -1
View File
@@ -29,7 +29,7 @@
<string name="noBtText">It looks like this device doesn\'t have Bluetooth LE</string>
<string name="locationDisabledText">You need to turn on Location to allow OpenPods to read the status</string>
<string name="supportedDevicesTitle"><u>Supported devices:</u></string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1st gen\n&#8226; Apple AirPods 2nd gen\n&#8226; Apple AirPods Pro</string>
<string name="supportedDevicesItems">&#8226; Apple AirPods 1st gen\n&#8226; Apple AirPods 2nd gen\n&#8226; Apple AirPods Pro\n&#8226; Apple AirPods Max</string>
<string name="batterySaver">Battery saver (Not recommended)</string>
<string name="batterySaver_desc">Enable this if Bluetooth uses a lot of battery</string>