forked from jens/Automation
Initial commit
This commit is contained in:
commit
a8950597d0
150
.gitignore
vendored
Normal file
150
.gitignore
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/androidstudio
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=androidstudio
|
||||
|
||||
### AndroidStudio ###
|
||||
# Covers files to be ignored for android development using Android Studio.
|
||||
|
||||
# Built application files
|
||||
*.apk
|
||||
*.ap_
|
||||
*.aab
|
||||
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
|
||||
# Gradle files
|
||||
.gradle
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Signing files
|
||||
.signing/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
||||
# Log Files
|
||||
*.log
|
||||
|
||||
# Android Studio
|
||||
/*/build/
|
||||
/*/local.properties
|
||||
/*/out
|
||||
/*/*/build
|
||||
/*/*/production
|
||||
captures/
|
||||
.navigation/
|
||||
*.ipr
|
||||
*~
|
||||
*.swp
|
||||
|
||||
# Keystore files
|
||||
*.jks
|
||||
*.keystore
|
||||
|
||||
# Google Services (e.g. APIs or Firebase)
|
||||
# google-services.json
|
||||
|
||||
# Android Patch
|
||||
gen-external-apklibs
|
||||
|
||||
# External native build folder generated in Android Studio 2.2 and later
|
||||
.externalNativeBuild
|
||||
|
||||
# NDK
|
||||
obj/
|
||||
|
||||
# IntelliJ IDEA
|
||||
*.iml
|
||||
*.iws
|
||||
/out/
|
||||
|
||||
# User-specific configurations
|
||||
.idea/caches/
|
||||
.idea/libraries/
|
||||
.idea/shelf/
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/.name
|
||||
.idea/compiler.xml
|
||||
.idea/copyright/profiles_settings.xml
|
||||
.idea/encodings.xml
|
||||
.idea/misc.xml
|
||||
.idea/modules.xml
|
||||
.idea/scopes/scope_settings.xml
|
||||
.idea/dictionaries
|
||||
.idea/vcs.xml
|
||||
.idea/jsLibraryMappings.xml
|
||||
.idea/datasources.xml
|
||||
.idea/dataSources.ids
|
||||
.idea/sqlDataSources.xml
|
||||
.idea/dynamic.xml
|
||||
.idea/uiDesigner.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/gradle.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/navEditor.xml
|
||||
|
||||
# OS-specific files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Legacy Eclipse project files
|
||||
.classpath
|
||||
.project
|
||||
.cproject
|
||||
.settings/
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml)
|
||||
hs_err_pid*
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/mongoSettings.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
### AndroidStudio Patch ###
|
||||
|
||||
!/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/androidstudio
|
||||
|
||||
|
||||
/app/app-release.apk
|
||||
Automation_settings.xml
|
3
.idea/.gitignore
generated
vendored
Normal file
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
150
app/.gitignore
vendored
Normal file
150
app/.gitignore
vendored
Normal file
@ -0,0 +1,150 @@
|
||||
|
||||
# Created by https://www.toptal.com/developers/gitignore/api/androidstudio
|
||||
# Edit at https://www.toptal.com/developers/gitignore?templates=androidstudio
|
||||
|
||||
### AndroidStudio ###
|
||||
# Covers files to be ignored for android development using Android Studio.
|
||||
|
||||
# Built application files
|
||||
*.apk
|
||||
*.ap_
|
||||
*.aab
|
||||
|
||||
# Files for the ART/Dalvik VM
|
||||
*.dex
|
||||
|
||||
# Java class files
|
||||
*.class
|
||||
|
||||
# Generated files
|
||||
bin/
|
||||
gen/
|
||||
out/
|
||||
|
||||
# Gradle files
|
||||
.gradle
|
||||
.gradle/
|
||||
build/
|
||||
|
||||
# Signing files
|
||||
.signing/
|
||||
|
||||
# Local configuration file (sdk path, etc)
|
||||
local.properties
|
||||
|
||||
# Proguard folder generated by Eclipse
|
||||
proguard/
|
||||
|
||||
# Log Files
|
||||
*.log
|
||||
|
||||
# Android Studio
|
||||
/*/build/
|
||||
/*/local.properties
|
||||
/*/out
|
||||
/*/*/build
|
||||
/*/*/production
|
||||
captures/
|
||||
.navigation/
|
||||
*.ipr
|
||||
*~
|
||||
*.swp
|
||||
|
||||
# Keystore files
|
||||
*.jks
|
||||
*.keystore
|
||||
|
||||
# Google Services (e.g. APIs or Firebase)
|
||||
# google-services.json
|
||||
|
||||
# Android Patch
|
||||
gen-external-apklibs
|
||||
|
||||
# External native build folder generated in Android Studio 2.2 and later
|
||||
.externalNativeBuild
|
||||
|
||||
# NDK
|
||||
obj/
|
||||
|
||||
# IntelliJ IDEA
|
||||
*.iml
|
||||
*.iws
|
||||
/out/
|
||||
|
||||
# User-specific configurations
|
||||
.idea/caches/
|
||||
.idea/libraries/
|
||||
.idea/shelf/
|
||||
.idea/workspace.xml
|
||||
.idea/tasks.xml
|
||||
.idea/.name
|
||||
.idea/compiler.xml
|
||||
.idea/copyright/profiles_settings.xml
|
||||
.idea/encodings.xml
|
||||
.idea/misc.xml
|
||||
.idea/modules.xml
|
||||
.idea/scopes/scope_settings.xml
|
||||
.idea/dictionaries
|
||||
.idea/vcs.xml
|
||||
.idea/jsLibraryMappings.xml
|
||||
.idea/datasources.xml
|
||||
.idea/dataSources.ids
|
||||
.idea/sqlDataSources.xml
|
||||
.idea/dynamic.xml
|
||||
.idea/uiDesigner.xml
|
||||
.idea/assetWizardSettings.xml
|
||||
.idea/gradle.xml
|
||||
.idea/jarRepositories.xml
|
||||
.idea/navEditor.xml
|
||||
|
||||
# OS-specific files
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
# Legacy Eclipse project files
|
||||
.classpath
|
||||
.project
|
||||
.cproject
|
||||
.settings/
|
||||
|
||||
# Mobile Tools for Java (J2ME)
|
||||
.mtj.tmp/
|
||||
|
||||
# Package Files #
|
||||
*.war
|
||||
*.ear
|
||||
|
||||
# virtual machine crash logs (Reference: http://www.java.com/en/download/help/error_hotspot.xml)
|
||||
hs_err_pid*
|
||||
|
||||
## Plugin-specific files:
|
||||
|
||||
# mpeltonen/sbt-idea plugin
|
||||
.idea_modules/
|
||||
|
||||
# JIRA plugin
|
||||
atlassian-ide-plugin.xml
|
||||
|
||||
# Mongo Explorer plugin
|
||||
.idea/mongoSettings.xml
|
||||
|
||||
# Crashlytics plugin (for Android Studio and IntelliJ)
|
||||
com_crashlytics_export_strings.xml
|
||||
crashlytics.properties
|
||||
crashlytics-build.properties
|
||||
fabric.properties
|
||||
|
||||
### AndroidStudio Patch ###
|
||||
|
||||
!/gradle/wrapper/gradle-wrapper.jar
|
||||
|
||||
# End of https://www.toptal.com/developers/gitignore/api/androidstudio
|
||||
|
||||
|
||||
/app/app-release.apk
|
||||
Automation_settings.xml
|
79
app/build.gradle
Normal file
79
app/build.gradle
Normal file
@ -0,0 +1,79 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion 29
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.jens.automation2"
|
||||
minSdkVersion 14
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.2'
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
versionCode 96
|
||||
versionName "1.6.21"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
checkReleaseBuilds false
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
flavorDimensions "version"
|
||||
|
||||
productFlavors
|
||||
{
|
||||
googlePlayFlavor
|
||||
{
|
||||
dimension "version"
|
||||
applicationIdSuffix ".googlePlay"
|
||||
versionNameSuffix "-googlePlay"
|
||||
targetSdkVersion 29
|
||||
}
|
||||
|
||||
fdroidFlavor
|
||||
{
|
||||
dimension "version"
|
||||
applicationIdSuffix ".fdroid"
|
||||
versionNameSuffix "-fdroid"
|
||||
targetSdkVersion 28
|
||||
}
|
||||
|
||||
apkFlavor
|
||||
{
|
||||
dimension "version"
|
||||
applicationIdSuffix ".apk"
|
||||
versionNameSuffix "-apk"
|
||||
targetSdkVersion 28
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:16.0.1'
|
||||
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:15.0.1'
|
||||
|
||||
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:16.0.1'
|
||||
apkFlavorImplementation 'com.google.android.gms:play-services-location:15.0.1'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
|
||||
implementation 'com.google.android.material:material:1.1.0'
|
||||
testImplementation 'junit:junit:4.+'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
}
|
21
app/proguard-rules.pro
vendored
Normal file
21
app/proguard-rules.pro
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
@ -0,0 +1,28 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.test.platform.app.InstrumentationRegistry;
|
||||
import androidx.test.ext.junit.runners.AndroidJUnit4;
|
||||
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
/**
|
||||
* Instrumented test, which will execute on an Android device.
|
||||
*
|
||||
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
|
||||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest
|
||||
{
|
||||
@Test
|
||||
public void useAppContext()
|
||||
{
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
assertEquals("com.jens.automation2", appContext.getPackageName());
|
||||
}
|
||||
}
|
203
app/src/apkFlavor/AndroidManifest.xml
Normal file
203
app/src/apkFlavor/AndroidManifest.xml
Normal file
@ -0,0 +1,203 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jens.automation2">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:smallScreens="true" />
|
||||
<!-- android:xlargeScreens="true" -->
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.location"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.gps"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.network"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.bluetooth"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.microphone"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.wifi"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.nfc"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
||||
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
|
||||
<!-- Commented out because of Google Play policy -->
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
android:required="false" />
|
||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
<meta-data
|
||||
android:name="firebase_analytics_collection_deactivated"
|
||||
android:value="true" />
|
||||
<meta-data
|
||||
android:name="google_analytics_adid_collection_enabled"
|
||||
android:value="false" />
|
||||
<meta-data
|
||||
android:name="google_analytics_ssaid_collection_enabled"
|
||||
android:value="false" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainScreen"
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManageSpecificPoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.SCREEN_ON" />-->
|
||||
<!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />-->
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.REBOOT"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.PackageReplacedReceiver"
|
||||
android:enabled="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_REPLACED" />
|
||||
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
|
||||
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
|
||||
<!--<data
|
||||
android:path="com.jens.automation2"
|
||||
android:scheme="package" />-->
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.AlarmListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
|
||||
<activity android:name=".ActivityManageSpecificRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<!-- <action android:name="android.nfc.action.TECH_DISCOVERED"/> -->
|
||||
<!-- <action android:name="android.nfc.action.TAG_DISCOVERED"/> -->
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/plain" />
|
||||
<!-- <data android:mimeType="application/com.jens.automation2" /> -->
|
||||
</intent-filter>
|
||||
|
||||
<!--
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="application/com.jens.automation2" />
|
||||
</intent-filter>
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
<meta-data
|
||||
android:name="android.nfc.action.TECH_DISCOVERED"
|
||||
android:resource="@xml/nfc_tech_filter" />
|
||||
-->
|
||||
</activity>
|
||||
<activity android:name=".ActivityMainPoi" />
|
||||
<activity android:name=".ActivityMainRules" />
|
||||
<activity android:name=".ActivityGeneric" />
|
||||
<activity android:name=".ActivityManageStartActivity" />
|
||||
<activity android:name=".ActivityManageNfc" />
|
||||
<activity android:name=".ActivityEditSpeakText" />
|
||||
<activity android:name=".ActivityManageBluetoothTrigger" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageSpecificProfile" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.ActivityDetectionReceiver"
|
||||
android:exported="false"
|
||||
android:label="@string/app_name"></service>
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.version"
|
||||
android:value="@integer/google_play_services_version" />
|
||||
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
|
||||
<service android:name=".location.GeofenceIntentService"/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
187
app/src/fdroidFlavor/AndroidManifest.xml
Normal file
187
app/src/fdroidFlavor/AndroidManifest.xml
Normal file
@ -0,0 +1,187 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jens.automation2">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:smallScreens="true" />
|
||||
<!-- android:xlargeScreens="true" -->
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.location"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.gps"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.network"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.bluetooth"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.microphone"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.wifi"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.nfc"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
android:required="false" />
|
||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
<meta-data
|
||||
android:name="firebase_analytics_collection_deactivated"
|
||||
android:value="true" />
|
||||
<meta-data
|
||||
android:name="google_analytics_adid_collection_enabled"
|
||||
android:value="false" />
|
||||
<meta-data
|
||||
android:name="google_analytics_ssaid_collection_enabled"
|
||||
android:value="false" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainScreen"
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManageSpecificPoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.SCREEN_ON" />-->
|
||||
<!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />-->
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.REBOOT"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.PackageReplacedReceiver"
|
||||
android:enabled="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_REPLACED" />
|
||||
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
|
||||
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
|
||||
<!--<data
|
||||
android:path="com.jens.automation2"
|
||||
android:scheme="package" />-->
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.AlarmListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
|
||||
<activity android:name=".ActivityManageSpecificRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<!-- <action android:name="android.nfc.action.TECH_DISCOVERED"/> -->
|
||||
<!-- <action android:name="android.nfc.action.TAG_DISCOVERED"/> -->
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/plain" />
|
||||
<!-- <data android:mimeType="application/com.jens.automation2" /> -->
|
||||
</intent-filter>
|
||||
|
||||
<!--
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="application/com.jens.automation2" />
|
||||
</intent-filter>
|
||||
-->
|
||||
|
||||
<!--
|
||||
<meta-data
|
||||
android:name="android.nfc.action.TECH_DISCOVERED"
|
||||
android:resource="@xml/nfc_tech_filter" />
|
||||
-->
|
||||
</activity>
|
||||
<activity android:name=".ActivityMainPoi" />
|
||||
<activity android:name=".ActivityMainRules" />
|
||||
<activity android:name=".ActivityGeneric" />
|
||||
<activity android:name=".ActivityManageStartActivity" />
|
||||
<activity android:name=".ActivityManageNfc" />
|
||||
<activity android:name=".ActivityEditSpeakText" />
|
||||
<activity android:name=".ActivityManageBluetoothTrigger" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageSpecificProfile" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
48
app/src/google-services.json
Normal file
48
app/src/google-services.json
Normal file
@ -0,0 +1,48 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "977361397436",
|
||||
"project_id": "automation-9bed6"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:977361397436:android:ee5ad5243b40934a",
|
||||
"android_client_info": {
|
||||
"package_name": "com.jens.automation2"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "977361397436-86ebgevdi3ttfhcki5l1ldnquocos854.apps.googleusercontent.com",
|
||||
"client_type": 1,
|
||||
"android_info": {
|
||||
"package_name": "com.jens.automation2",
|
||||
"certificate_hash": "86ec434e30ed99ec9ee1f4e5c33166558a8442a9"
|
||||
}
|
||||
},
|
||||
{
|
||||
"client_id": "977361397436-1n1769oadmm31pckln04pjdkela9p3e4.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyCeDEkuDmAr7b03auJKDrL1YAB-KlY7088"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"analytics_service": {
|
||||
"status": 1
|
||||
},
|
||||
"appinvite_service": {
|
||||
"status": 1,
|
||||
"other_platform_oauth_client": []
|
||||
},
|
||||
"ads_service": {
|
||||
"status": 1
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
203
app/src/googlePlayFlavor/AndroidManifest.xml
Normal file
203
app/src/googlePlayFlavor/AndroidManifest.xml
Normal file
@ -0,0 +1,203 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jens.automation2">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:smallScreens="true" />
|
||||
<!-- android:xlargeScreens="true" -->
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.location"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.gps"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.network"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.bluetooth"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.microphone"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.wifi"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.nfc"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
||||
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
|
||||
<!-- Commented out because of Google Play policy -->
|
||||
<!--
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
android:required="false" />
|
||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
-->
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
<meta-data
|
||||
android:name="firebase_analytics_collection_deactivated"
|
||||
android:value="true" />
|
||||
<meta-data
|
||||
android:name="google_analytics_adid_collection_enabled"
|
||||
android:value="false" />
|
||||
<meta-data
|
||||
android:name="google_analytics_ssaid_collection_enabled"
|
||||
android:value="false" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainScreen"
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManageSpecificPoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.SCREEN_ON" />-->
|
||||
<!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />-->
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.REBOOT"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.PackageReplacedReceiver"
|
||||
android:enabled="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_REPLACED" />
|
||||
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
|
||||
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
|
||||
<!--<data
|
||||
android:path="com.jens.automation2"
|
||||
android:scheme="package" />-->
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.AlarmListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
|
||||
<activity android:name=".ActivityManageSpecificRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<!-- <action android:name="android.nfc.action.TECH_DISCOVERED"/> -->
|
||||
<!-- <action android:name="android.nfc.action.TAG_DISCOVERED"/> -->
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/plain" />
|
||||
<!-- <data android:mimeType="application/com.jens.automation2" /> -->
|
||||
</intent-filter>
|
||||
|
||||
<!--
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="application/com.jens.automation2" />
|
||||
</intent-filter>
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
<meta-data
|
||||
android:name="android.nfc.action.TECH_DISCOVERED"
|
||||
android:resource="@xml/nfc_tech_filter" />
|
||||
-->
|
||||
</activity>
|
||||
<activity android:name=".ActivityMainPoi" />
|
||||
<activity android:name=".ActivityMainRules" />
|
||||
<activity android:name=".ActivityGeneric" />
|
||||
<activity android:name=".ActivityManageStartActivity" />
|
||||
<activity android:name=".ActivityManageNfc" />
|
||||
<activity android:name=".ActivityEditSpeakText" />
|
||||
<activity android:name=".ActivityManageBluetoothTrigger" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageSpecificProfile" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.ActivityDetectionReceiver"
|
||||
android:exported="false"
|
||||
android:label="@string/app_name"></service>
|
||||
|
||||
<meta-data
|
||||
android:name="com.google.android.gms.version"
|
||||
android:value="@integer/google_play_services_version" />
|
||||
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
|
||||
<service android:name=".location.GeofenceIntentService"/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
192
app/src/main/AndroidManifest.xml
Normal file
192
app/src/main/AndroidManifest.xml
Normal file
@ -0,0 +1,192 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jens.automation2">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:smallScreens="true" />
|
||||
<!-- android:xlargeScreens="true" -->
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.location"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.gps"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.network"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.bluetooth"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.microphone"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.wifi"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.nfc"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
||||
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
|
||||
<!-- Commented out because of Google Play policy -->
|
||||
<!--
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
android:required="false" />
|
||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
-->
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
<meta-data
|
||||
android:name="firebase_analytics_collection_deactivated"
|
||||
android:value="true" />
|
||||
<meta-data
|
||||
android:name="google_analytics_adid_collection_enabled"
|
||||
android:value="false" />
|
||||
<meta-data
|
||||
android:name="google_analytics_ssaid_collection_enabled"
|
||||
android:value="false" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainScreen"
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManageSpecificPoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.SCREEN_ON" />-->
|
||||
<!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />-->
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.REBOOT"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.PackageReplacedReceiver"
|
||||
android:enabled="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_REPLACED" />
|
||||
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
|
||||
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
|
||||
<!--<data
|
||||
android:path="com.jens.automation2"
|
||||
android:scheme="package" />-->
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.AlarmListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
|
||||
<activity android:name=".ActivityManageSpecificRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<!-- <action android:name="android.nfc.action.TECH_DISCOVERED"/> -->
|
||||
<!-- <action android:name="android.nfc.action.TAG_DISCOVERED"/> -->
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/plain" />
|
||||
<!-- <data android:mimeType="application/com.jens.automation2" /> -->
|
||||
</intent-filter>
|
||||
|
||||
<!--
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="application/com.jens.automation2" />
|
||||
</intent-filter>
|
||||
-->
|
||||
|
||||
|
||||
<!--
|
||||
<meta-data
|
||||
android:name="android.nfc.action.TECH_DISCOVERED"
|
||||
android:resource="@xml/nfc_tech_filter" />
|
||||
-->
|
||||
</activity>
|
||||
<activity android:name=".ActivityMainPoi" />
|
||||
<activity android:name=".ActivityMainRules" />
|
||||
<activity android:name=".ActivityGeneric" />
|
||||
<activity android:name=".ActivityManageStartActivity" />
|
||||
<activity android:name=".ActivityManageNfc" />
|
||||
<activity android:name=".ActivityEditSpeakText" />
|
||||
<activity android:name=".ActivityManageBluetoothTrigger" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageSpecificProfile" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
200
app/src/main/java/com/jens/automation2/AESCrypt.java
Normal file
200
app/src/main/java/com/jens/automation2/AESCrypt.java
Normal file
@ -0,0 +1,200 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.security.GeneralSecurityException;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.crypto.spec.IvParameterSpec;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
|
||||
/**
|
||||
* Encrypt and decrypt messages using AES 256 bit encryption that are compatible with AESCrypt-ObjC and AESCrypt Ruby.
|
||||
* <p/>
|
||||
* Created by scottab on 04/10/2014.
|
||||
*/
|
||||
public final class AESCrypt
|
||||
{
|
||||
private static final String TAG = "AESCrypt";
|
||||
|
||||
//AESCrypt-ObjC uses CBC and PKCS7Padding
|
||||
private static final String AES_MODE = "AES/CBC/PKCS7Padding";
|
||||
// private static final String AES_MODE = "AES/ECB/NoPadding";
|
||||
private static final String CHARSET = "UTF-8";
|
||||
|
||||
//AESCrypt-ObjC uses SHA-256 (and so a 256-bit key)
|
||||
private static final String HASH_ALGORITHM = "SHA-256";
|
||||
|
||||
//AESCrypt-ObjC uses blank IV (not the best security, but the aim here is compatibility)
|
||||
private static final byte[] ivBytes = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
|
||||
|
||||
//togglable log option (please turn off in live!)
|
||||
public static boolean DEBUG_LOG_ENABLED = false;
|
||||
|
||||
|
||||
/**
|
||||
* Generates SHA256 hash of the password which is used as key
|
||||
*
|
||||
* @param password used to generated key
|
||||
* @return SHA256 of the password
|
||||
*/
|
||||
private static SecretKeySpec generateKey(final String password) throws NoSuchAlgorithmException, UnsupportedEncodingException {
|
||||
final MessageDigest digest = MessageDigest.getInstance(HASH_ALGORITHM);
|
||||
byte[] bytes = password.getBytes("UTF-8");
|
||||
digest.update(bytes, 0, bytes.length);
|
||||
byte[] key = digest.digest();
|
||||
|
||||
log("SHA-256 key ", key);
|
||||
|
||||
SecretKeySpec secretKeySpec = new SecretKeySpec(key, "AES");
|
||||
return secretKeySpec;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Encrypt and encode message using 256-bit AES with key generated from password.
|
||||
*
|
||||
*
|
||||
* @param password used to generated key
|
||||
* @param message the thing you want to encrypt assumed String UTF-8
|
||||
* @return Base64 encoded CipherText
|
||||
* @throws GeneralSecurityException if problems occur during encryption
|
||||
*/
|
||||
public static String encrypt(final String password, String message)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
try {
|
||||
final SecretKeySpec key = generateKey(password);
|
||||
|
||||
log("message", message);
|
||||
|
||||
byte[] cipherText = encrypt(key, ivBytes, message.getBytes(CHARSET));
|
||||
|
||||
//NO_WRAP is important as was getting \n at the end
|
||||
String encoded = Base64.encodeToString(cipherText, Base64.NO_WRAP);
|
||||
log("Base64.NO_WRAP", encoded);
|
||||
return encoded;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (DEBUG_LOG_ENABLED)
|
||||
Log.e(TAG, "UnsupportedEncodingException ", e);
|
||||
throw new GeneralSecurityException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* More flexible AES encrypt that doesn't encode
|
||||
* @param key AES key typically 128, 192 or 256 bit
|
||||
* @param iv Initiation Vector
|
||||
* @param message in bytes (assumed it's already been decoded)
|
||||
* @return Encrypted cipher text (not encoded)
|
||||
* @throws GeneralSecurityException if something goes wrong during encryption
|
||||
*/
|
||||
public static byte[] encrypt(final SecretKeySpec key, final byte[] iv, final byte[] message)
|
||||
throws GeneralSecurityException {
|
||||
final Cipher cipher = Cipher.getInstance(AES_MODE);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||
cipher.init(Cipher.ENCRYPT_MODE, key, ivSpec);
|
||||
byte[] cipherText = cipher.doFinal(message);
|
||||
|
||||
log("cipherText", cipherText);
|
||||
|
||||
return cipherText;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Decrypt and decode ciphertext using 256-bit AES with key generated from password
|
||||
*
|
||||
* @param password used to generated key
|
||||
* @param base64EncodedCipherText the encrpyted message encoded with base64
|
||||
* @return message in Plain text (String UTF-8)
|
||||
* @throws GeneralSecurityException if there's an issue decrypting
|
||||
*/
|
||||
public static String decrypt(final String password, String base64EncodedCipherText)
|
||||
throws GeneralSecurityException {
|
||||
|
||||
try {
|
||||
final SecretKeySpec key = generateKey(password);
|
||||
|
||||
log("base64EncodedCipherText", base64EncodedCipherText);
|
||||
byte[] decodedCipherText = Base64.decode(base64EncodedCipherText, Base64.NO_WRAP);
|
||||
log("decodedCipherText", decodedCipherText);
|
||||
|
||||
byte[] decryptedBytes = decrypt(key, ivBytes, decodedCipherText);
|
||||
|
||||
log("decryptedBytes", decryptedBytes);
|
||||
String message = new String(decryptedBytes, CHARSET);
|
||||
log("message", message);
|
||||
|
||||
|
||||
return message;
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
if (DEBUG_LOG_ENABLED)
|
||||
Log.e(TAG, "UnsupportedEncodingException ", e);
|
||||
|
||||
throw new GeneralSecurityException(e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* More flexible AES decrypt that doesn't encode
|
||||
*
|
||||
* @param key AES key typically 128, 192 or 256 bit
|
||||
* @param iv Initiation Vector
|
||||
* @param decodedCipherText in bytes (assumed it's already been decoded)
|
||||
* @return Decrypted message cipher text (not encoded)
|
||||
* @throws GeneralSecurityException if something goes wrong during encryption
|
||||
*/
|
||||
public static byte[] decrypt(final SecretKeySpec key, final byte[] iv, final byte[] decodedCipherText)
|
||||
throws GeneralSecurityException {
|
||||
final Cipher cipher = Cipher.getInstance(AES_MODE);
|
||||
IvParameterSpec ivSpec = new IvParameterSpec(iv);
|
||||
cipher.init(Cipher.DECRYPT_MODE, key, ivSpec);
|
||||
byte[] decryptedBytes = cipher.doFinal(decodedCipherText);
|
||||
|
||||
log("decryptedBytes", decryptedBytes);
|
||||
|
||||
return decryptedBytes;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
private static void log(String what, byte[] bytes) {
|
||||
if (DEBUG_LOG_ENABLED)
|
||||
Log.d(TAG, what + "[" + bytes.length + "] [" + bytesToHex(bytes) + "]");
|
||||
}
|
||||
|
||||
private static void log(String what, String value) {
|
||||
if (DEBUG_LOG_ENABLED)
|
||||
Log.d(TAG, what + "[" + value.length() + "] [" + value + "]");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Converts byte array to hexidecimal useful for logging and fault finding
|
||||
* @param bytes
|
||||
* @return
|
||||
*/
|
||||
private static String bytesToHex(byte[] bytes) {
|
||||
final char[] hexArray = {'0', '1', '2', '3', '4', '5', '6', '7', '8',
|
||||
'9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
char[] hexChars = new char[bytes.length * 2];
|
||||
int v;
|
||||
for (int j = 0; j < bytes.length; j++) {
|
||||
v = bytes[j] & 0xFF;
|
||||
hexChars[j * 2] = hexArray[v >>> 4];
|
||||
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
|
||||
}
|
||||
return new String(hexChars);
|
||||
}
|
||||
|
||||
private AESCrypt() {
|
||||
}
|
||||
}
|
537
app/src/main/java/com/jens/automation2/Action.java
Normal file
537
app/src/main/java/com/jens/automation2/Action.java
Normal file
@ -0,0 +1,537 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import org.apache.http.client.methods.HttpGet;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
|
||||
|
||||
public class Action
|
||||
{
|
||||
public enum Action_Enum {
|
||||
setWifi,
|
||||
setBluetooth,
|
||||
setUsbTethering,
|
||||
setWifiTethering,
|
||||
setDisplayRotation,
|
||||
turnWifiOn,turnWifiOff,
|
||||
turnBluetoothOn,turnBluetoothOff,
|
||||
triggerUrl,
|
||||
changeSoundProfile,
|
||||
turnUsbTetheringOn,turnUsbTetheringOff,
|
||||
turnWifiTetheringOn,turnWifiTetheringOff,
|
||||
enableScreenRotation, disableScreenRotation,
|
||||
startOtherActivity,
|
||||
waitBeforeNextAction,
|
||||
wakeupDevice,
|
||||
setAirplaneMode,
|
||||
setDataConnection,
|
||||
speakText,
|
||||
playMusic,
|
||||
setScreenBrightness,
|
||||
sendTextMessage;
|
||||
|
||||
public String getFullName(Context context)
|
||||
{
|
||||
switch(this)
|
||||
{
|
||||
case setWifi:
|
||||
return context.getResources().getString(R.string.actionSetWifi);
|
||||
case setBluetooth:
|
||||
return context.getResources().getString(R.string.actionSetBluetooth);
|
||||
case setWifiTethering:
|
||||
return context.getResources().getString(R.string.actionSetWifiTethering);
|
||||
case setUsbTethering:
|
||||
return context.getResources().getString(R.string.actionSetUsbTethering);
|
||||
case setDisplayRotation:
|
||||
return context.getResources().getString(R.string.actionSetDisplayRotation);
|
||||
case turnWifiOn:
|
||||
return context.getResources().getString(R.string.actionTurnWifiOn);
|
||||
case turnWifiOff:
|
||||
return context.getResources().getString(R.string.actionTurnWifiOff);
|
||||
case turnBluetoothOn:
|
||||
return context.getResources().getString(R.string.actionTurnBluetoothOn);
|
||||
case turnBluetoothOff:
|
||||
return context.getResources().getString(R.string.actionTurnBluetoothOff);
|
||||
case triggerUrl:
|
||||
return context.getResources().getString(R.string.actionTriggerUrl);
|
||||
case changeSoundProfile:
|
||||
return context.getResources().getString(R.string.actionChangeSoundProfile);
|
||||
case turnUsbTetheringOn:
|
||||
return context.getResources().getString(R.string.actionTurnUsbTetheringOn);
|
||||
case turnUsbTetheringOff:
|
||||
return context.getResources().getString(R.string.actionTurnUsbTetheringOff);
|
||||
case turnWifiTetheringOn:
|
||||
return context.getResources().getString(R.string.actionTurnWifiTetheringOn);
|
||||
case turnWifiTetheringOff:
|
||||
return context.getResources().getString(R.string.actionTurnWifiTetheringOff);
|
||||
case enableScreenRotation:
|
||||
return context.getResources().getString(R.string.actionEnableScreenRotation);
|
||||
case disableScreenRotation:
|
||||
return context.getResources().getString(R.string.actionDisableScreenRotation);
|
||||
case startOtherActivity:
|
||||
return context.getResources().getString(R.string.startOtherActivity);
|
||||
case waitBeforeNextAction:
|
||||
return context.getResources().getString(R.string.waitBeforeNextAction);
|
||||
case wakeupDevice:
|
||||
return context.getResources().getString(R.string.wakeupDevice);
|
||||
case setAirplaneMode:
|
||||
return context.getResources().getString(R.string.airplaneMode);
|
||||
case setDataConnection:
|
||||
return context.getResources().getString(R.string.actionDataConnection);
|
||||
case speakText:
|
||||
return context.getResources().getString(R.string.actionSpeakText);
|
||||
case playMusic:
|
||||
return context.getResources().getString(R.string.actionPlayMusic);
|
||||
case sendTextMessage:
|
||||
return context.getResources().getString(R.string.sendTextMessage);
|
||||
case setScreenBrightness:
|
||||
return context.getResources().getString(R.string.setScreenBrightness);
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
private Action_Enum action;
|
||||
private boolean parameter1 = false;
|
||||
private String parameter2 = "";
|
||||
|
||||
public Action_Enum getAction()
|
||||
{
|
||||
return action;
|
||||
}
|
||||
public void setAction(Action_Enum action)
|
||||
{
|
||||
this.action = action;
|
||||
}
|
||||
|
||||
public boolean getParameter1()
|
||||
{
|
||||
return parameter1;
|
||||
}
|
||||
public void setParameter1(boolean parameter1)
|
||||
{
|
||||
this.parameter1 = parameter1;
|
||||
}
|
||||
public String getParameter2()
|
||||
{
|
||||
return parameter2;
|
||||
}
|
||||
public void setParameter2(String parameter)
|
||||
{
|
||||
this.parameter2 = parameter;
|
||||
}
|
||||
public String toStringShort()
|
||||
{
|
||||
String returnString = action.toString();
|
||||
|
||||
return returnString;
|
||||
}
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
StringBuilder returnString = new StringBuilder();
|
||||
|
||||
if(this.getAction().equals(Action_Enum.setWifi))
|
||||
{
|
||||
if(this.getParameter1())
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOn));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiOff));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setBluetooth))
|
||||
{
|
||||
if(this.getParameter1())
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothOn));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnBluetoothOff));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setUsbTethering))
|
||||
{
|
||||
if(this.getParameter1())
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnUsbTetheringOn));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnUsbTetheringOff));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setWifiTethering))
|
||||
{
|
||||
if(this.getParameter1())
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOn));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnWifiTetheringOff));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setDisplayRotation))
|
||||
{
|
||||
if(this.getParameter1())
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionEnableScreenRotation));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionDisableScreenRotation));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setAirplaneMode))
|
||||
{
|
||||
if(this.getParameter1())
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnAirplaneModeOn));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTurnAirplaneModeOff));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setDataConnection))
|
||||
{
|
||||
if(this.getParameter1())
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSetDataConnectionOn));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSetDataConnectionOff));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.startOtherActivity))
|
||||
{
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.startOtherActivity));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.triggerUrl))
|
||||
{
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionTriggerUrl));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.speakText))
|
||||
{
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionSpeakText));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.playMusic))
|
||||
{
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.actionPlayMusic));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.sendTextMessage))
|
||||
{
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.sendTextMessage));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.wakeupDevice))
|
||||
{
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.wakeupDevice));
|
||||
}
|
||||
else
|
||||
returnString.append(action.toString());
|
||||
|
||||
if(this.getAction().equals(Action_Enum.triggerUrl))
|
||||
{
|
||||
String[] components = parameter2.split(";");
|
||||
if(components.length >= 3)
|
||||
{
|
||||
returnString.append(": " + components[2]);
|
||||
|
||||
if(parameter1)
|
||||
returnString.append(" using authentication.");
|
||||
}
|
||||
else
|
||||
returnString.append(": " + components[0]);
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.sendTextMessage))
|
||||
{
|
||||
String[] components = parameter2.split(Actions.smsSeparator);
|
||||
if(components.length >= 2)
|
||||
{
|
||||
returnString.append(" to number " + components[0]);
|
||||
|
||||
returnString.append(". Message: " + components[1]);
|
||||
}
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.setScreenBrightness))
|
||||
{
|
||||
returnString.append(" to ");
|
||||
|
||||
if(parameter1)
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.brightnessAuto));
|
||||
else
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.brightnessManual));
|
||||
|
||||
returnString.append(" / " + Integer.parseInt(parameter2) + "%");
|
||||
}
|
||||
else
|
||||
if (parameter2 != null && parameter2.length() > 0)
|
||||
returnString.append(": " + parameter2);
|
||||
|
||||
return returnString.toString();
|
||||
}
|
||||
|
||||
public static CharSequence[] getActionTypesAsArray()
|
||||
{
|
||||
ArrayList<String> actionTypesList = new ArrayList<String>();
|
||||
|
||||
for(Action_Enum action : Action_Enum.values())
|
||||
{
|
||||
if( // exclusion for deprecated types
|
||||
!action.toString().equals("turnWifiOn")
|
||||
&&
|
||||
!action.toString().equals("turnWifiOff")
|
||||
&&
|
||||
!action.toString().equals("turnBluetoothOn")
|
||||
&&
|
||||
!action.toString().equals("turnBluetoothOff")
|
||||
&&
|
||||
!action.toString().equals("turnUsbTetheringOn")
|
||||
&&
|
||||
!action.toString().equals("turnUsbTetheringOff")
|
||||
&&
|
||||
!action.toString().equals("turnWifiTetheringOn")
|
||||
&&
|
||||
!action.toString().equals("turnWifiTetheringOff")
|
||||
&&
|
||||
!action.toString().equals("enableScreenRotation")
|
||||
&&
|
||||
!action.toString().equals("disableScreenRotation")
|
||||
) // exclusion for deprecated types
|
||||
actionTypesList.add(action.toString());
|
||||
}
|
||||
|
||||
return (String[])actionTypesList.toArray(new String[actionTypesList.size()]);
|
||||
}
|
||||
public static CharSequence[] getActionTypesFullNameStringAsArray(Context context)
|
||||
{
|
||||
ArrayList<String> actionTypesList = new ArrayList<String>();
|
||||
|
||||
for(Action_Enum action : Action_Enum.values())
|
||||
{
|
||||
if( // exclusion for deprecated types
|
||||
!action.toString().equals("turnWifiOn")
|
||||
&&
|
||||
!action.toString().equals("turnWifiOff")
|
||||
&&
|
||||
!action.toString().equals("turnBluetoothOn")
|
||||
&&
|
||||
!action.toString().equals("turnBluetoothOff")
|
||||
&&
|
||||
!action.toString().equals("turnUsbTetheringOn")
|
||||
&&
|
||||
!action.toString().equals("turnUsbTetheringOff")
|
||||
&&
|
||||
!action.toString().equals("turnWifiTetheringOn")
|
||||
&&
|
||||
!action.toString().equals("turnWifiTetheringOff")
|
||||
&&
|
||||
!action.toString().equals("enableScreenRotation")
|
||||
&&
|
||||
!action.toString().equals("disableScreenRotation")
|
||||
) // exclusion for deprecated types
|
||||
actionTypesList.add(action.getFullName(context));
|
||||
}
|
||||
|
||||
return (String[])actionTypesList.toArray(new String[actionTypesList.size()]);
|
||||
}
|
||||
|
||||
public void run(Context context, boolean toggleActionIfPossible)
|
||||
{
|
||||
switch(this.getAction())
|
||||
{
|
||||
case changeSoundProfile:
|
||||
/*
|
||||
* Old version. Those checks should not be necessary anymore. Also they didn't work
|
||||
* because profiles were created with names like silent, vibrate and normal.
|
||||
*/
|
||||
// if(this.getParameter2().equals("silent"))
|
||||
// Actions.setSound(context, AudioManager.RINGER_MODE_SILENT);
|
||||
// else if(this.getParameter2().equals("vibrate"))
|
||||
// Actions.setSound(context, AudioManager.RINGER_MODE_VIBRATE);
|
||||
// else if(this.getParameter2().equals("normal"))
|
||||
// Actions.setSound(context, AudioManager.RINGER_MODE_NORMAL);
|
||||
// else
|
||||
// {
|
||||
Profile p = Profile.getByName(this.getParameter2());
|
||||
if(p != null)
|
||||
p.activate(context);
|
||||
// }
|
||||
break;
|
||||
case triggerUrl:
|
||||
triggerUrl(context);
|
||||
break;
|
||||
case setBluetooth:
|
||||
Actions.setBluetooth(context, getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case setUsbTethering:
|
||||
Actions.setUsbTethering(context, getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case setWifi:
|
||||
Actions.setWifi(context, getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case setWifiTethering:
|
||||
Actions.setWifiTethering(context, getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case setDisplayRotation:
|
||||
Actions.setDisplayRotation(context, getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case startOtherActivity:
|
||||
Actions.startOtherActivity(getParameter2());
|
||||
break;
|
||||
case waitBeforeNextAction:
|
||||
Actions.waitBeforeNextAction(Long.parseLong(this.getParameter2()));
|
||||
break;
|
||||
case wakeupDevice:
|
||||
Actions.wakeupDevice(Long.parseLong(this.getParameter2()));
|
||||
// wakeupDevice() will create a seperate thread. That'll take some time, we wait 100ms.
|
||||
try
|
||||
{
|
||||
Thread.sleep(100);
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
break;
|
||||
case setAirplaneMode:
|
||||
Actions.setAirplaneMode(this.getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case setDataConnection:
|
||||
Actions.MobileDataStuff.setDataConnection(this.getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case speakText:
|
||||
Actions.speakText(this.getParameter2());
|
||||
break;
|
||||
case playMusic:
|
||||
Actions.playMusic(this.getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case sendTextMessage:
|
||||
Actions.sendTextMessage(context, this.getParameter2().split(Actions.smsSeparator));
|
||||
break;
|
||||
case setScreenBrightness:
|
||||
Actions.setScreenBrightness(getParameter1(), Integer.parseInt(getParameter2()));
|
||||
break;
|
||||
default:
|
||||
Miscellaneous.logEvent("w", "Action", context.getResources().getString(R.string.unknownActionSpecified), 3);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void triggerUrl(Context context)
|
||||
{
|
||||
String username = null;
|
||||
String password = null;
|
||||
String url;
|
||||
|
||||
String[] components = getParameter2().split(";");
|
||||
|
||||
if(components.length >= 3)
|
||||
{
|
||||
username = components[0];
|
||||
password = components[1];
|
||||
url = components[2];
|
||||
}
|
||||
else
|
||||
url = components[0];
|
||||
|
||||
try
|
||||
{
|
||||
url = Miscellaneous.replaceVariablesInText(url, context);
|
||||
|
||||
Actions myAction = new Actions();
|
||||
|
||||
Miscellaneous.logEvent("i", "HTTP", "Attempting download of " + url, 4); //getResources().getString("attemptingDownloadOf");
|
||||
|
||||
if(this.getParameter1()) // use authentication
|
||||
new DownloadTask().execute(url, username, password);
|
||||
else
|
||||
new DownloadTask().execute(url, null, null);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "triggerUrl", context.getResources().getString(R.string.errorTriggeringUrl) + ": " + e.getMessage() + ", detailed: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
|
||||
public class DownloadTask extends AsyncTask<String, Void, String>
|
||||
{
|
||||
@Override
|
||||
public String doInBackground(String... parameters)
|
||||
{
|
||||
Thread.setDefaultUncaughtExceptionHandler(Miscellaneous.uncaughtExceptionHandler);
|
||||
|
||||
int attempts=1;
|
||||
String urlString=parameters[0];
|
||||
|
||||
String urlUsername = null;
|
||||
String urlPassword = null;
|
||||
if(parameters.length >= 3)
|
||||
{
|
||||
urlUsername=parameters[1];
|
||||
urlPassword=parameters[2];
|
||||
}
|
||||
|
||||
String response = "httpError";
|
||||
HttpGet post;
|
||||
|
||||
if(Settings.httpAttempts < 1)
|
||||
Miscellaneous.logEvent("w", "HTTP Request", Miscellaneous.getAnyContext().getResources().getString(R.string.cantDownloadTooFewRequestsInSettings), 3);
|
||||
|
||||
while(attempts <= Settings.httpAttempts && response.equals("httpError"))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "HTTP Request", "Attempt " + String.valueOf(attempts++) + " of " + String.valueOf(Settings.httpAttempts), 3);
|
||||
|
||||
// try
|
||||
// {
|
||||
// Either thorough checking or no encryption
|
||||
if(!Settings.httpAcceptAllCertificates | !urlString.toLowerCase(Locale.getDefault()).contains("https"))
|
||||
// {
|
||||
// URL url = new URL(urlString);
|
||||
// URLConnection urlConnection = url.openConnection();
|
||||
// urlConnection.setReadTimeout(Settings.httpAttemptsTimeout * 1000);
|
||||
// InputStream in = urlConnection.getInputStream();
|
||||
// response = Miscellaneous.convertStreamToString(in);
|
||||
|
||||
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword);
|
||||
// }
|
||||
else
|
||||
// {
|
||||
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword);
|
||||
// post = new HttpGet(new URI(urlString));
|
||||
// final HttpParams httpParams = new BasicHttpParams();
|
||||
// HttpConnectionParams.setConnectionTimeout(httpParams, Settings.httpAttemptsTimeout * 1000);
|
||||
// HttpClient client = new DefaultHttpClient(httpParams);
|
||||
//
|
||||
// client = sslClient(client);
|
||||
//
|
||||
// // Execute HTTP Post Request
|
||||
// HttpResponse result = client.execute(post);
|
||||
// response = EntityUtils.toString(result.getEntity());
|
||||
// }
|
||||
// }
|
||||
// catch (URISyntaxException e)
|
||||
// {
|
||||
// Miscellaneous.logEvent("w", "HTTP RESULT", Log.getStackTraceString(e), 3);
|
||||
// }
|
||||
// catch (ClientProtocolException e)
|
||||
// {
|
||||
// Miscellaneous.logEvent("w", "HTTP RESULT", Log.getStackTraceString(e), 3);
|
||||
// }
|
||||
// catch (IOException e)
|
||||
// {
|
||||
// Miscellaneous.logEvent("w", "HTTP RESULT", Log.getStackTraceString(e), 3);
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
// finally
|
||||
// {
|
||||
try
|
||||
{
|
||||
Thread.sleep(Settings.httpAttemptGap * 1000);
|
||||
}
|
||||
catch (InterruptedException e1)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "HTTP RESULT", "Failed to pause between HTTP requests.", 5);
|
||||
}
|
||||
// }
|
||||
}
|
||||
|
||||
// Miscellaneous.logEvent("i", "HTTPS RESULT", response, 3);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPostExecute(String result)
|
||||
{
|
||||
//Do something with result
|
||||
//Toast.makeText(context, text, duration) result;
|
||||
Miscellaneous.logEvent("i", "HTTP RESULT", result, 3);
|
||||
Actions myAction=new Actions();
|
||||
myAction.useDownloadedWebpage(result);
|
||||
}
|
||||
}
|
||||
}
|
1192
app/src/main/java/com/jens/automation2/Actions.java
Normal file
1192
app/src/main/java/com/jens/automation2/Actions.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,181 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.ContactsContract;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
|
||||
public class ActivityEditSendTextMessage extends Activity
|
||||
{
|
||||
Button bSaveSendTextMessage, bImportNumberFromContacts;
|
||||
EditText etPhoneNumber, etSendTextMessage;
|
||||
|
||||
protected final static int requestCodeForContactsPermissions = 9876;
|
||||
|
||||
// private String existingUrl = "";
|
||||
|
||||
public static boolean edit = false;
|
||||
public static Action resultingAction = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.send_textmessage_editor);
|
||||
|
||||
etSendTextMessage = (EditText)findViewById(R.id.etSendTextMessage);
|
||||
etPhoneNumber = (EditText)findViewById(R.id.etPhoneNumber);
|
||||
bSaveSendTextMessage = (Button)findViewById(R.id.bSaveSendTextMessage);
|
||||
bImportNumberFromContacts = (Button)findViewById(R.id.bImportNumberFromContacts);
|
||||
|
||||
bSaveSendTextMessage.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(etSendTextMessage.getText().toString().length() > 0 && etPhoneNumber.getText().toString().length() > 0)
|
||||
{
|
||||
if(resultingAction == null)
|
||||
{
|
||||
resultingAction = new Action();
|
||||
resultingAction.setAction(Action_Enum.sendTextMessage);
|
||||
resultingAction.setParameter2(etPhoneNumber.getText().toString() + Actions.smsSeparator + etSendTextMessage.getText().toString());
|
||||
}
|
||||
backToRuleManager();
|
||||
}
|
||||
else
|
||||
Toast.makeText(getBaseContext(), getResources().getString(R.string.textTooShort), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
|
||||
bImportNumberFromContacts.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(!ActivityPermissions.havePermission("android.permission.READ_CONTACTS", ActivityEditSendTextMessage.this))
|
||||
{
|
||||
requestPermissions("android.permission.READ_CONTACTS");
|
||||
}
|
||||
else
|
||||
openContactsDialogue();
|
||||
}
|
||||
});
|
||||
|
||||
ActivityEditSendTextMessage.edit = getIntent().getBooleanExtra("edit", false);
|
||||
if(edit)
|
||||
{
|
||||
String[] parameters = ActivityEditSendTextMessage.resultingAction.getParameter2().split(Actions.smsSeparator);
|
||||
etPhoneNumber.setText(parameters[0]);
|
||||
etSendTextMessage.setText(parameters[1]);
|
||||
}
|
||||
|
||||
|
||||
// String url = getIntent().getStringExtra("urlToTrigger");
|
||||
// if(url != null)
|
||||
// existingUrl = url;
|
||||
}
|
||||
|
||||
private void backToRuleManager()
|
||||
{
|
||||
// Intent returnIntent = new Intent();
|
||||
// returnIntent.putExtra("urlToTrigger", existingUrl);
|
||||
|
||||
// setResult(RESULT_OK, returnIntent);
|
||||
|
||||
if(edit && resultingAction != null)
|
||||
{
|
||||
ActivityEditSendTextMessage.resultingAction.setParameter2(etPhoneNumber.getText().toString() + Actions.smsSeparator + etSendTextMessage.getText().toString());
|
||||
}
|
||||
|
||||
setResult(RESULT_OK);
|
||||
|
||||
this.finish();
|
||||
}
|
||||
protected void requestPermissions(String... requiredPermissions)
|
||||
{
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if(requiredPermissions.length > 0)
|
||||
{
|
||||
StringBuilder permissions = new StringBuilder();
|
||||
for (String perm : requiredPermissions)
|
||||
permissions.append(perm + "; ");
|
||||
if (permissions.length() > 0)
|
||||
permissions.delete(permissions.length() - 2, permissions.length());
|
||||
|
||||
Miscellaneous.logEvent("i", "Permissions", "Requesting permissions: " + permissions, 2);
|
||||
|
||||
requestPermissions(requiredPermissions, requestCodeForContactsPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
||||
{
|
||||
if(requestCode == requestCodeForContactsPermissions)
|
||||
{
|
||||
for(int i=0; i<permissions.length; i++)
|
||||
{
|
||||
if(permissions[i].equals("android.permission.READ_CONTACTS"))
|
||||
{
|
||||
if(grantResults[i] == PackageManager.PERMISSION_GRANTED)
|
||||
{
|
||||
openContactsDialogue();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void openContactsDialogue()
|
||||
{
|
||||
// Toast.makeText(ActivityEditSendTextMessage.this, "Opening contacts dialogue", Toast.LENGTH_LONG).show();
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
|
||||
startActivityForResult(intent, 1000);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if(requestCode == 1000)
|
||||
{
|
||||
if(resultCode == Activity.RESULT_OK)
|
||||
{
|
||||
String phoneNo = null;
|
||||
String name = null;
|
||||
|
||||
Uri uri = data.getData();
|
||||
Cursor cursor = ActivityEditSendTextMessage.this.getContentResolver().query(uri, null, null, null, null);
|
||||
|
||||
if (cursor.moveToFirst())
|
||||
{
|
||||
int phoneIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.NUMBER);
|
||||
int nameIndex = cursor.getColumnIndex(ContactsContract.CommonDataKinds.Phone.DISPLAY_NAME);
|
||||
|
||||
phoneNo = cursor.getString(phoneIndex);
|
||||
name = cursor.getString(nameIndex);
|
||||
|
||||
etPhoneNumber.setText(phoneNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
//super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
}
|
@ -0,0 +1,76 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
public class ActivityEditSpeakText extends Activity
|
||||
{
|
||||
private Button bSaveSpeakText;
|
||||
private EditText etSpeakText;
|
||||
|
||||
// private String existingUrl = "";
|
||||
|
||||
public static boolean edit = false;
|
||||
public static Action resultingAction = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.speak_text_editor);
|
||||
|
||||
etSpeakText = (EditText)findViewById(R.id.etTextToSpeak);
|
||||
bSaveSpeakText = (Button)findViewById(R.id.bSaveTriggerUrl);
|
||||
bSaveSpeakText.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(etSpeakText.getText().toString().length()>0)
|
||||
{
|
||||
if(resultingAction == null)
|
||||
{
|
||||
resultingAction = new Action();
|
||||
resultingAction.setAction(Action_Enum.speakText);
|
||||
resultingAction.setParameter2(etSpeakText.getText().toString());
|
||||
}
|
||||
backToRuleManager();
|
||||
}
|
||||
else
|
||||
Toast.makeText(getBaseContext(), getResources().getString(R.string.textTooShort), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
|
||||
ActivityEditSpeakText.edit = getIntent().getBooleanExtra("edit", false);
|
||||
if(edit)
|
||||
etSpeakText.setText(ActivityEditSpeakText.resultingAction.getParameter2());
|
||||
|
||||
|
||||
// String url = getIntent().getStringExtra("urlToTrigger");
|
||||
// if(url != null)
|
||||
// existingUrl = url;
|
||||
}
|
||||
|
||||
private void backToRuleManager()
|
||||
{
|
||||
// Intent returnIntent = new Intent();
|
||||
// returnIntent.putExtra("urlToTrigger", existingUrl);
|
||||
|
||||
// setResult(RESULT_OK, returnIntent);
|
||||
|
||||
if(edit && resultingAction != null)
|
||||
ActivityEditSpeakText.resultingAction.setParameter2(etSpeakText.getText().toString());
|
||||
|
||||
setResult(RESULT_OK);
|
||||
|
||||
this.finish();
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,171 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TableLayout;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
public class ActivityEditTriggerUrl extends Activity
|
||||
{
|
||||
Button bSaveTriggerUrl;
|
||||
EditText etTriggerUrl, etTriggerUrlUsername, etTriggerUrlPassword;
|
||||
ListView lvTriggerUrlPostParameters;
|
||||
CheckBox chkTriggerUrlUseAuthentication;
|
||||
TableLayout tlTriggerUrlAuthentication;
|
||||
|
||||
ArrayAdapter<Map<String,String>> lvTriggerUrlPostParametersAdapter;
|
||||
|
||||
// private String existingUrl = "";
|
||||
|
||||
public static boolean edit = false;
|
||||
public static Action resultingAction = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.trigger_url_editor);
|
||||
|
||||
etTriggerUrl = (EditText)findViewById(R.id.etTriggerUrl);
|
||||
etTriggerUrlUsername = (EditText)findViewById(R.id.etTriggerUrlUsername);
|
||||
etTriggerUrlPassword = (EditText)findViewById(R.id.etTriggerUrlPassword);
|
||||
chkTriggerUrlUseAuthentication = (CheckBox)findViewById(R.id.chkTriggerUrlUseAuthentication);
|
||||
lvTriggerUrlPostParameters = (ListView)findViewById(R.id.lvTriggerUrlPostParameters);
|
||||
tlTriggerUrlAuthentication = (TableLayout)findViewById(R.id.tlTriggerUrlAuthentication);
|
||||
bSaveTriggerUrl = (Button)findViewById(R.id.bSaveTriggerUrl);
|
||||
bSaveTriggerUrl.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(etTriggerUrl.getText().toString().length() > 0)
|
||||
{
|
||||
if(resultingAction == null)
|
||||
{
|
||||
resultingAction = new Action();
|
||||
resultingAction.setAction(Action_Enum.triggerUrl);
|
||||
resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
|
||||
|
||||
String username = etTriggerUrlUsername.getText().toString();
|
||||
String password = etTriggerUrlPassword.getText().toString();
|
||||
|
||||
if(username == null)
|
||||
username = "";
|
||||
|
||||
if(password == null)
|
||||
password = "";
|
||||
|
||||
ActivityEditTriggerUrl.resultingAction.setParameter2(
|
||||
username + ";" +
|
||||
password + ";" +
|
||||
etTriggerUrl.getText().toString().trim()
|
||||
);
|
||||
}
|
||||
backToRuleManager();
|
||||
}
|
||||
else
|
||||
Toast.makeText(getBaseContext(), getResources().getString(R.string.urlTooShort), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
chkTriggerUrlUseAuthentication.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
tlTriggerUrlAuthentication.setVisibility(View.VISIBLE);
|
||||
else
|
||||
tlTriggerUrlAuthentication.setVisibility(View.GONE);
|
||||
|
||||
etTriggerUrlUsername.setEnabled(isChecked);
|
||||
etTriggerUrlPassword.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
lvTriggerUrlPostParameters.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
});
|
||||
updateListView();
|
||||
|
||||
|
||||
ActivityEditTriggerUrl.edit = getIntent().getBooleanExtra("edit", false);
|
||||
if(edit)
|
||||
{
|
||||
// username,password,URL
|
||||
String[] components = ActivityEditTriggerUrl.resultingAction.getParameter2().split(";");
|
||||
|
||||
if(components.length >= 3)
|
||||
{
|
||||
etTriggerUrl.setText(components[2]);
|
||||
chkTriggerUrlUseAuthentication.setChecked(ActivityEditTriggerUrl.resultingAction.getParameter1());
|
||||
etTriggerUrlUsername.setText(components[0]);
|
||||
etTriggerUrlPassword.setText(components[1]);
|
||||
}
|
||||
else
|
||||
etTriggerUrl.setText(components[0]);
|
||||
}
|
||||
}
|
||||
|
||||
private void backToRuleManager()
|
||||
{
|
||||
if(edit && resultingAction != null)
|
||||
{
|
||||
String username = etTriggerUrlUsername.getText().toString();
|
||||
String password = etTriggerUrlPassword.getText().toString();
|
||||
|
||||
if(username == null)
|
||||
username = "";
|
||||
|
||||
if(password == null)
|
||||
password = "";
|
||||
|
||||
ActivityEditTriggerUrl.resultingAction.setParameter1(chkTriggerUrlUseAuthentication.isChecked());
|
||||
|
||||
ActivityEditTriggerUrl.resultingAction.setParameter2(
|
||||
username + ";" +
|
||||
password + ";" +
|
||||
etTriggerUrl.getText().toString()
|
||||
);
|
||||
}
|
||||
|
||||
setResult(RESULT_OK);
|
||||
|
||||
this.finish();
|
||||
}
|
||||
|
||||
private void updateListView()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "ListView", "Attempting to update lvTriggerUrlPostParameters", 4);
|
||||
try
|
||||
{
|
||||
if(lvTriggerUrlPostParameters.getAdapter() == null)
|
||||
lvTriggerUrlPostParameters.setAdapter(lvTriggerUrlPostParametersAdapter);
|
||||
|
||||
lvTriggerUrlPostParametersAdapter.notifyDataSetChanged();
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{}
|
||||
}
|
||||
}
|
67
app/src/main/java/com/jens/automation2/ActivityGeneric.java
Normal file
67
app/src/main/java/com/jens/automation2/ActivityGeneric.java
Normal file
@ -0,0 +1,67 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.ServiceConnection;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
|
||||
import com.jens.automation2.AutomationService.LocalBinder;
|
||||
|
||||
public class ActivityGeneric extends Activity
|
||||
{
|
||||
public static Intent myServiceIntent = null;
|
||||
AutomationService myAutomationService = null;
|
||||
boolean boundToService = false;
|
||||
|
||||
public void storeServiceReferenceInVariable()
|
||||
{
|
||||
if(AutomationService.isMyServiceRunning(getApplicationContext()) && myAutomationService == null)
|
||||
{
|
||||
bindToService();
|
||||
}
|
||||
}
|
||||
|
||||
public void bindToService()
|
||||
{
|
||||
Log.i("service", "binding to service");
|
||||
if(!boundToService)
|
||||
{
|
||||
// if(myServiceIntent == null)
|
||||
myServiceIntent = new Intent(this, AutomationService.class);
|
||||
|
||||
Miscellaneous.logEvent("i", "Service", getResources().getString(R.string.logAttemptingToBindToService) + String.valueOf(bindService(myServiceIntent, myServiceConnection, Context.BIND_AUTO_CREATE)), 5);
|
||||
}
|
||||
}
|
||||
public void unBindFromService()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", getResources().getString(R.string.logAttemptingToUnbindFromService), 5);
|
||||
if(boundToService)
|
||||
{
|
||||
unbindService(myServiceConnection);
|
||||
boundToService = false;
|
||||
Miscellaneous.logEvent("i", "Service", getResources().getString(R.string.logUnboundFromService), 5);
|
||||
}
|
||||
}
|
||||
|
||||
private ServiceConnection myServiceConnection = new ServiceConnection()
|
||||
{
|
||||
@Override
|
||||
public void onServiceConnected(ComponentName name, IBinder service)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", getResources().getString(R.string.logBoundToService), 5);
|
||||
LocalBinder binder = (LocalBinder)service;
|
||||
myAutomationService = binder.getService();
|
||||
boundToService = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onServiceDisconnected(ComponentName name)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", getResources().getString(R.string.logUnboundFromService), 5);
|
||||
boundToService = false;
|
||||
}
|
||||
};
|
||||
}
|
23
app/src/main/java/com/jens/automation2/ActivityHelp.java
Normal file
23
app/src/main/java/com/jens/automation2/ActivityHelp.java
Normal file
@ -0,0 +1,23 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.text.method.LinkMovementMethod;
|
||||
import android.widget.TextView;
|
||||
|
||||
import com.jens.automation2.R.layout;
|
||||
|
||||
public class ActivityHelp extends Activity
|
||||
{
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(layout.help_text);
|
||||
|
||||
TextView tvHelpTextEnergySaving = (TextView) findViewById(R.id.tvHelpTextEnergySaving);
|
||||
tvHelpTextEnergySaving.setMovementMethod(LinkMovementMethod.getInstance());
|
||||
}
|
||||
|
||||
}
|
201
app/src/main/java/com/jens/automation2/ActivityMainPoi.java
Normal file
201
app/src/main/java/com/jens/automation2/ActivityMainPoi.java
Normal file
@ -0,0 +1,201 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.AutomationService.serviceCommands;
|
||||
|
||||
public class ActivityMainPoi extends ActivityGeneric
|
||||
{
|
||||
private Button bAddPoi;
|
||||
ListView poiListView;
|
||||
|
||||
ArrayAdapter<PointOfInterest> poiListViewAdapter;
|
||||
|
||||
AutomationService myAutomationService;
|
||||
boolean boundToService = false;
|
||||
|
||||
protected static ActivityMainPoi instance = null;
|
||||
|
||||
public static PointOfInterest poiToEdit;
|
||||
|
||||
protected final static int requestCodeForPermission = 1002;
|
||||
|
||||
public static ActivityMainPoi getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
instance = new ActivityMainPoi();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main_poi_layout);
|
||||
|
||||
instance = this;
|
||||
|
||||
bAddPoi = (Button)findViewById(R.id.bAddPoi);
|
||||
bAddPoi.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(!ActivityPermissions.havePermission(ActivityPermissions.writeExternalStoragePermissionName, ActivityMainPoi.this))
|
||||
{
|
||||
Toast.makeText(ActivityMainPoi.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, ActivityMainPoi.this) || !ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, ActivityMainPoi.this))
|
||||
{
|
||||
Intent permissionIntent = new Intent(ActivityMainPoi.this, ActivityPermissions.class);
|
||||
|
||||
permissionIntent.putExtra(ActivityPermissions.intentExtraName, new String[] { ActivityPermissions.permissionNameLocationCoarse, ActivityPermissions.permissionNameLocationFine });
|
||||
|
||||
startActivityForResult(permissionIntent, requestCodeForPermission);
|
||||
}
|
||||
else
|
||||
{
|
||||
buttonAddPoi();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
poiListView = (ListView)findViewById(R.id.lvPoiList);
|
||||
|
||||
poiListViewAdapter = new ArrayAdapter<PointOfInterest>(this, R.layout.text_view_for_poi_listview_mediumtextsize, PointOfInterest.getPointOfInterestCollection());
|
||||
poiListView.setClickable(true);
|
||||
/*poiListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
poiToEdit = (PointOfInterest)poiListViewAdapter.getItem(arg2);
|
||||
Intent manageSpecificPoiIntent = new Intent (ActivityMainPoi.this, ActivityManageSpecificPoi.class);
|
||||
manageSpecificPoiIntent.putExtra("action", "change");
|
||||
startActivityForResult(manageSpecificPoiIntent, 2000);
|
||||
}
|
||||
});*/
|
||||
poiListView.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
getPoiOptionsDialog((PointOfInterest)poiListView.getItemAtPosition(arg2)).show();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
updateListView();
|
||||
|
||||
this.storeServiceReferenceInVariable();
|
||||
}
|
||||
|
||||
private void buttonAddPoi()
|
||||
{
|
||||
poiToEdit = null;
|
||||
Intent manageSpecificPoiIntent = new Intent(ActivityMainPoi.this, ActivityManageSpecificPoi.class);
|
||||
manageSpecificPoiIntent.putExtra("action", "create");
|
||||
startActivityForResult(manageSpecificPoiIntent, 1000);
|
||||
}
|
||||
|
||||
public void updateListView()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "ListView", "Attempting to update PoiListView", 5);
|
||||
try
|
||||
{
|
||||
if(poiListView.getAdapter() == null)
|
||||
poiListView.setAdapter(poiListViewAdapter);
|
||||
|
||||
poiListViewAdapter.notifyDataSetChanged();
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if(AutomationService.isMyServiceRunning(this))
|
||||
bindToService();
|
||||
|
||||
switch(requestCode)
|
||||
{
|
||||
case 1000: //add Poi
|
||||
// poiToEdit = null; //clear cache
|
||||
updateListView();
|
||||
break;
|
||||
case 2000://edit Poi
|
||||
poiToEdit = null; //clear cache
|
||||
updateListView();
|
||||
break;
|
||||
case requestCodeForPermission:
|
||||
if(resultCode == RESULT_OK)
|
||||
buttonAddPoi();
|
||||
break;
|
||||
}
|
||||
|
||||
if(boundToService && AutomationService.isMyServiceRunning(this))
|
||||
{
|
||||
myAutomationService.serviceInterface(serviceCommands.updateNotification); //in case names got changed.
|
||||
unBindFromService();
|
||||
}
|
||||
}
|
||||
|
||||
private AlertDialog getPoiOptionsDialog(final PointOfInterest pointOfInterest)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithPoi));
|
||||
alertDialogBuilder.setItems(new String[]{ getResources().getString(R.string.edit), getResources().getString(R.string.deleteCapital) }, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
switch(which)
|
||||
{
|
||||
/*case 0:
|
||||
if(AutomationService.isMyServiceRunning(ActivityMainPoi.this))
|
||||
{
|
||||
AutomationService runContext = AutomationService.getInstance();
|
||||
if(runContext != null)
|
||||
{
|
||||
pointOfInterest.activate(runContext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Toast.makeText(ActivityMainPoi.this, getResources().getString(R.string.serviceHasToRunForThat), Toast.LENGTH_LONG).show();
|
||||
break;*/
|
||||
case 0:
|
||||
poiToEdit = pointOfInterest;
|
||||
Intent manageSpecificPoiIntent = new Intent (ActivityMainPoi.this, ActivityManageSpecificPoi.class);
|
||||
manageSpecificPoiIntent.putExtra("action", "change");
|
||||
startActivityForResult(manageSpecificPoiIntent, 2000);
|
||||
break;
|
||||
case 1:
|
||||
if(pointOfInterest.delete(Miscellaneous.getAnyContext()))
|
||||
updateListView();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
}
|
198
app/src/main/java/com/jens/automation2/ActivityMainProfiles.java
Normal file
198
app/src/main/java/com/jens/automation2/ActivityMainProfiles.java
Normal file
@ -0,0 +1,198 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.AutomationService.serviceCommands;
|
||||
|
||||
public class ActivityMainProfiles extends ActivityGeneric
|
||||
{
|
||||
private Button bAddProfile;
|
||||
ListView profileListView;
|
||||
|
||||
ArrayAdapter<Profile> profileListViewAdapter;
|
||||
|
||||
AutomationService myAutomationService;
|
||||
|
||||
public static Profile profileToEdit;
|
||||
|
||||
protected static ActivityMainProfiles instance = null;
|
||||
|
||||
public static ActivityMainProfiles getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
instance = new ActivityMainProfiles();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main_profile_layout);
|
||||
|
||||
instance = this;
|
||||
|
||||
bAddProfile = (Button)findViewById(R.id.bAddProfile);
|
||||
bAddProfile.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(!ActivityPermissions.havePermission(ActivityPermissions.writeExternalStoragePermissionName, ActivityMainProfiles.this))
|
||||
{
|
||||
Toast.makeText(ActivityMainProfiles.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
profileToEdit = null;
|
||||
Intent manageSpecificProfileIntent = new Intent (ActivityMainProfiles.this, ActivityManageSpecificProfile.class);
|
||||
manageSpecificProfileIntent.putExtra("action", "create");
|
||||
startActivityForResult(manageSpecificProfileIntent, 1000);
|
||||
}
|
||||
});
|
||||
|
||||
profileListView = (ListView)findViewById(R.id.lvProfilesList);
|
||||
|
||||
profileListViewAdapter = new ArrayAdapter<Profile>(this, R.layout.text_view_for_poi_listview_mediumtextsize, Profile.getProfileCollection());
|
||||
profileListView.setClickable(true);
|
||||
/*profileListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
profileToEdit = (Profile)profileListViewAdapter.getItem(arg2);
|
||||
Intent manageSpecificProfileIntent = new Intent (ActivityMainProfiles.this, ActivityManageSpecificProfile.class);
|
||||
manageSpecificProfileIntent.putExtra("action", "change");
|
||||
startActivityForResult(manageSpecificProfileIntent, 2000);
|
||||
}
|
||||
});*/
|
||||
profileListView.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
getProfileDialog((Profile)profileListView.getItemAtPosition(arg2)).show();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if(Settings.executeRulesAndProfilesWithSingleClick)
|
||||
{
|
||||
profileListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
if(AutomationService.isMyServiceRunning(ActivityMainProfiles.this))
|
||||
{
|
||||
AutomationService runContext = AutomationService.getInstance();
|
||||
if(runContext != null)
|
||||
{
|
||||
Profile profile = (Profile)profileListView.getItemAtPosition(position);
|
||||
profile.activate(runContext);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateListView();
|
||||
|
||||
this.storeServiceReferenceInVariable();
|
||||
}
|
||||
|
||||
public void updateListView()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "ListView", "Attempting to update ProfileListView", 5);
|
||||
try
|
||||
{
|
||||
if(profileListView.getAdapter() == null)
|
||||
profileListView.setAdapter(profileListViewAdapter);
|
||||
|
||||
profileListViewAdapter.notifyDataSetChanged();
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
if(AutomationService.isMyServiceRunning(this))
|
||||
bindToService();
|
||||
|
||||
if(requestCode == 1000) //add Profile
|
||||
{
|
||||
// profileToEdit = null; //clear cache
|
||||
updateListView();
|
||||
}
|
||||
|
||||
if(requestCode == 2000) //edit Profile
|
||||
{
|
||||
profileToEdit = null; //clear cache
|
||||
updateListView();
|
||||
}
|
||||
|
||||
if(boundToService && AutomationService.isMyServiceRunning(this))
|
||||
{
|
||||
myAutomationService.serviceInterface(serviceCommands.updateNotification); // in case names got changed.
|
||||
unBindFromService();
|
||||
}
|
||||
}
|
||||
|
||||
private AlertDialog getProfileDialog(final Profile profile)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithProfile));
|
||||
alertDialogBuilder.setItems(new String[]{ getResources().getString(R.string.runManually), getResources().getString(R.string.edit), getResources().getString(R.string.deleteCapital) }, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
switch(which)
|
||||
{
|
||||
case 0:
|
||||
if(AutomationService.isMyServiceRunning(ActivityMainProfiles.this))
|
||||
{
|
||||
AutomationService runContext = AutomationService.getInstance();
|
||||
if(runContext != null)
|
||||
{
|
||||
profile.activate(runContext);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Toast.makeText(ActivityMainProfiles.this, getResources().getString(R.string.serviceHasToRunForThat), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case 1:
|
||||
profileToEdit = profile;
|
||||
Intent manageSpecificProfileIntent = new Intent (ActivityMainProfiles.this, ActivityManageSpecificProfile.class);
|
||||
manageSpecificProfileIntent.putExtra("action", "change");
|
||||
startActivityForResult(manageSpecificProfileIntent, 2000);
|
||||
break;
|
||||
case 2:
|
||||
if(profile.delete(myAutomationService))
|
||||
updateListView();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
}
|
252
app/src/main/java/com/jens/automation2/ActivityMainRules.java
Normal file
252
app/src/main/java/com/jens/automation2/ActivityMainRules.java
Normal file
@ -0,0 +1,252 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.AutomationService.serviceCommands;
|
||||
import com.jens.automation2.receivers.AlarmListener;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ActivityMainRules extends ActivityGeneric
|
||||
{
|
||||
private ListView ruleListView;
|
||||
private ArrayAdapter<Rule> ruleListViewAdapter;
|
||||
public static Rule ruleToEdit;
|
||||
protected static ActivityMainRules instance = null;
|
||||
|
||||
public static ActivityMainRules getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
instance = new ActivityMainRules();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main_rule_layout);
|
||||
|
||||
instance = this;
|
||||
|
||||
Button bAddRule = (Button)findViewById(R.id.bAddRule);
|
||||
bAddRule.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(!ActivityPermissions.havePermission(ActivityPermissions.writeExternalStoragePermissionName, ActivityMainRules.this))
|
||||
{
|
||||
Toast.makeText(ActivityMainRules.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
ruleToEdit = null;
|
||||
Intent startAddRuleIntent = new Intent(ActivityMainRules.this, ActivityManageSpecificRule.class);
|
||||
startActivityForResult(startAddRuleIntent, 3000);
|
||||
}
|
||||
});
|
||||
|
||||
ruleListView = (ListView)findViewById(R.id.lvRuleList);
|
||||
|
||||
ruleListViewAdapter = new RuleArrayAdapter(this, R.layout.view_for_rule_listview, Rule.getRuleCollection());
|
||||
ruleListView.setClickable(true);
|
||||
|
||||
ruleListView.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
getRuleDialog((Rule)ruleListView.getItemAtPosition(arg2)).show();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
if(Settings.executeRulesAndProfilesWithSingleClick)
|
||||
{
|
||||
ruleListView.setOnItemClickListener(new AdapterView.OnItemClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
if(AutomationService.isMyServiceRunning(ActivityMainRules.this))
|
||||
{
|
||||
AutomationService runContext = AutomationService.getInstance();
|
||||
if(runContext != null)
|
||||
{
|
||||
Rule rule = (Rule)ruleListView.getItemAtPosition(position);
|
||||
rule.activate(runContext, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateListView();
|
||||
|
||||
this.storeServiceReferenceInVariable();
|
||||
}
|
||||
|
||||
private static class RuleHolder
|
||||
{
|
||||
public ImageView ivActiveInactive;
|
||||
public TextView tvRuleName;
|
||||
}
|
||||
|
||||
private static class RuleArrayAdapter extends ArrayAdapter<Rule>
|
||||
{
|
||||
|
||||
public RuleArrayAdapter(Context context, int resource, ArrayList<Rule> objects)
|
||||
{
|
||||
super(context, resource, objects);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View getView(int position, View convertView, ViewGroup parent)
|
||||
{
|
||||
View v = convertView;
|
||||
RuleHolder holder = new RuleHolder();
|
||||
// First let's verify the convertView is not null
|
||||
if (convertView == null)
|
||||
{
|
||||
// This a new view we inflate the new layout
|
||||
LayoutInflater inflater = (LayoutInflater) this.getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
|
||||
v = inflater.inflate(R.layout.view_for_rule_listview, null);
|
||||
// Now we can fill the layout with the right values
|
||||
TextView tv = (TextView) v.findViewById(R.id.tvRuleName);
|
||||
ImageView img = (ImageView) v.findViewById(R.id.ivActiveInactive);
|
||||
holder.tvRuleName = tv;
|
||||
holder.ivActiveInactive = img;
|
||||
v.setTag(holder);
|
||||
}
|
||||
else
|
||||
holder = (RuleHolder) v.getTag();
|
||||
|
||||
System.out.println("Position ["+position+"]");
|
||||
Rule r = Rule.getRuleCollection().get(position);
|
||||
holder.tvRuleName.setText(r.getName());
|
||||
if(r.isRuleActive())
|
||||
{
|
||||
if (r.haveEnoughPermissions())
|
||||
holder.ivActiveInactive.setImageResource(R.drawable.status_active);
|
||||
else
|
||||
holder.ivActiveInactive.setImageResource(R.drawable.status_unable);
|
||||
}
|
||||
else
|
||||
holder.ivActiveInactive.setImageResource(R.drawable.status_inactive);
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
if(AutomationService.isMyServiceRunning(this))
|
||||
bindToService();
|
||||
|
||||
if(requestCode == 3000) //add Rule
|
||||
{
|
||||
ruleToEdit = null; //clear cache
|
||||
updateListView();
|
||||
}
|
||||
|
||||
if(requestCode == 4000) //editRule
|
||||
{
|
||||
ruleToEdit = null; //clear cache
|
||||
updateListView();
|
||||
}
|
||||
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
if(service != null)
|
||||
service.applySettingsAndRules();
|
||||
|
||||
if(boundToService && AutomationService.isMyServiceRunning(this))
|
||||
{
|
||||
myAutomationService.serviceInterface(serviceCommands.updateNotification); //in case names got changed.
|
||||
unBindFromService();
|
||||
}
|
||||
}
|
||||
|
||||
private AlertDialog getRuleDialog(final Rule ruleThisIsAbout)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithRule));
|
||||
alertDialogBuilder.setItems(new String[]{ getResources().getString(R.string.runManually), getResources().getString(R.string.edit), getResources().getString(R.string.deleteCapital) }, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
switch(which)
|
||||
{
|
||||
case 0:
|
||||
if(AutomationService.isMyServiceRunning(ActivityMainRules.this))
|
||||
{
|
||||
AutomationService runContext = AutomationService.getInstance();
|
||||
if(runContext != null)
|
||||
{
|
||||
ruleThisIsAbout.activate(runContext, true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Toast.makeText(ActivityMainRules.this, getResources().getString(R.string.serviceHasToRunForThat), Toast.LENGTH_LONG).show();
|
||||
break;
|
||||
case 1:
|
||||
ruleToEdit = ruleThisIsAbout;
|
||||
Intent manageSpecificRuleIntent = new Intent (ActivityMainRules.this, ActivityManageSpecificRule.class);
|
||||
startActivityForResult(manageSpecificRuleIntent, 4000);
|
||||
break;
|
||||
case 2:
|
||||
if(ruleThisIsAbout.delete())
|
||||
updateListView();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
public void updateListView()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "ListView", "Attempting to update RuleListView", 4);
|
||||
try
|
||||
{
|
||||
if(ruleListView.getAdapter() == null)
|
||||
ruleListView.setAdapter(ruleListViewAdapter);
|
||||
|
||||
ruleListViewAdapter.notifyDataSetChanged();
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{}
|
||||
|
||||
try
|
||||
{
|
||||
if(AutomationService.isMyServiceRunning(this))
|
||||
AlarmListener.reloadAlarms();
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{
|
||||
// AlarmManager instance not prepared, yet.
|
||||
}
|
||||
}
|
||||
}
|
600
app/src/main/java/com/jens/automation2/ActivityMainScreen.java
Normal file
600
app/src/main/java/com/jens/automation2/ActivityMainScreen.java
Normal file
@ -0,0 +1,600 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.ToggleButton;
|
||||
|
||||
import com.google.android.gms.appindexing.AppIndex;
|
||||
import com.google.android.gms.appindexing.Thing;
|
||||
import com.google.android.gms.common.api.GoogleApiClient;
|
||||
import com.jens.automation2.AutomationService.serviceCommands;
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class ActivityMainScreen extends ActivityGeneric
|
||||
{
|
||||
private static boolean guiChangeInProgress = false;
|
||||
|
||||
private static ActivityMainScreen activityMainScreenInstance = null;
|
||||
private ToggleButton toggleService, tbLockSound;
|
||||
private Button bShowHelp, bPrivacy, bSettingsErase, bSettingsSetToDefault, bVolumeTest, bAddSoundLockTIme;
|
||||
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNote, tvlockSoundDuration;
|
||||
|
||||
private ListView lvRuleHistory;
|
||||
private ArrayAdapter<Rule> ruleHistoryListViewAdapter;
|
||||
|
||||
private static boolean uiUpdateRunning = false;
|
||||
/**
|
||||
* ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
* See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
*/
|
||||
private GoogleApiClient client;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main_overview_layout);
|
||||
|
||||
activityMainScreenInstance = this;
|
||||
|
||||
if(ActivityPermissions.needMorePermissions(ActivityMainScreen.this))
|
||||
{
|
||||
Intent permissionsIntent = new Intent(ActivityMainScreen.this, ActivityPermissions.class);
|
||||
startActivityForResult(permissionsIntent, 7000);
|
||||
}
|
||||
|
||||
Settings.readFromPersistentStorage(this);
|
||||
|
||||
guiChangeInProgress = true;
|
||||
|
||||
tvActivePoi = (TextView) findViewById(R.id.tvActivePoi);
|
||||
tvClosestPoi = (TextView) findViewById(R.id.tvClosestPoi);
|
||||
lvRuleHistory = (ListView) findViewById(R.id.lvRuleHistory);
|
||||
tvLastRule = (TextView) findViewById(R.id.tvTimeFrameHelpText);
|
||||
tvMainScreenNote = (TextView) findViewById(R.id.tvMainScreenNote);
|
||||
tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
|
||||
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
|
||||
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if (!ActivityMainScreen.this.uiUpdateRunning)
|
||||
{
|
||||
if (toggleService.isChecked())
|
||||
{
|
||||
startAutomationService(getBaseContext(), false);
|
||||
} else
|
||||
{
|
||||
stopAutomationService();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
tvMainScreenNote.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(ActivityMainScreen.this, ActivityPermissions.class);
|
||||
startActivityForResult(intent, ActivityPermissions.requestCodeForPermissions);
|
||||
}
|
||||
});
|
||||
|
||||
tbLockSound.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
Settings.lockSoundChanges = isChecked;
|
||||
|
||||
if(!isChecked)
|
||||
{
|
||||
AutomationService.getInstance().nullLockSoundChangesEnd();
|
||||
updateMainScreen();
|
||||
}
|
||||
|
||||
if (!guiChangeInProgress)
|
||||
Settings.writeSettings(ActivityMainScreen.this);
|
||||
}
|
||||
});
|
||||
|
||||
Button bSettings = (Button) findViewById(R.id.bSettings);
|
||||
bSettings.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent myIntent = new Intent(ActivityMainScreen.this, ActivitySettings.class);
|
||||
startActivityForResult(myIntent, 6000);
|
||||
}
|
||||
});
|
||||
|
||||
Button bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||
bVolumeTest.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(ActivityMainScreen.this, ActivityVolumeTest.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
bShowHelp = (Button) findViewById(R.id.bShowHelp);
|
||||
bShowHelp.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent showHelpIntent = new Intent(ActivityMainScreen.this, ActivityHelp.class);
|
||||
startActivity(showHelpIntent);
|
||||
}
|
||||
});
|
||||
|
||||
bPrivacy = (Button) findViewById(R.id.bPrivacy);
|
||||
bPrivacy.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityMainScreen.this);
|
||||
builder.setMessage(getResources().getString(R.string.privacyConfirmationText));
|
||||
builder.setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
openPrivacyPolicy();
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(getResources().getString(R.string.no), null);
|
||||
builder.create().show();
|
||||
}
|
||||
});
|
||||
|
||||
/*bSettingsErase = (Button)findViewById(R.id.bSettingsErase);
|
||||
bSettingsErase.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getEraseSettingsDialog(ActivityMainScreen.this).show();
|
||||
}
|
||||
});*/
|
||||
bSettingsSetToDefault = (Button) findViewById(R.id.bSettingsSetToDefault);
|
||||
bSettingsSetToDefault.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getDefaultSettingsDialog(ActivityMainScreen.this).show();
|
||||
}
|
||||
});
|
||||
|
||||
lvRuleHistory.setOnTouchListener(new OnTouchListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event)
|
||||
{
|
||||
v.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
bAddSoundLockTIme = (Button)findViewById(R.id.bAddSoundLockTIme);
|
||||
bAddSoundLockTIme.setText("+" + Settings.lockSoundChangesInterval + " min");
|
||||
bAddSoundLockTIme.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(AutomationService.isMyServiceRunning(ActivityMainScreen.this))
|
||||
{
|
||||
AutomationService.getInstance().lockSoundChangesEndAddTime();
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMainScreen.this, getResources().getString(R.string.serviceNotRunning), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
|
||||
ruleHistoryListViewAdapter = new ArrayAdapter<Rule>(this, R.layout.text_view_for_poi_listview_mediumtextsize, Rule.getRuleRunHistory());
|
||||
|
||||
if (PointOfInterest.getPointOfInterestCollection() == null | PointOfInterest.getPointOfInterestCollection().size() == 0)
|
||||
PointOfInterest.loadPoisFromFile();
|
||||
if (Rule.getRuleCollection() == null | Rule.getRuleCollection().size() == 0)
|
||||
Rule.readFromFile();
|
||||
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
|
||||
this.storeServiceReferenceInVariable();
|
||||
|
||||
guiChangeInProgress = false;
|
||||
// ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
// See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
|
||||
}
|
||||
|
||||
private static AlertDialog getEraseSettingsDialog(final Context context)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(context.getResources().getString(R.string.areYouSure));
|
||||
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
if (Settings.eraseSettings(context))
|
||||
Toast.makeText(context, context.getResources().getString(R.string.settingsErased), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
private static AlertDialog getDefaultSettingsDialog(final Context context)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(context.getResources().getString(R.string.areYouSure));
|
||||
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
if (Settings.initializeSettings(context, true))
|
||||
Toast.makeText(context, context.getResources().getString(R.string.settingsSetToDefault), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
});
|
||||
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
public static ActivityMainScreen getActivityMainScreenInstance()
|
||||
{
|
||||
return activityMainScreenInstance;
|
||||
}
|
||||
|
||||
public static void updateMainScreen()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "MainScreen", "Request to update notification.", 5);
|
||||
|
||||
if (activityMainScreenInstance != null)
|
||||
{
|
||||
if(ActivityPermissions.needMorePermissions(activityMainScreenInstance))
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNote.setText(R.string.mainScreenPermissionNote);
|
||||
activityMainScreenInstance.tvMainScreenNote.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNote.setText("");
|
||||
activityMainScreenInstance.tvMainScreenNote.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (AutomationService.isMyServiceRunning(activityMainScreenInstance))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "MainScreen", "Service is running. Updating mainscreen with this info.", 5);
|
||||
uiUpdateRunning = true;
|
||||
activityMainScreenInstance.toggleService.setChecked(true);
|
||||
uiUpdateRunning = false;
|
||||
// if(activityMainScreenInstance.hasWindowFocus())
|
||||
// {
|
||||
try
|
||||
{
|
||||
PointOfInterest activePoi = PointOfInterest.getActivePoi();
|
||||
if (activePoi == null)
|
||||
{
|
||||
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(LocationProvider.getInstance().getCurrentLocation());
|
||||
activityMainScreenInstance.tvActivePoi.setText("none");
|
||||
activityMainScreenInstance.tvClosestPoi.setText(closestPoi.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
activityMainScreenInstance.tvActivePoi.setText(activePoi.getName());
|
||||
activityMainScreenInstance.tvClosestPoi.setText("n./a.");
|
||||
}
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
if (PointOfInterest.getPointOfInterestCollection().size() > 0)
|
||||
{
|
||||
if(
|
||||
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, AutomationService.getInstance())
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, AutomationService.getInstance())
|
||||
)
|
||||
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.stillGettingPosition));
|
||||
else
|
||||
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.locationEngineNotActive));
|
||||
|
||||
activityMainScreenInstance.tvClosestPoi.setText("n./a.");
|
||||
}
|
||||
else
|
||||
{
|
||||
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.noPoisDefinedShort));
|
||||
activityMainScreenInstance.tvClosestPoi.setText("n./a.");
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
activityMainScreenInstance.tvLastRule.setText(Rule.getLastActivatedRule().getName() + " " + activityMainScreenInstance.getResources().getString(R.string.at) + " " + Rule.getLastActivatedRuleActivationTime().toLocaleString());
|
||||
activityMainScreenInstance.updateListView();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
activityMainScreenInstance.tvLastRule.setText("n./a.");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "MainScreen", "Service not running. Updating mainscreen with this info.", 5);
|
||||
activityMainScreenInstance.toggleService.setChecked(false);
|
||||
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.serviceNotRunning));
|
||||
activityMainScreenInstance.tvClosestPoi.setText("");
|
||||
activityMainScreenInstance.tvLastRule.setText("");
|
||||
}
|
||||
|
||||
// uiUpdateRunning = true;
|
||||
if(AutomationService.isMyServiceRunning(ActivityMainScreen.getActivityMainScreenInstance()) && AutomationService.getInstance() != null)
|
||||
{
|
||||
AutomationService.getInstance().checkLockSoundChangesTimeElapsed();
|
||||
|
||||
Calendar end = AutomationService.getInstance().getLockSoundChangesEnd();
|
||||
activityMainScreenInstance.tbLockSound.setChecked(end != null);
|
||||
activityMainScreenInstance.tbLockSound.setEnabled(end != null);
|
||||
|
||||
if(end != null)
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
long millis = end.getTimeInMillis() - now.getTimeInMillis();
|
||||
long minutes = millis/1000/60;
|
||||
if(minutes < 60)
|
||||
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(minutes + " min..."));
|
||||
else
|
||||
{
|
||||
double hours = (double)minutes / 60.0;
|
||||
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(Math.round(hours * 100.0) / 100.0) + " h...");
|
||||
}
|
||||
}
|
||||
else
|
||||
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(""));
|
||||
}
|
||||
else
|
||||
{
|
||||
activityMainScreenInstance.tbLockSound.setChecked(false);
|
||||
activityMainScreenInstance.tbLockSound.setEnabled(false);
|
||||
activityMainScreenInstance.tvlockSoundDuration.setText("");
|
||||
}
|
||||
Settings.writeSettings(activityMainScreenInstance);
|
||||
// uiUpdateRunning = false;
|
||||
// }
|
||||
// else
|
||||
// Miscellaneous.logEvent("i", "ActivityMainScreen", "Window doesn't have focus. We're not updating anything.", 5);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "ActivityMainScreen", "Activity not running. No need to update.", 5);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
super.onActivityResult(requestCode, resultCode, data);
|
||||
|
||||
// Miscellaneous.logEvent("i", "ListView", "Notifying ListViewAdapter", 4);
|
||||
|
||||
if (AutomationService.isMyServiceRunning(this))
|
||||
bindToService();
|
||||
|
||||
switch (requestCode)
|
||||
{
|
||||
case ActivityPermissions.requestCodeForPermissions:
|
||||
updateMainScreen();
|
||||
break;
|
||||
case 6000: //settings
|
||||
Settings.readFromPersistentStorage(this);
|
||||
|
||||
if (boundToService && AutomationService.isMyServiceRunning(this))
|
||||
myAutomationService.serviceInterface(serviceCommands.reloadSettings);
|
||||
|
||||
if(AutomationService.isMyServiceRunning(ActivityMainScreen.this))
|
||||
Toast.makeText(this, getResources().getString(R.string.settingsWillTakeTime), Toast.LENGTH_LONG).show();
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (AutomationService.isMyServiceRunning(this))
|
||||
{
|
||||
// Let service reload via binding interface.
|
||||
if (boundToService)
|
||||
{
|
||||
myAutomationService.serviceInterface(serviceCommands.updateNotification); //in case names got changed.
|
||||
unBindFromService();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Let service reload classically.
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
if (service != null)
|
||||
service.applySettingsAndRules();
|
||||
}
|
||||
}
|
||||
|
||||
public static void startAutomationService(Context context, boolean startAtBoot)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (Rule.getRuleCollection().size() > 0)
|
||||
{
|
||||
if (!AutomationService.isMyServiceRunning(context))
|
||||
{
|
||||
// if(myServiceIntent == null) //do we need that line?????
|
||||
myServiceIntent = new Intent(context, AutomationService.class);
|
||||
myServiceIntent.putExtra("startAtBoot", startAtBoot);
|
||||
context.startService(myServiceIntent);
|
||||
} else
|
||||
Miscellaneous.logEvent("w", "Service", context.getResources().getString(R.string.logServiceAlreadyRunning), 3);
|
||||
} else
|
||||
{
|
||||
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStart), Toast.LENGTH_LONG).show();
|
||||
activityMainScreenInstance.toggleService.setChecked(false);
|
||||
}
|
||||
}
|
||||
catch (NullPointerException ne)
|
||||
{
|
||||
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStart), Toast.LENGTH_LONG).show();
|
||||
activityMainScreenInstance.toggleService.setChecked(false);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Toast.makeText(context, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
|
||||
activityMainScreenInstance.toggleService.setChecked(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void stopAutomationService()
|
||||
{
|
||||
if (myServiceIntent == null)
|
||||
myServiceIntent = new Intent(this, AutomationService.class);
|
||||
stopService(myServiceIntent);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onRestart()
|
||||
{
|
||||
super.onRestart();
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onStart()
|
||||
{
|
||||
super.onStart();// ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
// See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
client.connect();
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
// ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
// See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
AppIndex.AppIndexApi.start(client, getIndexApiAction());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 28 && !Settings.noticeAndroid9MicrophoneShown && Rule.isAnyRuleUsing(Trigger_Enum.noiseLevel))
|
||||
{
|
||||
Settings.noticeAndroid9MicrophoneShown = true;
|
||||
Settings.writeSettings(ActivityMainScreen.this);
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.app_name), getResources().getString(R.string.android9RecordAudioNotice) + " " + getResources().getString(R.string.messageNotShownAgain), ActivityMainScreen.this).show();
|
||||
}
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 29 && !Settings.noticeAndroid10WifiShown && Rule.isAnyRuleUsing(Action.Action_Enum.setWifi))
|
||||
{
|
||||
Settings.noticeAndroid10WifiShown = true;
|
||||
Settings.writeSettings(ActivityMainScreen.this);
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.app_name), getResources().getString(R.string.android10WifiToggleNotice) + " " + getResources().getString(R.string.messageNotShownAgain), ActivityMainScreen.this).show();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
activityMainScreenInstance = null;
|
||||
}
|
||||
|
||||
private void openPrivacyPolicy()
|
||||
{
|
||||
String privacyPolicyUrl = "http://server47.de/automation/privacy.html";
|
||||
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl));
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
|
||||
private void updateListView()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "ListView", "Attempting to update lvRuleHistory", 4);
|
||||
try
|
||||
{
|
||||
if (lvRuleHistory.getAdapter() == null)
|
||||
lvRuleHistory.setAdapter(ruleHistoryListViewAdapter);
|
||||
|
||||
ruleHistoryListViewAdapter.notifyDataSetChanged();
|
||||
} catch (NullPointerException e)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
* See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
*/
|
||||
public com.google.android.gms.appindexing.Action getIndexApiAction()
|
||||
{
|
||||
Thing object = new Thing.Builder()
|
||||
.setName("ActivityMainScreen Page") // TODO: Define a title for the content shown.
|
||||
// TODO: Make sure this auto-generated URL is correct.
|
||||
.setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
|
||||
.build();
|
||||
return new com.google.android.gms.appindexing.Action.Builder(com.google.android.gms.appindexing.Action.TYPE_VIEW)
|
||||
.setObject(object)
|
||||
.setActionStatus(com.google.android.gms.appindexing.Action.STATUS_TYPE_COMPLETED)
|
||||
.build();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop()
|
||||
{
|
||||
super.onStop();
|
||||
|
||||
// ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||
// See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||
AppIndex.AppIndexApi.end(client, getIndexApiAction());
|
||||
client.disconnect();
|
||||
}
|
||||
|
||||
public static void showMessageBox(String title, String text)
|
||||
{
|
||||
Miscellaneous.messageBox(title, text, ActivityMainScreen.getActivityMainScreenInstance());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,70 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.TabActivity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.widget.TabHost;
|
||||
import android.widget.TabHost.TabSpec;
|
||||
|
||||
import com.jens.automation2.receivers.NfcReceiver;
|
||||
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class ActivityMainTabLayout extends TabActivity
|
||||
{
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main_tab_layout);
|
||||
|
||||
TabHost tabHost = getTabHost();
|
||||
|
||||
TabSpec specOverview = tabHost.newTabSpec("overview");
|
||||
specOverview.setIndicator(getResources().getString(R.string.overview), getResources().getDrawable(R.drawable.icon_overview_tab));
|
||||
Intent overviewIntent = new Intent(this, ActivityMainScreen.class);
|
||||
specOverview.setContent(overviewIntent);
|
||||
|
||||
TabSpec specPoi = tabHost.newTabSpec("pois");
|
||||
specPoi.setIndicator(getResources().getString(R.string.pois), getResources().getDrawable(R.drawable.map));
|
||||
Intent mainPoiIntent = new Intent(this, ActivityMainPoi.class);
|
||||
specPoi.setContent(mainPoiIntent);
|
||||
|
||||
TabSpec specRules = tabHost.newTabSpec("rules");
|
||||
specRules.setIndicator(getResources().getString(R.string.rules), getResources().getDrawable(R.drawable.gear));
|
||||
Intent mainRulesIntent = new Intent(this, ActivityMainRules.class);
|
||||
specRules.setContent(mainRulesIntent);
|
||||
|
||||
TabSpec specProfiles = tabHost.newTabSpec("profiles");
|
||||
specProfiles.setIndicator(getResources().getString(R.string.profiles), getResources().getDrawable(R.drawable.sound));
|
||||
Intent mainProfilesIntent = new Intent(this, ActivityMainProfiles.class);
|
||||
specProfiles.setContent(mainProfilesIntent);
|
||||
|
||||
tabHost.addTab(specOverview);
|
||||
tabHost.addTab(specPoi);
|
||||
tabHost.addTab(specRules);
|
||||
tabHost.addTab(specProfiles);
|
||||
|
||||
tabHost.setCurrentTab(Settings.startScreen);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
// Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onResume().", 5);
|
||||
NfcReceiver.checkIntentForNFC(this, getIntent());
|
||||
// NfcReceiver.checkIntentForNFC(this, new Intent(this.getApplicationContext(), this.getClass()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent)
|
||||
{
|
||||
// Miscellaneous.logEvent("i", "NFC", "ActivityMainTabLayout.onNewIntent().", 5);
|
||||
// setIntent(intent);
|
||||
NfcReceiver.checkIntentForNFC(this, intent);
|
||||
}
|
||||
}
|
@ -0,0 +1,187 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
||||
|
||||
public class ActivityManageBluetoothTrigger extends Activity
|
||||
{
|
||||
protected static Trigger editedBluetoothTrigger;
|
||||
RadioButton radioAnyBluetoothDevice, radioNoDevice, radioDeviceFromList, radioBluetoothConnected, radioBluetoothDisconnected, radioBluetoothInRange, radioBluetoothOutRange;
|
||||
Button bSaveBluetoothTrigger;
|
||||
Spinner spinnerBluetoothDevices;
|
||||
|
||||
ArrayAdapter<String> bluetoothDevicesSpinnerAdapter;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_bluetooth_trigger);
|
||||
|
||||
radioAnyBluetoothDevice = (RadioButton)findViewById(R.id.radioAnyBluetoothDevice);
|
||||
radioNoDevice = (RadioButton)findViewById(R.id.radioNoDevice);
|
||||
radioDeviceFromList = (RadioButton)findViewById(R.id.radioDeviceFromList);
|
||||
radioBluetoothConnected = (RadioButton)findViewById(R.id.radioBluetoothConnected);
|
||||
radioBluetoothDisconnected = (RadioButton)findViewById(R.id.radioBluetoothDisconnected);
|
||||
radioBluetoothInRange = (RadioButton)findViewById(R.id.radioBluetoothInRange);
|
||||
radioBluetoothOutRange = (RadioButton)findViewById(R.id.radioBluetoothOutRange);
|
||||
bSaveBluetoothTrigger = (Button)findViewById(R.id.bSaveBluetoothTrigger);
|
||||
spinnerBluetoothDevices = (Spinner)findViewById(R.id.spinnerBluetoothDevices);
|
||||
|
||||
bluetoothDevicesSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, BluetoothReceiver.getAllPairedBluetoothDevicesStrings());
|
||||
|
||||
radioDeviceFromList.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
spinnerBluetoothDevices.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
bSaveBluetoothTrigger.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(saveTrigger())
|
||||
{
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
refreshBluetoothDeviceSpinner();
|
||||
spinnerBluetoothDevices.setEnabled(false);
|
||||
|
||||
if(editedBluetoothTrigger.getBluetoothDeviceAddress() != null && editedBluetoothTrigger.getBluetoothDeviceAddress().length() > 0)
|
||||
loadVariableIntoGui();
|
||||
}
|
||||
|
||||
protected void refreshBluetoothDeviceSpinner()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Spinner", "Attempting to update spinnerBluetoothDevices", 4);
|
||||
if(spinnerBluetoothDevices.getAdapter() == null)
|
||||
{
|
||||
spinnerBluetoothDevices.setAdapter(bluetoothDevicesSpinnerAdapter);
|
||||
}
|
||||
|
||||
bluetoothDevicesSpinnerAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
protected boolean saveTrigger()
|
||||
{
|
||||
try
|
||||
{
|
||||
// DEVICE
|
||||
|
||||
if(radioAnyBluetoothDevice.isChecked())
|
||||
{
|
||||
editedBluetoothTrigger.setBluetoothDeviceAddress("<any>");
|
||||
}
|
||||
else if(radioNoDevice.isChecked())
|
||||
{
|
||||
editedBluetoothTrigger.setBluetoothDeviceAddress("<none>");
|
||||
}
|
||||
else if(radioDeviceFromList.isChecked())
|
||||
{
|
||||
BluetoothDevice selectedDevice = BluetoothReceiver.getAllPairedBluetoothDevices()[spinnerBluetoothDevices.getSelectedItemPosition()];
|
||||
if(selectedDevice != null)
|
||||
{
|
||||
editedBluetoothTrigger.setBluetoothDeviceAddress(selectedDevice.getAddress());
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "ActivityManageBluetoothTrigger", "Device not found.", 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.makeText(ActivityManageBluetoothTrigger.this, getResources().getString(R.string.selectDeviceOption), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// EVENT
|
||||
|
||||
if(radioBluetoothConnected.isChecked())
|
||||
{
|
||||
editedBluetoothTrigger.setTriggerParameter(true);
|
||||
editedBluetoothTrigger.setBluetoothEvent(BluetoothDevice.ACTION_ACL_CONNECTED);
|
||||
}
|
||||
else if(radioBluetoothDisconnected.isChecked())
|
||||
{
|
||||
editedBluetoothTrigger.setTriggerParameter(false);
|
||||
editedBluetoothTrigger.setBluetoothEvent(BluetoothDevice.ACTION_ACL_DISCONNECTED);
|
||||
}
|
||||
else if(radioBluetoothInRange.isChecked())
|
||||
{
|
||||
editedBluetoothTrigger.setTriggerParameter(true);
|
||||
editedBluetoothTrigger.setBluetoothEvent(BluetoothDevice.ACTION_FOUND);
|
||||
}
|
||||
else if(radioBluetoothOutRange.isChecked())
|
||||
{
|
||||
editedBluetoothTrigger.setTriggerParameter(false);
|
||||
editedBluetoothTrigger.setBluetoothEvent(BluetoothDevice.ACTION_FOUND);
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.makeText(ActivityManageBluetoothTrigger.this, getResources().getString(R.string.selectConnectionOption), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "ActivityManageBluetoothTrigger", "Error during trigger create/change: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected void loadVariableIntoGui()
|
||||
{
|
||||
if(editedBluetoothTrigger != null)
|
||||
{
|
||||
if(editedBluetoothTrigger.getBluetoothDeviceAddress().equals("<any>"))
|
||||
{
|
||||
radioAnyBluetoothDevice.setChecked(true);
|
||||
}
|
||||
else if(editedBluetoothTrigger.getBluetoothDeviceAddress().equals("<none>"))
|
||||
{
|
||||
radioNoDevice.setChecked(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
radioDeviceFromList.setChecked(true);
|
||||
spinnerBluetoothDevices.setSelection(BluetoothReceiver.getDevicePositionByAddress(editedBluetoothTrigger.getBluetoothDeviceAddress()));
|
||||
}
|
||||
|
||||
if(editedBluetoothTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_CONNECTED))
|
||||
{
|
||||
radioBluetoothConnected.setChecked(true);
|
||||
}
|
||||
else if(editedBluetoothTrigger.getBluetoothEvent().equals(BluetoothDevice.ACTION_ACL_DISCONNECTED))
|
||||
{
|
||||
radioBluetoothDisconnected.setChecked(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
radioBluetoothInRange.setChecked(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,64 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class ActivityManageBrightnessSetting extends Activity
|
||||
{
|
||||
CheckBox chkAutoBrightness;
|
||||
SeekBar sbBrightness;
|
||||
Button bApplyBrightness;
|
||||
TextView tvAutoBrightnessNotice;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
setContentView(R.layout.activity_manage_brightness_setting);
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
chkAutoBrightness = (CheckBox)findViewById(R.id.chkAutoBrightness);
|
||||
sbBrightness = (SeekBar)findViewById(R.id.sbBrightness);
|
||||
bApplyBrightness = (Button)findViewById(R.id.bApplyBrightness);
|
||||
tvAutoBrightnessNotice = (TextView)findViewById(R.id.tvAutoBrightnessNotice);
|
||||
|
||||
Intent input = getIntent();
|
||||
|
||||
if(input.hasExtra("autoBrightness"))
|
||||
chkAutoBrightness.setChecked(input.getBooleanExtra("autoBrightness", false));
|
||||
|
||||
if(input.hasExtra("brightnessValue"))
|
||||
sbBrightness.setProgress(input.getIntExtra("brightnessValue", 0));
|
||||
|
||||
bApplyBrightness.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Intent answer = new Intent();
|
||||
answer.putExtra("autoBrightness", chkAutoBrightness.isChecked());
|
||||
answer.putExtra("brightnessValue", sbBrightness.getProgress());
|
||||
setResult(RESULT_OK, answer);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
chkAutoBrightness.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
tvAutoBrightnessNotice.setText(R.string.autoBrightnessNotice);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
306
app/src/main/java/com/jens/automation2/ActivityManageNfc.java
Normal file
306
app/src/main/java/com/jens/automation2/ActivityManageNfc.java
Normal file
@ -0,0 +1,306 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.DialogInterface.OnCancelListener;
|
||||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.nfc.NfcAdapter;
|
||||
import android.nfc.Tag;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.receivers.NfcReceiver;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class ActivityManageNfc extends Activity
|
||||
{
|
||||
public static String generatedId = null;
|
||||
private static Tag discoveredTag = null;
|
||||
|
||||
EditText etNewNfcIdValue;
|
||||
Button bReadNfcTag, bUseValueCurrentlyStored, bWriteNfcTag;
|
||||
TextView tvCurrentNfcId;
|
||||
|
||||
private static int currentStatus = 0;
|
||||
private static ProgressDialog progressDialog = null;
|
||||
|
||||
// Check if NFC is activated
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.manage_nfc);
|
||||
|
||||
etNewNfcIdValue = (EditText)findViewById(R.id.etNewNfcIdValue);
|
||||
bReadNfcTag = (Button)findViewById(R.id.bReadNfcTag);
|
||||
bUseValueCurrentlyStored = (Button)findViewById(R.id.bUseValueCurrentlyStored);
|
||||
bWriteNfcTag = (Button)findViewById(R.id.bWriteNfcTag);
|
||||
tvCurrentNfcId = (TextView)findViewById(R.id.tvCurrentNfcId);
|
||||
|
||||
bReadNfcTag.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(discoveredTag != null)
|
||||
{
|
||||
generatedId = NfcReceiver.readTag(discoveredTag);
|
||||
tvCurrentNfcId.setText(generatedId);
|
||||
}
|
||||
else
|
||||
{
|
||||
progressDialog = ProgressDialog.show(ActivityManageNfc.this, null, getResources().getString(R.string.nfcBringTagIntoRange), false, true, new OnCancelListener()
|
||||
{
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
progressDialog = null;
|
||||
currentStatus = 0;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bUseValueCurrentlyStored.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(discoveredTag != null)
|
||||
{
|
||||
if(checkEnteredText(false))
|
||||
{
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
progressDialog = ProgressDialog.show(ActivityManageNfc.this, null, getResources().getString(R.string.nfcBringTagIntoRange), false, true, new OnCancelListener()
|
||||
{
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
progressDialog = null;
|
||||
currentStatus = 0;
|
||||
}
|
||||
});
|
||||
|
||||
currentStatus = 1;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bWriteNfcTag.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(checkEnteredText(true))
|
||||
{
|
||||
// ActivityPermissions.requestSpecificPermission("android.permission.NFC");
|
||||
if(discoveredTag != null)
|
||||
{
|
||||
tryWrite();
|
||||
}
|
||||
else
|
||||
{
|
||||
progressDialog = ProgressDialog.show(ActivityManageNfc.this, null, getResources().getString(R.string.nfcBringTagIntoRange), false, true, new OnCancelListener()
|
||||
{
|
||||
@Override
|
||||
public void onCancel(DialogInterface dialog)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
progressDialog = null;
|
||||
currentStatus = 0;
|
||||
}
|
||||
});
|
||||
|
||||
currentStatus = 2;
|
||||
|
||||
// Toast.makeText(ActivityManageNfc.this, "No tag.", Toast.LENGTH_LONG).show();
|
||||
// Miscellaneous.logEvent("w", "NFC", "No tag.", 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(generatedId != null)
|
||||
etNewNfcIdValue.setText(generatedId);
|
||||
}
|
||||
|
||||
public static void enableForegroundDispatch(final Activity activity)
|
||||
{
|
||||
NfcAdapter nfcAdapter = NfcReceiver.getNfcAdapter(activity);
|
||||
|
||||
final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
|
||||
final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
|
||||
|
||||
IntentFilter[] filters = new IntentFilter[1];
|
||||
String[][] techList = new String[][]{};
|
||||
|
||||
// Notice that this is the same filter as in our manifest.
|
||||
filters[0] = new IntentFilter();
|
||||
filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
|
||||
filters[0].addAction(NfcAdapter.ACTION_TAG_DISCOVERED);
|
||||
filters[0].addAction(NfcAdapter.ACTION_TECH_DISCOVERED);
|
||||
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
|
||||
// try
|
||||
// {
|
||||
// filters[0].addDataType(NfcReceiver.MIME_TEXT_PLAIN);
|
||||
// }
|
||||
// catch (MalformedMimeTypeException e)
|
||||
// {
|
||||
// throw new RuntimeException("Check your mime type.");
|
||||
// }
|
||||
|
||||
nfcAdapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
|
||||
|
||||
Miscellaneous.logEvent("i", "NFC", "Enabled foreground dispatch.", 5);
|
||||
}
|
||||
|
||||
public static void disableForegroundDispatch(final Activity activity)
|
||||
{
|
||||
NfcAdapter nfcAdapter = NfcReceiver.getNfcAdapter(activity);
|
||||
nfcAdapter.disableForegroundDispatch(activity);
|
||||
Miscellaneous.logEvent("i", "NFC", "Disabled foreground dispatch.", 5);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause()
|
||||
{
|
||||
/**
|
||||
* Call this before onPause, otherwise an IllegalArgumentException is thrown as well.
|
||||
*/
|
||||
disableForegroundDispatch(this);
|
||||
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
/**
|
||||
* It's important, that the activity is in the foreground (resumed). Otherwise
|
||||
* an IllegalStateException is thrown.
|
||||
*/
|
||||
enableForegroundDispatch(this);
|
||||
|
||||
// NfcReceiver.checkIntentForNFC(this, new Intent(this.getApplicationContext(), this.getClass()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onNewIntent(Intent intent)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NFC", "ActivityManageNfc->onNewIntent().", 5);
|
||||
|
||||
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
|
||||
|
||||
if(tag == null)
|
||||
{
|
||||
tvCurrentNfcId.setText(getResources().getString(R.string.nfcNoTag));
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NFC", getResources().getString(R.string.nfcTagDiscovered), 4);
|
||||
Toast.makeText(this, getResources().getString(R.string.nfcTagDiscovered), Toast.LENGTH_LONG).show();
|
||||
discoveredTag = tag;
|
||||
if(progressDialog != null)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
progressDialog = null;
|
||||
}
|
||||
|
||||
if(currentStatus == 0)
|
||||
{
|
||||
generatedId = NfcReceiver.readTag(discoveredTag);
|
||||
if(generatedId != null && generatedId.length() > 0)
|
||||
tvCurrentNfcId.setText(generatedId);
|
||||
else
|
||||
tvCurrentNfcId.setText(getResources().getString(R.string.nfcTagDataNotUsable));
|
||||
}
|
||||
else if(currentStatus == 1)
|
||||
{
|
||||
tryRead();
|
||||
}
|
||||
else if(currentStatus == 2)
|
||||
if(checkEnteredText(true))
|
||||
tryWrite();
|
||||
}
|
||||
|
||||
// NfcReceiver.checkIntentForNFC(this, intent);
|
||||
}
|
||||
|
||||
private boolean checkEnteredText(boolean checkGuiValue)
|
||||
{
|
||||
if(checkGuiValue)
|
||||
generatedId = etNewNfcIdValue.getText().toString();
|
||||
|
||||
if(generatedId.length() == 0)
|
||||
{
|
||||
generatedId = null;
|
||||
Toast.makeText(ActivityManageNfc.this, getResources().getString(R.string.nfcEnterValidIdentifier), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
|
||||
private void tryWrite()
|
||||
{
|
||||
if(NfcReceiver.writeTag(generatedId, discoveredTag))
|
||||
{
|
||||
currentStatus = 0;
|
||||
Toast.makeText(ActivityManageNfc.this, getResources().getString(R.string.nfcTagWrittenSuccessfully), Toast.LENGTH_LONG).show();
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentStatus = 0;
|
||||
Toast.makeText(ActivityManageNfc.this, getResources().getString(R.string.nfcTagWriteError), Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("e", "NFC", getResources().getString(R.string.nfcTagWriteError), 2);
|
||||
}
|
||||
}
|
||||
|
||||
private void tryRead()
|
||||
{
|
||||
generatedId = NfcReceiver.readTag(discoveredTag);
|
||||
if(checkEnteredText(false))
|
||||
{
|
||||
currentStatus = 0;
|
||||
Toast.makeText(ActivityManageNfc.this, getResources().getString(R.string.nfcTagReadSuccessfully), Toast.LENGTH_LONG).show();
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
else
|
||||
{
|
||||
currentStatus = 0;
|
||||
Toast.makeText(ActivityManageNfc.this, getResources().getString(R.string.nfcValueNotSuitable), Toast.LENGTH_LONG).show();
|
||||
generatedId = null;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onDestroy()
|
||||
{
|
||||
super.onDestroy();
|
||||
discoveredTag = null;
|
||||
}
|
||||
}
|
@ -0,0 +1,476 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.location.Criteria;
|
||||
import android.location.Location;
|
||||
import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
public class ActivityManageSpecificPoi extends Activity
|
||||
{
|
||||
public LocationManager myLocationManager;
|
||||
MyLocationListenerGps myLocationListenerGps = new MyLocationListenerGps();
|
||||
Location locationGps = null, locationNetwork = null;
|
||||
// Location locationWifi = null;
|
||||
MyLocationListenerNetwork myLocationListenerNetwork = new MyLocationListenerNetwork();
|
||||
Button bGetPosition, bSavePoi;
|
||||
ImageButton ibShowOnMap;
|
||||
EditText guiPoiName, guiPoiLatitude, guiPoiLongitude, guiPoiRadius;
|
||||
|
||||
private static ProgressDialog progressDialog;
|
||||
|
||||
@Override
|
||||
protected void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
Miscellaneous.logEvent("i", "ActivityManageSpecificPoi", getResources().getString(R.string.logClearingBothLocationListeners) , 5);
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
myLocationManager.removeUpdates(myLocationListenerNetwork);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.manage_specific_poi);
|
||||
|
||||
myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||
bGetPosition = (Button)findViewById(R.id.bGetPosition);
|
||||
ibShowOnMap = (ImageButton)findViewById(R.id.ibShowOnMap);
|
||||
|
||||
guiPoiName = (EditText)findViewById(R.id.etPoiName);
|
||||
guiPoiLatitude = (EditText)findViewById(R.id.etPoiLatitude);
|
||||
guiPoiLongitude = (EditText)findViewById(R.id.etPoiLongitude);
|
||||
guiPoiRadius = (EditText)findViewById(R.id.etPoiRadius);
|
||||
|
||||
bGetPosition.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
hideKeyboard();
|
||||
getNotificationDialog(getResources().getString(R.string.positioningWindowNotice)).show();
|
||||
}
|
||||
});
|
||||
|
||||
bSavePoi = (Button)findViewById(R.id.bSavePoi);
|
||||
bSavePoi.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
hideKeyboard();
|
||||
|
||||
if(ActivityMainPoi.poiToEdit == null)
|
||||
createPoi();
|
||||
else
|
||||
changePoi();
|
||||
}
|
||||
});
|
||||
|
||||
ibShowOnMap.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
hideKeyboard();
|
||||
showOnMap();
|
||||
}
|
||||
});
|
||||
|
||||
if(ActivityMainPoi.poiToEdit != null)
|
||||
editPoi(ActivityMainPoi.poiToEdit);
|
||||
//else
|
||||
// new Poi to be created
|
||||
}
|
||||
|
||||
private void createPoi()
|
||||
{
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
ActivityMainPoi.poiToEdit = new PointOfInterest();
|
||||
ActivityMainPoi.poiToEdit.setLocation(new Location("POINT_LOCATION"));
|
||||
if(loadFormValuesToVariable())
|
||||
if(ActivityMainPoi.poiToEdit.create(this))
|
||||
{
|
||||
this.setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
private void changePoi()
|
||||
{
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
if(loadFormValuesToVariable())
|
||||
if(ActivityMainPoi.poiToEdit.change(this))
|
||||
{
|
||||
this.setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void getLocation()
|
||||
{
|
||||
Criteria critNetwork = new Criteria();
|
||||
critNetwork.setPowerRequirement(Criteria.POWER_LOW);
|
||||
critNetwork.setAltitudeRequired(false);
|
||||
critNetwork.setSpeedRequired(false);
|
||||
critNetwork.setBearingRequired(false);
|
||||
critNetwork.setCostAllowed(false);
|
||||
critNetwork.setAccuracy(Criteria.ACCURACY_COARSE);
|
||||
|
||||
Criteria critGps = new Criteria();
|
||||
critGps.setAltitudeRequired(false);
|
||||
critGps.setSpeedRequired(false);
|
||||
critGps.setBearingRequired(false);
|
||||
critGps.setCostAllowed(true);
|
||||
critGps.setAccuracy(Criteria.ACCURACY_FINE);
|
||||
|
||||
String provider1 = myLocationManager.getBestProvider(critNetwork, true);
|
||||
String provider2 = myLocationManager.getBestProvider(critGps, true);
|
||||
// String provider3 = myLocationManager.getProvider("wifi");
|
||||
|
||||
if(provider1 == null | provider2 == null)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.logNoSuitableProvider), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGettingPositionWithProvider) + " " + provider1, 3);
|
||||
myLocationManager.requestLocationUpdates(provider1, 500, Settings.satisfactoryAccuracyNetwork, myLocationListenerNetwork);
|
||||
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGettingPositionWithProvider) + " " + provider2, 3);
|
||||
myLocationManager.requestLocationUpdates(provider2, 500, Settings.satisfactoryAccuracyGps, myLocationListenerGps);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void compareLocations()
|
||||
{
|
||||
if(locationGps != null)
|
||||
{
|
||||
guiPoiLatitude.setText(String.valueOf(locationGps.getLatitude()));
|
||||
guiPoiLongitude.setText(String.valueOf(locationGps.getLongitude()));
|
||||
|
||||
if(locationNetwork != null)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.comparing), 4);
|
||||
|
||||
double variance = locationGps.distanceTo(locationNetwork);
|
||||
|
||||
String text = getResources().getString(R.string.distanceBetween) + " " + String.valueOf(Math.round(variance)) + " " + getResources().getString(R.string.radiusSuggestion);
|
||||
// Toast.makeText(getBaseContext(), text, Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("i", "POI Manager", text, 4);
|
||||
// if(variance > 50 && guiPoiRadius.getText().toString().length()>0 && Integer.parseInt(guiPoiRadius.getText().toString())<variance)
|
||||
// {
|
||||
// String text = "Positioning via network is off by " + variance + " meters. The radius you specify shouldn't be smaller than that.";
|
||||
getDialog(text, Math.round(variance) + 1).show();
|
||||
// Toast.makeText(getBaseContext(), "Positioning via network is off by " + variance + " meters. The radius you specify shouldn't be smaller than that.", Toast.LENGTH_LONG).show();
|
||||
// }
|
||||
}
|
||||
else
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
myLocationManager.removeUpdates(myLocationListenerNetwork);
|
||||
guiPoiRadius.setText("250");
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logNotAllMeasurings), 4);
|
||||
}
|
||||
|
||||
private AlertDialog getNotificationDialog(String text)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
// switch(which)
|
||||
// {
|
||||
// case DialogInterface.BUTTON_POSITIVE:
|
||||
// guiPoiRadius.setText(String.valueOf(value));
|
||||
// break;
|
||||
// case DialogInterface.BUTTON_NEGATIVE:
|
||||
// break;
|
||||
// }
|
||||
|
||||
progressDialog = ProgressDialog.show(ActivityManageSpecificPoi.this, "", getResources().getString(R.string.gettingPosition), true, true);
|
||||
getLocation();
|
||||
}
|
||||
};
|
||||
alertDialogBuilder.setMessage(text).setPositiveButton("Ok", dialogClickListener);
|
||||
//.setNegativeButton("No", dialogClickListener);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getDialog(String text, final double value)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
switch(which)
|
||||
{
|
||||
case DialogInterface.BUTTON_POSITIVE:
|
||||
guiPoiRadius.setText(String.valueOf(value));
|
||||
break;
|
||||
case DialogInterface.BUTTON_NEGATIVE:
|
||||
break;
|
||||
}
|
||||
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
};
|
||||
alertDialogBuilder.setMessage(text).setPositiveButton(getResources().getString(R.string.yes), dialogClickListener)
|
||||
.setNegativeButton(getResources().getString(R.string.no), dialogClickListener);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
public class MyLocationListenerGps implements LocationListener
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGotGpsUpdate) + " " + String.valueOf(location.getAccuracy()), 3);
|
||||
// Deactivate when accuracy reached
|
||||
// if(location.getAccuracy() < Settings.SATISFACTORY_ACCURACY_GPS)
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", "POI Manager", "satisfactoryNetworkAccuracy of " + String.valueOf(Settings.SATISFACTORY_ACCURACY_GPS) + "m reached. Removing location updates...");
|
||||
|
||||
myLocationManager.removeUpdates(this);
|
||||
locationGps = location;
|
||||
|
||||
compareLocations();
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
// public class MyLocationListenerWifi implements LocationListener
|
||||
// {
|
||||
//
|
||||
// @Override
|
||||
// public void onLocationChanged(Location location)
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.gotGpsUpdate) + " " + String.valueOf(location.getAccuracy()));
|
||||
// // Deactivate when accuracy reached
|
||||
//// if(location.getAccuracy() < Settings.SATISFACTORY_ACCURACY_GPS)
|
||||
//// {
|
||||
//// Miscellaneous.logEvent("i", "POI Manager", "satisfactoryNetworkAccuracy of " + String.valueOf(Settings.SATISFACTORY_ACCURACY_GPS) + "m reached. Removing location updates...");
|
||||
//
|
||||
// myLocationManager.removeUpdates(this);
|
||||
// locationGps = location;
|
||||
//
|
||||
// compareLocations();
|
||||
//// }
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onProviderDisabled(String provider)
|
||||
// {
|
||||
// // TODO Auto-generated method stub
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onProviderEnabled(String provider)
|
||||
// {
|
||||
// // TODO Auto-generated method stub
|
||||
//
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onStatusChanged(String provider, int status, Bundle extras)
|
||||
// {
|
||||
// // TODO Auto-generated method stub
|
||||
//
|
||||
// }
|
||||
//
|
||||
// }
|
||||
public class MyLocationListenerNetwork implements LocationListener
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGotNetworkUpdate) + " " + String.valueOf(location.getAccuracy()), 3);
|
||||
// Deactivate when accuracy reached
|
||||
// if(location.getAccuracy() < Settings.SATISFACTORY_ACCURACY_GPS)
|
||||
// {
|
||||
// String text = "Network position found. satisfactoryNetworkAccuracy of " + String.valueOf(Settings.SATISFACTORY_ACCURACY_NETWORK) + "m reached. Removing location updates...";
|
||||
// Miscellaneous.logEvent("i", "POI Manager", text);
|
||||
myLocationManager.removeUpdates(this);
|
||||
locationNetwork = location;
|
||||
|
||||
compareLocations();
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderDisabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProviderEnabled(String provider)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStatusChanged(String provider, int status, Bundle extras)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void editPoi(PointOfInterest poi)
|
||||
{
|
||||
guiPoiName.setText(poi.getName());
|
||||
guiPoiLatitude.setText(String.valueOf(poi.getLocation().getLatitude()));
|
||||
guiPoiLongitude.setText(String.valueOf(poi.getLocation().getLongitude()));
|
||||
guiPoiRadius.setText(String.valueOf(poi.getRadius()));
|
||||
}
|
||||
|
||||
public boolean loadFormValuesToVariable()
|
||||
{
|
||||
if(ActivityMainPoi.poiToEdit == null)
|
||||
ActivityMainPoi.poiToEdit = new PointOfInterest();
|
||||
|
||||
if(guiPoiName.getText().length() == 0)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidName), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
else
|
||||
ActivityMainPoi.poiToEdit.setName(guiPoiName.getText().toString());
|
||||
|
||||
if(ActivityMainPoi.poiToEdit.getLocation() == null)
|
||||
ActivityMainPoi.poiToEdit.setLocation(new Location("POINT_LOCATION"));
|
||||
|
||||
try
|
||||
{
|
||||
ActivityMainPoi.poiToEdit.getLocation().setLatitude(Double.parseDouble(guiPoiLatitude.getText().toString()));
|
||||
}
|
||||
catch(NumberFormatException e)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidLatitude), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ActivityMainPoi.poiToEdit.getLocation().setLongitude(Double.parseDouble(guiPoiLongitude.getText().toString()));
|
||||
}
|
||||
catch(NumberFormatException e)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidLongitude), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
ActivityMainPoi.poiToEdit.setRadius(Double.parseDouble(guiPoiRadius.getText().toString()), this);
|
||||
}
|
||||
catch(NumberFormatException e)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidRadius), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.unknownError), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void showOnMap()
|
||||
{
|
||||
if(loadFormValuesToVariable())
|
||||
{
|
||||
try
|
||||
{
|
||||
String uri = "geo:" + guiPoiLatitude.getText().toString() + "," + guiPoiLongitude.getText().toString();
|
||||
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(uri)));
|
||||
|
||||
// You can also choose to place a point like so:
|
||||
// String uri = "geo:"+ latitude + "," + longitude + "?q=my+street+address";
|
||||
// startActivity(new Intent(android.content.Intent.ACTION_VIEW, Uri.parse(uri)));
|
||||
|
||||
/*
|
||||
* The Possible Query params options are the following:
|
||||
*
|
||||
* Show map at location: geo:latitude,longitude
|
||||
* Show zoomed map at location: geo:latitude,longitude?z=zoom
|
||||
* Show map at locaiton with point: geo:0,0?q=my+street+address
|
||||
* Show map of businesses in area: geo:0,0?q=business+near+city
|
||||
*
|
||||
*/
|
||||
}
|
||||
catch(ActivityNotFoundException e)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.noMapsApplicationFound), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void hideKeyboard()
|
||||
{
|
||||
View view = this.getCurrentFocus();
|
||||
if (view != null)
|
||||
{
|
||||
InputMethodManager imm = (InputMethodManager)getSystemService(Context.INPUT_METHOD_SERVICE);
|
||||
imm.hideSoftInputFromWindow(view.getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,487 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.ActivityNotFoundException;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.media.AudioManager;
|
||||
import android.media.RingtoneManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.provider.MediaStore;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||
import android.widget.EditText;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
public class ActivityManageSpecificProfile extends Activity
|
||||
{
|
||||
private static ProgressDialog progressDialog;
|
||||
final static int intentCodeRingtonePickerCallsFile = 9010;
|
||||
final static int intentCodeRingtonePickerCallsRingtone = 9011;
|
||||
final static int intentCodeRingtonePickerNotificationsFile = 9020;
|
||||
final static int intentCodeRingtonePickerNotificationsRingtone = 9021;
|
||||
|
||||
CheckBox checkBoxChangeSoundMode, checkBoxChangeVolumeMusicVideoGameMedia, checkBoxChangeVolumeNotifications, checkBoxChangeVolumeAlarms, checkBoxChangeIncomingCallsRingtone, checkBoxChangeNotificationRingtone, checkBoxChangeAudibleSelection, checkBoxChangeScreenLockUnlockSound, checkBoxChangeHapticFeedback, checkBoxChangeVibrateWhenRinging, checkBoxVibrateWhenRinging, checkBoxAudibleSelection, checkBoxScreenLockUnlockSound, checkBoxHapticFeedback;
|
||||
Spinner spinnerSoundMode;
|
||||
SeekBar seekBarVolumeMusic, seekBarVolumeNotifications, seekBarVolumeAlarms;
|
||||
Button bChangeSoundIncomingCalls, bChangeSoundNotifications, bSaveProfile;
|
||||
TextView tvIncomingCallsRingtone, tvNotificationsRingtone;
|
||||
EditText etName;
|
||||
|
||||
File incomingCallsRingtone = null, notificationsRingtone = null;
|
||||
|
||||
ArrayAdapter<String> soundModeAdapter;
|
||||
|
||||
public void setIncomingCallsRingtone(File incomingCallsRingtone)
|
||||
{
|
||||
this.incomingCallsRingtone = incomingCallsRingtone;
|
||||
|
||||
if(incomingCallsRingtone != null)
|
||||
tvIncomingCallsRingtone.setText(this.incomingCallsRingtone.getAbsolutePath());
|
||||
else
|
||||
tvIncomingCallsRingtone.setText(getResources().getString(R.string.none));
|
||||
}
|
||||
|
||||
public File getIncomingCallsRingtone()
|
||||
{
|
||||
return incomingCallsRingtone;
|
||||
}
|
||||
|
||||
public void setNotificationsRingtone(File notificationsRingtone)
|
||||
{
|
||||
this.notificationsRingtone = notificationsRingtone;
|
||||
|
||||
if(this.notificationsRingtone != null)
|
||||
tvNotificationsRingtone.setText(this.notificationsRingtone.getAbsolutePath());
|
||||
else
|
||||
tvNotificationsRingtone.setText(getResources().getString(R.string.none));
|
||||
}
|
||||
|
||||
public File getNotificationsRingtone()
|
||||
{
|
||||
return notificationsRingtone;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.manage_specific_profile);
|
||||
|
||||
checkBoxChangeSoundMode = (CheckBox)findViewById(R.id.checkBoxChangeSoundMode);
|
||||
checkBoxChangeVolumeMusicVideoGameMedia = (CheckBox)findViewById(R.id.checkBoxChangeVolumeMusicVideoGameMedia);
|
||||
checkBoxChangeVolumeNotifications = (CheckBox)findViewById(R.id.checkBoxChangeVolumeNotifications);
|
||||
checkBoxChangeVolumeAlarms = (CheckBox)findViewById(R.id.checkBoxChangeVolumeAlarms);
|
||||
checkBoxChangeIncomingCallsRingtone = (CheckBox)findViewById(R.id.checkBoxChangeIncomingCallsRingtone);
|
||||
checkBoxChangeNotificationRingtone = (CheckBox)findViewById(R.id.checkBoxChangeNotificationRingtone);
|
||||
checkBoxChangeAudibleSelection = (CheckBox)findViewById(R.id.checkBoxChangeAudibleSelection);
|
||||
checkBoxChangeScreenLockUnlockSound = (CheckBox)findViewById(R.id.checkBoxChangeScreenLockUnlockSound);
|
||||
checkBoxChangeHapticFeedback = (CheckBox)findViewById(R.id.checkBoxChangeHapticFeedback);
|
||||
checkBoxChangeVibrateWhenRinging = (CheckBox)findViewById(R.id.checkBoxChangeVibrateWhenRinging);
|
||||
checkBoxAudibleSelection = (CheckBox)findViewById(R.id.checkBoxAudibleSelection);
|
||||
checkBoxScreenLockUnlockSound = (CheckBox)findViewById(R.id.checkBoxScreenLockUnlockSound);
|
||||
checkBoxHapticFeedback = (CheckBox)findViewById(R.id.checkBoxHapticFeedback);
|
||||
checkBoxVibrateWhenRinging = (CheckBox)findViewById(R.id.checkBoxVibrateWhenRinging);
|
||||
spinnerSoundMode = (Spinner)findViewById(R.id.spinnerSoundMode);
|
||||
seekBarVolumeMusic = (SeekBar)findViewById(R.id.seekBarVolumeMusic);
|
||||
seekBarVolumeNotifications = (SeekBar)findViewById(R.id.seekBarVolumeNotifications);
|
||||
seekBarVolumeAlarms = (SeekBar)findViewById(R.id.seekBarVolumeAlarms);
|
||||
bChangeSoundIncomingCalls = (Button)findViewById(R.id.bChangeSoundIncomingCalls);
|
||||
bChangeSoundNotifications = (Button)findViewById(R.id.bChangeSoundNotifications);
|
||||
tvIncomingCallsRingtone = (TextView)findViewById(R.id.tvIncomingCallsRingtone);
|
||||
tvNotificationsRingtone = (TextView)findViewById(R.id.tvNotificationsRingtone);
|
||||
bSaveProfile = (Button)findViewById(R.id.bSaveProfile);
|
||||
etName = (EditText)findViewById(R.id.etName);
|
||||
|
||||
checkBoxVibrateWhenRinging.setEnabled(false);
|
||||
checkBoxAudibleSelection.setEnabled(false);
|
||||
checkBoxScreenLockUnlockSound.setEnabled(false);
|
||||
checkBoxHapticFeedback.setEnabled(false);
|
||||
spinnerSoundMode.setEnabled(false);
|
||||
seekBarVolumeMusic.setEnabled(false);
|
||||
seekBarVolumeNotifications.setEnabled(false);
|
||||
seekBarVolumeAlarms.setEnabled(false);
|
||||
bChangeSoundIncomingCalls.setEnabled(false);
|
||||
bChangeSoundNotifications.setEnabled(false);
|
||||
|
||||
spinnerSoundMode.setSelection(0);
|
||||
|
||||
// Scale SeekBars to the system's maximum volume values
|
||||
AudioManager am = (AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE);
|
||||
seekBarVolumeMusic.setMax(am.getStreamMaxVolume(AudioManager.STREAM_MUSIC));
|
||||
seekBarVolumeNotifications.setMax(am.getStreamMaxVolume(AudioManager.STREAM_NOTIFICATION));
|
||||
seekBarVolumeAlarms.setMax(am.getStreamMaxVolume(AudioManager.STREAM_ALARM));
|
||||
|
||||
soundModeAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, new String[] { getResources().getString(R.string.soundModeSilent), getResources().getString(R.string.soundModeVibrate), getResources().getString(R.string.soundModeNormal) });
|
||||
spinnerSoundMode.setAdapter(soundModeAdapter);
|
||||
|
||||
checkBoxChangeSoundMode.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
spinnerSoundMode.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
checkBoxChangeVolumeMusicVideoGameMedia.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
seekBarVolumeMusic.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
checkBoxChangeVolumeNotifications.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
seekBarVolumeNotifications.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
checkBoxChangeVolumeAlarms.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
seekBarVolumeAlarms.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
checkBoxChangeIncomingCallsRingtone.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
bChangeSoundIncomingCalls.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
checkBoxChangeNotificationRingtone.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
bChangeSoundNotifications.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
checkBoxChangeAudibleSelection.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
checkBoxAudibleSelection.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
checkBoxChangeScreenLockUnlockSound.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
checkBoxScreenLockUnlockSound.setEnabled(isChecked);
|
||||
|
||||
if(isChecked && Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
Miscellaneous.messageBox("Info", getResources().getString(R.string.screenLockSoundNotice), ActivityManageSpecificProfile.this).show();
|
||||
}
|
||||
});
|
||||
checkBoxChangeHapticFeedback.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
checkBoxHapticFeedback.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
checkBoxChangeVibrateWhenRinging.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
checkBoxVibrateWhenRinging.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
bSaveProfile.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
try
|
||||
{
|
||||
if(ActivityMainProfiles.profileToEdit == null)
|
||||
createProfile(ActivityManageSpecificProfile.this);
|
||||
else
|
||||
changeProfile();
|
||||
}
|
||||
catch(Exception ex)
|
||||
{
|
||||
Toast.makeText(ActivityManageSpecificProfile.this, getResources().getString(R.string.errorWritingFile) + " " + ex.getMessage(), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bChangeSoundIncomingCalls.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
try
|
||||
{
|
||||
Intent fileIntent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
fileIntent.setType("audio/*");
|
||||
startActivityForResult(Intent.createChooser(fileIntent, "Select a ringtone"), intentCodeRingtonePickerCallsFile);
|
||||
}
|
||||
catch(ActivityNotFoundException e)
|
||||
{
|
||||
// Use media browser instead
|
||||
Intent fileSelectionIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
|
||||
|
||||
if(ActivityMainProfiles.profileToEdit != null)
|
||||
{
|
||||
Uri currenturi = Uri.parse(ActivityMainProfiles.profileToEdit.incomingCallsRingtone.getAbsolutePath());
|
||||
if(ActivityMainProfiles.profileToEdit.changeIncomingCallsRingtone)
|
||||
fileSelectionIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currenturi);
|
||||
}
|
||||
|
||||
startActivityForResult(fileSelectionIntent, intentCodeRingtonePickerCallsRingtone);
|
||||
}
|
||||
}
|
||||
});
|
||||
bChangeSoundNotifications.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
try
|
||||
{
|
||||
Intent fileIntent = new Intent(Intent.ACTION_GET_CONTENT);
|
||||
fileIntent.setType("audio/*");
|
||||
startActivityForResult(Intent.createChooser(fileIntent, "Select a ringtone"), intentCodeRingtonePickerNotificationsFile);
|
||||
}
|
||||
catch(ActivityNotFoundException e)
|
||||
{
|
||||
// Use media browser instead
|
||||
Intent fileSelectionIntent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
|
||||
|
||||
if(ActivityMainProfiles.profileToEdit != null)
|
||||
{
|
||||
Uri currenturi = Uri.parse(ActivityMainProfiles.profileToEdit.notificationRingtone.getAbsolutePath());
|
||||
if(ActivityMainProfiles.profileToEdit.changeNotificationRingtone)
|
||||
fileSelectionIntent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, currenturi);
|
||||
}
|
||||
|
||||
startActivityForResult(fileSelectionIntent, intentCodeRingtonePickerNotificationsRingtone);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if(ActivityMainProfiles.profileToEdit != null)
|
||||
editProfile(ActivityMainProfiles.profileToEdit);
|
||||
//else
|
||||
// new Profile to be created
|
||||
|
||||
// Toast.makeText(this, getResources().getString(R.string.someOptionsNotAvailableYet), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void createProfile(Context context)
|
||||
{
|
||||
if(plausibilityCheck())
|
||||
{
|
||||
if(loadFormValuesToVariable())
|
||||
if(ActivityMainProfiles.profileToEdit.create(context, true))
|
||||
{
|
||||
this.setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
private void changeProfile()
|
||||
{
|
||||
if(plausibilityCheck())
|
||||
{
|
||||
loadFormValuesToVariable();
|
||||
|
||||
if(ActivityMainProfiles.profileToEdit.change(this))
|
||||
{
|
||||
this.setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void editProfile(Profile profileToEdit)
|
||||
{
|
||||
etName.setText(ActivityMainProfiles.profileToEdit.getName());
|
||||
checkBoxChangeSoundMode.setChecked(ActivityMainProfiles.profileToEdit.getChangeSoundMode());
|
||||
checkBoxChangeVolumeMusicVideoGameMedia.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeMusicVideoGameMedia());
|
||||
checkBoxChangeVolumeNotifications.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeNotifications());
|
||||
checkBoxChangeVolumeAlarms.setChecked(ActivityMainProfiles.profileToEdit.getChangeVolumeAlarms());
|
||||
checkBoxChangeIncomingCallsRingtone.setChecked(ActivityMainProfiles.profileToEdit.getChangeIncomingCallsRingtone());
|
||||
checkBoxChangeNotificationRingtone.setChecked(ActivityMainProfiles.profileToEdit.getChangeNotificationRingtone());
|
||||
checkBoxChangeAudibleSelection.setChecked(ActivityMainProfiles.profileToEdit.getChangeAudibleSelection());
|
||||
checkBoxChangeScreenLockUnlockSound.setChecked(ActivityMainProfiles.profileToEdit.getChangeScreenLockUnlockSound());
|
||||
checkBoxChangeHapticFeedback.setChecked(ActivityMainProfiles.profileToEdit.getChangeHapticFeedback());
|
||||
checkBoxChangeVibrateWhenRinging.setChecked(ActivityMainProfiles.profileToEdit.getChangeVibrateWhenRinging());
|
||||
|
||||
spinnerSoundMode.setSelection(ActivityMainProfiles.profileToEdit.getSoundMode());
|
||||
seekBarVolumeMusic.setProgress(ActivityMainProfiles.profileToEdit.getVolumeMusic());
|
||||
seekBarVolumeNotifications.setProgress(ActivityMainProfiles.profileToEdit.getVolumeNotifications());
|
||||
seekBarVolumeAlarms.setProgress(ActivityMainProfiles.profileToEdit.getVolumeAlarms());
|
||||
checkBoxAudibleSelection.setChecked(ActivityMainProfiles.profileToEdit.audibleSelection);
|
||||
checkBoxScreenLockUnlockSound.setChecked(ActivityMainProfiles.profileToEdit.screenLockUnlockSound);
|
||||
checkBoxHapticFeedback.setChecked(ActivityMainProfiles.profileToEdit.hapticFeedback);
|
||||
checkBoxVibrateWhenRinging.setChecked(ActivityMainProfiles.profileToEdit.vibrateWhenRinging);
|
||||
|
||||
setIncomingCallsRingtone(ActivityMainProfiles.profileToEdit.getIncomingCallsRingtone());
|
||||
setNotificationsRingtone(ActivityMainProfiles.profileToEdit.getNotificationRingtone());
|
||||
}
|
||||
|
||||
private boolean loadFormValuesToVariable()
|
||||
{
|
||||
if(plausibilityCheck())
|
||||
{
|
||||
if(ActivityMainProfiles.profileToEdit == null)
|
||||
ActivityMainProfiles.profileToEdit = new Profile();
|
||||
|
||||
ActivityMainProfiles.profileToEdit.setName(etName.getText().toString());
|
||||
ActivityMainProfiles.profileToEdit.setChangeSoundMode(checkBoxChangeSoundMode.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeVolumeMusicVideoGameMedia(checkBoxChangeVolumeMusicVideoGameMedia.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeVolumeNotifications(checkBoxChangeVolumeNotifications.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeVolumeAlarms(checkBoxChangeVolumeAlarms.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeIncomingCallsRingtone(checkBoxChangeIncomingCallsRingtone.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeNotificationRingtone(checkBoxChangeNotificationRingtone.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeAudibleSelection(checkBoxChangeAudibleSelection.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeScreenLockUnlockSound(checkBoxChangeScreenLockUnlockSound.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeHapticFeedback(checkBoxChangeHapticFeedback.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setChangeVibrateWhenRinging(checkBoxChangeVibrateWhenRinging.isChecked());
|
||||
|
||||
ActivityMainProfiles.profileToEdit.setAudibleSelection(checkBoxAudibleSelection.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setScreenLockUnlockSound(checkBoxScreenLockUnlockSound.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setHapticFeedback(checkBoxHapticFeedback.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setVibrateWhenRinging(checkBoxVibrateWhenRinging.isChecked());
|
||||
ActivityMainProfiles.profileToEdit.setSoundMode(spinnerSoundMode.getSelectedItemPosition());
|
||||
ActivityMainProfiles.profileToEdit.setVolumeMusic(seekBarVolumeMusic.getProgress());
|
||||
ActivityMainProfiles.profileToEdit.setVolumeNotifications(seekBarVolumeNotifications.getProgress());
|
||||
ActivityMainProfiles.profileToEdit.setVolumeAlarms(seekBarVolumeAlarms.getProgress());
|
||||
ActivityMainProfiles.profileToEdit.setIncomingCallsRingtone(incomingCallsRingtone);
|
||||
ActivityMainProfiles.profileToEdit.setNotificationRingtone(notificationsRingtone);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean plausibilityCheck()
|
||||
{
|
||||
if(etName.getText().toString().length() > 0)
|
||||
{
|
||||
// Check for duplicates
|
||||
// for(Profile.)
|
||||
// if(etName.getText().toString()
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.enterAname), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!checkBoxChangeSoundMode.isChecked()
|
||||
&
|
||||
!checkBoxChangeVolumeMusicVideoGameMedia.isChecked()
|
||||
&
|
||||
!checkBoxChangeVolumeNotifications.isChecked()
|
||||
&
|
||||
!checkBoxChangeVolumeAlarms.isChecked()
|
||||
&
|
||||
!checkBoxChangeIncomingCallsRingtone.isChecked()
|
||||
&
|
||||
!checkBoxChangeNotificationRingtone.isChecked()
|
||||
&
|
||||
!checkBoxChangeAudibleSelection.isChecked()
|
||||
&
|
||||
!checkBoxChangeScreenLockUnlockSound.isChecked()
|
||||
&
|
||||
!checkBoxChangeHapticFeedback.isChecked()
|
||||
)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.noChangeSelectedProfileDoesntMakeSense), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
switch (requestCode)
|
||||
{
|
||||
case intentCodeRingtonePickerCallsRingtone: // incoming calls
|
||||
{
|
||||
// Method for ringtone selection
|
||||
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
||||
if (uri != null)
|
||||
{
|
||||
String ringTonePath = CompensateCrappyAndroidPaths.getPath(ActivityManageSpecificProfile.this, uri);
|
||||
setIncomingCallsRingtone(new File(ringTonePath));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case intentCodeRingtonePickerCallsFile:
|
||||
{
|
||||
String ringTonePath = CompensateCrappyAndroidPaths.getPath(ActivityManageSpecificProfile.this, data.getData());
|
||||
setIncomingCallsRingtone(new File(ringTonePath));
|
||||
break;
|
||||
}
|
||||
case intentCodeRingtonePickerNotificationsRingtone: // notifications
|
||||
{
|
||||
Uri uri = data.getParcelableExtra(RingtoneManager.EXTRA_RINGTONE_PICKED_URI);
|
||||
if (uri != null)
|
||||
{
|
||||
String ringTonePath = CompensateCrappyAndroidPaths.getPath(ActivityManageSpecificProfile.this, data.getData());
|
||||
setNotificationsRingtone(new File(ringTonePath));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case intentCodeRingtonePickerNotificationsFile:
|
||||
{
|
||||
String ringTonePath = CompensateCrappyAndroidPaths.getPath(ActivityManageSpecificProfile.this, data.getData());
|
||||
setNotificationsRingtone(new File(ringTonePath));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public String getRealPathFromURI(Uri uri)
|
||||
{
|
||||
String[] projection = { MediaStore.Images.Media.DATA };
|
||||
Cursor cursor = getContentResolver().query(uri, projection, null, null, null);
|
||||
if (cursor == null) return null;
|
||||
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||
cursor.moveToFirst();
|
||||
String s=cursor.getString(column_index);
|
||||
cursor.close();
|
||||
return s;
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,500 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.ProgressDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.View.OnTouchListener;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityManageStartActivity extends Activity
|
||||
{
|
||||
ListView lvIntentPairs;
|
||||
EditText etParameterName, etParameterValue;
|
||||
Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity;
|
||||
Spinner spinnerParameterType;
|
||||
TextView tvSelectedActivity;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
|
||||
private class CustomPackageInfo extends PackageInfo implements Comparable<CustomPackageInfo>
|
||||
{
|
||||
@Override
|
||||
public int compareTo(CustomPackageInfo another)
|
||||
{
|
||||
String name1 = "";
|
||||
String name2 = "";
|
||||
|
||||
ApplicationInfo aInfo1 = this.applicationInfo;
|
||||
if (aInfo1 != null)
|
||||
{
|
||||
name1 = (String) ActivityManageStartActivity.this.getPackageManager().getApplicationLabel(aInfo1);
|
||||
}
|
||||
ApplicationInfo aInfo2 = another.applicationInfo;
|
||||
if (aInfo2 != null)
|
||||
{
|
||||
name2 = (String) ActivityManageStartActivity.this.getPackageManager().getApplicationLabel(aInfo2);
|
||||
}
|
||||
|
||||
return name1.compareTo(name2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static List<PackageInfo> pInfos = null;
|
||||
public static Action resultingAction;
|
||||
|
||||
private static final String[] supportedIntentTypes = { "boolean", "byte", "char", "double", "float", "int", "long", "short", "String" };
|
||||
private ArrayList<String> intentPairList = new ArrayList<String>();
|
||||
|
||||
ArrayAdapter<String> intentTypeSpinnerAdapter, intentPairAdapter;
|
||||
|
||||
public static void getActivityList(final Context context)
|
||||
{
|
||||
if(pInfos == null)
|
||||
{
|
||||
pInfos = context.getPackageManager().getInstalledPackages(PackageManager.GET_ACTIVITIES);
|
||||
Collections.sort(pInfos, new Comparator<PackageInfo>()
|
||||
{
|
||||
public int compare(PackageInfo obj1, PackageInfo obj2)
|
||||
{
|
||||
String name1 = "";
|
||||
String name2 = "";
|
||||
|
||||
ApplicationInfo aInfo1 = obj1.applicationInfo;
|
||||
if (aInfo1 != null)
|
||||
{
|
||||
name1 = (String) context.getPackageManager().getApplicationLabel(aInfo1);
|
||||
}
|
||||
ApplicationInfo aInfo2 = obj2.applicationInfo;
|
||||
if (aInfo2 != null)
|
||||
{
|
||||
name2 = (String) context.getPackageManager().getApplicationLabel(aInfo2);
|
||||
}
|
||||
|
||||
return name1.compareTo(name2);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public static String[] getApplicationNameListString(Context myContext)
|
||||
{
|
||||
// Generate the actual list
|
||||
getActivityList(myContext);
|
||||
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
ApplicationInfo aInfo = pInfo.applicationInfo;
|
||||
if (aInfo != null)
|
||||
{
|
||||
String aLabel;
|
||||
|
||||
aLabel = (String) myContext.getPackageManager().getApplicationLabel(aInfo);
|
||||
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null && aInfos.length > 0) // Only put Applications into the list that have packages.
|
||||
{
|
||||
if(!returnList.contains(aLabel))
|
||||
returnList.add(aLabel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static String[] getPackageListString(Context myContext, String applicationLabel)
|
||||
{
|
||||
// Generate the actual list
|
||||
getActivityList(myContext);
|
||||
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
if(myContext.getPackageManager().getApplicationLabel(pInfo.applicationInfo).equals(applicationLabel))
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null && aInfos.length > 0)
|
||||
{
|
||||
returnList.add(pInfo.packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static String[] getPackageListString(Context myContext)
|
||||
{
|
||||
// Generate the actual list
|
||||
getActivityList(myContext);
|
||||
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null && aInfos.length > 0)
|
||||
{
|
||||
returnList.add(pInfo.packageName);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "Empty Application", "Application " + myContext.getPackageManager().getApplicationLabel(pInfo.applicationInfo) + " doesn\'t have packages.", 5);
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static String[] getActivityListForPackageName(String packageName)
|
||||
{
|
||||
ArrayList<String> returnList = new ArrayList<String>();
|
||||
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
if(pInfo.packageName.equals(packageName))
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null)
|
||||
{
|
||||
for (ActivityInfo activityInfo : aInfos)
|
||||
{
|
||||
returnList.add(activityInfo.name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return returnList.toArray(new String[returnList.size()]);
|
||||
}
|
||||
|
||||
public static ActivityInfo getActivityInfoForPackageNameAndActivityName(String packageName, String activityName)
|
||||
{
|
||||
for (PackageInfo pInfo : pInfos)
|
||||
{
|
||||
if(pInfo.packageName.equals(packageName))
|
||||
{
|
||||
ActivityInfo[] aInfos = pInfo.activities;
|
||||
if (aInfos != null)
|
||||
{
|
||||
for (ActivityInfo activityInfo : aInfos)
|
||||
{
|
||||
if(activityInfo.name.equals(activityName))
|
||||
return activityInfo;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private AlertDialog getActionStartActivityDialog1()
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectApplication));
|
||||
final String[] applicationArray = ActivityManageStartActivity.getApplicationNameListString(this);
|
||||
alertDialogBuilder.setItems(applicationArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
dialog.dismiss();
|
||||
getActionStartActivityDialog2(applicationArray[which]).show();
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getActionStartActivityDialog2(String applicationName)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectPackageOfApplication));
|
||||
final String[] packageArray = ActivityManageStartActivity.getPackageListString(this, applicationName);
|
||||
alertDialogBuilder.setItems(packageArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
getActionStartActivityDialog3(packageArray[which]).show();
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.chooseActivityHint), ActivityManageStartActivity.this).show();
|
||||
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getActionStartActivityDialog3(final String packageName)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.selectActivityToBeStarted));
|
||||
final String activityArray[] = ActivityManageStartActivity.getActivityListForPackageName(packageName);
|
||||
alertDialogBuilder.setItems(activityArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
ActivityInfo ai = ActivityManageStartActivity.getActivityInfoForPackageNameAndActivityName(packageName, activityArray[which]);
|
||||
tvSelectedActivity.setText(ai.packageName + ";" + ai.name);
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.action_start_activity);
|
||||
|
||||
lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs);
|
||||
etParameterName = (EditText)findViewById(R.id.etParameterName);
|
||||
etParameterValue = (EditText)findViewById(R.id.etParameterValue);
|
||||
bSelectApp = (Button)findViewById(R.id.bSelectApp);
|
||||
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
|
||||
bSaveActionStartOtherActivity = (Button)findViewById(R.id.bSaveActionStartOtherActivity);
|
||||
spinnerParameterType = (Spinner)findViewById(R.id.spinnerParameterType);
|
||||
tvSelectedActivity = (TextView)findViewById(R.id.tvSelectedActivity);
|
||||
|
||||
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageStartActivity.supportedIntentTypes);
|
||||
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
|
||||
intentTypeSpinnerAdapter.notifyDataSetChanged();
|
||||
|
||||
intentPairAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_smalltextsize, intentPairList);
|
||||
|
||||
bSelectApp.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
GetActivityListTask getActivityListTask = new GetActivityListTask();
|
||||
getActivityListTask.execute();
|
||||
progressDialog = ProgressDialog.show(ActivityManageStartActivity.this, "", ActivityManageStartActivity.this.getResources().getString(R.string.gettingListOfInstalledApplications));
|
||||
}
|
||||
});
|
||||
|
||||
bAddIntentPair.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
// type;name;value
|
||||
if(spinnerParameterType.getSelectedItem().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageStartActivity.this, getResources().getString(R.string.selectTypeOfIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(etParameterName.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageStartActivity.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(etParameterValue.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageStartActivity.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + "/" + etParameterName.getText().toString() + "/" + etParameterValue.getText().toString();
|
||||
intentPairList.add(param);
|
||||
|
||||
spinnerParameterType.setSelection(0);
|
||||
etParameterName.setText("");
|
||||
etParameterValue.setText("");
|
||||
|
||||
updateIntentPairList();
|
||||
}
|
||||
});
|
||||
|
||||
lvIntentPairs.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onItemLongClick(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
getIntentPairDialog(arg2).show();
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
bSaveActionStartOtherActivity.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(saveAction())
|
||||
{
|
||||
ActivityManageStartActivity.this.setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
lvIntentPairs.setOnTouchListener(new OnTouchListener()
|
||||
{
|
||||
@Override
|
||||
public boolean onTouch(View v, MotionEvent event)
|
||||
{
|
||||
v.getParent().requestDisallowInterceptTouchEvent(true);
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
spinnerParameterType.setOnItemSelectedListener(new OnItemSelectedListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> arg0, View arg1, int arg2, long arg3)
|
||||
{
|
||||
if(supportedIntentTypes[arg2].equals("double") | supportedIntentTypes[arg2].equals("float") | supportedIntentTypes[arg2].equals("int") | supportedIntentTypes[arg2].equals("long") | supportedIntentTypes[arg2].equals("short"))
|
||||
ActivityManageStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_NUMBER);
|
||||
else
|
||||
ActivityManageStartActivity.this.etParameterValue.setInputType(InputType.TYPE_CLASS_TEXT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> arg0)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
Intent i = getIntent();
|
||||
if(i.getBooleanExtra("edit", false) == true)
|
||||
{
|
||||
edit = true;
|
||||
loadValuesIntoGui();
|
||||
}
|
||||
}
|
||||
|
||||
private void loadValuesIntoGui()
|
||||
{
|
||||
String[] params = resultingAction.getParameter2().split(";");
|
||||
if(params.length >= 2)
|
||||
{
|
||||
tvSelectedActivity.setText(params[0] + ";" + params[1]);
|
||||
|
||||
if(params.length > 2)
|
||||
{
|
||||
intentPairList.clear();
|
||||
|
||||
for(int i=2; i<params.length; i++)
|
||||
{
|
||||
intentPairList.add(params[i]);
|
||||
}
|
||||
|
||||
updateIntentPairList();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void updateIntentPairList()
|
||||
{
|
||||
if(lvIntentPairs.getAdapter() == null)
|
||||
lvIntentPairs.setAdapter(intentPairAdapter);
|
||||
|
||||
intentPairAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
private boolean saveAction()
|
||||
{
|
||||
if(tvSelectedActivity.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageStartActivity.this, getResources().getString(R.string.selectApplication), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(tvSelectedActivity.getText().toString().equals(getResources().getString(R.string.selectApplication)))
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.selectApplication), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
if(resultingAction == null)
|
||||
resultingAction = new Action();
|
||||
|
||||
resultingAction.setAction(Action_Enum.startOtherActivity);
|
||||
|
||||
String parameter2 = tvSelectedActivity.getText().toString();
|
||||
for(String s : intentPairList)
|
||||
parameter2 += ";" + s;
|
||||
|
||||
resultingAction.setParameter2(parameter2);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private AlertDialog getIntentPairDialog(final int itemPosition)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(ActivityManageStartActivity.this);
|
||||
alertDialogBuilder.setTitle(getResources().getString(R.string.whatToDoWithIntentPair));
|
||||
alertDialogBuilder.setItems(new String[]{getResources().getString(R.string.delete)}, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
// Only 1 choice at the moment, no need to check
|
||||
ActivityManageStartActivity.this.intentPairList.remove(itemPosition);
|
||||
updateIntentPairList();
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
private class GetActivityListTask extends AsyncTask<Void, Void, Void>
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground(Void... params)
|
||||
{
|
||||
getActivityList(ActivityManageStartActivity.this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Void result)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
getActionStartActivityDialog1().show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,163 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.TimePicker;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.sql.Time;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class ActivityManageTimeFrame extends Activity
|
||||
{
|
||||
Button bSaveTimeFrame;
|
||||
TimePicker startPicker, stopPicker;
|
||||
CheckBox checkMonday, checkTuesday, checkWednesday, checkThursday, checkFriday, checkSaturday, checkSunday;
|
||||
RadioButton radioTimeFrameEntering, radioTimeFrameLeaving;
|
||||
|
||||
public static Trigger editedTimeFrameTrigger = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.trigger_timeframe_editor);
|
||||
|
||||
startPicker = (TimePicker)findViewById(R.id.tpTimeFrameStart);
|
||||
stopPicker = (TimePicker)findViewById(R.id.tpTimeFrameStop);
|
||||
startPicker.setIs24HourView(true);
|
||||
stopPicker.setIs24HourView(true);
|
||||
|
||||
bSaveTimeFrame = (Button)findViewById(R.id.bSaveTimeFrame);
|
||||
checkMonday = (CheckBox)findViewById(R.id.checkMonday);
|
||||
checkTuesday = (CheckBox)findViewById(R.id.checkTuesday);
|
||||
checkWednesday = (CheckBox)findViewById(R.id.checkWednesday);
|
||||
checkThursday = (CheckBox)findViewById(R.id.checkThursday);
|
||||
checkFriday = (CheckBox)findViewById(R.id.checkFriday);
|
||||
checkSaturday = (CheckBox)findViewById(R.id.checkSaturday);
|
||||
checkSunday = (CheckBox)findViewById(R.id.checkSunday);
|
||||
radioTimeFrameEntering = (RadioButton)findViewById(R.id.radioTimeFrameEntering);
|
||||
radioTimeFrameLeaving = (RadioButton)findViewById(R.id.radioTimeFrameLeaving);
|
||||
|
||||
bSaveTimeFrame.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Time startTime = new Time(0);
|
||||
startTime.setHours(startPicker.getCurrentHour());
|
||||
startTime.setMinutes(startPicker.getCurrentMinute());
|
||||
|
||||
Time stopTime = new Time(0);
|
||||
stopTime.setHours(stopPicker.getCurrentHour());
|
||||
stopTime.setMinutes(stopPicker.getCurrentMinute());
|
||||
|
||||
ArrayList<Integer> dayList = new ArrayList<Integer>();
|
||||
if(checkMonday.isChecked())
|
||||
dayList.add(Calendar.MONDAY);
|
||||
if(checkTuesday.isChecked())
|
||||
dayList.add(Calendar.TUESDAY);
|
||||
if(checkWednesday.isChecked())
|
||||
dayList.add(Calendar.WEDNESDAY);
|
||||
if(checkThursday.isChecked())
|
||||
dayList.add(Calendar.THURSDAY);
|
||||
if(checkFriday.isChecked())
|
||||
dayList.add(Calendar.FRIDAY);
|
||||
if(checkSaturday.isChecked())
|
||||
dayList.add(Calendar.SATURDAY);
|
||||
if(checkSunday.isChecked())
|
||||
dayList.add(Calendar.SUNDAY);
|
||||
|
||||
if(
|
||||
!checkMonday.isChecked()
|
||||
&&
|
||||
!checkTuesday.isChecked()
|
||||
&&
|
||||
!checkWednesday.isChecked()
|
||||
&&
|
||||
!checkThursday.isChecked()
|
||||
&&
|
||||
!checkFriday.isChecked()
|
||||
&&
|
||||
!checkSaturday.isChecked()
|
||||
&&
|
||||
!checkSunday.isChecked()
|
||||
)
|
||||
{
|
||||
Toast.makeText(getBaseContext(), getResources().getString(R.string.selectOneDay), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(editedTimeFrameTrigger.getTimeFrame() == null)
|
||||
// add new one
|
||||
editedTimeFrameTrigger.setTimeFrame(new TimeFrame(startTime, stopTime, dayList));
|
||||
else
|
||||
{
|
||||
// edit one
|
||||
editedTimeFrameTrigger.getTimeFrame().setTriggerTimeStart(startTime);
|
||||
editedTimeFrameTrigger.getTimeFrame().setTriggerTimeStop(stopTime);
|
||||
editedTimeFrameTrigger.getTimeFrame().getDayList().clear();
|
||||
editedTimeFrameTrigger.getTimeFrame().setDayList(dayList);
|
||||
}
|
||||
|
||||
editedTimeFrameTrigger.setTriggerParameter(radioTimeFrameEntering.isChecked());
|
||||
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
if(editedTimeFrameTrigger.getTimeFrame() != null)
|
||||
loadVariableIntoGui();
|
||||
}
|
||||
|
||||
private void loadVariableIntoGui()
|
||||
{
|
||||
startPicker.setCurrentHour(editedTimeFrameTrigger.getTimeFrame().getTriggerTimeStart().getHours());
|
||||
startPicker.setCurrentMinute(editedTimeFrameTrigger.getTimeFrame().getTriggerTimeStart().getMinutes());
|
||||
|
||||
stopPicker.setCurrentHour(editedTimeFrameTrigger.getTimeFrame().getTriggerTimeStop().getHours());
|
||||
stopPicker.setCurrentMinute(editedTimeFrameTrigger.getTimeFrame().getTriggerTimeStop().getMinutes());
|
||||
|
||||
radioTimeFrameEntering.setChecked(editedTimeFrameTrigger.getTriggerParameter());
|
||||
radioTimeFrameLeaving.setChecked(!editedTimeFrameTrigger.getTriggerParameter());
|
||||
|
||||
for(int day : editedTimeFrameTrigger.getTimeFrame().getDayList())
|
||||
{
|
||||
switch(day)
|
||||
{
|
||||
case Calendar.MONDAY:
|
||||
checkMonday.setChecked(true);
|
||||
break;
|
||||
case Calendar.TUESDAY:
|
||||
checkTuesday.setChecked(true);
|
||||
break;
|
||||
case Calendar.WEDNESDAY:
|
||||
checkWednesday.setChecked(true);
|
||||
break;
|
||||
case Calendar.THURSDAY:
|
||||
checkThursday.setChecked(true);
|
||||
break;
|
||||
case Calendar.FRIDAY:
|
||||
checkFriday.setChecked(true);
|
||||
break;
|
||||
case Calendar.SATURDAY:
|
||||
checkSaturday.setChecked(true);
|
||||
break;
|
||||
case Calendar.SUNDAY:
|
||||
checkSunday.setChecked(true);
|
||||
break;
|
||||
default:
|
||||
Miscellaneous.logEvent("w", "TimeFrame", "Daylist contains invalid day: " + String.valueOf(day), 4);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
1370
app/src/main/java/com/jens/automation2/ActivityPermissions.java
Normal file
1370
app/src/main/java/com/jens/automation2/ActivityPermissions.java
Normal file
File diff suppressed because it is too large
Load Diff
19
app/src/main/java/com/jens/automation2/ActivitySettings.java
Normal file
19
app/src/main/java/com/jens/automation2/ActivitySettings.java
Normal file
@ -0,0 +1,19 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.PreferenceActivity;
|
||||
|
||||
import com.jens.automation2.R.layout;
|
||||
|
||||
public class ActivitySettings extends PreferenceActivity
|
||||
{
|
||||
ListPreference lpStartScreenOptionsValues;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(layout.settings);
|
||||
}
|
||||
}
|
210
app/src/main/java/com/jens/automation2/ActivityVolumeTest.java
Normal file
210
app/src/main/java/com/jens/automation2/ActivityVolumeTest.java
Normal file
@ -0,0 +1,210 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Activity;
|
||||
import android.media.MediaRecorder;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.widget.EditText;
|
||||
import android.widget.SeekBar;
|
||||
import android.widget.SeekBar.OnSeekBarChangeListener;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class ActivityVolumeTest extends Activity
|
||||
{
|
||||
TextView tvCurrentVolume, tvVolumeTestExplanation;
|
||||
EditText etReferenceValue;
|
||||
SeekBar sbReferenceValue;
|
||||
|
||||
final int volumeRefreshInterval = 3;
|
||||
|
||||
static ActivityVolumeTest instance = null;
|
||||
|
||||
AsyncTask<Integer, Long, Void> volumeTask = null;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
instance = this;
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_volume_test);
|
||||
|
||||
tvCurrentVolume = (TextView)findViewById(R.id.tvCurrentVolume);
|
||||
etReferenceValue = (EditText)findViewById(R.id.etReferenceValue);
|
||||
sbReferenceValue = (SeekBar)findViewById(R.id.sbReferenceValue);
|
||||
tvVolumeTestExplanation = (TextView)findViewById(R.id.tvVolumeTestExplanation);
|
||||
|
||||
tvVolumeTestExplanation.setText(String.format(getResources().getString(R.string.volumeTesterExplanation), String.valueOf(volumeRefreshInterval)));
|
||||
|
||||
etReferenceValue.setText(String.valueOf(Settings.referenceValueForNoiseLevelMeasurements));
|
||||
|
||||
sbReferenceValue.setMax(500);
|
||||
sbReferenceValue.setProgress((int) Settings.referenceValueForNoiseLevelMeasurements);
|
||||
sbReferenceValue.setOnSeekBarChangeListener(new OnSeekBarChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onStopTrackingTouch(SeekBar seekBar)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStartTrackingTouch(SeekBar seekBar)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(SeekBar seekBar, int progress,
|
||||
boolean fromUser)
|
||||
{
|
||||
etReferenceValue.setText(String.valueOf(sbReferenceValue.getProgress()));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
|
||||
startVolumeMonitoring();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause()
|
||||
{
|
||||
super.onPause();
|
||||
stopVolumeMonitoring();
|
||||
}
|
||||
|
||||
public static ActivityVolumeTest getInstance()
|
||||
{
|
||||
return instance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed()
|
||||
{
|
||||
try
|
||||
{
|
||||
stopVolumeMonitoring();
|
||||
Settings.referenceValueForNoiseLevelMeasurements = Long.parseLong(etReferenceValue.getText().toString());
|
||||
Settings.writeSettings(ActivityVolumeTest.this);
|
||||
super.onBackPressed();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Toast.makeText(ActivityVolumeTest.this, ActivityVolumeTest.this.getResources().getString(R.string.enterValidReferenceValue), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
synchronized private void startVolumeMonitoring()
|
||||
{
|
||||
volumeTask = new NoiseListenerMeasuring();
|
||||
|
||||
// if(!(volumeTask.getStatus() == AsyncTask.Status.PENDING | volumeTask.getStatus() != AsyncTask.Status.RUNNING))
|
||||
volumeTask.execute(volumeRefreshInterval);
|
||||
}
|
||||
|
||||
synchronized private void stopVolumeMonitoring()
|
||||
{
|
||||
// if(volumeTask != null && (volumeTask.getStatus() == Status.PENDING | volumeTask.getStatus() == Status.RUNNING))
|
||||
volumeTask.cancel(true);
|
||||
}
|
||||
|
||||
synchronized void updateDisplayedNoiseLevel(long noise)
|
||||
{
|
||||
tvCurrentVolume.setText(String.valueOf(noise) + " dB");
|
||||
}
|
||||
|
||||
private static class NoiseListenerMeasuring extends AsyncTask<Integer, Long, Void>
|
||||
{
|
||||
static boolean isNoiseMonitoringActive;
|
||||
|
||||
@Override
|
||||
protected Void doInBackground(Integer... interval)
|
||||
{
|
||||
if(!isNoiseMonitoringActive)
|
||||
{
|
||||
isNoiseMonitoringActive = true;
|
||||
|
||||
Miscellaneous.logEvent("i", "Noise level", "Periodic noise level measurement started.", 5);
|
||||
|
||||
while(!isCancelled())
|
||||
{
|
||||
try
|
||||
{
|
||||
// Start recording but don't store data
|
||||
MediaRecorder mediaRecorder = new MediaRecorder();
|
||||
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
|
||||
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
|
||||
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
|
||||
mediaRecorder.setOutputFile("/dev/null");
|
||||
// Date myDate = new Date();
|
||||
// mediaRecorder.setOutputFile("/sdcard/temp/" + String.valueOf(myDate.getTime()) + ".3gpp");
|
||||
|
||||
mediaRecorder.prepare();
|
||||
mediaRecorder.getMaxAmplitude();
|
||||
mediaRecorder.start();
|
||||
mediaRecorder.getMaxAmplitude();
|
||||
|
||||
long noiseLevel;
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep(interval[0] * 1000);
|
||||
// Obtain maximum amplitude since last call of getMaxAmplitude()
|
||||
noiseLevel = mediaRecorder.getMaxAmplitude();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
noiseLevel = -1;
|
||||
Miscellaneous.logEvent("e", "Noise level", "Error getting noise level: " + e.getMessage(), 2);
|
||||
}
|
||||
|
||||
double currentReferenceValue = Double.parseDouble(ActivityVolumeTest.getInstance().etReferenceValue.getText().toString());
|
||||
double db = 20 * Math.log(noiseLevel / currentReferenceValue);
|
||||
long noiseLevelDb = Math.round(db);
|
||||
|
||||
publishProgress(noiseLevelDb);
|
||||
|
||||
// Message answer = new Message();
|
||||
// Bundle answerBundle = new Bundle();
|
||||
// answerBundle.putLong("noiseLevelDb", noiseLevelDb);
|
||||
// answer.setData(answerBundle);
|
||||
// volumeHandler.sendMessage(answer);
|
||||
|
||||
// Don't forget to release
|
||||
mediaRecorder.reset();
|
||||
mediaRecorder.release();
|
||||
|
||||
Miscellaneous.logEvent("i", "Noise level", "Measured noise level: " + String.valueOf(noiseLevel) + " / converted to db: " + String.valueOf(db), 3);
|
||||
}
|
||||
catch(Exception e)
|
||||
{}
|
||||
}
|
||||
|
||||
isNoiseMonitoringActive = false;
|
||||
|
||||
Miscellaneous.logEvent("i", "Noise level", "Periodic noise level measurement stopped.", 5);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onProgressUpdate(Long... values)
|
||||
{
|
||||
ActivityVolumeTest.getInstance().updateDisplayedNoiseLevel(values[0]);
|
||||
|
||||
// super.onProgressUpdate(values);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
713
app/src/main/java/com/jens/automation2/AutomationService.java
Normal file
713
app/src/main/java/com/jens/automation2/AutomationService.java
Normal file
@ -0,0 +1,713 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningServiceInfo;
|
||||
import android.app.Notification;
|
||||
import android.app.Notification.Builder;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.app.Service;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.media.AudioManager;
|
||||
import android.os.Binder;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.TextToSpeech.OnInitListener;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.receivers.PackageReplacedReceiver;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
|
||||
import java.util.Calendar;
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
public class AutomationService extends Service implements OnInitListener
|
||||
{
|
||||
protected TextToSpeech ttsEngine = null;
|
||||
protected final static int notificationId = 1000;
|
||||
|
||||
final static String NOTIFICATION_CHANNEL_ID = "com.jens.automation2";
|
||||
final static String channelName = "Automation notifications";
|
||||
|
||||
protected static Notification myNotification;
|
||||
protected static NotificationCompat.Builder notificationBuilder = null;
|
||||
protected static PendingIntent myPendingIntent;
|
||||
|
||||
protected Calendar lockSoundChangesEnd = null;
|
||||
protected boolean isRunning;
|
||||
|
||||
public void nullLockSoundChangesEnd()
|
||||
{
|
||||
lockSoundChangesEnd = null;
|
||||
}
|
||||
public Calendar getLockSoundChangesEnd()
|
||||
{
|
||||
return lockSoundChangesEnd;
|
||||
}
|
||||
public void lockSoundChangesEndAddTime()
|
||||
{
|
||||
if(lockSoundChangesEnd == null)
|
||||
lockSoundChangesEnd = Calendar.getInstance();
|
||||
|
||||
lockSoundChangesEnd.add(Calendar.MINUTE, Settings.lockSoundChangesInterval);
|
||||
// ActivityMainScreen.getActivityMainScreenInstance().updateMainScreen();
|
||||
}
|
||||
|
||||
public void checkLockSoundChangesTimeElapsed()
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
if(getLockSoundChangesEnd() != null && getLockSoundChangesEnd().getTimeInMillis() <= now.getTimeInMillis())
|
||||
lockSoundChangesEnd = null;
|
||||
}
|
||||
|
||||
public void setLockSoundChangesEnd(Calendar lockSoundChangesEnd)
|
||||
{
|
||||
this.lockSoundChangesEnd = lockSoundChangesEnd;
|
||||
}
|
||||
|
||||
protected final IBinder myBinder = new LocalBinder();
|
||||
|
||||
protected LocationProvider myLocationProvider;
|
||||
|
||||
public LocationProvider getLocationProvider()
|
||||
{
|
||||
return myLocationProvider;
|
||||
}
|
||||
|
||||
protected static AutomationService centralInstance = null;
|
||||
|
||||
public static AutomationService getInstance()
|
||||
{
|
||||
return centralInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
super.onCreate();
|
||||
|
||||
Thread.setDefaultUncaughtExceptionHandler(Miscellaneous.uncaughtExceptionHandler);
|
||||
|
||||
// Store a reference to myself. Other classes often need a context or something, this can provide that.
|
||||
centralInstance = this;
|
||||
}
|
||||
|
||||
public boolean checkStartupRequirements(Context context, boolean startAtBoot)
|
||||
{
|
||||
if (!ActivityPermissions.havePermission(ActivityPermissions.writeExternalStoragePermissionName, AutomationService.this))
|
||||
{
|
||||
/*
|
||||
Don't have permission to access external storage. This is a show stopper as
|
||||
the configuration file is stored on external storage.
|
||||
*/
|
||||
Miscellaneous.logEvent("e", "Permission", "Don't have permission to access external storage. Will request it now.", 4);
|
||||
// Toast.makeText(AutomationService.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
|
||||
ActivityPermissions.requestSpecificPermission(ActivityPermissions.writeExternalStoragePermissionName);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 28)
|
||||
{
|
||||
if (!ActivityPermissions.havePermission(ActivityPermissions.permissionNameStartService, AutomationService.this))
|
||||
{
|
||||
/*
|
||||
Don't have permission to start service. This is a show stopper.
|
||||
*/
|
||||
Miscellaneous.logEvent("e", "Permission", "Don't have permission to start foreground service. Will request it now.", 4);
|
||||
// Toast.makeText(AutomationService.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
|
||||
ActivityPermissions.requestSpecificPermission(ActivityPermissions.permissionNameStartService);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (PointOfInterest.getPointOfInterestCollection() == null | PointOfInterest.getPointOfInterestCollection().size() == 0
|
||||
|
|
||||
Rule.getRuleCollection() == null | Rule.getRuleCollection().size() == 0
|
||||
)
|
||||
{
|
||||
if (startAtBoot)
|
||||
{
|
||||
/*
|
||||
* In case we start at boot the sd card may not have been mounted, yet.
|
||||
* We will wait 3 seconds and check and do this 3 times.
|
||||
*/
|
||||
if (!XmlFileInterface.settingsFile.exists())
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
String state = Environment.getExternalStorageState();
|
||||
if (!state.equals(Environment.MEDIA_MOUNTED))
|
||||
{
|
||||
try
|
||||
{
|
||||
Miscellaneous.logEvent("w", "AutoStart", "Service is started via boot. Settingsfile not available because storage is not mounted, yet. Waiting for 3 seconds.", 4);
|
||||
Thread.sleep(3000);
|
||||
} catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
if (XmlFileInterface.settingsFile.exists())
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
PointOfInterest.loadPoisFromFile();
|
||||
Rule.readFromFile();
|
||||
}
|
||||
|
||||
//if still no POIs...
|
||||
if (//PointOfInterest.getPointOfInterestCollection() == null | PointOfInterest.getPointOfInterestCollection().size() == 0
|
||||
// &&
|
||||
Rule.getRuleCollection() == null | Rule.getRuleCollection().size() == 0
|
||||
)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "AutomationService", context.getResources().getString(R.string.serviceWontStart), 1);
|
||||
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStart), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
} else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId)
|
||||
{
|
||||
boolean startAtBoot = false;
|
||||
|
||||
if (intent != null)
|
||||
{
|
||||
Bundle b = intent.getExtras();
|
||||
startAtBoot = b.getBoolean("startAtBoot", false);
|
||||
}
|
||||
|
||||
if (checkStartupRequirements(this, startAtBoot))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.logServiceStarting), 1);
|
||||
|
||||
startUpRoutine();
|
||||
|
||||
Intent myIntent = new Intent(this, ActivityMainTabLayout.class);
|
||||
myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, 0);
|
||||
notificationBuilder = createDefaultNotificationBuilder();
|
||||
|
||||
updateNotification();
|
||||
|
||||
if (isMainActivityRunning(this))
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
|
||||
this.isRunning = true;
|
||||
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.serviceStarted) + " " + String.format(this.getResources().getString(R.string.version), BuildConfig.VERSION_NAME + "(Build " + BuildConfig.VERSION_CODE + ")"), 1);
|
||||
Toast.makeText(this, this.getResources().getString(R.string.serviceStarted), Toast.LENGTH_LONG).show();
|
||||
// ********** Test area **********
|
||||
// Miscellaneous.logEvent("i", "setNetworkType", "bin hier.", 3);
|
||||
// Actions.setData(true);
|
||||
// ********** Test area **********
|
||||
|
||||
return START_STICKY;
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Service", "checkStartupRequirements() delivered false. Stopping service...", 1);
|
||||
this.stopSelf();
|
||||
return START_NOT_STICKY;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public IBinder onBind(Intent arg0)
|
||||
{
|
||||
return myBinder;
|
||||
}
|
||||
|
||||
public enum serviceCommands
|
||||
{
|
||||
reloadSettings, reloadPointsOfInterest, reloadRules, updateNotification
|
||||
}
|
||||
|
||||
;
|
||||
|
||||
public void serviceInterface(serviceCommands command)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Bind", "Ahhhh, customers... How can I help you?", 5);
|
||||
|
||||
Miscellaneous.logEvent("i", "ServiceBind", "Request to " + command.toString(), 5);
|
||||
|
||||
switch (command)
|
||||
{
|
||||
case reloadPointsOfInterest:
|
||||
PointOfInterest.loadPoisFromFile();
|
||||
break;
|
||||
case reloadRules:
|
||||
Rule.readFromFile();
|
||||
break;
|
||||
case reloadSettings:
|
||||
Settings.readFromPersistentStorage(this);
|
||||
applySettingsAndRules();
|
||||
myLocationProvider.applySettingsAndRules();
|
||||
break;
|
||||
case updateNotification:
|
||||
this.updateNotification();
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void applySettingsAndRules()
|
||||
{
|
||||
if (Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate)
|
||||
{
|
||||
if (ttsEngine == null)
|
||||
ttsEngine = new TextToSpeech(this, this);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ttsEngine != null)
|
||||
ttsEngine.shutdown();
|
||||
}
|
||||
|
||||
startLocationProvider();
|
||||
ReceiverCoordinator.startAllReceivers();
|
||||
if(myLocationProvider != null) // This condition can be met if the user has no locations defined.
|
||||
myLocationProvider.applySettingsAndRules();
|
||||
|
||||
ReceiverCoordinator.applySettingsAndRules();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroy()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", getResources().getString(R.string.logServiceStopping), 1);
|
||||
|
||||
stopRoutine();
|
||||
this.isRunning = false;
|
||||
Toast.makeText(this, getResources().getString(R.string.serviceStopped), Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.logEvent("i", "Service", getResources().getString(R.string.serviceStopped), 1);
|
||||
}
|
||||
|
||||
public void checkForTtsEngine()
|
||||
{
|
||||
if (Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate | Rule.isAnyRuleUsing(Action.Action_Enum.speakText))
|
||||
{
|
||||
if (ttsEngine == null)
|
||||
ttsEngine = new TextToSpeech(this, this);
|
||||
} else
|
||||
{
|
||||
if (ttsEngine != null)
|
||||
ttsEngine.shutdown();
|
||||
}
|
||||
}
|
||||
|
||||
private void startUpRoutine()
|
||||
{
|
||||
checkForTtsEngine();
|
||||
checkForPermissions();
|
||||
|
||||
Actions.context = this;
|
||||
Actions.autoMationServerRef = this;
|
||||
|
||||
startLocationProvider();
|
||||
ReceiverCoordinator.startAllReceivers();
|
||||
|
||||
PackageReplacedReceiver.setHasServiceBeenRunning(true, this);
|
||||
}
|
||||
|
||||
protected void startLocationProvider()
|
||||
{
|
||||
if(ActivityPermissions.havePermission("android.permission.ACCESS_COARSE_LOCATION", AutomationService.this))
|
||||
myLocationProvider = new LocationProvider(this); //autostart with this (only) constructor
|
||||
}
|
||||
|
||||
protected void checkForPermissions()
|
||||
{
|
||||
if(ActivityPermissions.needMorePermissions(AutomationService.this))
|
||||
{
|
||||
boolean displayNotification = false;
|
||||
|
||||
for(Rule r : Rule.getRuleCollection())
|
||||
{
|
||||
if(r.isRuleActive())
|
||||
{
|
||||
if(!r.haveEnoughPermissions())
|
||||
// for (String permission : ActivityPermissions.getPermissionsForRule(r))
|
||||
{
|
||||
// if (!ActivityPermissions.havePermission(permission, AutomationService.this))
|
||||
{
|
||||
// r.setRuleActive(false);
|
||||
// r.change(AutomationService.this);
|
||||
if(!displayNotification)
|
||||
displayNotification = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(displayNotification)
|
||||
{
|
||||
// Toast.makeText(Miscellaneous.getAnyContext(), "Require more permissions.", Toast.LENGTH_LONG).show();
|
||||
// Update notification or show new one that notifiies of the lack or permissions.
|
||||
|
||||
Intent intent = new Intent(AutomationService.this, ActivityPermissions.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.appRunningInLimitedMode), ActivityPermissions.notificationIdPermissions, pi);
|
||||
}
|
||||
// else
|
||||
// Toast.makeText(Miscellaneous.getAnyContext(), "Have all required permissions.", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
public static void startAutomationService(Context context, boolean startAtBoot)
|
||||
{
|
||||
if(!(isMyServiceRunning(context)))
|
||||
{
|
||||
Intent myServiceIntent = new Intent(context, AutomationService.class);
|
||||
myServiceIntent.putExtra("startAtBoot", startAtBoot);
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
context.startForegroundService(myServiceIntent);
|
||||
else
|
||||
context.startService(myServiceIntent);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "Service", "Service is already running.", 1);
|
||||
}
|
||||
|
||||
private void stopRoutine()
|
||||
{
|
||||
Log.i("STOP", "Stopping");
|
||||
try
|
||||
{
|
||||
myLocationProvider.stopLocationService();
|
||||
ReceiverCoordinator.stopAllReceivers();
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", getResources().getString(R.string.serviceNotRunning), getResources().getString(R.string.serviceNotRunning) + ". " + getResources().getString(R.string.cantStopIt), 3);
|
||||
}
|
||||
|
||||
if(ttsEngine != null)
|
||||
ttsEngine.shutdown();
|
||||
|
||||
PackageReplacedReceiver.setHasServiceBeenRunning(false, this);
|
||||
}
|
||||
|
||||
protected static Builder createDefaultNotificationBuilderOld()
|
||||
{
|
||||
Builder builder = new Builder(AutomationService.getInstance());
|
||||
builder.setContentTitle("Automation");
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning)
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
|
||||
builder.setCategory(Notification.CATEGORY_SERVICE);
|
||||
builder.setWhen(System.currentTimeMillis());
|
||||
builder.setContentIntent(myPendingIntent);
|
||||
|
||||
// Notification defaultNotification = new Notification();
|
||||
Notification defaultNotification = builder.build();
|
||||
|
||||
defaultNotification.icon = R.drawable.ic_launcher;
|
||||
defaultNotification.when = System.currentTimeMillis();
|
||||
|
||||
// defaultNotification.defaults |= Notification.DEFAULT_VIBRATE;
|
||||
// defaultNotification.defaults |= Notification.DEFAULT_LIGHTS;
|
||||
|
||||
defaultNotification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||
// defaultNotification.flags |= Notification.FLAG_SHOW_LIGHTS;
|
||||
defaultNotification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
|
||||
|
||||
// defaultNotification.ledARGB = Color.YELLOW;
|
||||
// defaultNotification.ledOnMS = 1500;
|
||||
// defaultNotification.ledOffMS = 1500;
|
||||
|
||||
return builder;
|
||||
|
||||
/*NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
NotificationCompat.Builder builder;
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance());
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(Notification.CATEGORY_EVENT);
|
||||
|
||||
builder.setWhen(System.currentTimeMillis());
|
||||
|
||||
builder.setContentTitle("Automation");
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
// builder.setContentText(textToDisplay);
|
||||
// builder.setSmallIcon(icon);
|
||||
// builder.setContentIntent(pendingIntent);
|
||||
// builder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
NotificationChannel channel = new NotificationChannel("notify_001", "Channel human readable title", NotificationManager.IMPORTANCE_DEFAULT);
|
||||
mNotificationManager.createNotificationChannel(channel);
|
||||
}
|
||||
|
||||
return builder;*/
|
||||
}
|
||||
|
||||
protected static NotificationCompat.Builder createDefaultNotificationBuilder()
|
||||
{
|
||||
NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
NotificationCompat.Builder builder;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_LOW);
|
||||
// chan.setLightColor(Color.BLUE);
|
||||
chan.enableVibration(false);
|
||||
chan.setSound(null, null);
|
||||
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||
mNotificationManager.createNotificationChannel(chan);
|
||||
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance(), NOTIFICATION_CHANNEL_ID);
|
||||
}
|
||||
else
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance());
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
builder.setCategory(Notification.CATEGORY_SERVICE);
|
||||
|
||||
builder.setWhen(System.currentTimeMillis());
|
||||
builder.setContentIntent(myPendingIntent);
|
||||
|
||||
builder.setContentTitle(AutomationService.getInstance().getResources().getString(R.string.app_name));
|
||||
builder.setOnlyAlertOnce(true);
|
||||
|
||||
if(Settings.showIconWhenServiceIsRunning)
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
|
||||
// builder.setContentText(textToDisplay);
|
||||
// builder.setSmallIcon(icon);
|
||||
// builder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
|
||||
|
||||
return builder;
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void updateNotification()
|
||||
{
|
||||
AutomationService instance = getInstance();
|
||||
|
||||
if(instance != null)
|
||||
{
|
||||
// if(Settings.showIconWhenServiceIsRunning)
|
||||
// {
|
||||
Miscellaneous.logEvent("i", "Notification", "Request to update notification.", 4);
|
||||
|
||||
String bodyText="";
|
||||
String lastRuleString = "";
|
||||
|
||||
if(PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
|
||||
{
|
||||
try
|
||||
{
|
||||
PointOfInterest activePoi = PointOfInterest.getActivePoi();
|
||||
if(activePoi == null)
|
||||
{
|
||||
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
|
||||
bodyText = "Active POI: none" + "\n" + "Closest POI: " + closestPoi.getName() + lastRuleString;
|
||||
}
|
||||
else
|
||||
{
|
||||
bodyText = "Active POI: " + activePoi.getName() + lastRuleString;
|
||||
}
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{
|
||||
if(
|
||||
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, AutomationService.getInstance())
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, AutomationService.getInstance())
|
||||
)
|
||||
bodyText = instance.getResources().getString(R.string.stillGettingPosition);
|
||||
else
|
||||
bodyText = instance.getResources().getString(R.string.locationEngineNotActive);
|
||||
}
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
lastRuleString = instance.getResources().getString(R.string.lastRule) + " " + Rule.getLastActivatedRule().getName() + " " + instance.getResources().getString(R.string.at) + " " + Rule.getLastActivatedRuleActivationTime().toLocaleString();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
lastRuleString = instance.getResources().getString(R.string.lastRule) + " n./a.";
|
||||
}
|
||||
|
||||
String textToDisplay = bodyText + " " + lastRuleString;
|
||||
// if(Build.VERSION.SDK_INT < 11)
|
||||
// {
|
||||
// myNotification.setLatestEventInfo(instance, "Automation", textToDisplay, myPendingIntent);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
notificationBuilder.setContentText(textToDisplay);
|
||||
notificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
|
||||
|
||||
myNotification = notificationBuilder.build();
|
||||
myNotification.defaults = 0;
|
||||
// }
|
||||
|
||||
// NotificationManager notificationManager = (NotificationManager) instance.getSystemService(NOTIFICATION_SERVICE);
|
||||
// hide the notification after its selected
|
||||
// myNotification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||
myNotification.flags |= Notification.FLAG_NO_CLEAR;
|
||||
// notificationManager.notify(notificationId, myNotification);
|
||||
|
||||
instance.startForeground(notificationId, myNotification);
|
||||
// }
|
||||
// else
|
||||
// instance.startForeground(notificationId, null); // do not show icon in task bar
|
||||
}
|
||||
}
|
||||
|
||||
public class LocalBinder extends Binder
|
||||
{
|
||||
public AutomationService getService()
|
||||
{
|
||||
return AutomationService.this;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onInit(int status)
|
||||
{
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* force will skip volume settings and stuff
|
||||
**/
|
||||
public void speak(String text, boolean force)
|
||||
{
|
||||
if(text.length() > 0 && (force | Settings.useTextToSpeechOnNormal | Settings.useTextToSpeechOnSilent | Settings.useTextToSpeechOnVibrate))
|
||||
{
|
||||
AudioManager myAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
|
||||
int mode = myAudioManager.getRingerMode();
|
||||
|
||||
if(
|
||||
(mode == AudioManager.RINGER_MODE_NORMAL && Settings.useTextToSpeechOnNormal)
|
||||
|
|
||||
(mode == AudioManager.RINGER_MODE_VIBRATE && Settings.useTextToSpeechOnVibrate)
|
||||
|
|
||||
(mode == AudioManager.RINGER_MODE_SILENT && Settings.useTextToSpeechOnSilent)
|
||||
|
|
||||
force
|
||||
)
|
||||
{
|
||||
if(Settings.muteTextToSpeechDuringCalls && PhoneStatusListener.isInACall() && !force)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TextToSpeech", "Currently in a call. Not speaking as requested.", 4);
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
for(int i = 0; i < 5; i++)
|
||||
{
|
||||
if(ttsEngine != null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Miscellaneous.logEvent("i", "TTS", "Waiting for a moment to give the TTS service time to load...", 4);
|
||||
Thread.sleep(1000); // give the tts engine time to load
|
||||
}
|
||||
catch(Exception e)
|
||||
{}
|
||||
}
|
||||
}
|
||||
this.ttsEngine.speak(text, TextToSpeech.QUEUE_ADD, null);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "TextToSpeech", Log.getStackTraceString(e), 3);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isMainActivityRunning(Context context)
|
||||
{
|
||||
if(ActivityMainScreen.getActivityMainScreenInstance() == null)
|
||||
return false;
|
||||
else
|
||||
return true;
|
||||
|
||||
// boolean isActivityFound = false;
|
||||
// ActivityManager activityManager = (ActivityManager)context.getSystemService (Context.ACTIVITY_SERVICE);
|
||||
// List<RunningTaskInfo> activitys = activityManager.getRunningTasks(Integer.MAX_VALUE);
|
||||
// isActivityFound = false;
|
||||
// for (int i = 0; i < activitys.size(); i++)
|
||||
// {
|
||||
// if (activitys.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.jens.automation/com.jens.automation.ActivityMainScreen}"))
|
||||
// {
|
||||
// isActivityFound = true;
|
||||
// }
|
||||
// }
|
||||
// Miscellaneous.logEvent("i", "ActivityMainScreen", "Activity running status: " + String.valueOf(isActivityFound), 5);
|
||||
// return isActivityFound;
|
||||
|
||||
// ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
// List<RunningTaskInfo> tasks = activityManager.getRunningTasks(Integer.MAX_VALUE);
|
||||
//
|
||||
// for (RunningTaskInfo task : tasks)
|
||||
// {
|
||||
// if (context.getPackageName().equalsIgnoreCase(task.baseActivity.getPackageName()))
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// return false;
|
||||
}
|
||||
|
||||
public static boolean isMyServiceRunning(Context context)
|
||||
{
|
||||
try
|
||||
{
|
||||
ActivityManager manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
|
||||
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE))
|
||||
{
|
||||
if(AutomationService.class.getName().equals(service.service.getClassName()))
|
||||
{
|
||||
// return AutomationService.getInstance() != null && AutomationService.getInstance().isRunning;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{
|
||||
if(Log.getStackTraceString(e).contains("activate")) // Means that a poi has been activated/deactivated. Service is running.
|
||||
return true;
|
||||
// return AutomationService.getInstance() != null && AutomationService.getInstance().isRunning;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,371 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.content.ContentUris;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.provider.DocumentsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.text.TextUtils;
|
||||
import android.util.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.InputStream;
|
||||
|
||||
public class CompensateCrappyAndroidPaths
|
||||
{
|
||||
private static Uri contentUri = null;
|
||||
|
||||
/**
|
||||
* Get a file path from a Uri. This will get the the path for Storage Access
|
||||
* Framework Documents, as well as the _data field for the MediaStore and
|
||||
* other file-based ContentProviders.<br>
|
||||
* <br>
|
||||
* Callers should check whether the path is local before assuming it
|
||||
* represents a local file.
|
||||
*
|
||||
* @param context The context.
|
||||
* @param uri The Uri to query.
|
||||
*/
|
||||
@SuppressLint("NewApi")
|
||||
public static String getPath(final Context context, final Uri uri) {
|
||||
// check here to KITKAT or new version
|
||||
final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;
|
||||
String selection = null;
|
||||
String[] selectionArgs = null;
|
||||
// DocumentProvider
|
||||
if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
|
||||
// ExternalStorageProvider
|
||||
if (isExternalStorageDocument(uri)) {
|
||||
final String docId = DocumentsContract.getDocumentId(uri);
|
||||
final String[] split = docId.split(":");
|
||||
final String type = split[0];
|
||||
|
||||
String fullPath = getPathFromExtSD(split);
|
||||
if (fullPath != "") {
|
||||
return fullPath;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// DownloadsProvider
|
||||
else if (isDownloadsDocument(uri)) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
|
||||
final String id;
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = context.getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DISPLAY_NAME}, null, null, null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
String fileName = cursor.getString(0);
|
||||
String path = Environment.getExternalStorageDirectory().toString() + "/Download/" + fileName;
|
||||
if (!TextUtils.isEmpty(path)) {
|
||||
return path;
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
id = DocumentsContract.getDocumentId(uri);
|
||||
if (!TextUtils.isEmpty(id)) {
|
||||
if (id.startsWith("raw:")) {
|
||||
return id.replaceFirst("raw:", "");
|
||||
}
|
||||
String[] contentUriPrefixesToTry = new String[]{
|
||||
"content://downloads/public_downloads",
|
||||
"content://downloads/my_downloads"
|
||||
};
|
||||
for (String contentUriPrefix : contentUriPrefixesToTry) {
|
||||
try {
|
||||
final Uri contentUri = ContentUris.withAppendedId(Uri.parse(contentUriPrefix), Long.valueOf(id));
|
||||
|
||||
/* final Uri contentUri = ContentUris.withAppendedId(
|
||||
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));*/
|
||||
|
||||
return getDataColumn(context, contentUri, null, null);
|
||||
} catch (NumberFormatException e) {
|
||||
//In Android 8 and Android P the id is not a number
|
||||
return uri.getPath().replaceFirst("^/document/raw:", "").replaceFirst("^raw:", "");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
} else {
|
||||
final String id = DocumentsContract.getDocumentId(uri);
|
||||
final boolean isOreo = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O;
|
||||
if (id.startsWith("raw:")) {
|
||||
return id.replaceFirst("raw:", "");
|
||||
}
|
||||
try {
|
||||
contentUri = ContentUris.withAppendedId(
|
||||
Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
|
||||
|
||||
} catch (NumberFormatException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
if (contentUri != null) {
|
||||
return getDataColumn(context, contentUri, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// MediaProvider
|
||||
else if (isMediaDocument(uri)) {
|
||||
final String docId = DocumentsContract.getDocumentId(uri);
|
||||
final String[] split = docId.split(":");
|
||||
final String type = split[0];
|
||||
|
||||
Uri contentUri = null;
|
||||
|
||||
if ("image".equals(type)) {
|
||||
contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("video".equals(type)) {
|
||||
contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
|
||||
} else if ("audio".equals(type)) {
|
||||
contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
|
||||
}
|
||||
selection = "_id=?";
|
||||
selectionArgs = new String[]{split[1]};
|
||||
|
||||
|
||||
return getDataColumn(context, contentUri, selection,
|
||||
selectionArgs);
|
||||
} else if (isGoogleDriveUri(uri)) {
|
||||
return getDriveFilePath(uri, context);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// MediaStore (and general)
|
||||
else if ("content".equalsIgnoreCase(uri.getScheme())) {
|
||||
|
||||
if (isGooglePhotosUri(uri)) {
|
||||
return uri.getLastPathSegment();
|
||||
}
|
||||
|
||||
if (isGoogleDriveUri(uri)) {
|
||||
return getDriveFilePath(uri, context);
|
||||
}
|
||||
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.N) {
|
||||
// return getFilePathFromURI(context,uri);
|
||||
return getMediaFilePathForN(uri, context);
|
||||
// return getRealPathFromURI(context,uri);
|
||||
} else {
|
||||
|
||||
return getDataColumn(context, uri, null, null);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
// File
|
||||
else if ("file".equalsIgnoreCase(uri.getScheme())) {
|
||||
return uri.getPath();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a file exists on device
|
||||
*
|
||||
* @param filePath The absolute file path
|
||||
*/
|
||||
private static boolean fileExists(String filePath) {
|
||||
File file = new File(filePath);
|
||||
|
||||
return file.exists();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get full file path from external storage
|
||||
*
|
||||
* @param pathData The storage type and the relative path
|
||||
*/
|
||||
private static String getPathFromExtSD(String[] pathData) {
|
||||
final String type = pathData[0];
|
||||
final String relativePath = "/" + pathData[1];
|
||||
String fullPath = "";
|
||||
|
||||
// on my Sony devices (4.4.4 & 5.1.1), `type` is a dynamic string
|
||||
// something like "71F8-2C0A", some kind of unique id per storage
|
||||
// don't know any API that can get the root path of that storage based on its id.
|
||||
//
|
||||
// so no "primary" type, but let the check here for other devices
|
||||
if ("primary".equalsIgnoreCase(type)) {
|
||||
fullPath = Environment.getExternalStorageDirectory() + relativePath;
|
||||
if (fileExists(fullPath)) {
|
||||
return fullPath;
|
||||
}
|
||||
}
|
||||
|
||||
// Environment.isExternalStorageRemovable() is `true` for external and internal storage
|
||||
// so we cannot relay on it.
|
||||
//
|
||||
// instead, for each possible path, check if file exists
|
||||
// we'll start with secondary storage as this could be our (physically) removable sd card
|
||||
fullPath = System.getenv("SECONDARY_STORAGE") + relativePath;
|
||||
if (fileExists(fullPath)) {
|
||||
return fullPath;
|
||||
}
|
||||
|
||||
fullPath = System.getenv("EXTERNAL_STORAGE") + relativePath;
|
||||
if (fileExists(fullPath)) {
|
||||
return fullPath;
|
||||
}
|
||||