Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee7e75b5e8 | ||
|
|
b939674a62 | ||
|
|
ade3d0a481 | ||
|
|
70a05a1848 | ||
|
|
6803ef0691 | ||
|
|
71f08a4098 | ||
|
|
17afa55203 | ||
|
|
96ffaf1d90 | ||
|
|
047b9b373c | ||
|
|
feb2eac287 | ||
|
|
cd20f99747 | ||
|
|
535790aab1 | ||
|
|
d938817669 | ||
|
|
31cff2ac0c | ||
|
|
104dc3454b | ||
|
|
83b71cb488 | ||
|
|
97f7359057 | ||
|
|
ec67136d44 | ||
|
|
4f3f365e62 | ||
|
|
67a8a4cde9 | ||
|
|
b1a056a00b | ||
|
|
b6941b6686 | ||
|
|
84272fd7a5 | ||
|
|
6b7ddd4618 | ||
|
|
12bc363f45 | ||
|
|
cac56e641a | ||
|
|
cd416877f9 | ||
|
|
dfb76e7791 | ||
|
|
e47a1b0eee | ||
|
|
d4fea733b7 | ||
|
|
0479652a53 | ||
|
|
65c053002c | ||
|
|
73befc9e7b | ||
|
|
cd462fd2bb | ||
|
|
07047a97ec | ||
|
|
7e48ddd4c5 | ||
|
|
e66be09b4b |
@@ -1 +1,15 @@
|
|||||||
/_old_
|
# Android specific
|
||||||
|
local.properties
|
||||||
|
|
||||||
|
# Gradle
|
||||||
|
.cxx
|
||||||
|
.externalNativeBuild
|
||||||
|
.gradle
|
||||||
|
build
|
||||||
|
|
||||||
|
# IntelliJ IDEA
|
||||||
|
.idea
|
||||||
|
*.iml
|
||||||
|
|
||||||
|
# macOS
|
||||||
|
.DS_Store
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
*.iml
|
|
||||||
.gradle
|
|
||||||
/local.properties
|
|
||||||
/.idea/caches
|
|
||||||
/.idea/codeStyles
|
|
||||||
/.idea/dictionaries
|
|
||||||
/.idea/libraries
|
|
||||||
/.idea/gradle.xml
|
|
||||||
/.idea/misc.xml
|
|
||||||
/.idea/modules.xml
|
|
||||||
/.idea/workspace.xml
|
|
||||||
/.idea/navEditor.xml
|
|
||||||
/.idea/assetWizardSettings.xml
|
|
||||||
.DS_Store
|
|
||||||
/build
|
|
||||||
/captures
|
|
||||||
.externalNativeBuild
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="CompilerConfiguration">
|
|
||||||
<bytecodeTargetLevel target="11" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="Encoding" addBOMForNewFiles="with NO BOM" />
|
|
||||||
</project>
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
<component name="InspectionProjectProfileManager">
|
|
||||||
<profile version="1.0">
|
|
||||||
<option name="myName" value="Project Default" />
|
|
||||||
<inspection_tool class="HtmlUnknownAttribute" enabled="true" level="WARNING" enabled_by_default="true">
|
|
||||||
<option name="myValues">
|
|
||||||
<value>
|
|
||||||
<list size="3">
|
|
||||||
<item index="0" class="java.lang.String" itemvalue="data-wgscriptallow" />
|
|
||||||
<item index="1" class="java.lang.String" itemvalue="data-cbscriptallow" />
|
|
||||||
<item index="2" class="java.lang.String" itemvalue="data-acxscriptallow" />
|
|
||||||
</list>
|
|
||||||
</value>
|
|
||||||
</option>
|
|
||||||
<option name="myCustomValuesEnabled" value="true" />
|
|
||||||
</inspection_tool>
|
|
||||||
</profile>
|
|
||||||
</component>
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RemoteRepositoriesConfiguration">
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="central" />
|
|
||||||
<option name="name" value="Maven Central repository" />
|
|
||||||
<option name="url" value="https://repo1.maven.org/maven2" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="jboss.community" />
|
|
||||||
<option name="name" value="JBoss Community repository" />
|
|
||||||
<option name="url" value="https://repository.jboss.org/nexus/content/repositories/public/" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="BintrayJCenter" />
|
|
||||||
<option name="name" value="BintrayJCenter" />
|
|
||||||
<option name="url" value="https://jcenter.bintray.com/" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="Google" />
|
|
||||||
<option name="name" value="Google" />
|
|
||||||
<option name="url" value="https://dl.google.com/dl/android/maven2/" />
|
|
||||||
</remote-repository>
|
|
||||||
<remote-repository>
|
|
||||||
<option name="id" value="MavenRepo" />
|
|
||||||
<option name="name" value="MavenRepo" />
|
|
||||||
<option name="url" value="https://repo.maven.apache.org/maven2/" />
|
|
||||||
</remote-repository>
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="RenderSettings">
|
|
||||||
<option name="showDecorations" value="true" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -1,6 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<project version="4">
|
|
||||||
<component name="VcsDirectoryMappings">
|
|
||||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
|
||||||
</component>
|
|
||||||
</project>
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package com.dosse.airpods.pods.data;
|
|
||||||
|
|
||||||
public interface IPods {
|
|
||||||
|
|
||||||
String MODEL_AIRPODS_GEN1 = "airpods1";
|
|
||||||
String MODEL_AIRPODS_GEN2 = "airpods2";
|
|
||||||
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,16 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="120dp"
|
|
||||||
android:background="@color/bgColorPrimary"
|
|
||||||
android:gravity="center"
|
|
||||||
android:padding="@dimen/padding_default">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/locationDisabledText"
|
|
||||||
android:textColor="@color/textColorPrimary" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="70dp"
|
|
||||||
android:background="@color/bgColorPrimary"
|
|
||||||
android:gravity="center"
|
|
||||||
android:padding="@dimen/padding_default">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:gravity="center"
|
|
||||||
android:text="@string/locationDisabledText"
|
|
||||||
android:textColor="@color/textColorPrimary" />
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
||||||
@@ -1,23 +1,53 @@
|
|||||||

|
<p align="center"><img src="fastlane/metadata/android/en-US/images/icon.png" width="150"></p>
|
||||||
|
<h1 align="center"><b>OpenPods</b></h1>
|
||||||
|
<h4 align="center">The Free and Open Source app for monitoring your AirPods on Android</h4>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://github.com/adolfintel/OpenPods/releases">
|
||||||
|
<img src="https://img.shields.io/github/release/adolfintel/OpenPods.svg?color=blueviolet" alt="GitHub release">
|
||||||
|
</a>
|
||||||
|
<a href="https://www.gnu.org/licenses/gpl-3.0">
|
||||||
|
<img src="https://img.shields.io/badge/License-GPL%20v3-blue.svg" alt="License: GPLv3">
|
||||||
|
</a>
|
||||||
|
<img alt="Minimum SDK" src="https://img.shields.io/badge/API-23%2B-green">
|
||||||
|
</p>
|
||||||
|
<p align="center">
|
||||||
|
<a href="https://f-droid.org/packages/com.dosse.airpods">
|
||||||
|
<img src="assets/get-it-on-fdroid.png" alt="Get it on F-Droid" height="80">
|
||||||
|
</a>
|
||||||
|
<a href="https://downloads.fdossena.com/geth.php?r=openpods-apk">
|
||||||
|
<img src="assets/get-it-on-openpods.png" alt="Get it on OpenPods" height="80">
|
||||||
|
</a>
|
||||||
|
</p>
|
||||||
|
|
||||||
# OpenPods
|
## Screenshots
|
||||||
The Free and Open Source app for monitoring your AirPods on Android
|
|
||||||
|
|
||||||
## Download
|
|
||||||
<a href="https://f-droid.org/packages/com.dosse.airpods"><img src="https://fdroid.gitlab.io/artwork/badge/get-it-on.png" alt="Get it on F-Droid" height="80"></a>
|
|
||||||
|
|
||||||
[Download APK](https://downloads.fdossena.com/geth.php?r=openpods-apk)
|
|
||||||
|
|
||||||
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/screen1.png"
|
||||||
|
alt="Big notification"
|
||||||
|
width="200">](fastlane/metadata/android/en-US/images/phoneScreenshots/screen1.png)
|
||||||
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/screen2.png"
|
||||||
|
alt="Small notification"
|
||||||
|
width="200">](fastlane/metadata/android/en-US/images/phoneScreenshots/screen2.png)
|
||||||
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/screen3.png"
|
||||||
|
alt="Setup screen"
|
||||||
|
width="200">](fastlane/metadata/android/en-US/images/phoneScreenshots/screen3.png)
|
||||||
|
[<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/screen4.png"
|
||||||
|
alt="Home screen"
|
||||||
|
width="200">](fastlane/metadata/android/en-US/images/phoneScreenshots/screen4.png)
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
* Shows a notification with AirPods status when they are connected
|
* Shows a notification with AirPods status when they are connected
|
||||||
* Respects your privacy
|
* Respects your privacy
|
||||||
* Free and Open Source software
|
* Free and Open Source software
|
||||||
* Supports Dark Theme
|
* Supports Dark Theme
|
||||||
|
|
||||||
## Supported devices
|
## Supported devices
|
||||||
|
|
||||||
* Apple AirPods 1st gen
|
* Apple AirPods 1st gen
|
||||||
* Apple AirPods 2nd gen
|
* Apple AirPods 2nd gen
|
||||||
|
* Apple AirPods 3rd gen
|
||||||
* Apple AirPods Pro
|
* Apple AirPods Pro
|
||||||
|
* Apple AirPods Pro 2
|
||||||
* Apple AirPods Max
|
* Apple AirPods Max
|
||||||
* Beats X
|
* Beats X
|
||||||
* Beats Flex
|
* Beats Flex
|
||||||
@@ -33,13 +63,10 @@ Legal actions can and will be taken when uploading a compiled version to the Goo
|
|||||||
This paragraph was added due to multiple license violations found on the Google Play Store. If you're not sure whether you're allowed to distribute your modified version, please contact the developer.
|
This paragraph was added due to multiple license violations found on the Google Play Store. If you're not sure whether you're allowed to distribute your modified version, please contact the developer.
|
||||||
|
|
||||||
## Donate
|
## Donate
|
||||||
[Donate with PayPal](https://www.paypal.me/sineisochronic)
|
<a href="https://www.paypal.me/sineisochronic"><img src="assets/donate-with-paypal.png" alt="Donate with PayPal" height="80"></a>
|
||||||
|
|
||||||
## Screenshots
|
|
||||||
<img src="fastlane/metadata/android/en-US/images/phoneScreenshots/screen1.png" width="400"> <img src="fastlane/metadata/android/en-US/images/phoneScreenshots/screen2.png" width="400"> <img src="fastlane/metadata/android/en-US/images/phoneScreenshots/screen3.png" width="400"> <img src="fastlane/metadata/android/en-US/images/phoneScreenshots/screen4.png" width="400">
|
|
||||||
|
|
||||||
## License
|
## License
|
||||||
Copyright (C) 2021 Federico Dossena
|
[](https://www.gnu.org/licenses/gpl-3.0.en.html)
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
@@ -54,4 +81,9 @@ GNU General Public License for more details.
|
|||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (C) 2019-2022 Federico Dossena
|
||||||
|
|
||||||
AirPods is a trademark of Apple inc.
|
AirPods is a trademark of Apple inc.
|
||||||
|
|||||||
@@ -1,15 +1,17 @@
|
|||||||
apply plugin: 'com.android.application'
|
apply plugin: 'com.android.application'
|
||||||
|
|
||||||
android {
|
android {
|
||||||
compileSdkVersion 31
|
namespace 'com.dosse.airpods'
|
||||||
buildToolsVersion '30.0.3'
|
|
||||||
|
compileSdkVersion 33
|
||||||
|
buildToolsVersion '33.0.0'
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.dosse.airpods"
|
applicationId "com.dosse.airpods"
|
||||||
minSdkVersion 23
|
minSdkVersion 23
|
||||||
targetSdkVersion 31
|
targetSdkVersion 33
|
||||||
versionCode 18
|
versionCode 21
|
||||||
versionName '1.7'
|
versionName '1.9'
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
}
|
}
|
||||||
@@ -22,17 +24,19 @@ android {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
lintOptions {
|
|
||||||
abortOnError false
|
|
||||||
}
|
|
||||||
|
|
||||||
compileOptions {
|
compileOptions {
|
||||||
sourceCompatibility = 1.8
|
sourceCompatibility = 11
|
||||||
targetCompatibility = 1.8
|
targetCompatibility = 11
|
||||||
|
}
|
||||||
|
|
||||||
|
lint {
|
||||||
|
abortOnError false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
//noinspection GradleDependency 1.5.0/1.5.1 is broken
|
||||||
implementation "androidx.preference:preference:1.1.1"
|
implementation 'androidx.appcompat:appcompat:1.4.2'
|
||||||
|
implementation 'androidx.preference:preference:1.2.0'
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
{
|
||||||
|
"version": 3,
|
||||||
|
"artifactType": {
|
||||||
|
"type": "APK",
|
||||||
|
"kind": "Directory"
|
||||||
|
},
|
||||||
|
"applicationId": "com.dosse.airpods",
|
||||||
|
"variantName": "release",
|
||||||
|
"elements": [
|
||||||
|
{
|
||||||
|
"type": "SINGLE",
|
||||||
|
"filters": [],
|
||||||
|
"attributes": [],
|
||||||
|
"versionCode": 20,
|
||||||
|
"versionName": "1.8",
|
||||||
|
"outputFile": "app-release.apk"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"elementType": "File"
|
||||||
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<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_BACKGROUND_LOCATION" />
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_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" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||||
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
|
<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.FOREGROUND_SERVICE" />
|
||||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||||
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
<uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS" />
|
||||||
@@ -23,7 +26,8 @@
|
|||||||
android:icon="@mipmap/ic_launcher"
|
android:icon="@mipmap/ic_launcher"
|
||||||
android:label="@string/app_name"
|
android:label="@string/app_name"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme"
|
||||||
|
tools:ignore="DataExtractionRules">
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.MainActivity"
|
android:name=".ui.MainActivity"
|
||||||
@@ -47,13 +51,10 @@
|
|||||||
android:launchMode="singleTop"
|
android:launchMode="singleTop"
|
||||||
android:parentActivityName=".ui.MainActivity" />
|
android:parentActivityName=".ui.MainActivity" />
|
||||||
|
|
||||||
<activity
|
<activity android:name=".ui.NoBTActivity" />
|
||||||
android:name=".ui.NoBTActivity"
|
|
||||||
android:label="@string/app_name" />
|
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".ui.IntroActivity"
|
android:name=".ui.IntroActivity"
|
||||||
android:label="@string/app_name"
|
|
||||||
android:theme="@style/AppTheme.NoActionBar" />
|
android:theme="@style/AppTheme.NoActionBar" />
|
||||||
|
|
||||||
<receiver
|
<receiver
|
||||||
@@ -2,51 +2,38 @@ package com.dosse.airpods.notification;
|
|||||||
|
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.os.Build;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.widget.RemoteViews;
|
import android.widget.RemoteViews;
|
||||||
import androidx.core.app.NotificationCompat;
|
import androidx.core.app.NotificationCompat;
|
||||||
|
|
||||||
import com.dosse.airpods.R;
|
import com.dosse.airpods.R;
|
||||||
import com.dosse.airpods.pods.PodsStatus;
|
import com.dosse.airpods.pods.PodsStatus;
|
||||||
import com.dosse.airpods.pods.data.IPods;
|
import com.dosse.airpods.pods.models.IPods;
|
||||||
import com.dosse.airpods.pods.data.RegularPods;
|
import com.dosse.airpods.pods.models.RegularPods;
|
||||||
import com.dosse.airpods.pods.data.SinglePods;
|
import com.dosse.airpods.pods.models.SinglePods;
|
||||||
import com.dosse.airpods.utils.PermissionUtils;
|
|
||||||
|
|
||||||
public class NotificationBuilder {
|
public class NotificationBuilder {
|
||||||
public static final String TAG = "AirPods";
|
public static final String TAG = "AirPods";
|
||||||
public static final long TIMEOUT_CONNECTED = 30000;
|
public static final long TIMEOUT_CONNECTED = 30000;
|
||||||
public static final int NOTIFICATION_ID = 1;
|
public static final int NOTIFICATION_ID = 1;
|
||||||
|
|
||||||
private final RemoteViews[] notificationArr, notificationLocation;
|
private final RemoteViews[] notificationArr;
|
||||||
private final Context mContext;
|
|
||||||
private final NotificationCompat.Builder mBuilder;
|
private final NotificationCompat.Builder mBuilder;
|
||||||
|
|
||||||
public NotificationBuilder (Context context) {
|
public NotificationBuilder (Context context) {
|
||||||
mContext = context;
|
|
||||||
|
|
||||||
notificationArr = new RemoteViews[] {new RemoteViews(context.getPackageName(), R.layout.status_big), new RemoteViews(context.getPackageName(), R.layout.status_small)};
|
notificationArr = new RemoteViews[] {new RemoteViews(context.getPackageName(), R.layout.status_big), new RemoteViews(context.getPackageName(), R.layout.status_small)};
|
||||||
notificationLocation = new RemoteViews[] {new RemoteViews(context.getPackageName(), R.layout.location_disabled_big), new RemoteViews(context.getPackageName(), R.layout.location_disabled_small)};
|
|
||||||
|
|
||||||
mBuilder = new NotificationCompat.Builder(context, TAG);
|
mBuilder = new NotificationCompat.Builder(context, TAG);
|
||||||
mBuilder.setShowWhen(false);
|
mBuilder.setShowWhen(false);
|
||||||
mBuilder.setOngoing(true);
|
mBuilder.setOngoing(true);
|
||||||
mBuilder.setSmallIcon(R.mipmap.notification_icon);
|
mBuilder.setSmallIcon(R.mipmap.notification_icon);
|
||||||
mBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
mBuilder.setVisibility(NotificationCompat.VISIBILITY_PUBLIC);
|
||||||
|
mBuilder.setCustomContentView(notificationArr[1]);
|
||||||
|
mBuilder.setCustomBigContentView(notificationArr[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Notification build (PodsStatus status) {
|
public Notification build (PodsStatus status) {
|
||||||
|
|
||||||
// Apparently this restriction was removed ONLY in android Q
|
|
||||||
if (PermissionUtils.getLocationPermissions(mContext) || Build.VERSION.SDK_INT == Build.VERSION_CODES.Q) {
|
|
||||||
mBuilder.setCustomContentView(notificationArr[1]);
|
|
||||||
mBuilder.setCustomBigContentView(notificationArr[0]);
|
|
||||||
} else {
|
|
||||||
mBuilder.setCustomContentView(notificationLocation[1]);
|
|
||||||
mBuilder.setCustomBigContentView(notificationLocation[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
IPods airpods = status.getAirpods();
|
IPods airpods = status.getAirpods();
|
||||||
boolean single = airpods.isSingle();
|
boolean single = airpods.isSingle();
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package com.dosse.airpods.pods.data;
|
package com.dosse.airpods.pods;
|
||||||
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
|
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
package com.dosse.airpods.pods;
|
package com.dosse.airpods.pods;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
import android.app.Notification;
|
import android.app.Notification;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.NotificationManager;
|
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
|
* After decoding a beacon, the status is written to PodsStatus so that the NotificationThread can use the information
|
||||||
*/
|
*/
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
private void startAirPodsScanner () {
|
private void startAirPodsScanner () {
|
||||||
try {
|
try {
|
||||||
Logger.debug("START SCANNER");
|
Logger.debug("START SCANNER");
|
||||||
@@ -71,7 +73,6 @@ public class PodsService extends Service {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//if (batterySaver && btScanner != null && scanCallback != null) {
|
|
||||||
if (btScanner != null && scanCallback != null) {
|
if (btScanner != null && scanCallback != null) {
|
||||||
btScanner.stopScan(scanCallback);
|
btScanner.stopScan(scanCallback);
|
||||||
scanCallback = null;
|
scanCallback = null;
|
||||||
@@ -102,6 +103,7 @@ public class PodsService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
private void stopAirPodsScanner () {
|
private void stopAirPodsScanner () {
|
||||||
try {
|
try {
|
||||||
if (btScanner != null && scanCallback != null) {
|
if (btScanner != null && scanCallback != null) {
|
||||||
@@ -132,7 +134,7 @@ public class PodsService extends Service {
|
|||||||
public void onCreate () {
|
public void onCreate () {
|
||||||
super.onCreate();
|
super.onCreate();
|
||||||
|
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||||
startForeground(101, createBackgroundNotification());
|
startForeground(101, createBackgroundNotification());
|
||||||
|
|
||||||
unregisterBtReceiver();
|
unregisterBtReceiver();
|
||||||
@@ -233,6 +235,7 @@ public class PodsService extends Service {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
private static boolean checkUUID (BluetoothDevice bluetoothDevice) {
|
private static boolean checkUUID (BluetoothDevice bluetoothDevice) {
|
||||||
ParcelUuid[] AIRPODS_UUIDS = {
|
ParcelUuid[] AIRPODS_UUIDS = {
|
||||||
ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a"),
|
ParcelUuid.fromString("74ec2172-0bad-4d01-8f77-997b2be0722a"),
|
||||||
@@ -1,18 +1,19 @@
|
|||||||
package com.dosse.airpods.pods;
|
package com.dosse.airpods.pods;
|
||||||
|
|
||||||
import com.dosse.airpods.pods.data.AirPods1;
|
import com.dosse.airpods.pods.models.AirPods1;
|
||||||
import com.dosse.airpods.pods.data.AirPods2;
|
import com.dosse.airpods.pods.models.AirPods2;
|
||||||
import com.dosse.airpods.pods.data.AirPodsMax;
|
import com.dosse.airpods.pods.models.AirPods3;
|
||||||
import com.dosse.airpods.pods.data.AirPodsPro;
|
import com.dosse.airpods.pods.models.AirPodsMax;
|
||||||
import com.dosse.airpods.pods.data.BeatsFlex;
|
import com.dosse.airpods.pods.models.AirPodsPro;
|
||||||
import com.dosse.airpods.pods.data.BeatsSolo3;
|
import com.dosse.airpods.pods.models.AirPodsPro2;
|
||||||
import com.dosse.airpods.pods.data.BeatsStudio3;
|
import com.dosse.airpods.pods.models.BeatsFlex;
|
||||||
import com.dosse.airpods.pods.data.BeatsX;
|
import com.dosse.airpods.pods.models.BeatsSolo3;
|
||||||
import com.dosse.airpods.pods.data.IPods;
|
import com.dosse.airpods.pods.models.BeatsStudio3;
|
||||||
import com.dosse.airpods.pods.data.Pod;
|
import com.dosse.airpods.pods.models.BeatsX;
|
||||||
import com.dosse.airpods.pods.data.Powerbeats3;
|
import com.dosse.airpods.pods.models.IPods;
|
||||||
import com.dosse.airpods.pods.data.PowerbeatsPro;
|
import com.dosse.airpods.pods.models.Powerbeats3;
|
||||||
import com.dosse.airpods.pods.data.RegularPods;
|
import com.dosse.airpods.pods.models.PowerbeatsPro;
|
||||||
|
import com.dosse.airpods.pods.models.RegularPods;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decoding the beacon:
|
* Decoding the beacon:
|
||||||
@@ -68,29 +69,36 @@ public class PodsStatus {
|
|||||||
Pod casePod = new Pod(caseStatus, chargeCase, false);
|
Pod casePod = new Pod(caseStatus, chargeCase, false);
|
||||||
Pod singlePod = new Pod(singleStatus, chargeSingle, false);
|
Pod singlePod = new Pod(singleStatus, chargeSingle, false);
|
||||||
|
|
||||||
|
char idSingle = status.charAt(7); // We don't know the full ID for all devices
|
||||||
|
String idFull = status.substring(6, 10);
|
||||||
|
|
||||||
// Detect which model
|
// Detect which model
|
||||||
switch (status.charAt(7)) {
|
if ("0220".equals(idFull)) {
|
||||||
case '2': pods = new AirPods1(leftPod, rightPod, casePod); // Airpods 1st gen
|
pods = new AirPods1(leftPod, rightPod, casePod); // Airpods 1st gen
|
||||||
break;
|
} else if ("0F20".equals(idFull)) {
|
||||||
case 'F': pods = new AirPods2(leftPod, rightPod, casePod); // Airpods 2nd gen
|
pods = new AirPods2(leftPod, rightPod, casePod); // Airpods 2nd gen
|
||||||
break;
|
} else if ("1320".equals(idFull)) {
|
||||||
case 'E': pods = new AirPodsPro(leftPod, rightPod, casePod); // Airpods Pro
|
pods = new AirPods3(leftPod, rightPod, casePod); // Airpods 3rd gen
|
||||||
break;
|
} else if ("0E20".equals(idFull)) {
|
||||||
case 'A': pods = new AirPodsMax(singlePod); // Airpods Max
|
pods = new AirPodsPro(leftPod, rightPod, casePod); // Airpods Pro
|
||||||
break;
|
} else if ("1420".equals(idFull)) {
|
||||||
case 'B': pods = new PowerbeatsPro(leftPod, rightPod, casePod); // Powerbeats Pro
|
pods = new AirPodsPro2(leftPod, rightPod, casePod); // Airpods Pro 2
|
||||||
break;
|
} else if ('A' == idSingle) {
|
||||||
case '5': pods = new BeatsX(singlePod); // Beats X
|
pods = new AirPodsMax(singlePod); // Airpods Max
|
||||||
break;
|
} else if ('B' == idSingle) {
|
||||||
case '0': pods = new BeatsFlex(singlePod); // Beats Flex
|
pods = new PowerbeatsPro(leftPod, rightPod, casePod); // Powerbeats Pro
|
||||||
break;
|
} else if ("0520".equals(idFull)) {
|
||||||
case '6': pods = new BeatsSolo3(singlePod); // Beats Solo 3
|
pods = new BeatsX(singlePod); // Beats X
|
||||||
break;
|
} else if ("1020".equals(idFull)) {
|
||||||
case '9': pods = new BeatsStudio3(singlePod); // Beats Studio 3
|
pods = new BeatsFlex(singlePod); // Beats Flex
|
||||||
break;
|
} else if ("0620".equals(idFull)) {
|
||||||
case '3': pods = new Powerbeats3(singlePod); // Powerbeats 3
|
pods = new BeatsSolo3(singlePod); // Beats Solo 3
|
||||||
break;
|
} else if ('9' == idSingle) {
|
||||||
default: pods = new RegularPods(leftPod, rightPod, casePod); // Unknown
|
pods = new BeatsStudio3(singlePod); // Beats Studio 3
|
||||||
|
} else if ("0320".equals(idFull)) {
|
||||||
|
pods = new Powerbeats3(singlePod); // Powerbeats 3
|
||||||
|
} else {
|
||||||
|
pods = new RegularPods(leftPod, rightPod, casePod); // Unknown
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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 {
|
public class AirPods1 extends RegularPods {
|
||||||
|
|
||||||
@@ -8,7 +10,7 @@ public class AirPods1 extends RegularPods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
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 {
|
public class AirPods2 extends RegularPods {
|
||||||
|
|
||||||
@@ -8,7 +10,7 @@ public class AirPods2 extends RegularPods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
public String getModel () {
|
||||||
return MODEL_AIRPODS_GEN2;
|
return Constants.MODEL_AIRPODS_GEN2;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
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 () {
|
||||||
|
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.R;
|
||||||
|
import com.dosse.airpods.pods.Pod;
|
||||||
|
|
||||||
public class AirPodsMax extends SinglePods {
|
public class AirPodsMax extends SinglePods {
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ public class AirPodsMax extends SinglePods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
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.R;
|
||||||
|
import com.dosse.airpods.pods.Pod;
|
||||||
|
|
||||||
public class AirPodsPro extends RegularPods {
|
public class AirPodsPro extends RegularPods {
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ public class AirPodsPro extends RegularPods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
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.R;
|
||||||
|
import com.dosse.airpods.pods.Pod;
|
||||||
|
|
||||||
public class BeatsFlex extends SinglePods {
|
public class BeatsFlex extends SinglePods {
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ public class BeatsFlex extends SinglePods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
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.R;
|
||||||
|
import com.dosse.airpods.pods.Pod;
|
||||||
|
|
||||||
public class BeatsSolo3 extends SinglePods {
|
public class BeatsSolo3 extends SinglePods {
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ public class BeatsSolo3 extends SinglePods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
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.R;
|
||||||
|
import com.dosse.airpods.pods.Pod;
|
||||||
|
|
||||||
public class BeatsStudio3 extends SinglePods {
|
public class BeatsStudio3 extends SinglePods {
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ public class BeatsStudio3 extends SinglePods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
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.R;
|
||||||
|
import com.dosse.airpods.pods.Pod;
|
||||||
|
|
||||||
public class BeatsX extends SinglePods {
|
public class BeatsX extends SinglePods {
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ public class BeatsX extends SinglePods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
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.R;
|
||||||
|
import com.dosse.airpods.pods.Pod;
|
||||||
|
|
||||||
public class Powerbeats3 extends SinglePods {
|
public class Powerbeats3 extends SinglePods {
|
||||||
|
|
||||||
@@ -15,7 +16,7 @@ public class Powerbeats3 extends SinglePods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
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.R;
|
||||||
|
import com.dosse.airpods.pods.Pod;
|
||||||
|
|
||||||
public class PowerbeatsPro extends RegularPods {
|
public class PowerbeatsPro extends RegularPods {
|
||||||
|
|
||||||
@@ -25,7 +26,7 @@ public class PowerbeatsPro extends RegularPods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
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.R;
|
||||||
|
import com.dosse.airpods.pods.Pod;
|
||||||
|
|
||||||
import java.util.Locale;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -48,7 +49,7 @@ public class RegularPods implements IPods {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getModel () {
|
public String getModel () {
|
||||||
return MODEL_UNKNOWN;
|
return Constants.MODEL_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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;
|
import java.util.Locale;
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ public class StartupReceiver extends BroadcastReceiver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static void startPodsService (Context context) {
|
public static void startPodsService (Context context) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||||
context.startForegroundService(new Intent(context, PodsService.class));
|
context.startForegroundService(new Intent(context, PodsService.class));
|
||||||
else
|
else
|
||||||
context.startService(new Intent(context, PodsService.class));
|
context.startService(new Intent(context, PodsService.class));
|
||||||
@@ -72,7 +72,7 @@ public class IntroActivity extends AppCompatActivity {
|
|||||||
return STEP_PERMISSION_BATTERY_OPTIMIZATION;
|
return STEP_PERMISSION_BATTERY_OPTIMIZATION;
|
||||||
if (!PermissionUtils.getFineLocationPermission(this))
|
if (!PermissionUtils.getFineLocationPermission(this))
|
||||||
return STEP_PERMISSION_LOCATION;
|
return STEP_PERMISSION_LOCATION;
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) if (!PermissionUtils.getBackgroundLocationPermission(this))
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) if (!PermissionUtils.getBackgroundLocationPermission(this))
|
||||||
return STEP_PERMISSION_BACKGROUND_LOCATION;
|
return STEP_PERMISSION_BACKGROUND_LOCATION;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -81,7 +81,7 @@ public class IntroActivity extends AppCompatActivity {
|
|||||||
@SuppressLint("BatteryLife")
|
@SuppressLint("BatteryLife")
|
||||||
private void initScreen () {
|
private void initScreen () {
|
||||||
int currentStep = getPermissionState() - ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ? 0 : 1);
|
int currentStep = getPermissionState() - ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ? 0 : 1);
|
||||||
int numOfSteps = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) ? ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ? 4 : 3) : 2;
|
int numOfSteps = (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) ? ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) ? 4 : 3) : 2;
|
||||||
|
|
||||||
runOnUiThread(() -> {
|
runOnUiThread(() -> {
|
||||||
switch (getPermissionState()) {
|
switch (getPermissionState()) {
|
||||||
@@ -109,7 +109,7 @@ public class IntroActivity extends AppCompatActivity {
|
|||||||
case STEP_PERMISSION_BACKGROUND_LOCATION:
|
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)));
|
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 -> {
|
btn.setOnClickListener(view -> {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) requestPermissions(new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_REQUEST_CODE);
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) requestPermissions(new String[] {Manifest.permission.ACCESS_BACKGROUND_LOCATION}, BACKGROUND_LOCATION_REQUEST_CODE);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ public class PermissionUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static boolean getLocationPermissions (Context context) {
|
public static boolean getLocationPermissions (Context context) {
|
||||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||||
return getFineLocationPermission(context) && getBackgroundLocationPermission(context);
|
return getFineLocationPermission(context) && getBackgroundLocationPermission(context);
|
||||||
else
|
else
|
||||||
return getFineLocationPermission(context);
|
return getFineLocationPermission(context);
|
||||||
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 151 KiB After Width: | Height: | Size: 151 KiB |
|
Before Width: | Height: | Size: 150 KiB After Width: | Height: | Size: 150 KiB |
|
Before Width: | Height: | Size: 143 KiB After Width: | Height: | Size: 143 KiB |
|
Before Width: | Height: | Size: 142 KiB After Width: | Height: | Size: 142 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 92 KiB After Width: | Height: | Size: 92 KiB |
|
Before Width: | Height: | Size: 111 KiB After Width: | Height: | Size: 111 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 551 KiB After Width: | Height: | Size: 551 KiB |
|
Before Width: | Height: | Size: 543 KiB After Width: | Height: | Size: 543 KiB |
|
Before Width: | Height: | Size: 29 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 21 KiB After Width: | Height: | Size: 21 KiB |
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 18 KiB |
|
Before Width: | Height: | Size: 40 KiB After Width: | Height: | Size: 40 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 161 KiB |
|
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
|
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
|
Before Width: | Height: | Size: 161 KiB After Width: | Height: | Size: 161 KiB |
@@ -52,6 +52,11 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/airpods1" />
|
android:text="@string/airpods1" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/airpods3" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -89,6 +94,11 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/airpodsmax" />
|
android:text="@string/airpodsmax" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/airpodspro2" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
@@ -45,11 +45,21 @@
|
|||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/airpods2" />
|
android:text="@string/airpods2" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/airpods3" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="@string/airpodspro" />
|
android:text="@string/airpodspro" />
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:text="@string/airpodspro2" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
|
Before Width: | Height: | Size: 658 B After Width: | Height: | Size: 658 B |
|
Before Width: | Height: | Size: 12 KiB After Width: | Height: | Size: 12 KiB |
|
Before Width: | Height: | Size: 341 B After Width: | Height: | Size: 341 B |
|
Before Width: | Height: | Size: 15 KiB After Width: | Height: | Size: 15 KiB |