├── .circleci └── config.yml ├── .gitignore ├── .idea ├── codeStyles │ └── Project.xml ├── compiler.xml ├── copyright │ ├── Apache.xml │ └── profiles_settings.xml ├── encodings.xml ├── gradle.xml ├── misc.xml ├── modules.xml ├── runConfigurations.xml └── vcs.xml ├── LICENSE-2.0.html ├── Readme.md ├── apkdetails.sh ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ └── main │ ├── AndroidManifest.xml │ ├── assets │ └── licenses.html │ ├── java │ └── uk │ │ └── co │ │ └── alt236 │ │ └── floatinginfo │ │ ├── data │ │ └── access │ │ │ ├── BaseProvider.java │ │ │ └── generalinfo │ │ │ ├── GeneralInfoProvider.java │ │ │ ├── GeneralInfoReceiver.kt │ │ │ ├── PrefsChangeListener.kt │ │ │ ├── SystemWindowLayoutParamsFactory.kt │ │ │ └── monitortask │ │ │ ├── InnerTask.kt │ │ │ ├── ProcessMonitor.kt │ │ │ └── Update.kt │ │ ├── notifications │ │ ├── NotificationChannelFactory.java │ │ └── NotificationControl.java │ │ ├── permissions │ │ ├── AndroidPermissionChecker.java │ │ ├── OverlayPermissionChecker.java │ │ ├── PermissionChecker.java │ │ ├── PermissionCheckerWrapper.java │ │ └── UsageStatsPermissionChecker.java │ │ ├── service │ │ ├── FloatingInfoService.java │ │ └── ScreenStateListener.java │ │ ├── ui │ │ ├── activity │ │ │ ├── base │ │ │ │ ├── AppCompatPreferenceActivity.java │ │ │ │ ├── TabletAwarePreferenceActivity.java │ │ │ │ └── ValidFragments.java │ │ │ ├── main │ │ │ │ ├── AppearancePreferenceFragment.java │ │ │ │ ├── EnabledInfoPreferenceFragment.java │ │ │ │ ├── InfoPreferenceFragment.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── PrefsUtils.java │ │ │ │ └── dialogs │ │ │ │ │ ├── AboutDialog.java │ │ │ │ │ └── OpenSourceLicensesDialog.java │ │ │ ├── onboarding │ │ │ │ ├── OnBoardingActivity.java │ │ │ │ └── pagefactory │ │ │ │ │ ├── OverlayPermsissionPage.java │ │ │ │ │ ├── PageFactory.java │ │ │ │ │ └── UsageStatsPage.java │ │ │ └── share │ │ │ │ └── ShareActivity.kt │ │ └── views │ │ │ └── SeekBarPreference.java │ │ └── util │ │ ├── Constants.java │ │ └── ExecTerminal.java │ └── res │ ├── drawable-hdpi │ ├── ic_stat_clear.png │ ├── ic_stat_main.png │ ├── ic_stat_pause.png │ ├── ic_stat_play.png │ └── ic_stat_share.png │ ├── drawable-mdpi │ ├── ic_stat_clear.png │ ├── ic_stat_main.png │ ├── ic_stat_pause.png │ ├── ic_stat_play.png │ └── ic_stat_share.png │ ├── drawable-xhdpi │ ├── ic_stat_clear.png │ ├── ic_stat_main.png │ ├── ic_stat_pause.png │ ├── ic_stat_play.png │ └── ic_stat_share.png │ ├── drawable-xxhdpi │ ├── ic_stat_clear.png │ ├── ic_stat_main.png │ ├── ic_stat_pause.png │ ├── ic_stat_play.png │ └── ic_stat_share.png │ ├── drawable-xxxhdpi │ └── ic_stat_main.png │ ├── layout-land │ └── fragment_onboard_slide.xml │ ├── layout │ ├── activity_main.xml │ ├── dialog_about.xml │ ├── fragment_onboard_slide.xml │ ├── preference_widget_seekbar.xml │ └── toolbar.xml │ ├── mipmap-hdpi │ └── ic_launcher.png │ ├── mipmap-mdpi │ └── ic_launcher.png │ ├── mipmap-xhdpi │ └── ic_launcher.png │ ├── mipmap-xxhdpi │ └── ic_launcher.png │ ├── mipmap-xxxhdpi │ └── ic_launcher.png │ ├── values-v21 │ └── styles.xml │ ├── values-w820dp │ └── dimens.xml │ ├── values │ ├── attrs.xml │ ├── colors.xml │ ├── dimens.xml │ ├── strings.xml │ ├── styles.xml │ └── stylesBase.xml │ └── xml │ ├── pref_appearance.xml │ ├── pref_blank.xml │ ├── pref_enabled_info.xml │ ├── pref_headers.xml │ └── pref_info.xml ├── assets ├── Floating Info-feature-graphic.png ├── icons │ ├── duck-attribution.txt │ ├── duck-silhouette.svg │ ├── ic_launcher.svg │ └── web_icon.png └── screenshots │ ├── image1.png │ ├── image2.png │ ├── image3.png │ └── image4.png ├── build.gradle ├── buildconstants ├── android-sdk-versions.gradle └── dependency-versions.gradle ├── buildsystem ├── android-defaults.gradle ├── apkdetails │ └── apkdetails-1.2.2.jar ├── codequality │ └── lint.xml ├── common-methods.gradle ├── generate_dependency_hashfile.sh ├── jacocoxml │ └── jacocoxmlparser-1.0.0.jar ├── multidex │ └── multidex.pro ├── proguard-rules │ ├── dagger2-rules.pro │ ├── gson-rules.pro │ └── kotlin-rules.pro └── signing_keys │ └── debug.keystore ├── common ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── uk │ │ └── co │ │ └── alt236 │ │ └── floatinginfo │ │ └── common │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── uk │ │ │ └── co │ │ │ └── alt236 │ │ │ └── floatinginfo │ │ │ └── common │ │ │ ├── data │ │ │ ├── InfoStore.kt │ │ │ └── model │ │ │ │ ├── CpuData.kt │ │ │ │ ├── ForegroundAppData.kt │ │ │ │ ├── LocaleData.kt │ │ │ │ ├── MemoryData.java │ │ │ │ ├── bt │ │ │ │ ├── BluetoothData.kt │ │ │ │ ├── BondState.kt │ │ │ │ ├── LightBluetoothDevice.kt │ │ │ │ └── ScanMode.kt │ │ │ │ └── net │ │ │ │ ├── Interface.kt │ │ │ │ ├── IpAddress.kt │ │ │ │ └── NetData.kt │ │ │ ├── prefs │ │ │ ├── Alignment.kt │ │ │ ├── EnabledInfoPrefs.kt │ │ │ └── OverlayPrefs.kt │ │ │ └── string │ │ │ ├── HumanReadable.kt │ │ │ └── StringBuilderHelper.kt │ └── res │ │ ├── layout │ │ └── screen_overlay.xml │ │ └── values │ │ ├── preference_keys.xml │ │ └── values.xml │ └── test │ └── java │ └── uk │ └── co │ └── alt236 │ └── floatinginfo │ └── common │ └── ExampleUnitTest.java ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── import-summary.txt ├── inforeader ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── uk │ │ └── co │ │ └── alt236 │ │ └── floatinginfo │ │ └── inforeader │ │ └── ExampleInstrumentedTest.kt │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── uk │ │ └── co │ │ └── alt236 │ │ └── floatinginfo │ │ └── inforeader │ │ ├── bt │ │ └── BluetoothInfoReader.kt │ │ ├── cpu │ │ ├── CpuInfo.java │ │ └── CpuUtilisationReader.java │ │ ├── fgappinfo │ │ ├── FgAppDiscovery.kt │ │ ├── FgAppDiscovery21.kt │ │ ├── FgAppDiscoveryLegacy.kt │ │ ├── ForegroundAppDiscovery.kt │ │ └── ProcessStore.java │ │ ├── general │ │ └── LocaleInfoReader.kt │ │ ├── memory │ │ └── MemoryInfoReader.kt │ │ └── network │ │ ├── InterfaceReader.java │ │ ├── NetDataReader.kt │ │ ├── NetworkInfoReader.kt │ │ └── ProxyInfoReader.kt │ └── test │ └── java │ └── uk │ └── co │ └── alt236 │ └── floatinginfo │ └── inforeader │ └── ExampleUnitTest.kt ├── overlay ├── .gitignore ├── build.gradle ├── consumer-rules.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── uk │ │ └── co │ │ └── alt236 │ │ └── floatinginfo │ │ └── overlay │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ └── java │ │ └── uk │ │ └── co │ │ └── alt236 │ │ └── floatinginfo │ │ └── overlay │ │ ├── OverlayManager.java │ │ ├── TextOverlayController.java │ │ └── writers │ │ ├── BluetoothTextWriter.kt │ │ ├── CpuTextWriter.kt │ │ ├── FgProcessTextWriter.kt │ │ ├── LocaleDataTextWriter.kt │ │ ├── MemoryTextWriter.kt │ │ ├── TextWriter.kt │ │ ├── TextWriterWrapper.kt │ │ └── net │ │ ├── InterfaceWriter.kt │ │ ├── NetDataTextWriter.kt │ │ ├── NetInfoConstantResolver.kt │ │ └── WifiInfoTextWriter.kt │ └── test │ └── java │ └── uk │ └── co │ └── alt236 │ └── floatinginfo │ └── overlay │ └── ExampleUnitTest.java ├── print_codecov.sh └── settings.gradle /.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /.idea/copyright/Apache.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /.idea/copyright/profiles_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/gradle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 23 | 24 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 24 | 41 | 42 | 43 | 44 | 45 | 46 | 48 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/runConfigurations.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 12 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | Floating Info 2 | ========= 3 | 4 | Floating Info is an Android application that displays the following in a system overlay window: 5 | 6 | * The application name, package name and process id of the application which is currently in the device's foreground 7 | * The Global CPU utilisation with a per-core breakdown - This is not foreground application specific. 8 | * Memory usage breakdown for the currently foregrounded process (read the [notes](#notes) for the caveats). 9 | * Network information like connection type, proxy status and IP addresses. Both IPv4 and IPv6 10 | * Device Locale Information 11 | 12 | ## Limitations 13 | Since Nougat it is not possible to get the process id of an app different than the one making the request. 14 | As a result it no longer possible to get the memory utilisation of other applications. 15 | 16 | SE Linux can interfere with getting CPU information as files in the /proc/ folder may not be globally readable. 17 | 18 | 19 | Android app on Google Play 21 | 22 | 23 | ## Screenshots 24 | Click to see in full size: 25 | 26 | 27 | 28 | 29 | 30 | 31 | ## Changelog 32 | * 1.0: First public release 33 | * 2.0: Conversion to Android Studio, Lollipop support, network info, onboarding 34 | * 2.1: Added Locale info, Oreo support 35 | 36 | # Notes and Caveats 37 | * The application will show the memory allocation of the currently foregrounded process which it gets by getting the Process Id of the currently foregrounded activity. This means that if an application has spawned multiple processes, this application will only show the memory utilisation of the main process. 38 | * The Memory information displayed come via a [Debug.MemoryInfo](http://developer.android.com/reference/android/os/Debug.MemoryInfo.html) object, while using reflection to expose a number of hidden [fields](https://android.googlesource.com/platform/frameworks/base/+/refs/heads/master/core/java/android/os/Debug.java). 39 | * Data updates happen approximately every 1 second. 40 | 41 | # Android Memory Usage 42 | Memory management on Android is pretty complex and the easiest way to get started with understanding it is reading [this](https://developer.android.com/tools/debugging/debugging-memory.html) article - especially the "Viewing Overall Memory Allocations" section. 43 | 44 | ## Credits 45 | Author: [Alexandros Schillings](https://github.com/alt236) 46 | 47 | Based on [GhostLog](https://github.com/jgilfelt/GhostLog) by [Jeff Gilfelt](https://github.com/jgilfelt) 48 | 49 | The icon was adapted from [this](http://www.clker.com/clipart-duck-silhouette.html) one. 50 | 51 | ## License 52 | Copyright (C) 2017 Alexandros Schillings 53 | 54 | Licensed under the Apache License, Version 2.0 (the "License"); 55 | you may not use this file except in compliance with the License. 56 | You may obtain a copy of the License at 57 | 58 | http://www.apache.org/licenses/LICENSE-2.0 59 | 60 | Unless required by applicable law or agreed to in writing, software 61 | distributed under the License is distributed on an "AS IS" BASIS, 62 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 63 | See the License for the specific language governing permissions and 64 | limitations under the License. 65 | -------------------------------------------------------------------------------- /apkdetails.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | set -o xtrace 5 | java -jar ./buildsystem/apkdetails/apkdetails-1.2.2.jar "$@" 6 | set +o xtrace -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id 'com.android.application' 3 | id 'kotlin-android' 4 | id 'kotlin-android-extensions' 5 | id 'com.github.triplet.play' version '2.8.0' 6 | } 7 | 8 | apply from: "${project.rootDir}/buildsystem/android-defaults.gradle" 9 | 10 | android { 11 | 12 | final int buildNumber = getBuildNumber() 13 | final int versionMajor = 2 14 | final int versionMinor = 0 15 | final int versionPatch = buildNumber 16 | final int androidVersionCode = buildNumber 17 | 18 | final String semanticVersion = "${versionMajor}.${versionMinor}.${versionPatch}" 19 | 20 | signingConfigs { 21 | release { 22 | storeFile file(System.getenv("ANDROID_KEYSTORE") ?: "[KEY_NOT_DEFINED]") 23 | storePassword System.getenv("KEYSTORE_PASSWORD") 24 | keyAlias System.getenv("KEY_ALIAS") 25 | keyPassword System.getenv("KEY_PASSWORD") 26 | } 27 | 28 | debug { 29 | storeFile file("${project.rootDir}/buildsystem/signing_keys/debug.keystore") 30 | keyAlias 'androiddebugkey' 31 | keyPassword 'android' 32 | storePassword 'android' 33 | } 34 | } 35 | 36 | defaultConfig { 37 | versionCode androidVersionCode 38 | versionName semanticVersion 39 | } 40 | 41 | buildTypes { 42 | release { 43 | minifyEnabled false 44 | resValue "string", "app_name", "Floating Info" 45 | if (isRunningOnCi()) { 46 | signingConfig signingConfigs.release 47 | } 48 | } 49 | 50 | debug { 51 | minifyEnabled false 52 | applicationIdSuffix ".debug" 53 | signingConfig signingConfigs.debug 54 | 55 | resValue "string", "app_name", "Debug Floating Info" 56 | } 57 | } 58 | 59 | compileOptions { 60 | sourceCompatibility JavaVersion.VERSION_1_8 61 | targetCompatibility JavaVersion.VERSION_1_8 62 | } 63 | 64 | } 65 | 66 | dependencies { 67 | implementation project(":common") 68 | implementation project(":inforeader") 69 | implementation project(":overlay") 70 | 71 | implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" 72 | implementation "androidx.core:core:$androidx_core_version" 73 | implementation "androidx.core:core-ktx:$androidx_core_version" 74 | implementation "androidx.appcompat:appcompat:$androidx_appcompat_version" 75 | implementation "androidx.annotation:annotation:$androidx_annotation_version" 76 | 77 | implementation "io.github.dreierf:material-intro-screen:$material_intro_screen_version" 78 | 79 | testImplementation "junit:junit:$junit_version" 80 | testImplementation "org.mockito:mockito-core:$mockito_version" 81 | 82 | androidTestImplementation "androidx.test:core:$andoridx_test_runner_version" 83 | androidTestImplementation "androidx.test:runner:$andoridx_test_runner_version" 84 | } 85 | 86 | play { 87 | def credentialsPath = System.getenv("GPLAY_DEPLOY_KEY") ?: "[KEY_NOT_DEFINED]" 88 | def lastCommitMessage = getLastGitCommitMessage().take(50) 89 | 90 | logger.warn("GPP Config: $credentialsPath") 91 | logger.warn("Release Name: '$lastCommitMessage'") 92 | 93 | if (isRunningOnCi()) { 94 | enabled = true 95 | track = "internal" 96 | //userFraction = 1.0 97 | releaseStatus = "completed" 98 | serviceAccountCredentials = file(credentialsPath) 99 | releaseName = lastCommitMessage 100 | artifactDir = file("${project.rootDir}/app/build/outputs/apk/release/") 101 | } else { 102 | enabled = false 103 | } 104 | } 105 | repositories { 106 | mavenCentral() 107 | } 108 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in Android/sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 13 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/assets/licenses.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16 | 17 | 18 | 19 |

Floating Info

20 |
Copyright (C) 2014 Alexandros Schillings.
21 | 
22 | Licensed under the Apache License, Version 2.0 (the "License");
23 | you may not use this file except in compliance with the License.
24 | You may obtain a copy of the License at
25 | 
26 |      http://www.apache.org/licenses/LICENSE-2.0
27 | 
28 | Unless required by applicable law or agreed to in writing, software
29 | distributed under the License is distributed on an "AS IS" BASIS,
30 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 | See the License for the specific language governing permissions and
32 | limitations under the License.
33 | 
34 |

Android Open Source Project

35 |
Copyright (C) 2013 The Android Open Source Project
36 | 
37 | Licensed under the Apache License, Version 2.0 (the "License");
38 | you may not use this file except in compliance with the License.
39 | You may obtain a copy of the License at
40 | 
41 |      http://www.apache.org/licenses/LICENSE-2.0
42 | 
43 | Unless required by applicable law or agreed to in writing, software
44 | distributed under the License is distributed on an "AS IS" BASIS,
45 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
46 | See the License for the specific language governing permissions and
47 | limitations under the License.
48 | 
49 |

Ghost Log

50 |
Copyright (C) 2014 readyState Software Ltd.
51 | 
52 | Licensed under the Apache License, Version 2.0 (the "License");
53 | you may not use this file except in compliance with the License.
54 | You may obtain a copy of the License at
55 | 
56 |      http://www.apache.org/licenses/LICENSE-2.0
57 | 
58 | Unless required by applicable law or agreed to in writing, software
59 | distributed under the License is distributed on an "AS IS" BASIS,
60 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
61 | See the License for the specific language governing permissions and
62 | limitations under the License.
63 | 
64 |

libsuperuser

65 |
Copyright (C) 2013 The Android Open Source Project
66 | 
67 | Licensed under the Apache License, Version 2.0 (the "License");
68 | you may not use this file except in compliance with the License.
69 | You may obtain a copy of the License at
70 | 
71 |      http://www.apache.org/licenses/LICENSE-2.0
72 | 
73 | Unless required by applicable law or agreed to in writing, software
74 | distributed under the License is distributed on an "AS IS" BASIS,
75 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
76 | See the License for the specific language governing permissions and
77 | limitations under the License.
78 | 
79 |

Android Open Source Project

80 |
Copyright (C) 2013 The Android Open Source Project
81 | 
82 | Licensed under the Apache License, Version 2.0 (the "License");
83 | you may not use this file except in compliance with the License.
84 | You may obtain a copy of the License at
85 | 
86 |      http://www.apache.org/licenses/LICENSE-2.0
87 | 
88 | Unless required by applicable law or agreed to in writing, software
89 | distributed under the License is distributed on an "AS IS" BASIS,
90 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
91 | See the License for the specific language governing permissions and
92 | limitations under the License.
93 | 
94 | 95 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/data/access/BaseProvider.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package uk.co.alt236.floatinginfo.data.access; 17 | 18 | import android.app.Service; 19 | import android.content.BroadcastReceiver; 20 | import android.content.Context; 21 | import android.content.Intent; 22 | import android.content.IntentFilter; 23 | 24 | import androidx.annotation.IntegerRes; 25 | import androidx.annotation.StringRes; 26 | 27 | public abstract class BaseProvider { 28 | private final Service mService; 29 | 30 | 31 | public BaseProvider(final Service service) { 32 | mService = service; 33 | } 34 | 35 | public abstract void stop(); 36 | 37 | public Context getApplicationContext() { 38 | return mService.getApplicationContext(); 39 | } 40 | 41 | public Context getContext() { 42 | return mService; 43 | } 44 | 45 | public int getInteger(@IntegerRes final int resId) { 46 | return mService.getResources().getInteger(resId); 47 | } 48 | 49 | public String getString(@StringRes final int resId) { 50 | return mService.getString(resId); 51 | } 52 | 53 | public Object getSystemService(final String name) { 54 | return mService.getSystemService(name); 55 | } 56 | 57 | protected void registerReceiver(final BroadcastReceiver receiver, final IntentFilter filter) { 58 | getContext().registerReceiver(receiver, filter); 59 | } 60 | 61 | public abstract boolean start(); 62 | 63 | protected void startActivity(final Intent intent) { 64 | getContext().startActivity(intent); 65 | } 66 | 67 | protected void unregisterReceiver(final BroadcastReceiver receiver) { 68 | getContext().unregisterReceiver(receiver); 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/data/access/generalinfo/GeneralInfoReceiver.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package uk.co.alt236.floatinginfo.data.access.generalinfo 17 | 18 | import android.content.BroadcastReceiver 19 | import android.content.Context 20 | import android.content.Intent 21 | import android.content.IntentFilter 22 | 23 | class GeneralInfoReceiver(private val mCallbacks: Callbacks) : BroadcastReceiver() { 24 | val intentFilter: IntentFilter 25 | get() { 26 | val f = IntentFilter() 27 | f.addAction(ACTION_PLAY) 28 | f.addAction(ACTION_PAUSE) 29 | f.addAction(ACTION_CLEAR) 30 | f.addAction(ACTION_SHARE) 31 | return f 32 | } 33 | 34 | override fun onReceive(context: Context, intent: Intent) { 35 | val action = intent.action 36 | when { 37 | ACTION_PLAY == action -> mCallbacks.onLogResume() 38 | ACTION_PAUSE == action -> mCallbacks.onLogPause() 39 | ACTION_CLEAR == action -> mCallbacks.onLogClear() 40 | ACTION_SHARE == action -> mCallbacks.onLogShare() 41 | } 42 | } 43 | 44 | interface Callbacks { 45 | fun onLogPause() 46 | fun onLogResume() 47 | fun onLogClear() 48 | fun onLogShare() 49 | } 50 | 51 | companion object { 52 | @JvmField 53 | val ACTION_PLAY = GeneralInfoReceiver::class.java.name + ".ACTION_PLAY" 54 | 55 | @JvmField 56 | val ACTION_PAUSE = GeneralInfoReceiver::class.java.name + ".ACTION_PAUSE" 57 | 58 | @JvmField 59 | val ACTION_CLEAR = GeneralInfoReceiver::class.java.name + ".ACTION_CLEAR" 60 | 61 | @JvmField 62 | val ACTION_SHARE = GeneralInfoReceiver::class.java.name + ".ACTION_SHARE" 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/data/access/generalinfo/PrefsChangeListener.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package uk.co.alt236.floatinginfo.data.access.generalinfo 17 | 18 | import android.content.Context 19 | import android.content.SharedPreferences 20 | import android.content.SharedPreferences.OnSharedPreferenceChangeListener 21 | import android.preference.PreferenceManager 22 | import uk.co.alt236.floatinginfo.R 23 | import uk.co.alt236.floatinginfo.overlay.OverlayManager 24 | 25 | /*package*/ 26 | internal class PrefsChangeListener(private val mContext: Context, 27 | private val mOverlayManager: OverlayManager) : OnSharedPreferenceChangeListener { 28 | 29 | private val mPrefs: SharedPreferences = PreferenceManager.getDefaultSharedPreferences(mContext) 30 | 31 | override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences, key: String) { 32 | when (key) { 33 | mContext.getString(R.string.pref_key_bg_opacity) -> { 34 | mOverlayManager.updateBackground() 35 | } 36 | mContext.getString(R.string.pref_key_text_alpha) -> { 37 | mOverlayManager.updateTextColor() 38 | } 39 | mContext.getString(R.string.pref_key_text_size) -> { 40 | mOverlayManager.updateTextSize() 41 | } 42 | mContext.getString(R.string.pref_key_text_color_red) -> { 43 | mOverlayManager.updateTextColor() 44 | } 45 | mContext.getString(R.string.pref_key_text_color_green) -> { 46 | mOverlayManager.updateTextColor() 47 | } 48 | mContext.getString(R.string.pref_key_text_color_blue) -> { 49 | mOverlayManager.updateTextColor() 50 | } 51 | mContext.getString(R.string.pref_key_screen_position) -> { 52 | mOverlayManager.updateAlignment() 53 | } 54 | } 55 | } 56 | 57 | fun register() { 58 | mPrefs.registerOnSharedPreferenceChangeListener(this) 59 | } 60 | 61 | fun unRegister() { 62 | mPrefs.unregisterOnSharedPreferenceChangeListener(this) 63 | } 64 | 65 | } -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/data/access/generalinfo/SystemWindowLayoutParamsFactory.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package uk.co.alt236.floatinginfo.data.access.generalinfo 17 | 18 | import android.graphics.PixelFormat 19 | import android.os.Build 20 | import android.view.ViewGroup 21 | import android.view.WindowManager 22 | 23 | /*package*/ 24 | internal class SystemWindowLayoutParamsFactory { 25 | val params: ViewGroup.LayoutParams 26 | get() { 27 | val windowType = windowType 28 | val flags = (WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE 29 | or WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN 30 | or WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE) 31 | return WindowManager.LayoutParams( 32 | ViewGroup.LayoutParams.MATCH_PARENT, 33 | ViewGroup.LayoutParams.MATCH_PARENT, 34 | windowType, 35 | flags, 36 | PixelFormat.TRANSLUCENT 37 | ) 38 | } 39 | 40 | private val windowType = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 41 | WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY 42 | } else { 43 | WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/data/access/generalinfo/monitortask/ProcessMonitor.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package uk.co.alt236.floatinginfo.data.access.generalinfo.monitortask 17 | 18 | import android.content.Context 19 | import android.os.AsyncTask 20 | import uk.co.alt236.floatinginfo.common.prefs.EnabledInfoPrefs 21 | 22 | class ProcessMonitor(context: Context, 23 | prefs: EnabledInfoPrefs) { 24 | private val mContext: Context = context.applicationContext 25 | private val mEnabledInfoPrefs: EnabledInfoPrefs = prefs 26 | private var mTask: InnerTask? = null 27 | 28 | fun start(callback: UpdateCallback) { 29 | mTask = InnerTask(mContext, mEnabledInfoPrefs, callback) 30 | mTask!!.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR) 31 | } 32 | 33 | fun stop() { 34 | if (mTask != null) { 35 | mTask!!.cancel(true) 36 | mTask = null 37 | } 38 | } 39 | 40 | interface UpdateCallback { 41 | fun onUpdate(update: Update) 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/data/access/generalinfo/monitortask/Update.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2020 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package uk.co.alt236.floatinginfo.data.access.generalinfo.monitortask 17 | 18 | import uk.co.alt236.floatinginfo.common.data.model.CpuData 19 | import uk.co.alt236.floatinginfo.common.data.model.ForegroundAppData 20 | import uk.co.alt236.floatinginfo.common.data.model.LocaleData 21 | import uk.co.alt236.floatinginfo.common.data.model.MemoryData 22 | import uk.co.alt236.floatinginfo.common.data.model.bt.BluetoothData 23 | import uk.co.alt236.floatinginfo.common.data.model.net.NetData 24 | 25 | data class Update(val foregroundAppData: ForegroundAppData, 26 | val netData: NetData?, 27 | val memoryData: MemoryData?, 28 | val cpuData: CpuData?, 29 | val generalData: LocaleData?, 30 | val bluetoothData: BluetoothData?) -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/notifications/NotificationChannelFactory.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.notifications; 18 | 19 | import android.app.NotificationChannel; 20 | import android.app.NotificationManager; 21 | import android.content.Context; 22 | 23 | import androidx.annotation.NonNull; 24 | import uk.co.alt236.floatinginfo.R; 25 | 26 | /*package*/ class NotificationChannelFactory { 27 | private static final String CHANNEL_ID = "floating_info_control"; 28 | 29 | @NonNull 30 | public NotificationChannelWrapper create(final Context context) { 31 | final NotificationChannel channel = createChannel(context, CHANNEL_ID); 32 | return new NotificationChannelWrapper(channel, CHANNEL_ID); 33 | } 34 | 35 | private NotificationChannel createChannel(final Context context, 36 | final String id) { 37 | final String channelName = context.getString(R.string.notification_channel_name); 38 | final String description = context.getString(R.string.notification_channel_description); 39 | 40 | final NotificationChannel channel; 41 | if (isAtLeastOreo()) { 42 | final int importance = NotificationManager.IMPORTANCE_LOW; 43 | channel = new NotificationChannel(id, channelName, importance); 44 | channel.setName(channelName); 45 | channel.setDescription(description); 46 | channel.setImportance(importance); 47 | channel.setSound(null, null); 48 | channel.enableVibration(false); 49 | } else { 50 | channel = null; 51 | } 52 | 53 | return channel; 54 | } 55 | 56 | private static boolean isAtLeastOreo() { 57 | return android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O; 58 | } 59 | 60 | public static class NotificationChannelWrapper { 61 | private final NotificationChannel mChannel; 62 | private final String mChannelName; 63 | 64 | public NotificationChannelWrapper(final NotificationChannel mChannel, final String mChannelName) { 65 | this.mChannel = mChannel; 66 | this.mChannelName = mChannelName; 67 | } 68 | 69 | public NotificationChannel getChannel() { 70 | return mChannel; 71 | } 72 | 73 | public String getChannelName() { 74 | return mChannelName; 75 | } 76 | 77 | public boolean hasChannel() { 78 | return mChannel != null; 79 | } 80 | 81 | public void register(final NotificationManager manager) { 82 | if (isAtLeastOreo()) { 83 | manager.createNotificationChannel(mChannel); 84 | } 85 | } 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/permissions/AndroidPermissionChecker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.permissions; 18 | 19 | import android.content.Context; 20 | import android.content.pm.PackageInfo; 21 | import android.content.pm.PackageManager; 22 | 23 | import androidx.annotation.NonNull; 24 | import androidx.core.app.ActivityCompat; 25 | 26 | public class AndroidPermissionChecker implements PermissionChecker { 27 | 28 | private final Context mContext; 29 | 30 | public AndroidPermissionChecker(final Context context) { 31 | mContext = context.getApplicationContext(); 32 | } 33 | 34 | private boolean hasAllPermissions(@NonNull String[] permissions) { 35 | boolean hasAllPermissions = true; 36 | for (String perm : permissions) { 37 | hasAllPermissions &= ActivityCompat.checkSelfPermission(mContext, perm) 38 | == PackageManager.PERMISSION_GRANTED; 39 | } 40 | return hasAllPermissions; 41 | } 42 | 43 | @NonNull 44 | public String[] getRequiredPermissions() { 45 | final String packageName = mContext.getPackageName(); 46 | final PackageManager packageManager = mContext.getPackageManager(); 47 | 48 | try { 49 | final String[] permissions; 50 | 51 | final PackageInfo info = packageManager.getPackageInfo(packageName, PackageManager.GET_PERMISSIONS); 52 | if (info.requestedPermissions != null) { 53 | permissions = info.requestedPermissions; 54 | } else { 55 | permissions = new String[0]; 56 | } 57 | 58 | return permissions; 59 | } catch (PackageManager.NameNotFoundException e) { 60 | throw new IllegalStateException(e.getMessage(), e); 61 | } 62 | } 63 | 64 | @Override 65 | public boolean isNeeded() { 66 | final String[] permissions = getRequiredPermissions(); 67 | return hasAllPermissions(permissions); 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/permissions/OverlayPermissionChecker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.permissions; 18 | 19 | import android.content.Context; 20 | import android.os.Build; 21 | import android.provider.Settings; 22 | 23 | public class OverlayPermissionChecker implements PermissionChecker { 24 | private final Context mContext; 25 | 26 | public OverlayPermissionChecker(final Context context) { 27 | mContext = context.getApplicationContext(); 28 | } 29 | 30 | @Override 31 | public boolean isNeeded() { 32 | final boolean retVal; 33 | 34 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 35 | retVal = !Settings.canDrawOverlays(mContext); 36 | } else { 37 | retVal = false; 38 | } 39 | 40 | return retVal; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/permissions/PermissionChecker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.permissions; 18 | 19 | public interface PermissionChecker { 20 | boolean isNeeded(); 21 | } 22 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/permissions/PermissionCheckerWrapper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.permissions; 18 | 19 | import android.app.Activity; 20 | 21 | import java.util.Arrays; 22 | import java.util.List; 23 | 24 | public class PermissionCheckerWrapper { 25 | 26 | private final List mPermisionLogicList; 27 | 28 | public PermissionCheckerWrapper(final Activity activity) { 29 | mPermisionLogicList = Arrays.asList( 30 | new AndroidPermissionChecker(activity), 31 | new OverlayPermissionChecker(activity), 32 | new UsageStatsPermissionChecker(activity) 33 | ); 34 | } 35 | 36 | public boolean needToAsk() { 37 | boolean retVal = false; 38 | 39 | for (final PermissionChecker logic : mPermisionLogicList) { 40 | if (logic.isNeeded()) { 41 | retVal = true; 42 | break; 43 | } 44 | } 45 | 46 | return retVal; 47 | } 48 | 49 | 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/permissions/UsageStatsPermissionChecker.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.permissions; 18 | 19 | import android.app.usage.UsageStats; 20 | import android.app.usage.UsageStatsManager; 21 | import android.content.Context; 22 | import android.os.Build; 23 | 24 | import java.util.List; 25 | 26 | public class UsageStatsPermissionChecker implements PermissionChecker { 27 | private final Context mContext; 28 | 29 | public UsageStatsPermissionChecker(final Context context) { 30 | mContext = context.getApplicationContext(); 31 | } 32 | 33 | @SuppressWarnings("WrongConstant") 34 | @Override 35 | public boolean isNeeded() { 36 | final boolean retVal; 37 | 38 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 39 | final UsageStatsManager usageStatsManager = (UsageStatsManager) mContext.getSystemService("usagestats"); 40 | final List queryUsageStats = usageStatsManager.queryUsageStats( 41 | UsageStatsManager.INTERVAL_DAILY, 42 | 0, 43 | System.currentTimeMillis()); 44 | 45 | retVal = queryUsageStats == null || queryUsageStats.isEmpty(); 46 | } else { 47 | retVal = false; 48 | } 49 | 50 | return retVal; 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/service/FloatingInfoService.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package uk.co.alt236.floatinginfo.service; 17 | 18 | import android.app.Service; 19 | import android.content.Intent; 20 | import android.os.IBinder; 21 | 22 | import uk.co.alt236.floatinginfo.data.access.BaseProvider; 23 | import uk.co.alt236.floatinginfo.data.access.generalinfo.GeneralInfoProvider; 24 | 25 | public class FloatingInfoService extends Service { 26 | 27 | private static boolean sIsRunning = false; 28 | private BaseProvider mMonitor; 29 | private ScreenStateListener mScreenStateListener; 30 | 31 | @Override 32 | public IBinder onBind(final Intent intent) { 33 | throw new UnsupportedOperationException("Not implemented"); 34 | } 35 | 36 | @Override 37 | public void onCreate() { 38 | super.onCreate(); 39 | mMonitor = new GeneralInfoProvider(this); 40 | 41 | final ScreenStateListener.OnScreenStateListener listener = new ScreenStateListener.OnScreenStateListener() { 42 | @Override 43 | public void onScreenOn() { 44 | startMonitor(); 45 | } 46 | 47 | @Override 48 | public void onScreenOff() { 49 | stopMonitor(); 50 | } 51 | }; 52 | 53 | mScreenStateListener = new ScreenStateListener(this, listener); 54 | mScreenStateListener.register(); 55 | } 56 | 57 | @Override 58 | public void onDestroy() { 59 | super.onDestroy(); 60 | mScreenStateListener.unregister(); 61 | stopMonitor(); 62 | sIsRunning = false; 63 | } 64 | 65 | @Override 66 | public int onStartCommand(final Intent intent, final int flags, final int startId) { 67 | sIsRunning = true; 68 | startMonitor(); 69 | return Service.START_STICKY; 70 | } 71 | 72 | private void startMonitor() { 73 | mMonitor.start(); 74 | } 75 | 76 | private void stopMonitor() { 77 | mMonitor.stop(); 78 | } 79 | 80 | public static boolean isRunning() { 81 | return sIsRunning; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/service/ScreenStateListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.service; 18 | 19 | import android.content.BroadcastReceiver; 20 | import android.content.Context; 21 | import android.content.Intent; 22 | import android.content.IntentFilter; 23 | import android.util.Log; 24 | 25 | /*package*/ class ScreenStateListener { 26 | 27 | private final Context mContext; 28 | private final IntentFilter mFilter; 29 | private final BroadcastReceiver mReceiver; 30 | 31 | public ScreenStateListener(final Context context, 32 | final OnScreenStateListener listener) { 33 | mContext = context; 34 | 35 | mFilter = new IntentFilter(); 36 | mFilter.addAction(Intent.ACTION_SCREEN_ON); 37 | mFilter.addAction(Intent.ACTION_SCREEN_OFF); 38 | 39 | mReceiver = new ScreenReceiver(listener); 40 | } 41 | 42 | public void register() { 43 | mContext.registerReceiver(mReceiver, mFilter); 44 | } 45 | 46 | public void unregister() { 47 | mContext.unregisterReceiver(mReceiver); 48 | } 49 | 50 | public interface OnScreenStateListener { 51 | void onScreenOn(); 52 | 53 | void onScreenOff(); 54 | } 55 | 56 | private static class ScreenReceiver extends BroadcastReceiver { 57 | private final OnScreenStateListener mListener; 58 | 59 | public ScreenReceiver(final OnScreenStateListener listener) { 60 | mListener = listener; 61 | } 62 | 63 | @Override 64 | public void onReceive(Context context, Intent intent) { 65 | Log.d(ScreenStateListener.class.getSimpleName(), "Screen state changed: " + intent); 66 | if (Intent.ACTION_SCREEN_OFF.equals(intent.getAction())) { 67 | mListener.onScreenOff(); 68 | } else if (Intent.ACTION_SCREEN_ON.equals(intent.getAction())) { 69 | mListener.onScreenOn(); 70 | } 71 | } 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/ui/activity/base/ValidFragments.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2017 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.ui.activity.base; 18 | 19 | import java.util.HashSet; 20 | import java.util.Set; 21 | 22 | import uk.co.alt236.floatinginfo.ui.activity.main.AppearancePreferenceFragment; 23 | import uk.co.alt236.floatinginfo.ui.activity.main.EnabledInfoPreferenceFragment; 24 | import uk.co.alt236.floatinginfo.ui.activity.main.InfoPreferenceFragment; 25 | 26 | /*package*/ class ValidFragments { 27 | private final Set validClasses; 28 | 29 | public ValidFragments() { 30 | validClasses = new HashSet<>(); 31 | validClasses.add(AppearancePreferenceFragment.class.getName()); 32 | validClasses.add(EnabledInfoPreferenceFragment.class.getName()); 33 | validClasses.add(InfoPreferenceFragment.class.getName()); 34 | } 35 | 36 | public boolean isValidFragment(final String name) { 37 | return validClasses.contains(name); 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/ui/activity/main/AppearancePreferenceFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.ui.activity.main; 18 | 19 | import android.os.Bundle; 20 | import android.preference.PreferenceFragment; 21 | 22 | import uk.co.alt236.floatinginfo.R; 23 | 24 | /** 25 | * 26 | */ 27 | public class AppearancePreferenceFragment extends PreferenceFragment { 28 | @Override 29 | public void onCreate(final Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | // Load the preferences from an XML resource 32 | addPreferencesFromResource(R.xml.pref_appearance); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/ui/activity/main/EnabledInfoPreferenceFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.ui.activity.main; 18 | 19 | import android.os.Bundle; 20 | import android.preference.PreferenceFragment; 21 | 22 | import uk.co.alt236.floatinginfo.R; 23 | 24 | /** 25 | * 26 | */ 27 | public class EnabledInfoPreferenceFragment extends PreferenceFragment { 28 | @Override 29 | public void onCreate(final Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | // Load the preferences from an XML resource 32 | addPreferencesFromResource(R.xml.pref_enabled_info); 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/ui/activity/main/InfoPreferenceFragment.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.ui.activity.main; 18 | 19 | import android.os.Bundle; 20 | import android.preference.PreferenceFragment; 21 | 22 | import uk.co.alt236.floatinginfo.R; 23 | 24 | /** 25 | * 26 | */ 27 | public class InfoPreferenceFragment extends PreferenceFragment { 28 | @Override 29 | public void onCreate(final Bundle savedInstanceState) { 30 | super.onCreate(savedInstanceState); 31 | // Load the preferences from an XML resource 32 | addPreferencesFromResource(R.xml.pref_info); 33 | PrefsUtils.setupOpenSourceInfoPreference(getActivity(), findPreference(getString(R.string.pref_key_info_open_source))); 34 | PrefsUtils.setupVersionPref(getActivity(), findPreference(getString(R.string.pref_key_version))); 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/ui/activity/main/PrefsUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.ui.activity.main; 18 | 19 | import android.app.Activity; 20 | import android.app.DialogFragment; 21 | import android.app.Fragment; 22 | import android.app.FragmentManager; 23 | import android.app.FragmentTransaction; 24 | import android.preference.Preference; 25 | 26 | import uk.co.alt236.floatinginfo.ui.activity.main.dialogs.AboutDialog; 27 | import uk.co.alt236.floatinginfo.ui.activity.main.dialogs.OpenSourceLicensesDialog; 28 | 29 | /*package*/ final class PrefsUtils { 30 | 31 | private static final String DIALOG_TAG = "dialog"; 32 | 33 | private PrefsUtils() { 34 | // NOOP 35 | } 36 | 37 | public static void setupOpenSourceInfoPreference(final Activity activity, final Preference preference) { 38 | preference.setOnPreferenceClickListener(preference1 -> { 39 | replace(activity.getFragmentManager(), new OpenSourceLicensesDialog()); 40 | return true; 41 | }); 42 | } 43 | 44 | public static void setupVersionPref(final Activity activity, final Preference preference) { 45 | preference.setOnPreferenceClickListener(preference1 -> { 46 | replace(activity.getFragmentManager(), new AboutDialog()); 47 | return true; 48 | }); 49 | } 50 | 51 | 52 | private static void replace(final FragmentManager fm, final DialogFragment dialog) { 53 | final FragmentTransaction ft = fm.beginTransaction(); 54 | final Fragment prev = fm.findFragmentByTag(DIALOG_TAG); 55 | if (prev != null) { 56 | ft.remove(prev); 57 | } 58 | ft.addToBackStack(null); 59 | dialog.show(ft, DIALOG_TAG); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/ui/activity/main/dialogs/AboutDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.ui.activity.main.dialogs; 18 | 19 | import android.app.AlertDialog; 20 | import android.app.Dialog; 21 | import android.app.DialogFragment; 22 | import android.content.Context; 23 | import android.os.Bundle; 24 | import android.view.LayoutInflater; 25 | import android.view.View; 26 | import android.widget.TextView; 27 | 28 | import uk.co.alt236.floatinginfo.BuildConfig; 29 | import uk.co.alt236.floatinginfo.R; 30 | 31 | public class AboutDialog extends DialogFragment { 32 | 33 | public AboutDialog() { 34 | } 35 | 36 | @Override 37 | public Dialog onCreateDialog(final Bundle savedInstanceState) { 38 | final LayoutInflater inflater = (LayoutInflater) getActivity().getSystemService(Context.LAYOUT_INFLATER_SERVICE); 39 | 40 | final View content = inflater.inflate(R.layout.dialog_about, null, false); 41 | final TextView version = content.findViewById(R.id.version); 42 | 43 | final String name = BuildConfig.VERSION_NAME; 44 | version.setText(getString(R.string.version) + " " + name); 45 | 46 | return new AlertDialog.Builder(getActivity()) 47 | .setTitle(R.string.app_name) 48 | .setView(content) 49 | .setPositiveButton(R.string.ok, (dialog, whichButton) -> dialog.dismiss()) 50 | .create(); 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/ui/activity/main/dialogs/OpenSourceLicensesDialog.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.ui.activity.main.dialogs; 18 | 19 | import android.app.AlertDialog; 20 | import android.app.Dialog; 21 | import android.app.DialogFragment; 22 | import android.os.Bundle; 23 | import android.webkit.WebView; 24 | 25 | import uk.co.alt236.floatinginfo.R; 26 | 27 | public class OpenSourceLicensesDialog extends DialogFragment { 28 | 29 | public static final String LICENSES_FILE = "file:///android_asset/licenses.html"; 30 | 31 | public OpenSourceLicensesDialog() { 32 | } 33 | 34 | @Override 35 | public Dialog onCreateDialog(final Bundle savedInstanceState) { 36 | final WebView webView = new WebView(getActivity()); 37 | webView.loadUrl(LICENSES_FILE); 38 | 39 | return new AlertDialog.Builder(getActivity()) 40 | .setTitle(R.string.open_source_licences) 41 | .setView(webView) 42 | .setPositiveButton(R.string.ok, (dialog, whichButton) -> dialog.dismiss()) 43 | .create(); 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/ui/activity/onboarding/OnBoardingActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.ui.activity.onboarding; 18 | 19 | import android.os.Bundle; 20 | import android.util.Log; 21 | 22 | import java.util.List; 23 | 24 | import androidx.annotation.Nullable; 25 | import io.github.dreierf.materialintroscreen.MaterialIntroActivity; 26 | import io.github.dreierf.materialintroscreen.SlideFragment; 27 | import uk.co.alt236.floatinginfo.ui.activity.onboarding.pagefactory.PageFactory; 28 | 29 | public class OnBoardingActivity extends MaterialIntroActivity { 30 | private static final String TAG = OnBoardingActivity.class.getSimpleName(); 31 | 32 | @Override 33 | protected void onCreate(@Nullable Bundle savedInstanceState) { 34 | super.onCreate(savedInstanceState); 35 | 36 | final List pages = new PageFactory(this).getPages(); 37 | Log.d(TAG, "Number of pages: " + pages.size()); 38 | 39 | if (pages.isEmpty()) { 40 | finish(); 41 | } else { 42 | for (final SlideFragment page : pages) { 43 | addSlide(page); 44 | } 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/ui/activity/onboarding/pagefactory/OverlayPermsissionPage.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package uk.co.alt236.floatinginfo.ui.activity.onboarding.pagefactory; 18 | 19 | import android.content.Context; 20 | import android.content.Intent; 21 | import android.net.Uri; 22 | import android.os.Build; 23 | import android.os.Bundle; 24 | import android.provider.Settings; 25 | import android.view.LayoutInflater; 26 | import android.view.View; 27 | import android.view.ViewGroup; 28 | import android.widget.Button; 29 | import android.widget.TextView; 30 | 31 | import androidx.annotation.NonNull; 32 | import androidx.annotation.Nullable; 33 | import io.github.dreierf.materialintroscreen.SlideFragment; 34 | import uk.co.alt236.floatinginfo.BuildConfig; 35 | import uk.co.alt236.floatinginfo.R; 36 | import uk.co.alt236.floatinginfo.permissions.OverlayPermissionChecker; 37 | import uk.co.alt236.floatinginfo.permissions.PermissionChecker; 38 | 39 | public class OverlayPermsissionPage extends SlideFragment { 40 | 41 | private PermissionChecker mLogic; 42 | 43 | public void onAttach(@NonNull Context context) { 44 | super.onAttach(context); 45 | mLogic = new OverlayPermissionChecker(context); 46 | } 47 | 48 | @Nullable 49 | @Override 50 | public View onCreateView(LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) { 51 | final View view = inflater.inflate(R.layout.fragment_onboard_slide, container, false); 52 | final TextView title = view.findViewById(R.id.txt_title_slide); 53 | final TextView text = view.findViewById(R.id.txt_description_slide); 54 | final Button button = view.findViewById(R.id.button); 55 | 56 | title.setText(R.string.slide_overlay_title); 57 | text.setText(R.string.slide_overlay_description); 58 | 59 | button.setText(R.string.button_click_to_grant); 60 | button.setOnClickListener(v -> ask()); 61 | 62 | return view; 63 | } 64 | 65 | @Override 66 | public int backgroundColor() { 67 | return R.color.colorPrimary; 68 | } 69 | 70 | @Override 71 | public int buttonsColor() { 72 | return R.color.colorAccent; 73 | } 74 | 75 | @Override 76 | public boolean canMoveFurther() { 77 | return !mLogic.isNeeded(); 78 | } 79 | 80 | @Override 81 | public String cantMoveFurtherErrorMessage() { 82 | return getString(R.string.message_access_needed); 83 | } 84 | 85 | private void ask() { 86 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 87 | /** check if we already have permission to draw over other apps */ 88 | if (mLogic.isNeeded()) { 89 | /** if not construct intent to request permission */ 90 | final Intent intent = new Intent( 91 | Settings.ACTION_MANAGE_OVERLAY_PERMISSION, 92 | Uri.parse("package:" + BuildConfig.APPLICATION_ID)); 93 | /** request permission via start activity for result */ 94 | getActivity().startActivityForResult(intent, 1337); 95 | } 96 | } 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/ui/activity/share/ShareActivity.kt: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package uk.co.alt236.floatinginfo.ui.activity.share 17 | 18 | import android.app.Activity 19 | import android.content.Intent 20 | import android.os.Bundle 21 | import uk.co.alt236.floatinginfo.data.access.generalinfo.GeneralInfoReceiver 22 | 23 | class ShareActivity : Activity() { 24 | // this activity exists so we can launch the share chooser 25 | // from a notification action - see LogService.onLogShare() 26 | override fun onCreate(savedInstanceState: Bundle) { 27 | super.onCreate(savedInstanceState) 28 | // simply post the share event and finish 29 | val intent = Intent(GeneralInfoReceiver.ACTION_SHARE) 30 | sendBroadcast(intent) 31 | finish() 32 | } 33 | 34 | } -------------------------------------------------------------------------------- /app/src/main/java/uk/co/alt236/floatinginfo/util/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 Alexandros Schillings 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | package uk.co.alt236.floatinginfo.util; 17 | 18 | public class Constants { 19 | public static final int PROC_MONITOR_SLEEP = 1000; 20 | } 21 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_stat_clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-hdpi/ic_stat_clear.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_stat_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-hdpi/ic_stat_main.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_stat_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-hdpi/ic_stat_pause.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_stat_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-hdpi/ic_stat_play.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/ic_stat_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-hdpi/ic_stat_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_stat_clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-mdpi/ic_stat_clear.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_stat_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-mdpi/ic_stat_main.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_stat_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-mdpi/ic_stat_pause.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_stat_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-mdpi/ic_stat_play.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/ic_stat_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-mdpi/ic_stat_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_stat_clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xhdpi/ic_stat_clear.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_stat_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xhdpi/ic_stat_main.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_stat_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xhdpi/ic_stat_pause.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_stat_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xhdpi/ic_stat_play.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/ic_stat_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xhdpi/ic_stat_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_stat_clear.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xxhdpi/ic_stat_clear.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_stat_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xxhdpi/ic_stat_main.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_stat_pause.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xxhdpi/ic_stat_pause.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_stat_play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xxhdpi/ic_stat_play.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/ic_stat_share.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xxhdpi/ic_stat_share.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/ic_stat_main.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alt236/Floating-Info---Android/81239735ea9e1e477dbf1ba57f4acea5621fa2ac/app/src/main/res/drawable-xxxhdpi/ic_stat_main.png -------------------------------------------------------------------------------- /app/src/main/res/layout-land/fragment_onboard_slide.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 28 | 29 | 35 | 36 | 44 | 45 | 53 | 54 |