Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
613f116b28 | ||
|
|
f06206f125 | ||
|
|
f421e0febf | ||
|
|
34be06663d | ||
|
|
09af4a76e1 | ||
|
|
e233938851 | ||
|
|
4ff0535a4e | ||
|
|
7edc1a01ef | ||
|
|
05451b5e88 | ||
|
|
d4459ea3a3 | ||
|
|
8262db31d8 | ||
|
|
9e6ef70fab |
@@ -6,8 +6,8 @@ android {
|
||||
applicationId "com.dosse.airpods"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 28
|
||||
versionCode 3
|
||||
versionName '0.3'
|
||||
versionCode 4
|
||||
versionName '0.4'
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
|
||||
@@ -45,7 +45,6 @@
|
||||
<activity android:name=".MainActivity">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.dosse.airpods;
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.Service;
|
||||
@@ -52,6 +53,7 @@ public class PodsService extends Service {
|
||||
* What we did to workaround this issue is this:
|
||||
* - When a beacon arrives that looks like a pair of AirPods, look at the other beacons received in the last 10 seconds and get the strongest one
|
||||
* - If the strongest beacon's fake address is the same as this, use this beacon; otherwise use the strongest beacon
|
||||
* - Filter for signals stronger than -70db
|
||||
* - Decode...
|
||||
*
|
||||
* Decoding the beacon:
|
||||
@@ -91,6 +93,7 @@ public class PodsService extends Service {
|
||||
}
|
||||
if(strongestBeacon!=null&&strongestBeacon.getDevice().getAddress().equals(result.getDevice().getAddress())) strongestBeacon=result;
|
||||
result=strongestBeacon;
|
||||
if(result.getRssi()<-70) return;
|
||||
String a=decodeHex(result.getScanRecord().getManufacturerSpecificData(76));
|
||||
String str = ""; //left airpod (0-10 batt; 15=disconnected)
|
||||
String str2 = ""; //right airpod (0-10 batt; 15=disconnected)
|
||||
@@ -179,13 +182,14 @@ public class PodsService extends Service {
|
||||
channel.enableVibration(false);
|
||||
channel.enableLights(false);
|
||||
channel.setShowBadge(true);
|
||||
channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
|
||||
mNotifyManager.createNotificationChannel(channel);
|
||||
}
|
||||
mBuilder.setShowWhen(false);
|
||||
mBuilder.setOngoing(true);
|
||||
mBuilder.setSmallIcon(R.drawable.left_pod);
|
||||
mBuilder.setSmallIcon(R.mipmap.notification_icon);
|
||||
for(;;){
|
||||
if(maybeConnected &&!(leftStatus==15&&rightStatus==15&&caseStatus==15)){
|
||||
if(maybeConnected &&!(leftStatus==15&&rightStatus==15&&caseStatus==15)/*&&System.currentTimeMillis()-lastSeenConnected<TIMEOUT_CONNECTED*/){
|
||||
if(!notificationShowing){
|
||||
if(ENABLE_LOGGING) Log.d(TAG,"Creating notification");
|
||||
notificationShowing=true;
|
||||
@@ -196,6 +200,7 @@ public class PodsService extends Service {
|
||||
if(ENABLE_LOGGING) Log.d(TAG,"Removing notification");
|
||||
notificationShowing=false;
|
||||
mNotifyManager.cancel(1);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if(isLocationEnabled()) {
|
||||
@@ -223,12 +228,12 @@ public class PodsService extends Service {
|
||||
notificationSmall.setViewVisibility(R.id.leftPodUpdating, View.INVISIBLE);
|
||||
notificationSmall.setViewVisibility(R.id.rightPodUpdating, View.INVISIBLE);
|
||||
notificationSmall.setViewVisibility(R.id.podCaseUpdating, View.INVISIBLE);
|
||||
notificationBig.setTextViewText(R.id.leftPodText, (leftStatus <= 10 ? (leftStatus * 10) + "%" : "") + ((chargeL && leftStatus < 10) ? "+" : ""));
|
||||
notificationBig.setTextViewText(R.id.rightPodText, (rightStatus <= 10 ? (rightStatus * 10) + "%" : "") + ((chargeR && rightStatus < 10) ? "+" : ""));
|
||||
notificationBig.setTextViewText(R.id.podCaseText, (caseStatus <= 10 ? (caseStatus * 10) + "%" : "") + (chargeCase ? "+" : ""));
|
||||
notificationSmall.setTextViewText(R.id.leftPodText, (leftStatus <= 10 ? (leftStatus * 10) + "%" : "") + (chargeL ? "+" : ""));
|
||||
notificationSmall.setTextViewText(R.id.rightPodText, (rightStatus <= 10 ? (rightStatus * 10) + "%" : "") + (chargeR ? "+" : ""));
|
||||
notificationSmall.setTextViewText(R.id.podCaseText, (caseStatus <= 10 ? (caseStatus * 10) + "%" : "") + (chargeCase ? "+" : ""));
|
||||
notificationBig.setTextViewText(R.id.leftPodText, (leftStatus==10?"100%":leftStatus<10?((leftStatus+1)*10+"%"):"") + ((chargeL && leftStatus < 10) ? "+" : ""));
|
||||
notificationBig.setTextViewText(R.id.rightPodText, (rightStatus==10?"100%":rightStatus<10?((rightStatus+1)*10+"%"):"") + ((chargeR && rightStatus < 10) ? "+" : ""));
|
||||
notificationBig.setTextViewText(R.id.podCaseText, (caseStatus==10?"100%":caseStatus<10?((caseStatus+1)*10+"%"):"") + ((chargeCase && caseStatus < 10) ? "+" : ""));
|
||||
notificationSmall.setTextViewText(R.id.leftPodText, (leftStatus==10?"100%":leftStatus<10?((leftStatus+1)*10+"%"):"") + ((chargeL && leftStatus < 10) ? "+" : ""));
|
||||
notificationSmall.setTextViewText(R.id.rightPodText, (rightStatus==10?"100%":rightStatus<10?((rightStatus+1)*10+"%"):"") + ((chargeR && rightStatus < 10) ? "+" : ""));
|
||||
notificationSmall.setTextViewText(R.id.podCaseText, (caseStatus==10?"100%":caseStatus<10?((caseStatus+1)*10+"%"):"") + ((chargeCase && caseStatus < 10) ? "+" : ""));
|
||||
}else{
|
||||
notificationBig.setViewVisibility(R.id.leftPodText, View.INVISIBLE);
|
||||
notificationBig.setViewVisibility(R.id.rightPodText, View.INVISIBLE);
|
||||
@@ -288,7 +293,7 @@ public class PodsService extends Service {
|
||||
String action = intent.getAction();
|
||||
if(action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)){
|
||||
int state= intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR);
|
||||
if(state==BluetoothAdapter.STATE_OFF){ //bluetooth turned off, stop scanner and remove notification
|
||||
if(state==BluetoothAdapter.STATE_OFF||state==BluetoothAdapter.STATE_TURNING_OFF){ //bluetooth turned off, stop scanner and remove notification
|
||||
maybeConnected =false;
|
||||
stopAirPodsScanner();
|
||||
recentBeacons.clear();
|
||||
@@ -298,11 +303,11 @@ public class PodsService extends Service {
|
||||
}
|
||||
}
|
||||
if (bluetoothDevice != null && action != null && !action.isEmpty()&&checkUUID(bluetoothDevice)){ //airpods filter
|
||||
if(action.equals("android.bluetooth.device.action.ACL_CONNECTED")){ //airpods connected, show notification
|
||||
if(action.equals(BluetoothDevice.ACTION_ACL_CONNECTED)){ //airpods connected, show notification
|
||||
if(ENABLE_LOGGING) Log.d(TAG,"ACL CONNECTED");
|
||||
maybeConnected =true;
|
||||
}
|
||||
if(action.equals("android.bluetooth.device.action.ACL_DISCONNECTED")){ //airpods disconnected, remove notification but leave the scanner going
|
||||
if(action.equals(BluetoothDevice.ACTION_ACL_DISCONNECTED)||action.equals(BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED)){ //airpods disconnected, remove notification but leave the scanner going
|
||||
if(ENABLE_LOGGING) Log.d(TAG,"ACL DISCONNECTED");
|
||||
maybeConnected =false;
|
||||
recentBeacons.clear();
|
||||
|
||||
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 12 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 20 KiB |
|
After Width: | Height: | Size: 6.8 KiB |
|
After Width: | Height: | Size: 24 KiB |
|
After Width: | Height: | Size: 7.1 KiB |
@@ -0,0 +1,13 @@
|
||||
<resources>
|
||||
<string name="intro1">Esta aplicación te permite ver el estado de tus AirPods en cualquier dispositivo Android</string>
|
||||
<string name="intro2">Para operar, necesitamos permiso para usar Bluetooth LE (Localización) y permiso para ejecutarnos en el fondo</string>
|
||||
<string name="introAllow">Permitir</string>
|
||||
<string name="main1">Esta aplicación mostrará una notificación cuando tus AirPods estén conectados</string>
|
||||
<string name="main2">Puedes ocultar la app si gustas</string>
|
||||
<string name="mainHide">Ocultar app</string>
|
||||
<string name="hideClicked">El ícono desaparecerá pronto</string>
|
||||
<string name="noBtText">Parece que este dispositivo no tiene Bluetooth LE</string>
|
||||
<string name="locationDisabledText">Necesitas encender Localización para permitir que OpenPods lea el estado</string>
|
||||
<string name="supportedDevices">Dispositivos compatibles:\n
|
||||
• Apple AirPods 1st gen</string>
|
||||
</resources>
|
||||
@@ -6,9 +6,9 @@ The Free and Open Source app for monitoring your AirPods on Android
|
||||
## Download
|
||||
The project is currently in Alpha.
|
||||
|
||||
[Download from F-Droid](https://f-droid.org/repository/browse/?fdid=com.dosse.airpods)
|
||||
[Download APK](https://downloads.fdossena.com/geth.php?r=openpods-apk)
|
||||
|
||||
|
||||
## Features
|
||||
* Shows a notification with AirPods status when they are connected
|
||||
* Respects your privacy
|
||||
|
||||