Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
35a9d96398 | ||
|
|
298ce85990 | ||
|
|
18158d70b2 | ||
|
|
0f74a0607e | ||
|
|
3bd3ec74e7 | ||
|
|
5c39fb37f7 | ||
|
|
243a947110 | ||
|
|
e299e5e346 | ||
|
|
aaab15ee87 | ||
|
|
5fb7c3a39a | ||
|
|
6c65cb36f9 | ||
|
|
24963be8bd | ||
|
|
5a82530057 | ||
|
|
d6d8b3a586 | ||
|
|
ae4f6ea1af | ||
|
|
f771481a2d | ||
|
|
44580f2f2a | ||
|
|
c043ade2d9 |
|
Before Width: | Height: | Size: 59 KiB |
@@ -1,29 +0,0 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<Objective-C-extensions>
|
||||
<file>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
|
||||
</file>
|
||||
<class>
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
|
||||
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
|
||||
</class>
|
||||
<extensions>
|
||||
<pair source="cpp" header="h" fileNamingConvention="NONE" />
|
||||
<pair source="c" header="h" fileNamingConvention="NONE" />
|
||||
</extensions>
|
||||
</Objective-C-extensions>
|
||||
</code_scheme>
|
||||
</component>
|
||||
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
|
||||
</project>
|
||||
@@ -6,8 +6,8 @@ android {
|
||||
applicationId "com.dosse.airpods"
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 28
|
||||
versionCode 5
|
||||
versionName '0.5'
|
||||
versionCode 8
|
||||
versionName '0.8'
|
||||
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
|
||||
@@ -11,7 +11,10 @@ import android.bluetooth.BluetoothManager;
|
||||
import android.bluetooth.BluetoothProfile;
|
||||
import android.bluetooth.le.BluetoothLeScanner;
|
||||
import android.bluetooth.le.ScanCallback;
|
||||
import android.bluetooth.le.ScanFilter;
|
||||
import android.bluetooth.le.ScanFilter.Builder;
|
||||
import android.bluetooth.le.ScanResult;
|
||||
import android.bluetooth.le.ScanSettings;
|
||||
import android.content.BroadcastReceiver;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
@@ -21,13 +24,13 @@ import android.os.Build;
|
||||
import android.os.IBinder;
|
||||
import android.os.ParcelUuid;
|
||||
import android.os.SystemClock;
|
||||
import android.provider.Settings;
|
||||
import android.support.v4.app.NotificationCompat;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* This is the class that does most of the work. It has 3 functions:
|
||||
@@ -78,7 +81,20 @@ public class PodsService extends Service {
|
||||
btScanner = btAdapter.getBluetoothLeScanner();
|
||||
if (btAdapter == null) throw new Exception("No BT");
|
||||
if (!btAdapter.isEnabled()) throw new Exception("BT Off");
|
||||
btScanner.startScan(new ScanCallback() {
|
||||
|
||||
List<ScanFilter> filters = getScanFilters();
|
||||
ScanSettings settings = new ScanSettings.Builder().setScanMode(2).setReportDelay(2).build();
|
||||
|
||||
btScanner.startScan(
|
||||
filters,
|
||||
settings,
|
||||
new ScanCallback() {
|
||||
@Override
|
||||
public void onBatchScanResults(List<ScanResult> scanResults) {
|
||||
for (ScanResult result : scanResults) onScanResult(-1, result);
|
||||
super.onBatchScanResults(scanResults);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScanResult(int callbackType, ScanResult result) {
|
||||
try {
|
||||
@@ -128,6 +144,21 @@ public class PodsService extends Service {
|
||||
}
|
||||
}
|
||||
|
||||
private List<ScanFilter> getScanFilters() {
|
||||
byte[] manufacturerData = new byte[27];
|
||||
byte[] manufacturerDataMask = new byte[27];
|
||||
|
||||
manufacturerData[0] = 7;
|
||||
manufacturerData[1] = 25;
|
||||
|
||||
manufacturerDataMask[0] = -1;
|
||||
manufacturerDataMask[1] = -1;
|
||||
|
||||
Builder builder = new Builder();
|
||||
builder.setManufacturerData(76, manufacturerData, manufacturerDataMask);
|
||||
return Collections.singletonList(builder.build());
|
||||
}
|
||||
|
||||
private void stopAirPodsScanner(){
|
||||
try{
|
||||
if(btScanner!=null){
|
||||
@@ -203,9 +234,9 @@ public class PodsService extends Service {
|
||||
if(notificationShowing){
|
||||
if(ENABLE_LOGGING) Log.d(TAG,"Removing notification");
|
||||
notificationShowing=false;
|
||||
mNotifyManager.cancel(1);
|
||||
continue;
|
||||
}
|
||||
mNotifyManager.cancel(1);
|
||||
}
|
||||
if(isLocationEnabled()) {
|
||||
mBuilder.setCustomContentView(notificationSmall);
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:gravity="center"
|
||||
android:background="@color/white"
|
||||
>
|
||||
|
||||
|
||||
@@ -30,6 +31,7 @@
|
||||
android:gravity="center"
|
||||
android:text="100%+"
|
||||
android:id="@+id/leftPodText"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<ProgressBar
|
||||
@@ -65,6 +67,7 @@
|
||||
android:gravity="center"
|
||||
android:text="100%+"
|
||||
android:id="@+id/rightPodText"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<ProgressBar
|
||||
@@ -100,6 +103,7 @@
|
||||
android:gravity="center"
|
||||
android:text="100%+"
|
||||
android:id="@+id/podCaseText"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<ProgressBar
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
android:gravity="center"
|
||||
android:background="@color/white"
|
||||
>
|
||||
|
||||
<RelativeLayout
|
||||
@@ -29,6 +30,7 @@
|
||||
android:gravity="center_vertical"
|
||||
android:text="100%+"
|
||||
android:id="@+id/leftPodText"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<ProgressBar
|
||||
@@ -65,6 +67,7 @@
|
||||
android:gravity="center_vertical"
|
||||
android:text="100%+"
|
||||
android:id="@+id/rightPodText"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<ProgressBar
|
||||
@@ -101,6 +104,7 @@
|
||||
android:gravity="center_vertical"
|
||||
android:text="100%+"
|
||||
android:id="@+id/podCaseText"
|
||||
android:textColor="@color/black"
|
||||
/>
|
||||
|
||||
<ProgressBar
|
||||
|
||||
|
Before Width: | Height: | Size: 5.8 KiB After Width: | Height: | Size: 658 B |
|
Before Width: | Height: | Size: 5.5 KiB After Width: | Height: | Size: 341 B |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 684 B |
|
Before Width: | Height: | Size: 6.8 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 2.1 KiB |
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="intro1">Diese App erlaubt es dir, den Status deiner AirPods auf einem beliebigen Android-Gerät zu überprüfen</string>
|
||||
<string name="intro2">Um zu funktionieren, benötigen wir die Berechtigungen um Bluetooth LE (Standort) zu benutzen und im Hintergrund zu laufen</string>
|
||||
<string name="introAllow">Erlauben</string>
|
||||
<string name="main1">Die App zeigt eine Benachrichtigung wenn deine AirPods verbunden sind</string>
|
||||
<string name="main2">Du kannst die App jetzt verstecken wenn du möchtest</string>
|
||||
<string name="mainHide">App verstecken</string>
|
||||
<string name="hideClicked">Das Icon wird bald verschwinden</string>
|
||||
<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="supportedDevices">Unterstützte Geräte:\n• Apple AirPods 1st gen\n• Apple AirPods 2nd gen</string>
|
||||
</resources>
|
||||
@@ -8,6 +8,5 @@
|
||||
<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>
|
||||
<string name="supportedDevices">Dispositivos compatibles:\n• Apple AirPods 1st gen\n• Apple AirPods 2nd gen</string>
|
||||
</resources>
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
<string name="hideClicked">L\'icona sarà rimossa presto</string>
|
||||
<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="supportedDevices">Dispositivi supportati:\n• Apple AirPods 1st gen</string>
|
||||
<string name="supportedDevices">Dispositivi supportati:\n• Apple AirPods 1st gen\n• Apple AirPods 2nd gen</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="intro1">此应用可以让您在任何安卓设备上查看 AirPods 的状态</string>
|
||||
<string name="intro2">我们需要蓝牙、定位以及在后台运行的权限来正常运作</string>
|
||||
<string name="introAllow">允许</string>
|
||||
<string name="main1">当您的 AirPods 接入时,我们会在通知栏显示通知</string>
|
||||
<string name="main2">您可以隐藏此应用</string>
|
||||
<string name="mainHide">隐藏</string>
|
||||
<string name="hideClicked">桌面图标很快就会隐藏掉</string>
|
||||
<string name="noBtText">看起来您的设备并不支持蓝牙</string>
|
||||
<string name="locationDisabledText">您需要开启定位来让 OpenPods 读取状态</string>
|
||||
<string name="supportedDevices">支持的设备:\n• Apple AirPods 1st gen\n• Apple AirPods 2nd gen</string>
|
||||
</resources>
|
||||
@@ -3,5 +3,6 @@
|
||||
<color name="colorPrimary">#448aff</color>
|
||||
<color name="colorPrimaryDark">#0d47a1</color>
|
||||
<color name="colorAccent">#448aff</color>
|
||||
|
||||
<color name="white">#ffffff</color>
|
||||
<color name="black">#000000</color>
|
||||
</resources>
|
||||
|
||||
@@ -9,5 +9,5 @@
|
||||
<string name="hideClicked">The icon will disappear soon</string>
|
||||
<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="supportedDevices">Supported devices:\n• Apple AirPods 1st gen</string>
|
||||
<string name="supportedDevices">Supported devices:\n• Apple AirPods 1st gen\n• Apple AirPods 2nd gen</string>
|
||||
</resources>
|
||||
|
||||
@@ -7,7 +7,7 @@ buildscript {
|
||||
|
||||
}
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.3.2'
|
||||
classpath 'com.android.tools.build:gradle:3.4.0'
|
||||
|
||||
// NOTE: Do not place your application dependencies here; they belong
|
||||
// in the individual module build.gradle files
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
#Tue Mar 12 08:48:48 CET 2019
|
||||
#Tue May 14 16:46:59 CEST 2019
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-4.10.1-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||

|
||||

|
||||
|
||||
# OpenPods
|
||||
The Free and Open Source app for monitoring your AirPods on Android
|
||||
@@ -16,6 +16,7 @@ The project is currently in Alpha.
|
||||
|
||||
## Supported devices
|
||||
* Apple AirPods 1st gen
|
||||
* Apple AirPods 2nd gen
|
||||
|
||||
## Project status
|
||||
Right now, this project should be considered in alpha state. It was not extensively tested, it may not be stable or work at all on your device.
|
||||
@@ -26,10 +27,10 @@ Right now, this project should be considered in alpha state. It was not extensiv
|
||||
[Donate with PayPal](https://www.paypal.me/sineisochronic)
|
||||
|
||||
## Screenshots
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## License
|
||||
Copyright (C) 2019 Federico Dossena
|
||||
|
||||
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 815 KiB After Width: | Height: | Size: 815 KiB |
|
Before Width: | Height: | Size: 994 KiB After Width: | Height: | Size: 994 KiB |
|
Before Width: | Height: | Size: 60 KiB After Width: | Height: | Size: 60 KiB |
|
After Width: | Height: | Size: 63 KiB |