Compare commits
92 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 14655fe55d | |||
| cfc145c6c4 | |||
| 325bff305c | |||
| 4371fb56f7 | |||
| 6593f6c923 | |||
| 7fbac92360 | |||
| 7415830dd7 | |||
| dce68d79bd | |||
| 397dadd8c7 | |||
| c51c46707b | |||
| d699285b5a | |||
| cf3db22ffb | |||
| f53abe2b23 | |||
| ba2f96713d | |||
| 21d9351b2b | |||
| a8bfc6f7ec | |||
| 71d9791603 | |||
| d71177f3da | |||
| eef6c3234a | |||
| 192142c76b | |||
| 9a2a0aa6a4 | |||
| c18a880ad7 | |||
| a845ea7c63 | |||
| 2d9695344b | |||
| 24d05e6d87 | |||
| 07b0513eae | |||
| e445b787a9 | |||
| 82156059fa | |||
| b976ff95b6 | |||
| a4b2745b7b | |||
| 844be6a4a7 | |||
| 49a48fc371 | |||
| 722750b724 | |||
| ab51eb3655 | |||
| 7b88e7a612 | |||
| bb2f5c9842 | |||
| 883a7e8341 | |||
| bfc0e3ac4f | |||
| 23ded3a851 | |||
| 6d363fd02d | |||
| 3c0f889db7 | |||
| d018c27f0e | |||
| 7e36f0f32e | |||
| 666129de16 | |||
| becdbd6546 | |||
| d292988737 | |||
| 21ee06e9b1 | |||
| f22e4854ee | |||
| 7182698b8a | |||
| 7fd8d1cfd0 | |||
| 943928089b | |||
| f70e45701f | |||
| 9b33f13f66 | |||
| 2f3a33b1b8 | |||
| 6c8ca59e3f | |||
| 5ffb36a87f | |||
| 1560fd3343 | |||
| a0ff8c80f0 | |||
| 1ea3bdaea3 | |||
| f325b30917 | |||
| 8ce2a09b3b | |||
| 4a18a6ed19 | |||
| 9a8519d3e3 | |||
| 0a0399c2b0 | |||
| 3844079781 | |||
| 191ad904a3 | |||
| e988cedf7c | |||
| 9a7f66fa22 | |||
| c926c85dd0 | |||
| cddd8cfac5 | |||
| e57b888393 | |||
| c922f8c7fc | |||
| 357c7f894f | |||
| 34091a7b73 | |||
| 8d26abdede | |||
| 8d42bb48d2 | |||
| f79efa7739 | |||
| d257c4ccb0 | |||
| e39f0c2497 | |||
| 327a992cac | |||
| 9021b03732 | |||
| 514a9ae0e4 | |||
| 09298bce55 | |||
| 74f50d3e13 | |||
| 1946fb6b9f | |||
| acc0f592d1 | |||
| 2e09ea1c90 | |||
| 769f227689 | |||
| 22533fcfee | |||
| 004ca6993a | |||
| 0bea81a630 | |||
| 88decce426 |
Generated
+117
@@ -0,0 +1,117 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<code_scheme name="Project" version="173">
|
||||
<codeStyleSettings language="XML">
|
||||
<option name="FORCE_REARRANGE_MODE" value="1" />
|
||||
<indentOptions>
|
||||
<option name="CONTINUATION_INDENT_SIZE" value="4" />
|
||||
</indentOptions>
|
||||
<arrangement>
|
||||
<rules>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:android</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>xmlns:.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:id</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*:name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>name</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>style</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>^$</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>ANDROID_ATTRIBUTE_ORDER</order>
|
||||
</rule>
|
||||
</section>
|
||||
<section>
|
||||
<rule>
|
||||
<match>
|
||||
<AND>
|
||||
<NAME>.*</NAME>
|
||||
<XML_ATTRIBUTE />
|
||||
<XML_NAMESPACE>.*</XML_NAMESPACE>
|
||||
</AND>
|
||||
</match>
|
||||
<order>BY_NAME</order>
|
||||
</rule>
|
||||
</section>
|
||||
</rules>
|
||||
</arrangement>
|
||||
</codeStyleSettings>
|
||||
</code_scheme>
|
||||
</component>
|
||||
Generated
+5
@@ -0,0 +1,5 @@
|
||||
<component name="ProjectCodeStyleConfiguration">
|
||||
<state>
|
||||
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||
</state>
|
||||
</component>
|
||||
Generated
+17
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="deploymentTargetDropDown">
|
||||
<targetSelectedWithDropDown>
|
||||
<Target>
|
||||
<type value="QUICK_BOOT_TARGET" />
|
||||
<deviceKey>
|
||||
<Key>
|
||||
<type value="VIRTUAL_DEVICE_PATH" />
|
||||
<value value="C:\Users\jens\.android\avd\Android_11.avd" />
|
||||
</Key>
|
||||
</deviceKey>
|
||||
</Target>
|
||||
</targetSelectedWithDropDown>
|
||||
<timeTargetWasSelectedWithDropDown value="2021-08-14T11:41:28.444891400Z" />
|
||||
</component>
|
||||
</project>
|
||||
+12
-11
@@ -11,8 +11,8 @@ android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.2'
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
versionCode 103
|
||||
versionName "1.6.32"
|
||||
versionCode 109
|
||||
versionName "1.6.39"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
@@ -40,7 +40,6 @@ android {
|
||||
googlePlayFlavor
|
||||
{
|
||||
dimension "version"
|
||||
// applicationIdSuffix ".googlePlay"
|
||||
versionNameSuffix "-googlePlay"
|
||||
targetSdkVersion 29
|
||||
}
|
||||
@@ -48,15 +47,12 @@ android {
|
||||
fdroidFlavor
|
||||
{
|
||||
dimension "version"
|
||||
// applicationIdSuffix ".fdroid"
|
||||
// versionNameSuffix "-fdroid"
|
||||
targetSdkVersion 28
|
||||
}
|
||||
|
||||
apkFlavor
|
||||
{
|
||||
dimension "version"
|
||||
// applicationIdSuffix ".apk"
|
||||
versionNameSuffix "-apk"
|
||||
targetSdkVersion 28
|
||||
}
|
||||
@@ -64,13 +60,18 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
|
||||
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:17.1.0'
|
||||
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0'
|
||||
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:18.0.0'
|
||||
|
||||
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
|
||||
apkFlavorImplementation 'com.google.android.gms:play-services-location:17.1.0'
|
||||
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:20.0.0'
|
||||
apkFlavorImplementation 'com.google.android.gms:play-services-location:18.0.0'
|
||||
|
||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||
implementation 'com.linkedin.dexmaker:dexmaker:2.25.0'
|
||||
implementation 'org.apache.commons:commons-lang3:3.0'
|
||||
|
||||
//implementation "androidx.security:security-crypto:1.0.0"
|
||||
//implementation "androidx.security:security-identity-credential:1.0.0-alpha02"
|
||||
implementation 'androidx.appcompat:appcompat:1.3.0'
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
testImplementation 'junit:junit:4.+'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
|
||||
@@ -5,13 +5,13 @@
|
||||
"kind": "Directory"
|
||||
},
|
||||
"applicationId": "com.jens.automation2",
|
||||
"variantName": "processGooglePlayFlavorReleaseResources",
|
||||
"variantName": "googlePlayFlavorRelease",
|
||||
"elements": [
|
||||
{
|
||||
"type": "SINGLE",
|
||||
"filters": [],
|
||||
"versionCode": 102,
|
||||
"versionName": "1.6.30-googlePlay",
|
||||
"versionCode": 107,
|
||||
"versionName": "1.6.36-googlePlay",
|
||||
"outputFile": "app-googlePlayFlavor-release.apk"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -51,6 +51,7 @@
|
||||
<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.WRITE_SECURE_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" />
|
||||
@@ -63,8 +64,7 @@
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
<uses-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
|
||||
|
||||
<!-- Commented out because of Google Play policy -->
|
||||
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@@ -75,9 +75,10 @@
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:usesClearTextTraffic="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
@@ -96,15 +97,15 @@
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManagePoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
android:label="@string/app_name" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
@@ -142,8 +143,11 @@
|
||||
<activity android:name=".ActivityManageActionSendTextMessage" />
|
||||
<activity android:name=".ActivityManageActionPlaySound" />
|
||||
<activity android:name=".ActivityManageTriggerTimeFrame" />
|
||||
<activity android:name=".ActivityMaintenance" />
|
||||
<activity android:name=".ActivityManageTriggerPhoneCall" />
|
||||
<activity android:name=".ActivityManageActionBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity android:name=".ActivityManageActionVibrate" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
@@ -186,27 +190,10 @@
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
<activity android:name=".ActivityManageTriggerWifi" />
|
||||
<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>
|
||||
|
||||
|
||||
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
<service android:name=".location.GeofenceIntentService"/>
|
||||
|
||||
|
||||
<activity android:name=".ActivityManageTriggerNotification"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
@@ -218,6 +205,22 @@
|
||||
|
||||
</service>
|
||||
|
||||
|
||||
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
|
||||
<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" />
|
||||
<service android:name=".location.GeofenceIntentService"/>
|
||||
|
||||
|
||||
<provider
|
||||
android:name=".FileShareProvider"
|
||||
android:authorities="com.jens.automation2"
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -33,6 +34,8 @@ import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT;
|
||||
import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
|
||||
public class Rule implements Comparable<Rule>
|
||||
{
|
||||
@@ -174,6 +177,15 @@ public class Rule implements Comparable<Rule>
|
||||
Miscellaneous.logEvent("i", "Rule", "Creating rule: " + this.toString(), 3);
|
||||
ruleCollection.add(this);
|
||||
boolean returnValue = XmlFileInterface.writeFile();
|
||||
|
||||
try
|
||||
{
|
||||
XmlFileInterface.readFile();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Read file", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
|
||||
if(returnValue)
|
||||
{
|
||||
@@ -217,10 +229,23 @@ public class Rule implements Comparable<Rule>
|
||||
|
||||
return XmlFileInterface.writeFile();
|
||||
}
|
||||
|
||||
public boolean cloneRule(Context context)
|
||||
{
|
||||
Rule newRule = new Rule();
|
||||
newRule.setName(this.getName() + " - clone");
|
||||
newRule.setRuleActive(this.isRuleActive());
|
||||
newRule.setRuleToggle(this.isRuleToggle());
|
||||
|
||||
newRule.setTriggerSet(this.getTriggerSet());
|
||||
newRule.setActionSet(this.getActionSet());
|
||||
|
||||
return newRule.create(context);
|
||||
}
|
||||
|
||||
private boolean checkBeforeSaving(Context context, boolean changeExistingRule)
|
||||
{
|
||||
if(this.getName() == null | this.getName().length()==0)
|
||||
if(this.getName() == null || this.getName().length()==0)
|
||||
{
|
||||
Toast.makeText(context, context.getResources().getString(R.string.pleaseEnterValidName), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
@@ -415,13 +440,13 @@ public class Rule implements Comparable<Rule>
|
||||
&&
|
||||
Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0
|
||||
)
|
||||
|
|
||||
||
|
||||
// Other case, start time higher than end time, timeframe goes over midnight
|
||||
(
|
||||
Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), oneTrigger.getTimeFrame().getTriggerTimeStop()) < 0
|
||||
&&
|
||||
(Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), nowTime) >= 0
|
||||
|
|
||||
||
|
||||
Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0)
|
||||
)
|
||||
|
||||
@@ -548,12 +573,12 @@ public class Rule implements Comparable<Rule>
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for wifi state", 4);
|
||||
if(oneTrigger.getTriggerParameter() == WifiBroadcastReceiver.lastConnectedState) // connected / disconnected
|
||||
{
|
||||
if(oneTrigger.getWifiName().length() > 0) // only check if any wifi name specified, otherwise any wifi will do
|
||||
if(oneTrigger.getTriggerParameter2().length() > 0) // only check if any wifi name specified, otherwise any wifi will do
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi name specified, checking that.", 4);
|
||||
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(oneTrigger.getWifiName()))
|
||||
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(oneTrigger.getTriggerParameter2()))
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), oneTrigger.getWifiName(), WifiBroadcastReceiver.getLastWifiSsid()), 3);
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), oneTrigger.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()), 3);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -601,13 +626,29 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.phoneCall))
|
||||
{
|
||||
if(oneTrigger.getPhoneNumber().equals("any") | oneTrigger.getPhoneNumber().equals(PhoneStatusListener.getLastPhoneNumber()))
|
||||
String[] elements = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
// state dir number
|
||||
|
||||
if(elements[2].equals(Trigger.triggerPhoneCallNumberAny) || Miscellaneous.comparePhoneNumbers(PhoneStatusListener.getLastPhoneNumber(), elements[2]) || (Miscellaneous.isRegularExpression(elements[2]) && PhoneStatusListener.getLastPhoneNumber().matches(elements[2])))
|
||||
{
|
||||
if(PhoneStatusListener.isInACall() == oneTrigger.getTriggerParameter())
|
||||
//if(PhoneStatusListener.isInACall() == oneTrigger.getTriggerParameter())
|
||||
if(
|
||||
(elements[0].equals(Trigger.triggerPhoneCallStateRinging) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_RINGING)
|
||||
||
|
||||
(elements[0].equals(Trigger.triggerPhoneCallStateStarted) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_OFFHOOK)
|
||||
||
|
||||
(elements[0].equals(Trigger.triggerPhoneCallStateStopped) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_IDLE)
|
||||
)
|
||||
{
|
||||
if(oneTrigger.getPhoneDirection() == 0 | (oneTrigger.getPhoneDirection() == PhoneStatusListener.getLastPhoneDirection()))
|
||||
if(
|
||||
elements[1].equals(Trigger.triggerPhoneCallDirectionAny)
|
||||
||
|
||||
(elements[1].equals(Trigger.triggerPhoneCallDirectionIncoming) && PhoneStatusListener.getLastPhoneDirection() == 1)
|
||||
||
|
||||
(elements[1].equals(Trigger.triggerPhoneCallDirectionOutgoing) && PhoneStatusListener.getLastPhoneDirection() == 2)
|
||||
)
|
||||
{
|
||||
// Everything's allright
|
||||
// Trigger conditions are met
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -622,7 +663,10 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong phone number. Demanded: " + oneTrigger.getPhoneNumber() + ", got: " + PhoneStatusListener.getLastPhoneNumber(), 4);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.nfcTag))
|
||||
{
|
||||
@@ -770,38 +814,42 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(getLastExecution() == null || sbn.getPostTime() > this.lastExecution.getTimeInMillis())
|
||||
{
|
||||
String app = sbn.getPackageName();
|
||||
String title = sbn.getNotification().extras.getString(EXTRA_TITLE);
|
||||
String text = sbn.getNotification().extras.getString(EXTRA_TEXT);
|
||||
String notificationApp = sbn.getPackageName();
|
||||
String notificationTitle = sbn.getNotification().extras.getString(EXTRA_TITLE);
|
||||
String notificationText = sbn.getNotification().extras.getString(EXTRA_TEXT);
|
||||
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Checking if this notification matches our rule " + this.getName() + ". App: " + app + ", title: " + title + ", text: " + text, 5);
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Checking if this notification matches our rule " + this.getName() + ". App: " + notificationApp + ", title: " + notificationTitle + ", text: " + notificationText, 5);
|
||||
|
||||
if (!myApp.equals("-1"))
|
||||
{
|
||||
if (!app.equalsIgnoreCase(myApp))
|
||||
if (!notificationApp.equalsIgnoreCase(myApp))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification app name does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (myTitle.length() > 0)
|
||||
if (!StringUtils.isEmpty(myTitle))
|
||||
{
|
||||
if (!Miscellaneous.compare(myTitleDir, myTitle, title))
|
||||
if (!Miscellaneous.compare(myTitleDir, myTitle, notificationTitle))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification title does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "A required title for a notification trigger was not specified.", 5);
|
||||
|
||||
if (myText.length() > 0)
|
||||
if (!StringUtils.isEmpty(myText))
|
||||
{
|
||||
if (!Miscellaneous.compare(myTextDir, myText, text))
|
||||
if (!Miscellaneous.compare(myTextDir, myText, notificationText))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "Notification text does not match rule.", 5);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "NotificationCheck", "A required text for a notification trigger was not specified.", 5);
|
||||
|
||||
foundMatch = true;
|
||||
break;
|
||||
@@ -855,7 +903,7 @@ public class Rule implements Comparable<Rule>
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleIsDeactivatedCantApply), this.getName()), 3);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private class ActivateRuleTask extends AsyncTask<Object, String, Void>
|
||||
{
|
||||
boolean wasActivated = false;
|
||||
@@ -916,7 +964,7 @@ public class Rule implements Comparable<Rule>
|
||||
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||
boolean doToggle = ruleToggle && isActuallyToggable;
|
||||
|
||||
if(notLastActive | force | doToggle)
|
||||
if(notLastActive || force || doToggle)
|
||||
{
|
||||
String message;
|
||||
if(!doToggle)
|
||||
@@ -1069,7 +1117,7 @@ public class Rule implements Comparable<Rule>
|
||||
if(oneTrigger.getTimeFrame().getTriggerTimeStart().getTime() > oneTrigger.getTimeFrame().getTriggerTimeStop().getTime())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Timeframe search", "Rule goes over midnight.", 5);
|
||||
if(oneTrigger.getTimeFrame().getTriggerTimeStart().getTime() <= searchTime.getTime() | searchTime.getTime() <= oneTrigger.getTimeFrame().getTriggerTimeStop().getTime()+20000) //add 20 seconds because of delay
|
||||
if(oneTrigger.getTimeFrame().getTriggerTimeStart().getTime() <= searchTime.getTime() || searchTime.getTime() <= oneTrigger.getTimeFrame().getTriggerTimeStop().getTime()+20000) //add 20 seconds because of delay
|
||||
{
|
||||
ruleCandidates.add(oneRule);
|
||||
break innerloop; //if the poi is found we don't need to search the other triggers in the same rule
|
||||
@@ -1340,10 +1388,10 @@ public class Rule implements Comparable<Rule>
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
public static ArrayList<Rule> findRuleCandidatesByPhoneCall(boolean triggerParameter)
|
||||
public static ArrayList<Rule> findRuleCandidatesByPhoneCall(String direction)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = new ArrayList<Rule>();
|
||||
|
||||
|
||||
for(Rule oneRule : ruleCollection)
|
||||
{
|
||||
innerloop:
|
||||
@@ -1351,7 +1399,8 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(oneTrigger.getTriggerType() == Trigger.Trigger_Enum.phoneCall)
|
||||
{
|
||||
if(oneTrigger.getTriggerParameter() == triggerParameter)
|
||||
String[] elements = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
if(elements[1].equals(Trigger.triggerPhoneCallDirectionAny) || elements[1].equals(direction))
|
||||
{
|
||||
ruleCandidates.add(oneRule);
|
||||
break innerloop; //we don't need to search the other triggers in the same rule
|
||||
@@ -1359,7 +1408,7 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,8 @@
|
||||
<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-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
|
||||
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@@ -70,9 +72,10 @@
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:usesClearTextTraffic="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
@@ -91,15 +94,15 @@
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManagePoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
android:label="@string/app_name" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
@@ -135,9 +138,13 @@
|
||||
<activity android:name=".ActivityManageActionTriggerUrl" />
|
||||
<activity android:name=".ActivityDisplayLongMessage" />
|
||||
<activity android:name=".ActivityManageActionSendTextMessage" />
|
||||
<activity android:name=".ActivityManageActionPlaySound" />
|
||||
<activity android:name=".ActivityManageTriggerTimeFrame" />
|
||||
<activity android:name=".ActivityMaintenance" />
|
||||
<activity android:name=".ActivityManageTriggerPhoneCall" />
|
||||
<activity android:name=".ActivityManageActionBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity android:name=".ActivityManageActionVibrate" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
@@ -180,6 +187,7 @@
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
<activity android:name=".ActivityManageTriggerWifi" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
@@ -194,6 +202,10 @@
|
||||
|
||||
</service>
|
||||
|
||||
<activity android:name=".ActivityPermissions" />
|
||||
|
||||
|
||||
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
<provider
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -171,6 +172,15 @@ public class Rule implements Comparable<Rule>
|
||||
Miscellaneous.logEvent("i", "Rule", "Creating rule: " + this.toString(), 3);
|
||||
ruleCollection.add(this);
|
||||
boolean returnValue = XmlFileInterface.writeFile();
|
||||
|
||||
try
|
||||
{
|
||||
XmlFileInterface.readFile();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Read file", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
|
||||
if(returnValue)
|
||||
{
|
||||
@@ -214,10 +224,23 @@ public class Rule implements Comparable<Rule>
|
||||
|
||||
return XmlFileInterface.writeFile();
|
||||
}
|
||||
|
||||
public boolean cloneRule(Context context)
|
||||
{
|
||||
Rule newRule = new Rule();
|
||||
newRule.setName(this.getName() + " - clone");
|
||||
newRule.setRuleActive(this.isRuleActive());
|
||||
newRule.setRuleToggle(this.isRuleToggle());
|
||||
|
||||
newRule.setTriggerSet(this.getTriggerSet());
|
||||
newRule.setActionSet(this.getActionSet());
|
||||
|
||||
return newRule.create(context);
|
||||
}
|
||||
|
||||
private boolean checkBeforeSaving(Context context, boolean changeExistingRule)
|
||||
{
|
||||
if(this.getName() == null | this.getName().length()==0)
|
||||
if(this.getName() == null || this.getName().length()==0)
|
||||
{
|
||||
Toast.makeText(context, context.getResources().getString(R.string.pleaseEnterValidName), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
@@ -412,13 +435,13 @@ public class Rule implements Comparable<Rule>
|
||||
&&
|
||||
Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0
|
||||
)
|
||||
|
|
||||
||
|
||||
// Other case, start time higher than end time, timeframe goes over midnight
|
||||
(
|
||||
Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), oneTrigger.getTimeFrame().getTriggerTimeStop()) < 0
|
||||
&&
|
||||
(Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), nowTime) >= 0
|
||||
|
|
||||
||
|
||||
Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0)
|
||||
)
|
||||
|
||||
@@ -545,12 +568,12 @@ public class Rule implements Comparable<Rule>
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for wifi state", 4);
|
||||
if(oneTrigger.getTriggerParameter() == WifiBroadcastReceiver.lastConnectedState) // connected / disconnected
|
||||
{
|
||||
if(oneTrigger.getWifiName().length() > 0) // only check if any wifi name specified, otherwise any wifi will do
|
||||
if(oneTrigger.getTriggerParameter2().length() > 0) // only check if any wifi name specified, otherwise any wifi will do
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi name specified, checking that.", 4);
|
||||
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(oneTrigger.getWifiName()))
|
||||
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(oneTrigger.getTriggerParameter2()))
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), oneTrigger.getWifiName(), WifiBroadcastReceiver.getLastWifiSsid()), 3);
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), oneTrigger.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()), 3);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -598,13 +621,29 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.phoneCall))
|
||||
{
|
||||
if(oneTrigger.getPhoneNumber().equals("any") | oneTrigger.getPhoneNumber().equals(PhoneStatusListener.getLastPhoneNumber()))
|
||||
String[] elements = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
// state dir number
|
||||
|
||||
if(elements[2].equals(Trigger.triggerPhoneCallNumberAny) || Miscellaneous.comparePhoneNumbers(PhoneStatusListener.getLastPhoneNumber(), elements[2]) || (Miscellaneous.isRegularExpression(elements[2]) && PhoneStatusListener.getLastPhoneNumber().matches(elements[2])))
|
||||
{
|
||||
if(PhoneStatusListener.isInACall() == oneTrigger.getTriggerParameter())
|
||||
//if(PhoneStatusListener.isInACall() == oneTrigger.getTriggerParameter())
|
||||
if(
|
||||
(elements[0].equals(Trigger.triggerPhoneCallStateRinging) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_RINGING)
|
||||
||
|
||||
(elements[0].equals(Trigger.triggerPhoneCallStateStarted) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_OFFHOOK)
|
||||
||
|
||||
(elements[0].equals(Trigger.triggerPhoneCallStateStopped) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_IDLE)
|
||||
)
|
||||
{
|
||||
if(oneTrigger.getPhoneDirection() == 0 | (oneTrigger.getPhoneDirection() == PhoneStatusListener.getLastPhoneDirection()))
|
||||
if(
|
||||
elements[1].equals(Trigger.triggerPhoneCallDirectionAny)
|
||||
||
|
||||
(elements[1].equals(Trigger.triggerPhoneCallDirectionIncoming) && PhoneStatusListener.getLastPhoneDirection() == 1)
|
||||
||
|
||||
(elements[1].equals(Trigger.triggerPhoneCallDirectionOutgoing) && PhoneStatusListener.getLastPhoneDirection() == 2)
|
||||
)
|
||||
{
|
||||
// Everything's allright
|
||||
// Trigger conditions are met
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -619,7 +658,10 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong phone number. Demanded: " + oneTrigger.getPhoneNumber() + ", got: " + PhoneStatusListener.getLastPhoneNumber(), 4);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.nfcTag))
|
||||
{
|
||||
@@ -772,6 +814,7 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
|
||||
foundMatch = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -840,7 +883,7 @@ public class Rule implements Comparable<Rule>
|
||||
|
||||
if (Looper.myLooper() == null)
|
||||
Looper.prepare();
|
||||
|
||||
|
||||
wasActivated = activateInternally((AutomationService)params[0], (Boolean)params[1]);
|
||||
|
||||
return null;
|
||||
@@ -870,8 +913,8 @@ public class Rule implements Comparable<Rule>
|
||||
ActivityMainScreen.updateMainScreen();
|
||||
super.onPostExecute(result);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Will activate the rule. Should be called by a separate execution thread
|
||||
* @param automationService
|
||||
@@ -879,15 +922,15 @@ public class Rule implements Comparable<Rule>
|
||||
protected boolean activateInternally(AutomationService automationService, boolean force)
|
||||
{
|
||||
boolean isActuallyToggable = isActuallyToggable();
|
||||
|
||||
|
||||
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||
boolean doToggle = ruleToggle && isActuallyToggable;
|
||||
|
||||
if(notLastActive | force | doToggle)
|
||||
|
||||
if(notLastActive || force || doToggle)
|
||||
{
|
||||
String message;
|
||||
if(!doToggle)
|
||||
message = String.format(automationService.getResources().getString(R.string.ruleActivate), Rule.this.getName());
|
||||
message = String.format(automationService.getResources().getString(R.string.ruleActivate), Rule.this.getName());
|
||||
else
|
||||
message = String.format(automationService.getResources().getString(R.string.ruleActivateToggle), Rule.this.getName());
|
||||
Miscellaneous.logEvent("i", "Rule", message, 2);
|
||||
@@ -895,7 +938,7 @@ public class Rule implements Comparable<Rule>
|
||||
// Toast.makeText(automationService, message, Toast.LENGTH_LONG).show();
|
||||
if(Settings.startNewThreadForRuleActivation)
|
||||
publishProgress(message);
|
||||
|
||||
|
||||
for(int i = 0; i< Rule.this.getActionSet().size(); i++)
|
||||
{
|
||||
try
|
||||
@@ -1036,7 +1079,7 @@ public class Rule implements Comparable<Rule>
|
||||
if(oneTrigger.getTimeFrame().getTriggerTimeStart().getTime() > oneTrigger.getTimeFrame().getTriggerTimeStop().getTime())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Timeframe search", "Rule goes over midnight.", 5);
|
||||
if(oneTrigger.getTimeFrame().getTriggerTimeStart().getTime() <= searchTime.getTime() | searchTime.getTime() <= oneTrigger.getTimeFrame().getTriggerTimeStop().getTime()+20000) //add 20 seconds because of delay
|
||||
if(oneTrigger.getTimeFrame().getTriggerTimeStart().getTime() <= searchTime.getTime() || searchTime.getTime() <= oneTrigger.getTimeFrame().getTriggerTimeStop().getTime()+20000) //add 20 seconds because of delay
|
||||
{
|
||||
ruleCandidates.add(oneRule);
|
||||
break innerloop; //if the poi is found we don't need to search the other triggers in the same rule
|
||||
@@ -1307,10 +1350,10 @@ public class Rule implements Comparable<Rule>
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
public static ArrayList<Rule> findRuleCandidatesByPhoneCall(boolean triggerParameter)
|
||||
public static ArrayList<Rule> findRuleCandidatesByPhoneCall(String direction)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = new ArrayList<Rule>();
|
||||
|
||||
|
||||
for(Rule oneRule : ruleCollection)
|
||||
{
|
||||
innerloop:
|
||||
@@ -1318,7 +1361,8 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(oneTrigger.getTriggerType() == Trigger.Trigger_Enum.phoneCall)
|
||||
{
|
||||
if(oneTrigger.getTriggerParameter() == triggerParameter)
|
||||
String[] elements = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
if(elements[1].equals(Trigger.triggerPhoneCallDirectionAny) || elements[1].equals(direction))
|
||||
{
|
||||
ruleCandidates.add(oneRule);
|
||||
break innerloop; //we don't need to search the other triggers in the same rule
|
||||
@@ -1326,7 +1370,7 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,12 +61,15 @@
|
||||
<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-permission android:name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE"/>
|
||||
<uses-permission android:name="com.wireguard.android.permission.CONTROL_TUNNELS"/>
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:usesClearTextTraffic="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
@@ -85,15 +88,15 @@
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManagePoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
android:label="@string/app_name"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
android:label="@string/app_name" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
@@ -131,8 +134,11 @@
|
||||
<activity android:name=".ActivityManageActionSendTextMessage" />
|
||||
<activity android:name=".ActivityManageActionPlaySound" />
|
||||
<activity android:name=".ActivityManageTriggerTimeFrame" />
|
||||
<activity android:name=".ActivityMaintenance" />
|
||||
<activity android:name=".ActivityManageTriggerPhoneCall" />
|
||||
<activity android:name=".ActivityManageActionBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity android:name=".ActivityManageActionVibrate" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
@@ -172,12 +178,14 @@
|
||||
<activity android:name=".ActivityManageActionStartActivity" />
|
||||
<activity android:name=".ActivityManageTriggerNfc" />
|
||||
<activity android:name=".ActivityManageActionSpeakText" />
|
||||
<activity android:name=".ActivityManageActionPlaySound" />
|
||||
<activity android:name=".ActivityManageTriggerBluetooth" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
<activity android:name=".ActivityManageTriggerWifi" />
|
||||
<activity android:name=".ActivityVolumeTest" />
|
||||
<activity android:name=".ActivityPermissions"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification"></activity>
|
||||
<activity android:name=".ActivityManageTriggerNotification" />
|
||||
|
||||
<service
|
||||
android:name=".receivers.NotificationListener"
|
||||
@@ -189,6 +197,13 @@
|
||||
|
||||
</service>
|
||||
|
||||
<activity android:name=".ActivityPermissions" />
|
||||
|
||||
|
||||
<!-- https://developer.android.com/about/versions/pie/android-9.0-changes-28#apache-p-->
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
|
||||
<service
|
||||
android:name=".receivers.ActivityDetectionReceiver"
|
||||
android:exported="false"
|
||||
@@ -197,12 +212,8 @@
|
||||
<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"/>
|
||||
|
||||
<uses-library android:name="org.apache.http.legacy" android:required="false"/>
|
||||
|
||||
<provider
|
||||
android:name=".FileShareProvider"
|
||||
|
||||
@@ -7,6 +7,7 @@ import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Looper;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -63,7 +64,7 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
this.lastExecution = lastExecution;
|
||||
}
|
||||
|
||||
|
||||
public boolean isRuleToggle()
|
||||
{
|
||||
return ruleToggle;
|
||||
@@ -173,6 +174,15 @@ public class Rule implements Comparable<Rule>
|
||||
Miscellaneous.logEvent("i", "Rule", "Creating rule: " + this.toString(), 3);
|
||||
ruleCollection.add(this);
|
||||
boolean returnValue = XmlFileInterface.writeFile();
|
||||
|
||||
try
|
||||
{
|
||||
XmlFileInterface.readFile();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Read file", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
|
||||
if(returnValue)
|
||||
{
|
||||
@@ -216,10 +226,23 @@ public class Rule implements Comparable<Rule>
|
||||
|
||||
return XmlFileInterface.writeFile();
|
||||
}
|
||||
|
||||
public boolean cloneRule(Context context)
|
||||
{
|
||||
Rule newRule = new Rule();
|
||||
newRule.setName(this.getName() + " - clone");
|
||||
newRule.setRuleActive(this.isRuleActive());
|
||||
newRule.setRuleToggle(this.isRuleToggle());
|
||||
|
||||
newRule.setTriggerSet(this.getTriggerSet());
|
||||
newRule.setActionSet(this.getActionSet());
|
||||
|
||||
return newRule.create(context);
|
||||
}
|
||||
|
||||
private boolean checkBeforeSaving(Context context, boolean changeExistingRule)
|
||||
{
|
||||
if(this.getName() == null | this.getName().length()==0)
|
||||
if(this.getName() == null || this.getName().length()==0)
|
||||
{
|
||||
Toast.makeText(context, context.getResources().getString(R.string.pleaseEnterValidName), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
@@ -414,13 +437,13 @@ public class Rule implements Comparable<Rule>
|
||||
&&
|
||||
Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0
|
||||
)
|
||||
|
|
||||
||
|
||||
// Other case, start time higher than end time, timeframe goes over midnight
|
||||
(
|
||||
Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), oneTrigger.getTimeFrame().getTriggerTimeStop()) < 0
|
||||
&&
|
||||
(Miscellaneous.compareTimes(oneTrigger.getTimeFrame().getTriggerTimeStart(), nowTime) >= 0
|
||||
|
|
||||
||
|
||||
Miscellaneous.compareTimes(nowTime, oneTrigger.getTimeFrame().getTriggerTimeStop()) > 0)
|
||||
)
|
||||
|
||||
@@ -547,12 +570,12 @@ public class Rule implements Comparable<Rule>
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Checking for wifi state", 4);
|
||||
if(oneTrigger.getTriggerParameter() == WifiBroadcastReceiver.lastConnectedState) // connected / disconnected
|
||||
{
|
||||
if(oneTrigger.getWifiName().length() > 0) // only check if any wifi name specified, otherwise any wifi will do
|
||||
if(oneTrigger.getTriggerParameter2().length() > 0) // only check if any wifi name specified, otherwise any wifi will do
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), "Wifi name specified, checking that.", 4);
|
||||
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(oneTrigger.getWifiName()))
|
||||
if(!WifiBroadcastReceiver.getLastWifiSsid().equals(oneTrigger.getTriggerParameter2()))
|
||||
{
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), oneTrigger.getWifiName(), WifiBroadcastReceiver.getLastWifiSsid()), 3);
|
||||
Miscellaneous.logEvent("i", String.format(context.getResources().getString(R.string.ruleCheckOf), this.getName()), String.format(context.getResources().getString(R.string.ruleDoesntApplyNotTheCorrectSsid), oneTrigger.getTriggerParameter2(), WifiBroadcastReceiver.getLastWifiSsid()), 3);
|
||||
return false;
|
||||
}
|
||||
else
|
||||
@@ -600,13 +623,29 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.phoneCall))
|
||||
{
|
||||
if(oneTrigger.getPhoneNumber().equals("any") | oneTrigger.getPhoneNumber().equals(PhoneStatusListener.getLastPhoneNumber()))
|
||||
String[] elements = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
// state dir number
|
||||
|
||||
if(elements[2].equals(Trigger.triggerPhoneCallNumberAny) || Miscellaneous.comparePhoneNumbers(PhoneStatusListener.getLastPhoneNumber(), elements[2]) || (Miscellaneous.isRegularExpression(elements[2]) && PhoneStatusListener.getLastPhoneNumber().matches(elements[2])))
|
||||
{
|
||||
if(PhoneStatusListener.isInACall() == oneTrigger.getTriggerParameter())
|
||||
//if(PhoneStatusListener.isInACall() == oneTrigger.getTriggerParameter())
|
||||
if(
|
||||
(elements[0].equals(Trigger.triggerPhoneCallStateRinging) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_RINGING)
|
||||
||
|
||||
(elements[0].equals(Trigger.triggerPhoneCallStateStarted) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_OFFHOOK)
|
||||
||
|
||||
(elements[0].equals(Trigger.triggerPhoneCallStateStopped) && PhoneStatusListener.getCurrentState() == TelephonyManager.CALL_STATE_IDLE)
|
||||
)
|
||||
{
|
||||
if(oneTrigger.getPhoneDirection() == 0 | (oneTrigger.getPhoneDirection() == PhoneStatusListener.getLastPhoneDirection()))
|
||||
if(
|
||||
elements[1].equals(Trigger.triggerPhoneCallDirectionAny)
|
||||
||
|
||||
(elements[1].equals(Trigger.triggerPhoneCallDirectionIncoming) && PhoneStatusListener.getLastPhoneDirection() == 1)
|
||||
||
|
||||
(elements[1].equals(Trigger.triggerPhoneCallDirectionOutgoing) && PhoneStatusListener.getLastPhoneDirection() == 2)
|
||||
)
|
||||
{
|
||||
// Everything's allright
|
||||
// Trigger conditions are met
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -621,7 +660,10 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Rule", "Rule doesn't apply. Wrong phone number. Demanded: " + oneTrigger.getPhoneNumber() + ", got: " + PhoneStatusListener.getLastPhoneNumber(), 4);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if(oneTrigger.getTriggerType().equals(Trigger.Trigger_Enum.nfcTag))
|
||||
{
|
||||
@@ -872,7 +914,7 @@ public class Rule implements Comparable<Rule>
|
||||
|
||||
if (Looper.myLooper() == null)
|
||||
Looper.prepare();
|
||||
|
||||
|
||||
wasActivated = activateInternally((AutomationService)params[0], (Boolean)params[1]);
|
||||
|
||||
return null;
|
||||
@@ -915,7 +957,7 @@ public class Rule implements Comparable<Rule>
|
||||
boolean notLastActive = getLastActivatedRule() == null || !getLastActivatedRule().equals(Rule.this);
|
||||
boolean doToggle = ruleToggle && isActuallyToggable;
|
||||
|
||||
if(notLastActive | force | doToggle)
|
||||
if(notLastActive || force || doToggle)
|
||||
{
|
||||
String message;
|
||||
if(!doToggle)
|
||||
@@ -1068,7 +1110,7 @@ public class Rule implements Comparable<Rule>
|
||||
if(oneTrigger.getTimeFrame().getTriggerTimeStart().getTime() > oneTrigger.getTimeFrame().getTriggerTimeStop().getTime())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Timeframe search", "Rule goes over midnight.", 5);
|
||||
if(oneTrigger.getTimeFrame().getTriggerTimeStart().getTime() <= searchTime.getTime() | searchTime.getTime() <= oneTrigger.getTimeFrame().getTriggerTimeStop().getTime()+20000) //add 20 seconds because of delay
|
||||
if(oneTrigger.getTimeFrame().getTriggerTimeStart().getTime() <= searchTime.getTime() || searchTime.getTime() <= oneTrigger.getTimeFrame().getTriggerTimeStop().getTime()+20000) //add 20 seconds because of delay
|
||||
{
|
||||
ruleCandidates.add(oneRule);
|
||||
break innerloop; //if the poi is found we don't need to search the other triggers in the same rule
|
||||
@@ -1339,10 +1381,10 @@ public class Rule implements Comparable<Rule>
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
public static ArrayList<Rule> findRuleCandidatesByPhoneCall(boolean triggerParameter)
|
||||
public static ArrayList<Rule> findRuleCandidatesByPhoneCall(String direction)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = new ArrayList<Rule>();
|
||||
|
||||
|
||||
for(Rule oneRule : ruleCollection)
|
||||
{
|
||||
innerloop:
|
||||
@@ -1350,7 +1392,8 @@ public class Rule implements Comparable<Rule>
|
||||
{
|
||||
if(oneTrigger.getTriggerType() == Trigger.Trigger_Enum.phoneCall)
|
||||
{
|
||||
if(oneTrigger.getTriggerParameter() == triggerParameter)
|
||||
String[] elements = oneTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
if(elements[1].equals(Trigger.triggerPhoneCallDirectionAny) || elements[1].equals(direction))
|
||||
{
|
||||
ruleCandidates.add(oneRule);
|
||||
break innerloop; //we don't need to search the other triggers in the same rule
|
||||
@@ -1358,7 +1401,7 @@ public class Rule implements Comparable<Rule>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return ruleCandidates;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,7 +2,6 @@ package com.jens.automation2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.text.style.TabStopSpan;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
@@ -15,6 +14,8 @@ import java.util.Locale;
|
||||
public class Action
|
||||
{
|
||||
public static final String actionParameter2Split = "ap2split";
|
||||
public static final String intentPairSeperator = "intPairSplit";
|
||||
public static final String vibrateSeparator = ",";
|
||||
|
||||
public enum Action_Enum {
|
||||
setWifi,
|
||||
@@ -38,6 +39,7 @@ public class Action
|
||||
playMusic,
|
||||
setScreenBrightness,
|
||||
playSound,
|
||||
vibrate,
|
||||
sendTextMessage;
|
||||
|
||||
public String getFullName(Context context)
|
||||
@@ -84,6 +86,8 @@ public class Action
|
||||
return context.getResources().getString(R.string.waitBeforeNextAction);
|
||||
case wakeupDevice:
|
||||
return context.getResources().getString(R.string.wakeupDevice);
|
||||
case vibrate:
|
||||
return context.getResources().getString(R.string.vibrate);
|
||||
case setAirplaneMode:
|
||||
return context.getResources().getString(R.string.airplaneMode);
|
||||
case setDataConnection:
|
||||
@@ -237,6 +241,10 @@ public class Action
|
||||
else
|
||||
returnString.append(": " + components[0]);
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.startOtherActivity))
|
||||
{
|
||||
returnString.append(": " + parameter2.replace(Action.intentPairSeperator, "/"));
|
||||
}
|
||||
else if(this.getAction().equals(Action_Enum.sendTextMessage))
|
||||
{
|
||||
String[] components = parameter2.split(Actions.smsSeparator);
|
||||
@@ -341,18 +349,11 @@ public class Action
|
||||
* 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);
|
||||
@@ -373,7 +374,7 @@ public class Action
|
||||
Actions.setDisplayRotation(context, getParameter1(), toggleActionIfPossible);
|
||||
break;
|
||||
case startOtherActivity:
|
||||
Actions.startOtherActivity(getParameter2());
|
||||
Actions.startOtherActivity(getParameter1(), getParameter2());
|
||||
break;
|
||||
case waitBeforeNextAction:
|
||||
Actions.waitBeforeNextAction(Long.parseLong(this.getParameter2()));
|
||||
@@ -408,6 +409,9 @@ public class Action
|
||||
case setScreenBrightness:
|
||||
Actions.setScreenBrightness(getParameter1(), Integer.parseInt(getParameter2()));
|
||||
break;
|
||||
case vibrate:
|
||||
Actions.vibrate(getParameter1(), getParameter2());
|
||||
break;
|
||||
case playSound:
|
||||
Actions.playSound(getParameter1(), getParameter2());
|
||||
break;
|
||||
@@ -455,7 +459,7 @@ public class Action
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "triggerUrl", context.getResources().getString(R.string.errorTriggeringUrl) + ": " + e.getMessage() + ", detailed: " + Log.getStackTraceString(e), 2);
|
||||
Miscellaneous.logEvent("e", "triggerUrl", context.getResources().getString(R.string.logErrorTriggeringUrl) + ": " + e.getMessage() + ", detailed: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -486,62 +490,24 @@ public class Action
|
||||
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);
|
||||
}
|
||||
// }
|
||||
|
||||
// Either thorough checking or no encryption
|
||||
if(!Settings.httpAcceptAllCertificates || !urlString.toLowerCase(Locale.getDefault()).contains("https"))
|
||||
response = Miscellaneous.downloadURL(urlString, urlUsername, urlPassword);
|
||||
else
|
||||
response = Miscellaneous.downloadURLwithoutCertificateChecking(urlString, urlUsername, urlPassword);
|
||||
|
||||
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);
|
||||
Miscellaneous.logEvent("i", "HTTPS RESULT", response, 5);
|
||||
|
||||
return response;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,6 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
@@ -60,11 +61,11 @@ public class ActivityMainPoi extends ActivityGeneric
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, ActivityMainPoi.this) || !ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, ActivityMainPoi.this))
|
||||
if (!ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, ActivityMainPoi.this) || !ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, ActivityMainPoi.this))
|
||||
{
|
||||
Intent permissionIntent = new Intent(ActivityMainPoi.this, ActivityPermissions.class);
|
||||
|
||||
permissionIntent.putExtra(ActivityPermissions.intentExtraName, new String[]{ActivityPermissions.permissionNameLocationCoarse, ActivityPermissions.permissionNameLocationFine});
|
||||
permissionIntent.putExtra(ActivityPermissions.intentExtraName, new String[]{Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION});
|
||||
|
||||
startActivityForResult(permissionIntent, requestCodeForPermission);
|
||||
}
|
||||
|
||||
@@ -26,10 +26,14 @@ import java.util.ArrayList;
|
||||
public class ActivityMainRules extends ActivityGeneric
|
||||
{
|
||||
private ListView ruleListView;
|
||||
ArrayList<Rule> ruleList = new ArrayList<>();
|
||||
private ArrayAdapter<Rule> ruleListViewAdapter;
|
||||
public static Rule ruleToEdit;
|
||||
protected static ActivityMainRules instance = null;
|
||||
|
||||
public static final int requestCodeCreateRule = 3000;
|
||||
public static final int requestCodeChangeRule = 4000;
|
||||
|
||||
public static ActivityMainRules getInstance()
|
||||
{
|
||||
if(instance == null)
|
||||
@@ -52,21 +56,14 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
@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, ActivityManageRule.class);
|
||||
startActivityForResult(startAddRuleIntent, 3000);
|
||||
startActivityForResult(startAddRuleIntent, requestCodeCreateRule);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
ruleListViewAdapter = new RuleArrayAdapter(this, R.layout.view_for_rule_listview, ruleList);
|
||||
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()
|
||||
@@ -112,7 +109,6 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
|
||||
private static class RuleArrayAdapter extends ArrayAdapter<Rule>
|
||||
{
|
||||
|
||||
public RuleArrayAdapter(Context context, int resource, ArrayList<Rule> objects)
|
||||
{
|
||||
super(context, resource, objects);
|
||||
@@ -163,13 +159,13 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
if(AutomationService.isMyServiceRunning(this))
|
||||
bindToService();
|
||||
|
||||
if(requestCode == 3000) //add Rule
|
||||
if(requestCode == requestCodeCreateRule) //add Rule
|
||||
{
|
||||
ruleToEdit = null; //clear cache
|
||||
updateListView();
|
||||
}
|
||||
|
||||
if(requestCode == 4000) //editRule
|
||||
if(requestCode == requestCodeChangeRule) //editRule
|
||||
{
|
||||
ruleToEdit = null; //clear cache
|
||||
updateListView();
|
||||
@@ -190,7 +186,7 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
{
|
||||
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()
|
||||
alertDialogBuilder.setItems(new String[]{ getResources().getString(R.string.runManually), getResources().getString(R.string.edit), getResources().getString(R.string.deleteCapital), getResources().getString(R.string.clone) }, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
@@ -212,11 +208,22 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
case 1:
|
||||
ruleToEdit = ruleThisIsAbout;
|
||||
Intent manageSpecificRuleIntent = new Intent (ActivityMainRules.this, ActivityManageRule.class);
|
||||
startActivityForResult(manageSpecificRuleIntent, 4000);
|
||||
startActivityForResult(manageSpecificRuleIntent, requestCodeChangeRule);
|
||||
break;
|
||||
case 2:
|
||||
if(ruleThisIsAbout.delete())
|
||||
{
|
||||
ruleToEdit = null; //clear cache
|
||||
updateListView();
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
ruleToEdit = ruleThisIsAbout;
|
||||
if(ruleToEdit.cloneRule(ActivityMainRules.this))
|
||||
{
|
||||
ruleToEdit = null; //clear cache
|
||||
updateListView();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -229,6 +236,11 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
public void updateListView()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "ListView", "Attempting to update RuleListView", 4);
|
||||
|
||||
ruleList.clear();
|
||||
for(Rule r : Rule.getRuleCollection())
|
||||
ruleList.add(r);
|
||||
|
||||
try
|
||||
{
|
||||
if(ruleListView.getAdapter() == null)
|
||||
@@ -249,4 +261,4 @@ public class ActivityMainRules extends ActivityGeneric
|
||||
// AlarmManager instance not prepared, yet.
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.PendingIntent;
|
||||
@@ -42,8 +43,9 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
|
||||
private static ActivityMainScreen activityMainScreenInstance = null;
|
||||
private ToggleButton toggleService, tbLockSound;
|
||||
private Button bShowHelp, bPrivacy, bSettingsErase, bSettingsSetToDefault, bVolumeTest, bAddSoundLockTIme, bShareConfigAndLog;
|
||||
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvlockSoundDuration, tvFileStoreLocation;
|
||||
private Button bShowHelp, bPrivacy, bSettingsErase, bAddSoundLockTIme;
|
||||
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvlockSoundDuration;
|
||||
private static boolean updateNoteDisplayed = false;
|
||||
|
||||
private ListView lvRuleHistory;
|
||||
private ArrayAdapter<Rule> ruleHistoryListViewAdapter;
|
||||
@@ -77,11 +79,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
tvMainScreenNoteLocationImpossibleBlameGoogle = (TextView) findViewById(R.id.tvMainScreenNoteLocationImpossibleBlameGoogle);
|
||||
tvMainScreenNoteNews = (TextView) findViewById(R.id.tvMainScreenNoteNews);
|
||||
tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
|
||||
tvFileStoreLocation = (TextView)findViewById(R.id.tvFileStoreLocation);
|
||||
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
|
||||
bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||
bSettingsSetToDefault = (Button) findViewById(R.id.bSettingsSetToDefault);
|
||||
bShareConfigAndLog = (Button) findViewById(R.id.bShareConfigAndLog);
|
||||
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||
@@ -136,18 +134,8 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent myIntent = new Intent(ActivityMainScreen.this, ActivitySettings.class);
|
||||
startActivityForResult(myIntent, 6000);
|
||||
}
|
||||
});
|
||||
|
||||
bVolumeTest.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(ActivityMainScreen.this, ActivityVolumeTest.class);
|
||||
startActivity(intent);
|
||||
Intent myIntent = new Intent(ActivityMainScreen.this, ActivityMaintenance.class);
|
||||
startActivity(myIntent);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -183,24 +171,6 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
builder.create().show();
|
||||
}
|
||||
});
|
||||
|
||||
bSettingsSetToDefault.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getDefaultSettingsDialog(ActivityMainScreen.this).show();
|
||||
}
|
||||
});
|
||||
|
||||
bShareConfigAndLog.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getShareConfigAndLogDialogue(ActivityMainScreen.this).show();
|
||||
}
|
||||
});
|
||||
|
||||
lvRuleHistory.setOnTouchListener(new OnTouchListener()
|
||||
{
|
||||
@@ -264,81 +234,6 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
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;
|
||||
}
|
||||
|
||||
AlertDialog getShareConfigAndLogDialogue(final Context context)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(context.getResources().getString(R.string.shareConfigAndLogFilesWithDev));
|
||||
alertDialogBuilder.setMessage(context.getResources().getString(R.string.shareConfigAndLogExplanation));
|
||||
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
File dstZipFile = new File(Miscellaneous.getAnyContext().getCacheDir() + "/" + Settings.zipFileName);
|
||||
|
||||
ArrayList<String> srcFilesList = new ArrayList<>();
|
||||
srcFilesList.add(Miscellaneous.getWriteableFolder() + "/" + XmlFileInterface.settingsFileName);
|
||||
|
||||
String logFilePath = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName;
|
||||
if((new File(logFilePath)).exists())
|
||||
srcFilesList.add(logFilePath);
|
||||
|
||||
String logFilePathArchive = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName + "-old";
|
||||
if((new File(logFilePathArchive)).exists())
|
||||
srcFilesList.add(logFilePathArchive);
|
||||
|
||||
String[] srcFiles = srcFilesList.toArray(new String[srcFilesList.size()]);
|
||||
|
||||
if(dstZipFile.exists())
|
||||
dstZipFile.delete();
|
||||
|
||||
Miscellaneous.zip(srcFiles, dstZipFile.getAbsolutePath());
|
||||
|
||||
/*
|
||||
Without root the zip file in the cache directory is not directly accessible.
|
||||
But have to route it through this content provider crap.
|
||||
*/
|
||||
|
||||
String subject = "Automation logs";
|
||||
|
||||
StringBuilder emailBody = new StringBuilder();
|
||||
emailBody.append("Device details" + Miscellaneous.lineSeparator);
|
||||
emailBody.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
|
||||
emailBody.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Product: " + android.os.Build.PRODUCT);
|
||||
|
||||
Uri uri = Uri.parse("content://com.jens.automation2/" + Settings.zipFileName);
|
||||
|
||||
Miscellaneous.sendEmail(ActivityMainScreen.this, "android-development@gmx.de", "Automation logs", emailBody.toString(), uri);
|
||||
}
|
||||
});
|
||||
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
public static ActivityMainScreen getActivityMainScreenInstance()
|
||||
{
|
||||
return activityMainScreenInstance;
|
||||
@@ -430,9 +325,9 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
if(
|
||||
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, Miscellaneous.getAnyContext())
|
||||
ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, Miscellaneous.getAnyContext())
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, Miscellaneous.getAnyContext())
|
||||
ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, Miscellaneous.getAnyContext())
|
||||
)
|
||||
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.stillGettingPosition));
|
||||
else
|
||||
@@ -513,36 +408,17 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
else
|
||||
activityMainScreenInstance.checkForNews();
|
||||
|
||||
if(BuildConfig.FLAVOR.equals("apkFlavor") && Settings.automaticUpdateCheck)
|
||||
{
|
||||
Calendar now = Calendar.getInstance();
|
||||
if (Settings.lastUpdateCheck == Settings.default_lastUpdateCheck || now.getTimeInMillis() >= Settings.lastUpdateCheck + (long)(Settings.updateCheckFrequencyDays * 24 * 60 * 60 * 1000))
|
||||
{
|
||||
activityMainScreenInstance.checkForUpdate();
|
||||
}
|
||||
}
|
||||
|
||||
Settings.considerDone(Settings.constNewsOptInDone);
|
||||
Settings.writeSettings(Miscellaneous.getAnyContext());
|
||||
|
||||
String folder = Miscellaneous.getWriteableFolder();
|
||||
if(folder != null && folder.length() > 0)
|
||||
{
|
||||
activityMainScreenInstance.tvFileStoreLocation.setText(String.format(activityMainScreenInstance.getResources().getString(R.string.filesStoredAt), folder));
|
||||
activityMainScreenInstance.tvFileStoreLocation.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Uri selectedUri = Uri.parse(folder);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(selectedUri, "resource/folder");
|
||||
|
||||
if (intent.resolveActivityInfo(activityMainScreenInstance.getPackageManager(), 0) != null)
|
||||
{
|
||||
activityMainScreenInstance.startActivity(intent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if you reach this place, it means there is no any file
|
||||
// explorer app installed on your device
|
||||
Toast.makeText(activityMainScreenInstance, activityMainScreenInstance.getResources().getString(R.string.noFileManageInstalled), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -598,16 +474,6 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
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))
|
||||
@@ -732,6 +598,15 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
Miscellaneous.messageBox(title, text, ActivityMainScreen.getActivityMainScreenInstance());
|
||||
}
|
||||
|
||||
synchronized void checkForUpdate()
|
||||
{
|
||||
if(Settings.automaticUpdateCheck)
|
||||
{
|
||||
AsyncTasks.AsyncTaskUpdateCheck updateCheckTask = new AsyncTasks.AsyncTaskUpdateCheck();
|
||||
updateCheckTask.execute(ActivityMainScreen.this);
|
||||
}
|
||||
}
|
||||
|
||||
synchronized void checkForNews()
|
||||
{
|
||||
if(Settings.displayNewsOnMainScreen)
|
||||
@@ -761,4 +636,38 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
Miscellaneous.logEvent("e", "Error displaying news", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
}
|
||||
|
||||
public void processUpdateCheckResult(Boolean result)
|
||||
{
|
||||
if(result && !updateNoteDisplayed)
|
||||
{
|
||||
updateNoteDisplayed = true;
|
||||
|
||||
AlertDialog.Builder updateNoteBuilder = new AlertDialog.Builder(ActivityMainScreen.this);
|
||||
updateNoteBuilder.setMessage(getResources().getString(R.string.updateAvailable));
|
||||
updateNoteBuilder.setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
String url = "https://server47.de/automation/";
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
|
||||
startActivity(browserIntent);
|
||||
|
||||
updateNoteDisplayed = false;
|
||||
}
|
||||
});
|
||||
updateNoteBuilder.setNegativeButton(getResources().getString(R.string.no), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i)
|
||||
{
|
||||
updateNoteDisplayed = false;
|
||||
}
|
||||
});
|
||||
updateNoteBuilder.show();
|
||||
}
|
||||
|
||||
AsyncTasks.AsyncTaskUpdateCheck.checkRunning = false;
|
||||
}
|
||||
}
|
||||
@@ -13,12 +13,17 @@ 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);
|
||||
|
||||
Settings.readFromPersistentStorage(ActivityMainTabLayout.this);
|
||||
|
||||
if(Settings.tabsPlacement == 1)
|
||||
setContentView(R.layout.main_tab_layout_tabs_at_bottom);
|
||||
else
|
||||
setContentView(R.layout.main_tab_layout_tabs_at_top);
|
||||
|
||||
TabHost tabHost = getTabHost();
|
||||
|
||||
|
||||
@@ -0,0 +1,370 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class ActivityMaintenance extends Activity
|
||||
{
|
||||
final static int requestCodeImport = 1001;
|
||||
final static int requestCodeExport = 1002;
|
||||
final static int requestCodeMoreSettings = 6000;
|
||||
|
||||
final static String prefsFileName = "com.jens.automation2_preferences.xml";
|
||||
|
||||
TextView tvFileStoreLocation, tvAppVersion;
|
||||
Button bVolumeTest, bMoreSettings, bSettingsSetToDefault, bShareConfigAndLog, bImportConfiguration, bExportConfiguration;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_maintenance);
|
||||
|
||||
bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||
bVolumeTest.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(ActivityMaintenance.this, ActivityVolumeTest.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
});
|
||||
|
||||
bShareConfigAndLog = (Button) findViewById(R.id.bShareConfigAndLog);
|
||||
bShareConfigAndLog.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getShareConfigAndLogDialogue(ActivityMaintenance.this).show();
|
||||
}
|
||||
});
|
||||
|
||||
bSettingsSetToDefault = (Button) findViewById(R.id.bSettingsSetToDefault);
|
||||
bSettingsSetToDefault.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
getDefaultSettingsDialog(ActivityMaintenance.this).show();
|
||||
}
|
||||
});
|
||||
|
||||
Button bMoreSettings = (Button) findViewById(R.id.bMoreSettings);
|
||||
bMoreSettings.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent myIntent = new Intent(ActivityMaintenance.this, ActivitySettings.class);
|
||||
startActivityForResult(myIntent, requestCodeMoreSettings);
|
||||
}
|
||||
});
|
||||
|
||||
bImportConfiguration = (Button) findViewById(R.id.bImportConfiguration);
|
||||
bImportConfiguration.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
startActivityForResult(intent, requestCodeImport);
|
||||
}
|
||||
});
|
||||
|
||||
bExportConfiguration = (Button) findViewById(R.id.bExportConfiguration);
|
||||
bExportConfiguration.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
|
||||
startActivityForResult(intent, requestCodeExport);
|
||||
}
|
||||
});
|
||||
|
||||
tvFileStoreLocation = (TextView)findViewById(R.id.tvFileStoreLocation);
|
||||
tvAppVersion = (TextView)findViewById(R.id.tvAppVersion);
|
||||
|
||||
tvAppVersion.setText(
|
||||
"Version: " + BuildConfig.VERSION_NAME + Miscellaneous.lineSeparator +
|
||||
"Version code: " + String.valueOf(BuildConfig.VERSION_CODE) + Miscellaneous.lineSeparator +
|
||||
"Flavor: " + BuildConfig.FLAVOR
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
switch(requestCode)
|
||||
{
|
||||
case requestCodeMoreSettings: //settings
|
||||
Settings.readFromPersistentStorage(this);
|
||||
|
||||
if (AutomationService.isMyServiceRunning(this))
|
||||
AutomationService.getInstance().serviceInterface(AutomationService.serviceCommands.reloadSettings);
|
||||
|
||||
if (AutomationService.isMyServiceRunning(ActivityMaintenance.this))
|
||||
Toast.makeText(this, getResources().getString(R.string.settingsWillTakeTime), Toast.LENGTH_LONG).show();
|
||||
|
||||
break;
|
||||
case requestCodeImport:
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
Uri uriTree = data.getData();
|
||||
importFiles(uriTree);
|
||||
}
|
||||
break;
|
||||
case requestCodeExport:
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
Uri uriTree = data.getData();
|
||||
exportFiles(uriTree);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void importFiles(Uri uriTree)
|
||||
{
|
||||
// https://stackoverflow.com/questions/46237558/android-strange-behavior-of-documentfile-inputstream
|
||||
|
||||
File dstRules = new File(Miscellaneous.getWriteableFolder() + "/" + XmlFileInterface.settingsFileName);
|
||||
File dstPrefs = new File(Miscellaneous.getWriteableFolder() + "/../shared_prefs/" + prefsFileName);
|
||||
|
||||
DocumentFile directory = DocumentFile.fromTreeUri(this, uriTree);
|
||||
|
||||
int applicableFilesFound = 0;
|
||||
int filesImported = 0;
|
||||
|
||||
if(directory.listFiles().length > 0)
|
||||
{
|
||||
for (DocumentFile file : directory.listFiles())
|
||||
{
|
||||
if (file.getName().equals(XmlFileInterface.settingsFileName))
|
||||
{
|
||||
applicableFilesFound++;
|
||||
|
||||
if(file.canRead())
|
||||
{
|
||||
// import rules, locations, etc.
|
||||
if (Miscellaneous.copyDocumentFileToFile(file, dstRules))
|
||||
filesImported++;
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.rulesImportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
else if (file.getName().equals(prefsFileName))
|
||||
{
|
||||
applicableFilesFound++;
|
||||
|
||||
if(file.canRead())
|
||||
{
|
||||
// import rules, locations, etc.
|
||||
if (Miscellaneous.copyDocumentFileToFile(file, dstPrefs))
|
||||
filesImported++;
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.prefsImportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(applicableFilesFound > 0)
|
||||
{
|
||||
if(filesImported == 0)
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.noFilesImported), Toast.LENGTH_LONG).show();
|
||||
else if(filesImported < applicableFilesFound)
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.notAllFilesImported), Toast.LENGTH_LONG).show();
|
||||
else if (filesImported == applicableFilesFound)
|
||||
{
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.configurationImportedSuccessfully), Toast.LENGTH_LONG).show();
|
||||
|
||||
try
|
||||
{
|
||||
XmlFileInterface.readFile();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Reading import", "Rules re-read failed: " + Log.getStackTraceString(e), 1);
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.errorReadingPoisAndRulesFromFile), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
Settings.readFromPersistentStorage(ActivityMaintenance.this);
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.noFilesImported), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.noApplicableFilesFoundInDirectory), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.noApplicableFilesFoundInDirectory), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
void exportFiles(Uri uriTree)
|
||||
{
|
||||
DocumentFile directory = DocumentFile.fromTreeUri(this, uriTree);
|
||||
|
||||
File srcRules = new File(Miscellaneous.getWriteableFolder() + "/" + XmlFileInterface.settingsFileName);
|
||||
File srcPrefs = new File(Miscellaneous.getWriteableFolder() + "/../shared_prefs/" + prefsFileName);
|
||||
|
||||
// Clean up
|
||||
for(DocumentFile file : directory.listFiles())
|
||||
{
|
||||
/*
|
||||
On some few users' devices it seems this caused a crash because file.getName() was null.
|
||||
The reason for that remains unknown, but we don't want the export to crash because of it.
|
||||
*/
|
||||
if(!StringUtils.isEmpty(file.getName()))
|
||||
{
|
||||
if (file.getName().equals(XmlFileInterface.settingsFileName) && file.canWrite())
|
||||
file.delete();
|
||||
else if (file.getName().equals(prefsFileName) && file.canWrite())
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
DocumentFile dstRules = directory.createFile("text/xml", XmlFileInterface.settingsFileName);
|
||||
DocumentFile dstPrefs = directory.createFile("text/xml", prefsFileName);
|
||||
|
||||
if(dstRules.canWrite() && dstPrefs.canWrite())
|
||||
{
|
||||
if(Miscellaneous.copyFileToDocumentFile(srcRules, dstRules) && Miscellaneous.copyFileToDocumentFile(srcPrefs, dstPrefs))
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.configurationExportedSuccessfully), Toast.LENGTH_LONG).show();
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.ConfigurationExportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
else
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.ConfigurationExportError), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
AlertDialog getShareConfigAndLogDialogue(final Context context)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(context.getResources().getString(R.string.shareConfigAndLogFilesWithDev));
|
||||
alertDialogBuilder.setMessage(context.getResources().getString(R.string.shareConfigAndLogExplanation));
|
||||
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
File dstZipFile = new File(Miscellaneous.getAnyContext().getCacheDir() + "/" + Settings.zipFileName);
|
||||
|
||||
ArrayList<String> srcFilesList = new ArrayList<>();
|
||||
srcFilesList.add(Miscellaneous.getWriteableFolder() + "/" + XmlFileInterface.settingsFileName);
|
||||
srcFilesList.add(Miscellaneous.getWriteableFolder() + "/../shared_prefs/" + prefsFileName);
|
||||
|
||||
String logFilePath = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName;
|
||||
if((new File(logFilePath)).exists())
|
||||
srcFilesList.add(logFilePath);
|
||||
|
||||
String logFilePathArchive = Miscellaneous.getWriteableFolder() + "/" + Miscellaneous.logFileName + "-old";
|
||||
if((new File(logFilePathArchive)).exists())
|
||||
srcFilesList.add(logFilePathArchive);
|
||||
|
||||
String[] srcFiles = srcFilesList.toArray(new String[srcFilesList.size()]);
|
||||
|
||||
if(dstZipFile.exists())
|
||||
dstZipFile.delete();
|
||||
|
||||
Miscellaneous.zip(srcFiles, dstZipFile.getAbsolutePath());
|
||||
|
||||
/*
|
||||
Without root the zip file in the cache directory is not directly accessible.
|
||||
But have to route it through this content provider crap.
|
||||
*/
|
||||
|
||||
String subject = "Automation logs";
|
||||
|
||||
StringBuilder emailBody = new StringBuilder();
|
||||
emailBody.append("Device details" + Miscellaneous.lineSeparator);
|
||||
emailBody.append("OS version: " + System.getProperty("os.version") + Miscellaneous.lineSeparator);
|
||||
emailBody.append("API Level: " + android.os.Build.VERSION.SDK + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Device: " + android.os.Build.DEVICE + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Model: " + android.os.Build.MODEL + Miscellaneous.lineSeparator);
|
||||
emailBody.append("Product: " + android.os.Build.PRODUCT);
|
||||
emailBody.append("Flavor: " + BuildConfig.FLAVOR);
|
||||
|
||||
Uri uri = Uri.parse("content://com.jens.automation2/" + Settings.zipFileName);
|
||||
|
||||
Miscellaneous.sendEmail(ActivityMaintenance.this, "android-development@gmx.de", "Automation logs", emailBody.toString(), uri);
|
||||
}
|
||||
});
|
||||
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume()
|
||||
{
|
||||
super.onResume();
|
||||
|
||||
String folder = Miscellaneous.getWriteableFolder();
|
||||
if (folder != null && folder.length() > 0)
|
||||
{
|
||||
tvFileStoreLocation.setText(String.format(getResources().getString(R.string.filesStoredAt), folder));
|
||||
tvFileStoreLocation.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Uri selectedUri = Uri.parse(folder);
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setDataAndType(selectedUri, "resource/folder");
|
||||
|
||||
if (intent.resolveActivityInfo(getPackageManager(), 0) != null)
|
||||
{
|
||||
startActivity(intent);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if you reach this place, it means there is no any file
|
||||
// explorer app installed on your device
|
||||
Toast.makeText(ActivityMaintenance.this, getResources().getString(R.string.noFileManageInstalled), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,6 @@ import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
@@ -27,7 +26,7 @@ public class ActivityManageActionPlaySound extends Activity
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_play_sound);
|
||||
setContentView(R.layout.activity_manage_action_play_sound);
|
||||
|
||||
chkPlaySoundAlwaysPlay = (CheckBox)findViewById(R.id.chkPlaySoundAlwaysPlay);
|
||||
etSelectedSoundFile = (EditText)findViewById(R.id.etSelectedSoundFile);
|
||||
|
||||
@@ -25,6 +25,7 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
EditText etPhoneNumber, etSendTextMessage;
|
||||
|
||||
protected final static int requestCodeForContactsPermissions = 9876;
|
||||
protected final static int requestCodeGetContact = 3235;
|
||||
|
||||
// private String existingUrl = "";
|
||||
|
||||
@@ -35,7 +36,7 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.send_textmessage_editor);
|
||||
this.setContentView(R.layout.activity_manage_action_send_textmessage);
|
||||
|
||||
etSendTextMessage = (EditText)findViewById(R.id.etSendTextMessage);
|
||||
etPhoneNumber = (EditText)findViewById(R.id.etPhoneNumber);
|
||||
@@ -83,20 +84,10 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
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)
|
||||
{
|
||||
ActivityManageActionSendTextMessage.resultingAction.setParameter2(etPhoneNumber.getText().toString() + Actions.smsSeparator + etSendTextMessage.getText().toString());
|
||||
@@ -145,16 +136,14 @@ public class ActivityManageActionSendTextMessage extends Activity
|
||||
|
||||
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);
|
||||
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
|
||||
startActivityForResult(intent, requestCodeGetContact);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if(requestCode == 1000)
|
||||
if(requestCode == requestCodeGetContact)
|
||||
{
|
||||
if(resultCode == Activity.RESULT_OK)
|
||||
{
|
||||
|
||||
@@ -24,7 +24,7 @@ public class ActivityManageActionSpeakText extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.speak_text_editor);
|
||||
this.setContentView(R.layout.activity_manage_action_speak_text);
|
||||
|
||||
etSpeakText = (EditText)findViewById(R.id.etTextToSpeak);
|
||||
bSaveSpeakText = (Button)findViewById(R.id.bSaveTriggerUrl);
|
||||
|
||||
@@ -10,6 +10,7 @@ import android.content.pm.ActivityInfo;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Bundle;
|
||||
import android.text.InputType;
|
||||
@@ -22,10 +23,11 @@ import android.widget.AdapterView.OnItemLongClickListener;
|
||||
import android.widget.AdapterView.OnItemSelectedListener;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ListView;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
@@ -37,12 +39,21 @@ import java.util.List;
|
||||
|
||||
public class ActivityManageActionStartActivity extends Activity
|
||||
{
|
||||
/*
|
||||
This page might qualify as a help page: https://stackoverflow.com/questions/55323947/open-url-in-firefox-for-android-using-intent
|
||||
*/
|
||||
|
||||
ListView lvIntentPairs;
|
||||
EditText etParameterName, etParameterValue, etSelectedActivity;
|
||||
Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity;
|
||||
EditText etParameterName, etParameterValue, etPackageName, etActivityOrActionPath;
|
||||
Button bSelectApp, bAddIntentPair, bSaveActionStartOtherActivity, showStartProgramExamples;
|
||||
Spinner spinnerParameterType;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
RadioButton rbStartAppSelectByActivity, rbStartAppSelectByAction, rbStartAppByActivity, rbStartAppByBroadcast;
|
||||
|
||||
final String urlShowExamples = "https://server47.de/automation/examples_startProgram.html";
|
||||
final static String startByActivityString = "0";
|
||||
final static String startByBroadcastString = "1";
|
||||
|
||||
private class CustomPackageInfo extends PackageInfo implements Comparable<CustomPackageInfo>
|
||||
{
|
||||
@@ -71,7 +82,7 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
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 static final String[] supportedIntentTypes = { "boolean", "byte", "char", "double", "float", "int", "long", "short", "String", "Uri" };
|
||||
private ArrayList<String> intentPairList = new ArrayList<String>();
|
||||
|
||||
ArrayAdapter<String> intentTypeSpinnerAdapter, intentPairAdapter;
|
||||
@@ -267,7 +278,8 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
ActivityInfo ai = ActivityManageActionStartActivity.getActivityInfoForPackageNameAndActivityName(packageName, activityArray[which]);
|
||||
etSelectedActivity.setText(ai.packageName + ";" + ai.name);
|
||||
etPackageName.setText(ai.packageName);
|
||||
etActivityOrActionPath.setText(ai.name);
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
@@ -279,7 +291,7 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.action_start_activity);
|
||||
setContentView(R.layout.activity_manage_action_start_activity);
|
||||
|
||||
lvIntentPairs = (ListView)findViewById(R.id.lvIntentPairs);
|
||||
etParameterName = (EditText)findViewById(R.id.etParameterName);
|
||||
@@ -288,7 +300,14 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
bAddIntentPair = (Button)findViewById(R.id.bAddIntentPair);
|
||||
bSaveActionStartOtherActivity = (Button)findViewById(R.id.bSaveActionStartOtherActivity);
|
||||
spinnerParameterType = (Spinner)findViewById(R.id.spinnerParameterType);
|
||||
etSelectedActivity = (EditText) findViewById(R.id.etSelectedApplication);
|
||||
etPackageName = (EditText) findViewById(R.id.etPackageName);
|
||||
etActivityOrActionPath = (EditText) findViewById(R.id.etActivityOrActionPath);
|
||||
rbStartAppSelectByActivity = (RadioButton)findViewById(R.id.rbStartAppSelectByActivity);
|
||||
rbStartAppSelectByAction = (RadioButton)findViewById(R.id.rbStartAppSelectByAction);
|
||||
showStartProgramExamples = (Button)findViewById(R.id.showStartProgramExamples);
|
||||
|
||||
rbStartAppByActivity = (RadioButton)findViewById(R.id.rbStartAppByActivity);
|
||||
rbStartAppByBroadcast = (RadioButton)findViewById(R.id.rbStartAppByBroadcast);
|
||||
|
||||
intentTypeSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, ActivityManageActionStartActivity.supportedIntentTypes);
|
||||
spinnerParameterType.setAdapter(intentTypeSpinnerAdapter);
|
||||
@@ -324,14 +343,34 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterNameForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterName.getText().toString().contains(Action.intentPairSeperator))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeperator), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterName.getText().toString().contains(";"))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if(etParameterValue.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterValueForIntentPair), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterValue.getText().toString().contains(Action.intentPairSeperator))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), Action.intentPairSeperator), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
else if(etParameterValue.getText().toString().contains(";"))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, String.format(getResources().getString(R.string.stringNotAllowed), ";"), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + "/" + etParameterName.getText().toString() + "/" + etParameterValue.getText().toString();
|
||||
String param = supportedIntentTypes[spinnerParameterType.getSelectedItemPosition()] + Action.intentPairSeperator + etParameterName.getText().toString() + Action.intentPairSeperator + etParameterValue.getText().toString();
|
||||
intentPairList.add(param);
|
||||
|
||||
spinnerParameterType.setSelection(0);
|
||||
@@ -344,6 +383,16 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
lvIntentPairs.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
showStartProgramExamples.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(urlShowExamples));
|
||||
startActivity(browserIntent);
|
||||
}
|
||||
});
|
||||
|
||||
lvIntentPairs.setOnItemLongClickListener(new OnItemLongClickListener()
|
||||
{
|
||||
@@ -396,6 +445,26 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
rbStartAppSelectByActivity.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
bSelectApp.setEnabled(isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
rbStartAppSelectByAction.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener()
|
||||
{
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||
{
|
||||
if(isChecked)
|
||||
bSelectApp.setEnabled(!isChecked);
|
||||
}
|
||||
});
|
||||
|
||||
Intent i = getIntent();
|
||||
if(i.getBooleanExtra("edit", false) == true)
|
||||
@@ -407,25 +476,46 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
|
||||
private void loadValuesIntoGui()
|
||||
{
|
||||
String[] params = resultingAction.getParameter2().split(";");
|
||||
if(params.length >= 2)
|
||||
{
|
||||
etSelectedActivity.setText(params[0] + ";" + params[1]);
|
||||
|
||||
if(params.length > 2)
|
||||
{
|
||||
intentPairList.clear();
|
||||
|
||||
for(int i=2; i<params.length; i++)
|
||||
{
|
||||
if(lvIntentPairs.getVisibility() != View.VISIBLE)
|
||||
lvIntentPairs.setVisibility(View.VISIBLE);
|
||||
boolean selectionByAction = resultingAction.getParameter1();
|
||||
rbStartAppSelectByActivity.setChecked(!selectionByAction);
|
||||
rbStartAppSelectByAction.setChecked(selectionByAction);
|
||||
|
||||
intentPairList.add(params[i]);
|
||||
}
|
||||
|
||||
updateIntentPairList();
|
||||
String[] params = resultingAction.getParameter2().split(";");
|
||||
|
||||
rbStartAppByActivity.setChecked(params[2].equals(startByActivityString));
|
||||
rbStartAppByBroadcast.setChecked(params[2].equals(startByBroadcastString));
|
||||
|
||||
int startIndex = -1;
|
||||
|
||||
if(!selectionByAction)
|
||||
{
|
||||
etPackageName.setText(params[0]);
|
||||
etActivityOrActionPath.setText(params[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
if(!params[0].contains(Actions.dummyPackageString))
|
||||
etPackageName.setText(params[0]);
|
||||
|
||||
etActivityOrActionPath.setText(params[1]);
|
||||
}
|
||||
|
||||
if (params.length >= 3)
|
||||
startIndex = 3;
|
||||
|
||||
if(startIndex > -1 && params.length > startIndex)
|
||||
{
|
||||
intentPairList.clear();
|
||||
|
||||
for(int i=startIndex; i<params.length; i++)
|
||||
{
|
||||
if(lvIntentPairs.getVisibility() != View.VISIBLE)
|
||||
lvIntentPairs.setVisibility(View.VISIBLE);
|
||||
|
||||
intentPairList.add(params[i]);
|
||||
}
|
||||
|
||||
updateIntentPairList();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -439,39 +529,51 @@ public class ActivityManageActionStartActivity extends Activity
|
||||
|
||||
private boolean saveAction()
|
||||
{
|
||||
if(etSelectedActivity.getText().toString().length() == 0)
|
||||
if(rbStartAppSelectByActivity.isChecked())
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.selectApplication), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
if (etPackageName.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.enterPackageName), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
else if (etActivityOrActionPath.getText().toString().length() == 0)
|
||||
{
|
||||
Toast.makeText(ActivityManageActionStartActivity.this, getResources().getString(R.string.selectApplication), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// else
|
||||
// {
|
||||
// Intent testIntent = new Intent(ActivityManageActionStartActivity.this, etSelectedActivity);
|
||||
// Intent externalActivityIntent = new Intent(Intent.ACTION_MAIN);
|
||||
// externalActivityIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
// externalActivityIntent.addCategory(Intent.CATEGORY_LAUNCHER);
|
||||
// externalActivityIntent.setClassName(packageName, className);
|
||||
//
|
||||
// boolean activityExists = externalActivityIntent.resolveActivityInfo(getPackageManager(), 0) != null;
|
||||
// }
|
||||
|
||||
if(etSelectedActivity.getText().toString().equals(getResources().getString(R.string.selectApplication)))
|
||||
else
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.selectApplication), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
if(etActivityOrActionPath.getText().toString().contains(";"))
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.enterValidAction), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if(resultingAction == null)
|
||||
resultingAction = new Action();
|
||||
|
||||
resultingAction.setParameter1(rbStartAppSelectByAction.isChecked());
|
||||
|
||||
resultingAction.setAction(Action_Enum.startOtherActivity);
|
||||
|
||||
String parameter2;
|
||||
String parameter2 = "";
|
||||
|
||||
if(etSelectedActivity.getText().toString().contains(";"))
|
||||
parameter2 = etSelectedActivity.getText().toString();
|
||||
if(rbStartAppSelectByActivity.isChecked())
|
||||
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
|
||||
else
|
||||
parameter2 = "dummyPkg;" + etSelectedActivity.getText().toString();
|
||||
{
|
||||
if(etPackageName.getText().toString() != null && etPackageName.getText().toString().length() > 0)
|
||||
parameter2 += etPackageName.getText().toString() + ";" + etActivityOrActionPath.getText().toString();
|
||||
else
|
||||
parameter2 += Actions.dummyPackageString + ";" + etActivityOrActionPath.getText().toString();
|
||||
}
|
||||
|
||||
if(rbStartAppByActivity.isChecked())
|
||||
parameter2 += ";" + startByActivityString;
|
||||
else
|
||||
parameter2 += ";" + startByBroadcastString;
|
||||
|
||||
for(String s : intentPairList)
|
||||
parameter2 += ";" + s;
|
||||
|
||||
@@ -39,7 +39,7 @@ public class ActivityManageActionTriggerUrl extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.trigger_url_editor);
|
||||
this.setContentView(R.layout.activity_manage_action_trigger_url);
|
||||
|
||||
etTriggerUrl = (EditText)findViewById(R.id.etTriggerUrl);
|
||||
etTriggerUrlUsername = (EditText)findViewById(R.id.etTriggerUrlUsername);
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.VibrationEffect;
|
||||
import android.os.Vibrator;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.apache.commons.lang3.StringUtils;
|
||||
|
||||
public class ActivityManageActionVibrate extends Activity
|
||||
{
|
||||
TextView etVibratePattern;
|
||||
Button bTestVibratePattern, bSaveVibratePattern;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_action_vibrate);
|
||||
|
||||
etVibratePattern = (EditText)findViewById(R.id.etVibratePattern);
|
||||
bTestVibratePattern = (Button)findViewById(R.id.bTestVibratePattern);
|
||||
bSaveVibratePattern = (Button)findViewById(R.id.bSaveVibratePattern);
|
||||
|
||||
bSaveVibratePattern.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(checkInput())
|
||||
{
|
||||
Intent answer = new Intent();
|
||||
answer.putExtra("vibratePattern", etVibratePattern.getText().toString());
|
||||
setResult(RESULT_OK, answer);
|
||||
finish();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
bTestVibratePattern.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
if(checkInput())
|
||||
{
|
||||
if (ActivityPermissions.havePermission(Manifest.permission.VIBRATE, ActivityManageActionVibrate.this))
|
||||
{
|
||||
String pattern = etVibratePattern.getText().toString();
|
||||
Actions.vibrate(false, pattern);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
Intent input = getIntent();
|
||||
|
||||
if(input.hasExtra("vibratePattern"))
|
||||
etVibratePattern.setText(input.getStringExtra("vibratePattern"));
|
||||
}
|
||||
|
||||
boolean checkInput()
|
||||
{
|
||||
String vibratePattern = etVibratePattern.getText().toString();
|
||||
String regex = "^[0-9,]+$";
|
||||
if(StringUtils.isEmpty(vibratePattern) || !vibratePattern.matches(regex) || vibratePattern.substring(0, 1).equals(",") || vibratePattern.substring(vibratePattern.length()-1).equals(","))
|
||||
{
|
||||
Toast.makeText(ActivityManageActionVibrate.this, getResources().getString(R.string.pleaseEnterValidVibrationPattern), Toast.LENGTH_SHORT).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import android.location.LocationListener;
|
||||
import android.location.LocationManager;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.os.Looper;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
@@ -21,6 +22,10 @@ import android.widget.EditText;
|
||||
import android.widget.ImageButton;
|
||||
import android.widget.Toast;
|
||||
|
||||
import java.util.Calendar;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
|
||||
public class ActivityManagePoi extends Activity
|
||||
{
|
||||
public LocationManager myLocationManager;
|
||||
@@ -31,6 +36,11 @@ public class ActivityManagePoi extends Activity
|
||||
Button bGetPosition, bSavePoi;
|
||||
ImageButton ibShowOnMap;
|
||||
EditText guiPoiName, guiPoiLatitude, guiPoiLongitude, guiPoiRadius;
|
||||
Calendar locationSearchStart = null;
|
||||
Timer timer = null;
|
||||
|
||||
final static int defaultRadius = 250;
|
||||
final static int searchTimeout = 120;
|
||||
|
||||
private static ProgressDialog progressDialog;
|
||||
|
||||
@@ -47,7 +57,7 @@ public class ActivityManagePoi extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.manage_specific_poi);
|
||||
this.setContentView(R.layout.activity_manage_specific_poi);
|
||||
|
||||
myLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
|
||||
bGetPosition = (Button)findViewById(R.id.bGetPosition);
|
||||
@@ -104,7 +114,7 @@ public class ActivityManagePoi extends Activity
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
ActivityMainPoi.poiToEdit = new PointOfInterest();
|
||||
ActivityMainPoi.poiToEdit.setLocation(new Location("POINT_LOCATION"));
|
||||
if(loadFormValuesToVariable())
|
||||
if(loadFormValuesToVariable(false))
|
||||
if(ActivityMainPoi.poiToEdit.create(this))
|
||||
{
|
||||
this.setResult(RESULT_OK);
|
||||
@@ -114,7 +124,7 @@ public class ActivityManagePoi extends Activity
|
||||
private void changePoi()
|
||||
{
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
if(loadFormValuesToVariable())
|
||||
if(loadFormValuesToVariable(false))
|
||||
if(ActivityMainPoi.poiToEdit.change(this))
|
||||
{
|
||||
this.setResult(RESULT_OK);
|
||||
@@ -150,47 +160,142 @@ public class ActivityManagePoi extends Activity
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGettingPositionWithProvider) + " " + provider1, 3);
|
||||
myLocationManager.requestLocationUpdates(provider1, 500, Settings.satisfactoryAccuracyNetwork, myLocationListenerNetwork);
|
||||
|
||||
locationSearchStart = Calendar.getInstance();
|
||||
startTimeout();
|
||||
|
||||
if(!Settings.privacyLocationing)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGettingPositionWithProvider) + " " + provider1, 3);
|
||||
myLocationManager.requestLocationUpdates(provider1, 500, Settings.satisfactoryAccuracyNetwork, myLocationListenerNetwork);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "POI Manager", "Skipping network location query because private locationing is active.", 4);
|
||||
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logGettingPositionWithProvider) + " " + provider2, 3);
|
||||
myLocationManager.requestLocationUpdates(provider2, 500, Settings.satisfactoryAccuracyGps, myLocationListenerGps);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void compareLocations()
|
||||
|
||||
private void startTimeout()
|
||||
{
|
||||
if(timer != null)
|
||||
stopTimeout();
|
||||
|
||||
timer = new Timer();
|
||||
|
||||
class TimeoutTask extends TimerTask
|
||||
{
|
||||
public void run()
|
||||
{
|
||||
evaluateLocationResults();
|
||||
}
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("i", "POI Manager", "Starting timeout for location search: " + String.valueOf(searchTimeout) + " seconds", 5);
|
||||
|
||||
TimerTask timeoutTask = new TimeoutTask();
|
||||
timer.schedule(timeoutTask, searchTimeout * 1000);
|
||||
}
|
||||
|
||||
private void stopTimeout()
|
||||
{
|
||||
Miscellaneous.logEvent("i", "POI Manager", "Stopping timeout for location search.", 5);
|
||||
|
||||
if(timer != null)
|
||||
{
|
||||
timer.purge();
|
||||
timer.cancel();
|
||||
}
|
||||
}
|
||||
|
||||
private void evaluateLocationResults()
|
||||
{
|
||||
/*
|
||||
Procedure:
|
||||
If we get a GPS result we take it and suggest a default minimum radius.
|
||||
If private locationing is active that's the only possible outcome other than a timeout.
|
||||
|
||||
If private locationing is not active
|
||||
If we get a network
|
||||
*/
|
||||
|
||||
// We have GPS
|
||||
if(locationGps != null)
|
||||
{
|
||||
myLocationManager.removeUpdates(myLocationListenerNetwork);
|
||||
|
||||
guiPoiLatitude.setText(String.valueOf(locationGps.getLatitude()));
|
||||
guiPoiLongitude.setText(String.valueOf(locationGps.getLongitude()));
|
||||
|
||||
String text;
|
||||
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();
|
||||
// }
|
||||
text = String.format(getResources().getString(R.string.distanceBetween), Math.round(variance));
|
||||
getRadiusConfirmationDialog(text, Math.round(variance) + 1).show();
|
||||
}
|
||||
else
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
myLocationManager.removeUpdates(myLocationListenerNetwork);
|
||||
guiPoiRadius.setText("250");
|
||||
text = String.format(getResources().getString(R.string.locationFound), defaultRadius);
|
||||
getRadiusConfirmationDialog(text, defaultRadius).show();
|
||||
}
|
||||
Miscellaneous.logEvent("i", "POI Manager", text, 4);
|
||||
} // we have a great network signal:
|
||||
else if(locationNetwork != null && locationNetwork.getAccuracy() <= Settings.satisfactoryAccuracyGps && locationNetwork.getAccuracy() <= defaultRadius)
|
||||
{
|
||||
/*
|
||||
We do not yet have a GPS result. But we have a network result that is good enough
|
||||
to accept it a sole result. In that case we suggest a default radius, no variance.
|
||||
*/
|
||||
|
||||
guiPoiLatitude.setText(String.valueOf(locationNetwork.getLatitude()));
|
||||
guiPoiLongitude.setText(String.valueOf(locationNetwork.getLongitude()));
|
||||
|
||||
String text = String.format(getResources().getString(R.string.locationFound), defaultRadius);
|
||||
Miscellaneous.logEvent("i", "POI Manager", text, 4);
|
||||
|
||||
getRadiusConfirmationDialog(text, defaultRadius).show();
|
||||
}
|
||||
else if( // we have a bad network signal and nothing else, GPS result may still come in
|
||||
locationNetwork != null
|
||||
&&
|
||||
Calendar.getInstance().getTimeInMillis()
|
||||
<
|
||||
(locationSearchStart.getTimeInMillis() + ((long)searchTimeout * 1000))
|
||||
)
|
||||
{
|
||||
// Only a network location was found and it is also not very accurate.
|
||||
}
|
||||
else if( // we have a bad network signal and nothing else, timeout has expired, nothing else can possibly come in
|
||||
locationNetwork != null
|
||||
&&
|
||||
Calendar.getInstance().getTimeInMillis()
|
||||
>
|
||||
(locationSearchStart.getTimeInMillis() + ((long)searchTimeout * 1000))
|
||||
)
|
||||
{
|
||||
// Only a network location was found and it is also not very accurate.
|
||||
|
||||
guiPoiLatitude.setText(String.valueOf(locationNetwork.getLatitude()));
|
||||
guiPoiLongitude.setText(String.valueOf(locationNetwork.getLongitude()));
|
||||
|
||||
String text = String.format(getResources().getString(R.string.locationFoundInaccurate), defaultRadius);
|
||||
getRadiusConfirmationDialog(text, defaultRadius).show();
|
||||
Miscellaneous.logEvent("i", "POI Manager", text, 4);
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "POI Manager", getResources().getString(R.string.logNotAllMeasurings), 4);
|
||||
{
|
||||
String text = String.format(getResources().getString(R.string.noLocationCouldBeFound), String.valueOf(searchTimeout));
|
||||
Miscellaneous.logEvent("i", "POI Manager", text, 2);
|
||||
|
||||
if(myLocationListenerNetwork != null)
|
||||
myLocationManager.removeUpdates(myLocationListenerNetwork);
|
||||
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
progressDialog.dismiss();
|
||||
getErrorDialog(text).show();
|
||||
}
|
||||
}
|
||||
|
||||
private AlertDialog getNotificationDialog(String text)
|
||||
@@ -202,15 +307,6 @@ public class ActivityManagePoi extends Activity
|
||||
@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(ActivityManagePoi.this, "", getResources().getString(R.string.gettingPosition), true, true);
|
||||
getLocation();
|
||||
}
|
||||
@@ -221,8 +317,11 @@ public class ActivityManagePoi extends Activity
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getDialog(String text, final double value)
|
||||
|
||||
private AlertDialog getRadiusConfirmationDialog(String text, final double value)
|
||||
{
|
||||
stopTimeout();
|
||||
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
|
||||
{
|
||||
@@ -247,10 +346,31 @@ public class ActivityManagePoi extends Activity
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
private AlertDialog getErrorDialog(String text)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
|
||||
DialogInterface.OnClickListener dialogClickListener = new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
progressDialog.dismiss();
|
||||
}
|
||||
};
|
||||
alertDialogBuilder.setMessage(text);
|
||||
alertDialogBuilder.setPositiveButton(getResources().getString(R.string.ok), null);
|
||||
|
||||
if (Looper.myLooper() == null)
|
||||
Looper.prepare();
|
||||
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
public class MyLocationListenerGps implements LocationListener
|
||||
{
|
||||
|
||||
@Override
|
||||
public void onLocationChanged(Location location)
|
||||
{
|
||||
@@ -260,10 +380,11 @@ public class ActivityManagePoi extends Activity
|
||||
// {
|
||||
// Miscellaneous.logEvent("i", "POI Manager", "satisfactoryNetworkAccuracy of " + String.valueOf(Settings.SATISFACTORY_ACCURACY_GPS) + "m reached. Removing location updates...");
|
||||
|
||||
Miscellaneous.logEvent("i", "POI Manager", "Unsubscribing from GPS location updates.", 5);
|
||||
myLocationManager.removeUpdates(this);
|
||||
locationGps = location;
|
||||
|
||||
compareLocations();
|
||||
evaluateLocationResults();
|
||||
// }
|
||||
}
|
||||
|
||||
@@ -287,66 +408,27 @@ public class ActivityManagePoi extends Activity
|
||||
// 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);
|
||||
|
||||
myLocationManager.removeUpdates(this);
|
||||
locationNetwork = location;
|
||||
|
||||
// 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();
|
||||
// }
|
||||
if(location.getAccuracy() <= Settings.satisfactoryAccuracyGps)
|
||||
{
|
||||
// Accuracy is so good that we don't need to wait for GPS result
|
||||
Miscellaneous.logEvent("i", "POI Manager", "Unsubscribing from network location updates.", 5);
|
||||
myLocationManager.removeUpdates(myLocationListenerGps);
|
||||
}
|
||||
|
||||
evaluateLocationResults();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -369,7 +451,6 @@ public class ActivityManagePoi extends Activity
|
||||
// TODO Auto-generated method stub
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void editPoi(PointOfInterest poi)
|
||||
@@ -380,19 +461,22 @@ public class ActivityManagePoi extends Activity
|
||||
guiPoiRadius.setText(String.valueOf(poi.getRadius()));
|
||||
}
|
||||
|
||||
public boolean loadFormValuesToVariable()
|
||||
public boolean loadFormValuesToVariable(boolean checkOnlyCoordinates)
|
||||
{
|
||||
if(ActivityMainPoi.poiToEdit == null)
|
||||
ActivityMainPoi.poiToEdit = new PointOfInterest();
|
||||
|
||||
if(guiPoiName.getText().length() == 0)
|
||||
|
||||
if(!checkOnlyCoordinates)
|
||||
{
|
||||
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidName), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
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());
|
||||
}
|
||||
else
|
||||
ActivityMainPoi.poiToEdit.setName(guiPoiName.getText().toString());
|
||||
|
||||
|
||||
if(ActivityMainPoi.poiToEdit.getLocation() == null)
|
||||
ActivityMainPoi.poiToEdit.setLocation(new Location("POINT_LOCATION"));
|
||||
|
||||
@@ -415,28 +499,31 @@ public class ActivityManagePoi extends Activity
|
||||
Toast.makeText(this, getResources().getString(R.string.pleaseEnterValidLongitude), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
|
||||
if(!checkOnlyCoordinates)
|
||||
{
|
||||
ActivityMainPoi.poiToEdit.setRadius(Double.parseDouble(guiPoiRadius.getText().toString()), this);
|
||||
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;
|
||||
}
|
||||
}
|
||||
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())
|
||||
if(loadFormValuesToVariable(true))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -82,7 +82,7 @@ public class ActivityManageProfile extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
this.setContentView(R.layout.manage_specific_profile);
|
||||
this.setContentView(R.layout.activity_manage_specific_profile);
|
||||
|
||||
checkBoxChangeSoundMode = (CheckBox)findViewById(R.id.checkBoxChangeSoundMode);
|
||||
checkBoxChangeVolumeMusicVideoGameMedia = (CheckBox)findViewById(R.id.checkBoxChangeVolumeMusicVideoGameMedia);
|
||||
|
||||
@@ -99,6 +99,13 @@ public class ActivityManageRule extends Activity
|
||||
final static int requestCodeTriggerNfcNotificationEdit = 8001;
|
||||
final static int requestCodeActionPlaySoundAdd = 501;
|
||||
final static int requestCodeActionPlaySoundEdit = 502;
|
||||
final static int requestCodeTriggerPhoneCallAdd = 601;
|
||||
final static int requestCodeTriggerPhoneCallEdit = 602;
|
||||
final static int requestCodeTriggerWifiAdd = 723;
|
||||
final static int requestCodeTriggerWifiEdit = 724;
|
||||
final static int requestCodeActionSendTextMessageAdd = 5001;
|
||||
final static int requestCodeActionVibrateAdd = 801;
|
||||
final static int requestCodeActionVibrateEdit = 802;
|
||||
|
||||
public static ActivityManageRule getInstance()
|
||||
{
|
||||
@@ -224,27 +231,11 @@ public class ActivityManageRule extends Activity
|
||||
Trigger selectedTrigger = (Trigger)triggerListView.getItemAtPosition(arg2);
|
||||
switch(selectedTrigger.getTriggerType())
|
||||
{
|
||||
// case batteryLevel:
|
||||
// break;
|
||||
// case charging:
|
||||
// break;
|
||||
// case noiseLevel:
|
||||
// break;
|
||||
// case pointOfInterest:
|
||||
// break;
|
||||
// case process_started_stopped:
|
||||
// break;
|
||||
// case speed:
|
||||
// break;
|
||||
case timeFrame:
|
||||
ActivityManageTriggerTimeFrame.editedTimeFrameTrigger = selectedTrigger;
|
||||
Intent timeFrameEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerTimeFrame.class);
|
||||
startActivityForResult(timeFrameEditor, requestCodeTriggerTimeframeEdit);
|
||||
break;
|
||||
// case usb_host_connection:
|
||||
// break;
|
||||
// case wifiConnection:
|
||||
// break;
|
||||
case bluetoothConnection:
|
||||
ActivityManageTriggerBluetooth.editedBluetoothTrigger = selectedTrigger;
|
||||
Intent bluetoothEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerBluetooth.class);
|
||||
@@ -256,6 +247,19 @@ public class ActivityManageRule extends Activity
|
||||
notificationEditor.putExtra("edit", true);
|
||||
startActivityForResult(notificationEditor, requestCodeTriggerNfcNotificationEdit);
|
||||
break;
|
||||
case phoneCall:
|
||||
ActivityManageTriggerPhoneCall.editedPhoneCallTrigger = selectedTrigger;
|
||||
Intent phoneCallEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerPhoneCall.class);
|
||||
phoneCallEditor.putExtra("edit", true);
|
||||
startActivityForResult(phoneCallEditor, requestCodeTriggerPhoneCallEdit);
|
||||
break;
|
||||
case wifiConnection:
|
||||
Intent wifiEditor = new Intent(ActivityManageRule.this, ActivityManageTriggerWifi.class);
|
||||
wifiEditor.putExtra("edit", true);
|
||||
wifiEditor.putExtra("wifiState", selectedTrigger.getTriggerParameter());
|
||||
wifiEditor.putExtra("wifiName", selectedTrigger.getTriggerParameter2());
|
||||
startActivityForResult(wifiEditor, requestCodeTriggerWifiEdit);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -289,14 +293,6 @@ public class ActivityManageRule extends Activity
|
||||
Action a = (Action)actionListView.getItemAtPosition(arg2);
|
||||
switch(a.getAction())
|
||||
{
|
||||
// case changeSoundProfile:
|
||||
// break;
|
||||
// case disableScreenRotation:
|
||||
// break;
|
||||
// case enableScreenRotation:
|
||||
// break;
|
||||
// case setAirplaneMode:
|
||||
// break;
|
||||
case startOtherActivity:
|
||||
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionStartActivity.class);
|
||||
ActivityManageActionStartActivity.resultingAction = a;
|
||||
@@ -305,31 +301,10 @@ public class ActivityManageRule extends Activity
|
||||
break;
|
||||
case triggerUrl:
|
||||
Intent activityEditTriggerUrlIntent = new Intent(ActivityManageRule.this, ActivityManageActionTriggerUrl.class);
|
||||
// activityEditTriggerUrlIntent.putExtra("urlToTrigger", a.getParameter2());
|
||||
ActivityManageActionTriggerUrl.resultingAction = a;
|
||||
activityEditTriggerUrlIntent.putExtra("edit", true);
|
||||
startActivityForResult(activityEditTriggerUrlIntent, requestCodeActionTriggerUrlEdit);
|
||||
break;
|
||||
// case turnBluetoothOff:
|
||||
// break;
|
||||
// case turnBluetoothOn:
|
||||
// break;
|
||||
// case turnUsbTetheringOff:
|
||||
// break;
|
||||
// case turnUsbTetheringOn:
|
||||
// break;
|
||||
// case turnWifiOff:
|
||||
// break;
|
||||
// case turnWifiOn:
|
||||
// break;
|
||||
// case turnWifiTetheringOff:
|
||||
// break;
|
||||
// case turnWifiTetheringOn:
|
||||
// break;
|
||||
// case waitBeforeNextAction:
|
||||
// break;
|
||||
// case wakeupDevice:
|
||||
// break;
|
||||
case speakText:
|
||||
Intent activitySpeakTextIntent = new Intent(ActivityManageRule.this, ActivityManageActionSpeakText.class);
|
||||
ActivityManageActionSpeakText.resultingAction = a;
|
||||
@@ -344,11 +319,15 @@ public class ActivityManageRule extends Activity
|
||||
break;
|
||||
case setScreenBrightness:
|
||||
Intent activityEditScreenBrightnessIntent = new Intent(ActivityManageRule.this, ActivityManageActionBrightnessSetting.class);
|
||||
// ActivityEditTriggerUrl.resultingAction = a;
|
||||
activityEditScreenBrightnessIntent.putExtra("autoBrightness", a.getParameter1());
|
||||
activityEditScreenBrightnessIntent.putExtra("brightnessValue", Integer.parseInt(a.getParameter2()));
|
||||
startActivityForResult(activityEditScreenBrightnessIntent, requestCodeActionScreenBrightnessEdit);
|
||||
break;
|
||||
case vibrate:
|
||||
Intent activityEditVibrateIntent = new Intent(ActivityManageRule.this, ActivityManageActionVibrate.class);
|
||||
activityEditVibrateIntent.putExtra("vibratePattern", a.getParameter2());
|
||||
startActivityForResult(activityEditVibrateIntent, requestCodeActionVibrateEdit);
|
||||
break;
|
||||
case playSound:
|
||||
Intent actionPlaySoundIntent = new Intent(context, ActivityManageActionPlaySound.class);
|
||||
actionPlaySoundIntent.putExtra("edit", true);
|
||||
@@ -552,7 +531,15 @@ public class ActivityManageRule extends Activity
|
||||
else if(triggerType == Trigger_Enum.speed | triggerType == Trigger_Enum.noiseLevel | triggerType == Trigger_Enum.batteryLevel)
|
||||
booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)};
|
||||
else if(triggerType == Trigger_Enum.wifiConnection)
|
||||
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
|
||||
{
|
||||
newTrigger.setTriggerType(Trigger_Enum.wifiConnection);
|
||||
Intent wifiTriggerEditor = new Intent(myContext, ActivityManageTriggerWifi.class);
|
||||
startActivityForResult(wifiTriggerEditor, requestCodeTriggerWifiAdd);
|
||||
return;
|
||||
// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
|
||||
}
|
||||
// else if(triggerType == Trigger_Enum.wifiConnection)
|
||||
// booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
|
||||
else if(triggerType == Trigger_Enum.process_started_stopped)
|
||||
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
|
||||
else if(triggerType == Trigger_Enum.notification)
|
||||
@@ -567,7 +554,13 @@ public class ActivityManageRule extends Activity
|
||||
else if(triggerType == Trigger_Enum.roaming)
|
||||
booleanChoices = new String[]{getResources().getString(R.string.activated), getResources().getString(R.string.deactivated)};
|
||||
else if(triggerType == Trigger_Enum.phoneCall)
|
||||
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
|
||||
{
|
||||
newTrigger.setTriggerType(Trigger_Enum.phoneCall);
|
||||
Intent phoneTriggerEditor = new Intent(myContext, ActivityManageTriggerPhoneCall.class);
|
||||
startActivityForResult(phoneTriggerEditor, requestCodeTriggerPhoneCallAdd);
|
||||
return;
|
||||
// booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
|
||||
}
|
||||
else if(triggerType == Trigger_Enum.activityDetection)
|
||||
{
|
||||
try
|
||||
@@ -676,13 +669,6 @@ public class ActivityManageRule extends Activity
|
||||
String[] choices = (String[]) choicesList.toArray(new String[choicesList.size()]);
|
||||
getTriggerNoiseDialog(myContext, choices).show();
|
||||
}
|
||||
// else if(triggerType.equals(Trigger.Event_Enum.timeFrame))
|
||||
// {
|
||||
// newTrigger.setTriggerType(Trigger.Event_Enum.timeFrame);
|
||||
// ActivityManageTimeFrame.editedTimeFrameTrigger = null;
|
||||
// Intent timeFrameEditor = new Intent(myContext, ActivityManageTimeFrame.class);
|
||||
// startActivityForResult(timeFrameEditor, 2000);
|
||||
// }
|
||||
else if(triggerType.equals(Trigger_Enum.wifiConnection))
|
||||
{
|
||||
newTrigger.setTriggerType(Trigger_Enum.wifiConnection);
|
||||
@@ -693,7 +679,6 @@ public class ActivityManageRule extends Activity
|
||||
progressDialog = ProgressDialog.show(myContext, null, getResources().getString(R.string.gettingListOfInstalledApplications), true, false);
|
||||
newTrigger.setTriggerType(Trigger_Enum.process_started_stopped);
|
||||
new GenerateApplicationSelectionsDialogTask().execute(ActivityManageRule.this);
|
||||
// getTriggerRunningProcessDialog1(myContext).show();
|
||||
}
|
||||
else if(triggerType.equals(Trigger_Enum.phoneCall))
|
||||
{
|
||||
@@ -826,7 +811,7 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
public void onClick(DialogInterface dialog, int whichButton)
|
||||
{
|
||||
newTrigger.setWifiName(input.getText().toString());
|
||||
// newTrigger.setWifiName(input.getText().toString());
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
refreshTriggerList();
|
||||
}
|
||||
@@ -1133,6 +1118,25 @@ public class ActivityManageRule extends Activity
|
||||
else
|
||||
Miscellaneous.logEvent("w", "TimeFrameEdit", "No timeframe returned. Assuming abort.", 5);
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerWifiAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newTrigger.setTriggerParameter(data.getBooleanExtra("wifiState", false));
|
||||
newTrigger.setTriggerParameter2(data.getStringExtra("wifiName"));
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerWifiEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newTrigger.setTriggerParameter(data.getBooleanExtra("wifiState", false));
|
||||
newTrigger.setTriggerParameter2(data.getStringExtra("wifiName"));
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionStartActivityAdd)
|
||||
{
|
||||
// manage start of other activity
|
||||
@@ -1170,7 +1174,6 @@ public class ActivityManageRule extends Activity
|
||||
//add notification
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
//newTrigger.setNfcTagId(ActivityManageNfc.generatedId);
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
|
||||
newTrigger.setTriggerParameter2(
|
||||
@@ -1182,8 +1185,6 @@ public class ActivityManageRule extends Activity
|
||||
);
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("w", "ActivityManageNfc", "No nfc id returned. Assuming abort.", 5);
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerNfcNotificationEdit)
|
||||
{
|
||||
@@ -1193,6 +1194,23 @@ public class ActivityManageRule extends Activity
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerPhoneCallAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
newTrigger.setTriggerParameter2(data.getStringExtra("triggerParameter2"));
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeTriggerPhoneCallEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newTrigger = ActivityManageTriggerPhoneCall.resultingTrigger;
|
||||
this.refreshTriggerList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionSpeakTextAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
@@ -1255,6 +1273,25 @@ public class ActivityManageRule extends Activity
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionVibrateAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
newAction.setParameter2(data.getStringExtra("vibratePattern"));
|
||||
ruleToEdit.getActionSet().add(newAction);
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionVibrateEdit)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
{
|
||||
if(data.hasExtra("vibratePattern"))
|
||||
ruleToEdit.getActionSet().get(editIndex).setParameter2(data.getStringExtra("vibratePattern"));
|
||||
|
||||
this.refreshActionList();
|
||||
}
|
||||
}
|
||||
else if(requestCode == requestCodeActionPlaySoundAdd)
|
||||
{
|
||||
if(resultCode == RESULT_OK)
|
||||
@@ -1332,6 +1369,8 @@ public class ActivityManageRule extends Activity
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.brightness));
|
||||
else if(types[i].toString().equals(Action_Enum.playSound.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.sound));
|
||||
else if(types[i].toString().equals(Action_Enum.vibrate.toString()))
|
||||
items.add(new Item(typesLong[i].toString(), R.drawable.vibrate));
|
||||
else if(types[i].toString().equals(Action_Enum.sendTextMessage.toString()))
|
||||
{
|
||||
// if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageSpecificRule.this, "android.permission.SEND_SMS") && !Miscellaneous.isGooglePlayInstalled(ActivityManageSpecificRule.this))
|
||||
@@ -1396,7 +1435,7 @@ public class ActivityManageRule extends Activity
|
||||
{
|
||||
newAction.setAction(Action_Enum.setUsbTethering);
|
||||
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.GINGERBREAD_MR1)
|
||||
Toast.makeText(context, context.getResources().getString(R.string.usbTetheringFailForAboveGingerbread), Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.messageBox(context.getResources().getString(R.string.warning), context.getResources().getString(R.string.usbTetheringFailForAboveGingerbread), context).show();
|
||||
getActionParameter1Dialog(ActivityManageRule.this).show();
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setWifiTethering.toString()))
|
||||
@@ -1437,13 +1476,13 @@ public class ActivityManageRule extends Activity
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setAirplaneMode.toString()))
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= 17)
|
||||
{
|
||||
Toast.makeText(context, getResources().getString(R.string.airplaneModeSdk17Warning), Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.airplaneMode), getResources().getString(R.string.rootExplanation), ActivityManageRule.this).show();
|
||||
}
|
||||
newAction.setAction(Action_Enum.setAirplaneMode);
|
||||
getActionParameter1Dialog(ActivityManageRule.this).show();
|
||||
if(Build.VERSION.SDK_INT >= 17)
|
||||
{
|
||||
// Toast.makeText(context, getResources().getString(R.string.airplaneModeSdk17Warning), Toast.LENGTH_LONG).show();
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.airplaneMode), getResources().getString(R.string.rootExplanation), ActivityManageRule.this).show();
|
||||
}
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setDataConnection.toString()))
|
||||
{
|
||||
@@ -1461,14 +1500,13 @@ public class ActivityManageRule extends Activity
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.sendTextMessage.toString()))
|
||||
{
|
||||
// if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageSpecificRule.this, "android.permission.SEND_SMS") && !Miscellaneous.isGooglePlayInstalled(ActivityManageSpecificRule.this))
|
||||
if(ActivityPermissions.isPermissionDeclaratedInManifest(ActivityManageRule.this, "android.permission.SEND_SMS"))
|
||||
{
|
||||
//launch other activity to enter parameters;
|
||||
newAction.setAction(Action_Enum.sendTextMessage);
|
||||
ActivityManageActionSendTextMessage.resultingAction = null;
|
||||
Intent editTriggerIntent = new Intent(context, ActivityManageActionSendTextMessage.class);
|
||||
startActivityForResult(editTriggerIntent, 5001);
|
||||
startActivityForResult(editTriggerIntent, requestCodeActionSendTextMessageAdd);
|
||||
}
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.playMusic.toString()))
|
||||
@@ -1477,6 +1515,12 @@ public class ActivityManageRule extends Activity
|
||||
ruleToEdit.getActionSet().add(newAction);
|
||||
refreshActionList();
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.vibrate.toString()))
|
||||
{
|
||||
newAction.setAction(Action_Enum.vibrate);
|
||||
Intent intent = new Intent(ActivityManageRule.this, ActivityManageActionVibrate.class);
|
||||
startActivityForResult(intent, requestCodeActionVibrateAdd);
|
||||
}
|
||||
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setScreenBrightness.toString()))
|
||||
{
|
||||
newAction.setAction(Action_Enum.setScreenBrightness);
|
||||
@@ -1594,63 +1638,6 @@ public class ActivityManageRule extends Activity
|
||||
return alertDialog;
|
||||
}
|
||||
|
||||
/*private AlertDialog getActionStartActivityDialog1(final Context myContext)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(myContext.getResources().getString(R.string.selectApplication));
|
||||
final String[] applicationArray = ActivityManageStartActivity.getApplicationNameListString(ActivityManageSpecificRule.this);
|
||||
alertDialogBuilder.setItems(applicationArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
getActionStartActivityDialog2(myContext, applicationArray[which]).show();
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getActionStartActivityDialog2(final Context myContext, String applicationName)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(myContext.getResources().getString(R.string.selectPackageOfApplication));
|
||||
final String[] packageArray = ActivityManageStartActivity.getPackageListString(ActivityManageSpecificRule.this, applicationName);
|
||||
alertDialogBuilder.setItems(packageArray, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
getActionStartActivityDialog3(ActivityManageSpecificRule.this, packageArray[which]).show();
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
private AlertDialog getActionStartActivityDialog3(final Context myContext, final String packageName)
|
||||
{
|
||||
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||
alertDialogBuilder.setTitle(myContext.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]);
|
||||
// Log.i("Selected", ai.packageName + " / " + ai.name);
|
||||
newAction.setParameter2(ai.packageName + ";" + ai.name);
|
||||
newAction.toString();
|
||||
ruleToEdit.getActionSet().add(newAction);
|
||||
refreshActionList();
|
||||
}
|
||||
});
|
||||
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||
|
||||
return alertDialog;
|
||||
}*/
|
||||
|
||||
private AlertDialog getActionWaitBeforeNextActionDialog(final Context myContext)
|
||||
{
|
||||
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
|
||||
|
||||
@@ -29,7 +29,7 @@ public class ActivityManageTriggerBluetooth extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_bluetooth_trigger);
|
||||
setContentView(R.layout.activity_manage_trigger_bluetooth);
|
||||
|
||||
radioAnyBluetoothDevice = (RadioButton)findViewById(R.id.radioAnyBluetoothDevice);
|
||||
radioNoDevice = (RadioButton)findViewById(R.id.radioNoDevice);
|
||||
|
||||
@@ -32,13 +32,14 @@ import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
public class ActivityManageTriggerNotification extends Activity
|
||||
{
|
||||
public static Trigger editedNotificationTrigger;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
|
||||
EditText etNotificationTitle, etNotificationText;
|
||||
Button bSelectApp, bSaveTriggerNotification;
|
||||
Spinner spinnerTitleDirection, spinnerTextDirection;
|
||||
TextView tvSelectedApplication;
|
||||
CheckBox chkNotificationDirection;
|
||||
boolean edit = false;
|
||||
ProgressDialog progressDialog = null;
|
||||
|
||||
private static List<PackageInfo> pInfos = null;
|
||||
public static Trigger resultingTrigger;
|
||||
@@ -250,7 +251,7 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.manage_trigger_notification);
|
||||
setContentView(R.layout.activity_manage_trigger_notification);
|
||||
|
||||
etNotificationTitle = (EditText)findViewById(R.id.etNotificationTitle);
|
||||
etNotificationText = (EditText)findViewById(R.id.etNotificationText);
|
||||
@@ -258,7 +259,7 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
bSaveTriggerNotification = (Button)findViewById(R.id.bSaveTriggerNotification);
|
||||
spinnerTitleDirection = (Spinner)findViewById(R.id.spinnerTitleDirection);
|
||||
spinnerTextDirection = (Spinner)findViewById(R.id.spinnerTextDirection);
|
||||
tvSelectedApplication = (TextView)findViewById(R.id.etSelectedApplication);
|
||||
tvSelectedApplication = (TextView)findViewById(R.id.etActivityOrActionPath);
|
||||
chkNotificationDirection = (CheckBox)findViewById(R.id.chkNotificationDirection);
|
||||
|
||||
directions = new String[] {
|
||||
@@ -393,7 +394,5 @@ public class ActivityManageTriggerNotification extends Activity
|
||||
progressDialog.dismiss();
|
||||
getActionStartActivityDialog1().show();
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,212 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ProgressDialog;
|
||||
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.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
|
||||
public class ActivityManageTriggerPhoneCall extends Activity
|
||||
{
|
||||
public static Trigger editedPhoneCallTrigger;
|
||||
boolean edit = false;
|
||||
public static Trigger resultingTrigger;
|
||||
ProgressDialog progressDialog = null;
|
||||
protected final static int requestCodeForContactsPermissions = 2345;
|
||||
protected final static int requestCodeGetContact = 3235;
|
||||
|
||||
EditText etTriggerPhoneCallPhoneNumber;
|
||||
RadioButton rbTriggerPhoneCallStateRinging, rbTriggerPhoneCallStateStarted, rbTriggerPhoneCallStateStopped, rbTriggerPhoneCallDirectionAny, rbTriggerPhoneCallDirectionIncoming, rbTriggerPhoneCallDirectionOutgoing;
|
||||
Button bSaveTriggerPhoneCall, bTriggerPhoneCallImportFromContacts;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_trigger_phone_call);
|
||||
|
||||
etTriggerPhoneCallPhoneNumber = (EditText)findViewById(R.id.etTriggerPhoneCallPhoneNumber);
|
||||
rbTriggerPhoneCallStateRinging = (RadioButton)findViewById(R.id.rbTriggerPhoneCallStateRinging);
|
||||
rbTriggerPhoneCallStateStarted = (RadioButton)findViewById(R.id.rbTriggerPhoneCallStateStarted);
|
||||
rbTriggerPhoneCallStateStopped = (RadioButton)findViewById(R.id.rbTriggerPhoneCallStateStopped);
|
||||
rbTriggerPhoneCallDirectionAny = (RadioButton)findViewById(R.id.rbTriggerPhoneCallDirectionAny);
|
||||
rbTriggerPhoneCallDirectionIncoming = (RadioButton)findViewById(R.id.rbTriggerPhoneCallDirectionIncoming);
|
||||
rbTriggerPhoneCallDirectionOutgoing = (RadioButton)findViewById(R.id.rbTriggerPhoneCallDirectionOutgoing);
|
||||
bTriggerPhoneCallImportFromContacts = (Button) findViewById(R.id.bTriggerPhoneCallImportFromContacts);
|
||||
bSaveTriggerPhoneCall = (Button) findViewById(R.id.bSaveTriggerPhoneCall);
|
||||
|
||||
bSaveTriggerPhoneCall.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
String tp2Result = "";
|
||||
|
||||
if(rbTriggerPhoneCallStateRinging.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallStateRinging;
|
||||
else if(rbTriggerPhoneCallStateStarted.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallStateStarted;
|
||||
else if(rbTriggerPhoneCallStateStopped.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallStateStopped;
|
||||
|
||||
tp2Result += triggerParameter2Split;
|
||||
|
||||
if(rbTriggerPhoneCallDirectionAny.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallDirectionAny;
|
||||
else if(rbTriggerPhoneCallDirectionIncoming.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallDirectionIncoming;
|
||||
else if(rbTriggerPhoneCallDirectionOutgoing.isChecked())
|
||||
tp2Result += Trigger.triggerPhoneCallDirectionOutgoing;
|
||||
|
||||
tp2Result += triggerParameter2Split;
|
||||
|
||||
if(etTriggerPhoneCallPhoneNumber.getText() != null && etTriggerPhoneCallPhoneNumber.getText().toString().length() > 0)
|
||||
tp2Result += etTriggerPhoneCallPhoneNumber.getText().toString();
|
||||
else
|
||||
tp2Result += Trigger.triggerPhoneCallNumberAny;
|
||||
|
||||
if(edit)
|
||||
{
|
||||
editedPhoneCallTrigger.setTriggerParameter(false);
|
||||
editedPhoneCallTrigger.setTriggerParameter2(tp2Result);
|
||||
ActivityManageTriggerPhoneCall.this.setResult(RESULT_OK);
|
||||
}
|
||||
else
|
||||
{
|
||||
Intent data = new Intent();
|
||||
data.putExtra("triggerParameter", false);
|
||||
data.putExtra("triggerParameter2", tp2Result);
|
||||
ActivityManageTriggerPhoneCall.this.setResult(RESULT_OK, data);
|
||||
}
|
||||
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
bTriggerPhoneCallImportFromContacts.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && !ActivityPermissions.havePermission("android.permission.READ_CONTACTS", ActivityManageTriggerPhoneCall.this))
|
||||
{
|
||||
requestPermissions("android.permission.READ_CONTACTS");
|
||||
}
|
||||
else
|
||||
openContactsDialogue();
|
||||
}
|
||||
});
|
||||
|
||||
Intent i = getIntent();
|
||||
if(i.getBooleanExtra("edit", false) == true)
|
||||
{
|
||||
edit = true;
|
||||
loadValuesIntoGui();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void openContactsDialogue()
|
||||
{
|
||||
Intent intent = new Intent(Intent.ACTION_PICK, ContactsContract.CommonDataKinds.Phone.CONTENT_URI);
|
||||
startActivityForResult(intent, requestCodeGetContact);
|
||||
}
|
||||
|
||||
private void loadValuesIntoGui()
|
||||
{
|
||||
String[] parts = editedPhoneCallTrigger.getTriggerParameter2().split(triggerParameter2Split);
|
||||
|
||||
if(parts[0].equals(Trigger.triggerPhoneCallStateRinging))
|
||||
rbTriggerPhoneCallStateRinging.setChecked(true);
|
||||
else if(parts[0].equals(Trigger.triggerPhoneCallStateStarted))
|
||||
rbTriggerPhoneCallStateStarted.setChecked(true);
|
||||
else if(parts[0].equals(Trigger.triggerPhoneCallStateStopped))
|
||||
rbTriggerPhoneCallStateStopped.setChecked(true);
|
||||
|
||||
if(parts[1].equals(Trigger.triggerPhoneCallDirectionAny))
|
||||
rbTriggerPhoneCallDirectionAny.setChecked(true);
|
||||
else if(parts[1].equals(Trigger.triggerPhoneCallDirectionIncoming))
|
||||
rbTriggerPhoneCallDirectionIncoming.setChecked(true);
|
||||
else if(parts[1].equals(Trigger.triggerPhoneCallDirectionOutgoing))
|
||||
rbTriggerPhoneCallDirectionOutgoing.setChecked(true);
|
||||
|
||||
if(!parts[2].equals(Trigger.triggerPhoneCallNumberAny))
|
||||
etTriggerPhoneCallPhoneNumber.setText(parts[2]);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||
{
|
||||
if(requestCode == requestCodeGetContact)
|
||||
{
|
||||
if(resultCode == Activity.RESULT_OK)
|
||||
{
|
||||
String phoneNo = null;
|
||||
String name = null;
|
||||
|
||||
Uri uri = data.getData();
|
||||
Cursor cursor = ActivityManageTriggerPhoneCall.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);
|
||||
|
||||
etTriggerPhoneCallPhoneNumber.setText(phoneNo);
|
||||
}
|
||||
}
|
||||
}
|
||||
//super.onActivityResult(requestCode, resultCode, data);
|
||||
}
|
||||
|
||||
@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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -27,7 +27,7 @@ public class ActivityManageTriggerTimeFrame extends Activity
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.manage_trigger_timeframe);
|
||||
setContentView(R.layout.activity_manage_trigger_timeframe);
|
||||
|
||||
startPicker = (TimePicker)findViewById(R.id.tpTimeFrameStart);
|
||||
stopPicker = (TimePicker)findViewById(R.id.tpTimeFrameStop);
|
||||
|
||||
@@ -0,0 +1,193 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.net.wifi.ScanResult;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.RadioButton;
|
||||
import android.widget.Spinner;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.ActivityCompat;
|
||||
|
||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivityManageTriggerWifi extends Activity
|
||||
{
|
||||
RadioButton rbTriggerWifiConnected, rbTriggerWifiDisconnected;
|
||||
EditText etTriggerWifiName;
|
||||
Spinner spinnerWifiList;
|
||||
Button btriggerWifiSave, bLoadWifiList;
|
||||
List<String> wifiList = new ArrayList<>();
|
||||
ArrayAdapter<String> wifiSpinnerAdapter;
|
||||
private final static int requestCodeLocationPermission = 124;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_manage_trigger_wifi);
|
||||
|
||||
rbTriggerWifiConnected = (RadioButton) findViewById(R.id.rbTriggerWifiConnected);
|
||||
rbTriggerWifiDisconnected = (RadioButton) findViewById(R.id.rbTriggerWifiDisconnected);
|
||||
etTriggerWifiName = (EditText) findViewById(R.id.etTriggerWifiName);
|
||||
spinnerWifiList = (Spinner) findViewById(R.id.spinnerWifiList);
|
||||
btriggerWifiSave = (Button) findViewById(R.id.btriggerWifiSave);
|
||||
bLoadWifiList = (Button) findViewById(R.id.bLoadWifiList);
|
||||
|
||||
wifiSpinnerAdapter = new ArrayAdapter<String>(this, R.layout.text_view_for_poi_listview_mediumtextsize, wifiList);
|
||||
spinnerWifiList.setAdapter(wifiSpinnerAdapter);
|
||||
spinnerWifiList.setEnabled(false); // bug in Android; this only works when done in code, not in xml
|
||||
|
||||
if (getIntent().hasExtra("edit"))
|
||||
{
|
||||
boolean connected = getIntent().getBooleanExtra("wifiState", false);
|
||||
String wifiName = getIntent().getStringExtra("wifiName");
|
||||
|
||||
rbTriggerWifiConnected.setChecked(connected);
|
||||
rbTriggerWifiDisconnected.setChecked(!connected);
|
||||
|
||||
etTriggerWifiName.setText(wifiName);
|
||||
}
|
||||
|
||||
btriggerWifiSave.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
Intent response = new Intent();
|
||||
response.putExtra("wifiState", rbTriggerWifiConnected.isChecked());
|
||||
response.putExtra("wifiName", etTriggerWifiName.getText().toString());
|
||||
setResult(RESULT_OK, response);
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
spinnerWifiList.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener()
|
||||
{
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id)
|
||||
{
|
||||
etTriggerWifiName.setText(wifiList.get(position));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent)
|
||||
{
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
bLoadWifiList.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
loadWifis();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void loadWifis()
|
||||
{
|
||||
if(!ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, ActivityManageTriggerWifi.this))
|
||||
{
|
||||
AlertDialog dialog = Miscellaneous.messageBox(getResources().getString(R.string.permissionsTitle), getResources().getString(R.string.needLocationPermForWifiList), ActivityManageTriggerWifi.this);
|
||||
dialog.setOnDismissListener(new DialogInterface.OnDismissListener()
|
||||
{
|
||||
@Override
|
||||
public void onDismiss(DialogInterface dialog)
|
||||
{
|
||||
ActivityCompat.requestPermissions(ActivityManageTriggerWifi.this, new String[] { Manifest.permission.ACCESS_FINE_LOCATION }, requestCodeLocationPermission);
|
||||
}
|
||||
});
|
||||
dialog.show();
|
||||
}
|
||||
else
|
||||
{
|
||||
reallyLoadWifiList();
|
||||
}
|
||||
}
|
||||
|
||||
void reallyLoadWifiList()
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= 30)
|
||||
{
|
||||
Miscellaneous.messageBox(getResources().getString(R.string.hint), getResources().getString(R.string.wifiApi30), ActivityManageTriggerWifi.this).show();
|
||||
loadListOfVisibleWifis();
|
||||
}
|
||||
else
|
||||
{
|
||||
WifiManager myWifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
|
||||
|
||||
for (WifiConfiguration wifi : myWifiManager.getConfiguredNetworks())
|
||||
wifiList.add(wifi.SSID.replaceAll("\"+$", "").replaceAll("^\"+", ""));
|
||||
}
|
||||
|
||||
if (wifiList.size() > 0)
|
||||
{
|
||||
spinnerWifiList.setEnabled(true);
|
||||
Collections.sort(wifiList);
|
||||
}
|
||||
else
|
||||
{
|
||||
spinnerWifiList.setEnabled(false);
|
||||
Toast.makeText(ActivityManageTriggerWifi.this, getResources().getString(R.string.noKnownWifis), Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
|
||||
wifiSpinnerAdapter.notifyDataSetChanged();
|
||||
}
|
||||
|
||||
void loadListOfVisibleWifis()
|
||||
{
|
||||
List<ScanResult> results = null;
|
||||
|
||||
try
|
||||
{
|
||||
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
|
||||
results = wifiManager.getScanResults();
|
||||
|
||||
for (ScanResult wifi : results)
|
||||
wifiList.add(wifi.SSID.replaceAll("\"+$", "").replaceAll("^\"+", ""));
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "loadListOfVisibleWifis()", Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
|
||||
{
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
|
||||
switch (requestCode)
|
||||
{
|
||||
case requestCodeLocationPermission:
|
||||
if(grantResults[0] == PackageManager.PERMISSION_GRANTED)
|
||||
reallyLoadWifiList();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,7 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.preference.CheckBoxPreference;
|
||||
import android.preference.ListPreference;
|
||||
import android.preference.PreferenceActivity;
|
||||
|
||||
@@ -9,11 +10,18 @@ import com.jens.automation2.R.layout;
|
||||
public class ActivitySettings extends PreferenceActivity
|
||||
{
|
||||
ListPreference lpStartScreenOptionsValues;
|
||||
CheckBoxPreference chkPrefUpdateCheck;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
addPreferencesFromResource(layout.settings);
|
||||
addPreferencesFromResource(layout.activity_settings);
|
||||
|
||||
if(BuildConfig.FLAVOR.equals("apkFlavor"))
|
||||
{
|
||||
chkPrefUpdateCheck = (CheckBoxPreference) findPreference("automaticUpdateCheck");
|
||||
chkPrefUpdateCheck.setEnabled(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,65 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.content.Context;
|
||||
import android.os.AsyncTask;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
public class AsyncTasks
|
||||
{
|
||||
public static class AsyncTaskUpdateCheck extends AsyncTask<Context, Void, Boolean>
|
||||
{
|
||||
public static boolean checkRunning = false;
|
||||
|
||||
@Override
|
||||
protected Boolean doInBackground(Context... contexts)
|
||||
{
|
||||
if(checkRunning)
|
||||
return false;
|
||||
else
|
||||
checkRunning = true;
|
||||
|
||||
try
|
||||
{
|
||||
String result = Miscellaneous.downloadURL("https://server47.de/automation/?action=getLatestVersionCode", null, null).trim();
|
||||
int latestVersion = Integer.parseInt(result);
|
||||
|
||||
// At this point the update check itself has already been successful.
|
||||
|
||||
Settings.lastUpdateCheck = Calendar.getInstance().getTimeInMillis();
|
||||
Settings.writeSettings(contexts[0]);
|
||||
|
||||
if (latestVersion > BuildConfig.VERSION_CODE)
|
||||
{
|
||||
// There's a new update
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Error checking for update", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPostExecute(Boolean result)
|
||||
{
|
||||
try
|
||||
{
|
||||
ActivityMainScreen.getActivityMainScreenInstance().processUpdateCheckResult(result);
|
||||
}
|
||||
catch (NullPointerException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "NewsDownload", "There was a problem displaying the update check result, probably ActivityMainScreen isn't currently shown: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "NewsDownload", "There was a problem displaying the update check result: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.ActivityManager;
|
||||
import android.app.ActivityManager.RunningServiceInfo;
|
||||
@@ -121,14 +122,14 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
if(Build.VERSION.SDK_INT >= 28)
|
||||
{
|
||||
if (!ActivityPermissions.havePermission(ActivityPermissions.permissionNameStartService, AutomationService.this))
|
||||
if (!ActivityPermissions.havePermission(Manifest.permission.FOREGROUND_SERVICE, 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);
|
||||
ActivityPermissions.requestSpecificPermission(Manifest.permission.FOREGROUND_SERVICE);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -196,7 +197,7 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
if (checkStartupRequirements(this, startAtBoot))
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.logServiceStarting), 1);
|
||||
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.logServiceStarting) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
|
||||
|
||||
startUpRoutine();
|
||||
|
||||
@@ -210,7 +211,7 @@ public class AutomationService extends Service implements OnInitListener
|
||||
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);
|
||||
Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.serviceStarted) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1);
|
||||
Toast.makeText(this, this.getResources().getString(R.string.serviceStarted), Toast.LENGTH_LONG).show();
|
||||
// ********** Test area **********
|
||||
// Miscellaneous.logEvent("i", "setNetworkType", "bin hier.", 3);
|
||||
@@ -257,7 +258,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
case reloadSettings:
|
||||
Settings.readFromPersistentStorage(this);
|
||||
applySettingsAndRules();
|
||||
myLocationProvider.applySettingsAndRules();
|
||||
if(myLocationProvider != null)
|
||||
myLocationProvider.applySettingsAndRules();
|
||||
break;
|
||||
case updateNotification:
|
||||
this.updateNotification();
|
||||
@@ -341,6 +343,9 @@ public class AutomationService extends Service implements OnInitListener
|
||||
{
|
||||
boolean displayNotification = false;
|
||||
|
||||
String rule = "";
|
||||
|
||||
outerLoop:
|
||||
for(Rule r : Rule.getRuleCollection())
|
||||
{
|
||||
if(r.isRuleActive())
|
||||
@@ -353,7 +358,11 @@ public class AutomationService extends Service implements OnInitListener
|
||||
// r.setRuleActive(false);
|
||||
// r.change(AutomationService.this);
|
||||
if(!displayNotification)
|
||||
{
|
||||
displayNotification = true;
|
||||
rule = r.getName();
|
||||
break outerLoop;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -361,18 +370,16 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
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.logEvent("w", "Features disabled", "Features disabled because of rule " + rule, 5);
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(1010, getResources().getString(R.string.featuresDisabled), ActivityPermissions.notificationIdPermissions, pi);
|
||||
else
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), ActivityPermissions.notificationIdPermissions, pi);
|
||||
}
|
||||
// else
|
||||
// Toast.makeText(Miscellaneous.getAnyContext(), "Have all required permissions.", Toast.LENGTH_LONG).show();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,6 +396,9 @@ public class AutomationService extends Service implements OnInitListener
|
||||
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
// Miscellaneous.createDismissableNotification(getResources().getString(R.string.settingsReferringToRestrictedFeatures), ActivityPermissions.notificationIdPermissions, pi);
|
||||
|
||||
Miscellaneous.logEvent("w", "Features disabled", "Background location disabled because Google to blame.", 5);
|
||||
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(3300, getResources().getString(R.string.featuresDisabled), notificationIdRestrictions, pi);
|
||||
else
|
||||
@@ -404,6 +414,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
|
||||
Miscellaneous.logEvent("w", "Features disabled", "Background location disabled because Google to blame.", 5);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(2200, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
else
|
||||
@@ -445,7 +457,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
private void stopRoutine()
|
||||
{
|
||||
Log.i("STOP", "Stopping");
|
||||
Miscellaneous.logEvent("i", "Service", "Stopping service...", 3);
|
||||
// Log.i("STOP", "Stopping");
|
||||
try
|
||||
{
|
||||
myLocationProvider.stopLocationService();
|
||||
@@ -581,11 +594,11 @@ public class AutomationService extends Service implements OnInitListener
|
||||
if(activePoi == null)
|
||||
{
|
||||
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(instance.getLocationProvider().getCurrentLocation());
|
||||
bodyText = "Active POI: none" + "\n" + "Closest POI: " + closestPoi.getName() + lastRuleString;
|
||||
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + AutomationService.getInstance().getResources().getString(R.string.none) + "\n" + AutomationService.getInstance().getResources().getString(R.string.closestPoi) + ": " + closestPoi.getName() + lastRuleString;
|
||||
}
|
||||
else
|
||||
{
|
||||
bodyText = "Active POI: " + activePoi.getName() + lastRuleString;
|
||||
bodyText = AutomationService.getInstance().getResources().getString(R.string.activePoi) + ": " + activePoi.getName() + lastRuleString;
|
||||
}
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
@@ -593,9 +606,9 @@ public class AutomationService extends Service implements OnInitListener
|
||||
if(
|
||||
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, AutomationService.getInstance())
|
||||
ActivityPermissions.havePermission(Manifest.permission.ACCESS_COARSE_LOCATION, AutomationService.getInstance())
|
||||
&&
|
||||
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, AutomationService.getInstance())
|
||||
ActivityPermissions.havePermission(Manifest.permission.ACCESS_FINE_LOCATION, AutomationService.getInstance())
|
||||
)
|
||||
bodyText = instance.getResources().getString(R.string.stillGettingPosition);
|
||||
else
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.Manifest;
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Notification;
|
||||
@@ -21,11 +22,14 @@ import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.telephony.PhoneNumberUtils;
|
||||
import android.telephony.TelephonyManager;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.receivers.NotificationListener;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
|
||||
import org.apache.http.HttpEntity;
|
||||
@@ -90,6 +94,7 @@ import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.documentfile.provider.DocumentFile;
|
||||
|
||||
import static android.provider.CalendarContract.CalendarCache.URI;
|
||||
import static com.jens.automation2.AutomationService.NOTIFICATION_CHANNEL_ID;
|
||||
@@ -116,15 +121,6 @@ public class Miscellaneous extends Service
|
||||
if(url.toLowerCase().contains("https"))
|
||||
{
|
||||
connection = (HttpsURLConnection) urlObject.openConnection();
|
||||
|
||||
// if(Settings.httpAcceptAllCertificates)
|
||||
// {
|
||||
// SSLContext sc = SSLContext.getInstance("TLS");
|
||||
// sc.init(null, getInsecureTrustManager(), new java.security.SecureRandom());
|
||||
// HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
|
||||
// Miscellaneous.disableSSLCertificateChecking();
|
||||
// HttpsURLConnection.setDefaultHostnameVerifier(getInsecureHostnameVerifier());
|
||||
// }
|
||||
}
|
||||
else
|
||||
connection = (HttpURLConnection) urlObject.openConnection();
|
||||
@@ -332,7 +328,7 @@ public class Miscellaneous extends Service
|
||||
migration:
|
||||
if (!newConfigFile.exists())
|
||||
{
|
||||
if (ActivityPermissions.havePermission(ActivityPermissions.writeExternalStoragePermissionName, Miscellaneous.getAnyContext()))
|
||||
if (ActivityPermissions.havePermission(Manifest.permission.WRITE_EXTERNAL_STORAGE, Miscellaneous.getAnyContext()))
|
||||
{
|
||||
// We have the storage permission, probably because it's an old installation. Files should be migrated to app-specific folder.
|
||||
|
||||
@@ -595,6 +591,26 @@ public class Miscellaneous extends Service
|
||||
source = source.replace("[s]", String.valueOf(cal.get(Calendar.SECOND)));
|
||||
source = source.replace("[ms]", String.valueOf(cal.get(Calendar.MILLISECOND)));
|
||||
}
|
||||
|
||||
if(source.contains("[notificationTitle]"))
|
||||
{
|
||||
String notificationTitle = NotificationListener.getLastNotification().getTitle();
|
||||
|
||||
if(notificationTitle != null && notificationTitle.length() > 0)
|
||||
source = source.replace("[notificationTitle]", notificationTitle);
|
||||
else
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "notificationTitle was empty.", 3);
|
||||
}
|
||||
|
||||
if(source.contains("[notificationText]"))
|
||||
{
|
||||
String notificationText = NotificationListener.getLastNotification().getText();
|
||||
|
||||
if(notificationText != null && notificationText.length() > 0)
|
||||
source = source.replace("[notificationText]", notificationText);
|
||||
else
|
||||
Miscellaneous.logEvent("w", "Variable replacement", "notificationText was empty.", 3);
|
||||
}
|
||||
|
||||
// Miscellaneous.logEvent("i", "URL after replace", source);
|
||||
|
||||
@@ -1214,6 +1230,122 @@ public class Miscellaneous extends Service
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public static boolean copyDocumentFileToFile(DocumentFile src, File dst)
|
||||
{
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
String error = null;
|
||||
|
||||
try
|
||||
{
|
||||
in = Miscellaneous.getAnyContext().getContentResolver().openInputStream(src.getUri());
|
||||
out = new FileOutputStream(dst);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int read;
|
||||
|
||||
while ((read = in.read(buffer)) != -1)
|
||||
{
|
||||
out.write(buffer, 0, read);
|
||||
}
|
||||
|
||||
in.close();
|
||||
// write the output file (You have now copied the file)
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (FileNotFoundException fnfe1)
|
||||
{
|
||||
error = fnfe1.getMessage();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = e.getMessage();
|
||||
}
|
||||
|
||||
return false;
|
||||
// return error;
|
||||
}
|
||||
|
||||
public static boolean copyFileToDocumentFile(File src, DocumentFile dst)
|
||||
{
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
String error = null;
|
||||
|
||||
try
|
||||
{
|
||||
in = new FileInputStream(src);
|
||||
out = Miscellaneous.getAnyContext().getContentResolver().openOutputStream(dst.getUri());
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int read;
|
||||
|
||||
while ((read = in.read(buffer)) != -1)
|
||||
{
|
||||
out.write(buffer, 0, read);
|
||||
}
|
||||
|
||||
in.close();
|
||||
// write the output file (You have now copied the file)
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (FileNotFoundException fnfe1)
|
||||
{
|
||||
error = fnfe1.getMessage();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = e.getMessage();
|
||||
}
|
||||
|
||||
return false;
|
||||
// return error;
|
||||
}
|
||||
|
||||
/*public static String copyDocumentFile(String inputPath, String inputFile, Uri treeUri)
|
||||
{
|
||||
InputStream in = null;
|
||||
OutputStream out = null;
|
||||
String error = null;
|
||||
DocumentFile pickedDir = DocumentFile.fromTreeUri(getActivity(), treeUri);
|
||||
String extension = inputFile.substring(inputFile.lastIndexOf(".")+1,inputFile.length());
|
||||
|
||||
try
|
||||
{
|
||||
DocumentFile newFile = pickedDir.createFile("audio/"+extension, inputFile);
|
||||
out = getActivity().getContentResolver().openOutputStream(newFile.getUri());
|
||||
in = new FileInputStream(inputPath + inputFile);
|
||||
|
||||
byte[] buffer = new byte[1024];
|
||||
int read;
|
||||
while ((read = in.read(buffer)) != -1)
|
||||
{
|
||||
out.write(buffer, 0, read);
|
||||
}
|
||||
in.close();
|
||||
// write the output file (You have now copied the file)
|
||||
out.flush();
|
||||
out.close();
|
||||
|
||||
}
|
||||
catch (FileNotFoundException fnfe1)
|
||||
{
|
||||
error = fnfe1.getMessage();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
error = e.getMessage();
|
||||
}
|
||||
|
||||
return error;
|
||||
}*/
|
||||
|
||||
public static boolean googleToBlameForLocation(boolean checkExistingRules)
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
@@ -1333,4 +1465,31 @@ public class Miscellaneous extends Service
|
||||
{
|
||||
return intent.resolveActivityInfo(context.getPackageManager(), 0) != null;
|
||||
}
|
||||
|
||||
public static boolean isRegularExpression(String regex)
|
||||
{
|
||||
try
|
||||
{
|
||||
"compareString".matches(regex); //will cause expection if no valid regex
|
||||
return true;
|
||||
}
|
||||
catch(java.util.regex.PatternSyntaxException e)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public static boolean comparePhoneNumbers(String number1, String number2)
|
||||
{
|
||||
/* To be activated when Android S SDK comes out
|
||||
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.Q)
|
||||
{
|
||||
TelephonyManager tm = (TelephonyManager)Miscellaneous.getAnyContext().getSystemService(Context.TELEPHONY_SERVICE);
|
||||
return PhoneNumberUtils.areSamePhoneNumber(number1, number2, tm.getNetworkCountryIso());
|
||||
}
|
||||
else*/
|
||||
return PhoneNumberUtils.compare(number1, number2);
|
||||
}
|
||||
}
|
||||
@@ -76,7 +76,7 @@ public class News
|
||||
if(oldFilePath.exists())
|
||||
oldFilePath.delete();
|
||||
|
||||
if (!(new File(filePath)).exists() || Settings.lastNewsPolltime == -1 || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.newsDisplayForXDays * 24 * 60 * 60 * 1000))
|
||||
if (!(new File(filePath)).exists() || Settings.lastNewsPolltime == Settings.default_lastNewsPolltime || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.newsDisplayForXDays * 24 * 60 * 60 * 1000))
|
||||
{
|
||||
String newsUrl = "https://server47.de/automation/appNews.php";
|
||||
newsContent = Miscellaneous.downloadURL(newsUrl, null, null);
|
||||
|
||||
@@ -491,9 +491,17 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
if (service != null)
|
||||
{
|
||||
service.applySettingsAndRules();
|
||||
//Easiest way to check for changes in location, reset the last known location.
|
||||
service.getLocationProvider().setCurrentLocation(service.getLocationProvider().getCurrentLocation(), true);
|
||||
try
|
||||
{
|
||||
service.applySettingsAndRules();
|
||||
//Easiest way to check for changes in location, reset the last known location.
|
||||
service.getLocationProvider().setCurrentLocation(service.getLocationProvider().getCurrentLocation(), true);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
// Just log the event. This should not cause an interruption in the program flow.
|
||||
Miscellaneous.logEvent("e", "save POI", "Error when trying to apply settings and rules: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -530,14 +538,18 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
PointOfInterest.writePoisToFile();
|
||||
|
||||
AutomationService service = AutomationService.getInstance();
|
||||
if(service != null)
|
||||
|
||||
try
|
||||
{
|
||||
service.applySettingsAndRules();
|
||||
|
||||
//Easiest way to check for changes in location, reset the last known location.
|
||||
service.getLocationProvider().setCurrentLocation(service.getLocationProvider().getCurrentLocation(), true);
|
||||
}
|
||||
|
||||
catch(Exception e)
|
||||
{
|
||||
// Just log the event. This should not cause an interruption in the program flow.
|
||||
Miscellaneous.logEvent("e", "save POI", "Error when trying to apply settings and rules: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -793,6 +805,7 @@ public class PointOfInterest implements Comparable<PointOfInterest>
|
||||
{
|
||||
String text = String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.overlapBetweenPois), otherPoi.getName(), String.valueOf(overlap));
|
||||
Miscellaneous.logEvent("w", "POI", text, 2);
|
||||
// Miscellaneous.messageBox("POI", text, Miscellaneous.getAnyContext()).show();
|
||||
Toast.makeText(Miscellaneous.getAnyContext(), text, Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -271,41 +271,45 @@ public class ReceiverCoordinator
|
||||
ProcessListener.stopProcessListener(AutomationService.getInstance());
|
||||
}
|
||||
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
|
||||
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
|
||||
{
|
||||
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);;
|
||||
if(runResult instanceof Boolean)
|
||||
if (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
|
||||
{
|
||||
boolean isRunning = (Boolean) runResult;
|
||||
if (isRunning)
|
||||
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);
|
||||
|
||||
if (runResult instanceof Boolean)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Restarting ActivityDetectionReceiver because used in a new/changed rule.", 4);
|
||||
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective(activityDetectionClassPath, "haveAllPermission", null);
|
||||
if (haveAllPerms)
|
||||
Miscellaneous.runMethodReflective(activityDetectionClassPath, "restartActivityDetectionReceiver", null);
|
||||
boolean isRunning = (Boolean) runResult;
|
||||
if (isRunning)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Restarting ActivityDetectionReceiver because used in a new/changed rule.", 4);
|
||||
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective(activityDetectionClassPath, "haveAllPermission", null);
|
||||
if (haveAllPerms)
|
||||
Miscellaneous.runMethodReflective(activityDetectionClassPath, "restartActivityDetectionReceiver", null);
|
||||
// ActivityDetectionReceiver.restartActivityDetectionReceiver();
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting ActivityDetectionReceiver because used in a new/changed rule.", 4);
|
||||
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective(activityDetectionClassPath, "haveAllPermission", null);
|
||||
if (haveAllPerms)
|
||||
Miscellaneous.runMethodReflective(activityDetectionClassPath, "startActivityDetectionReceiver", null);
|
||||
}
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Starting ActivityDetectionReceiver because used in a new/changed rule.", 4);
|
||||
boolean haveAllPerms = (Boolean) Miscellaneous.runMethodReflective(activityDetectionClassPath, "haveAllPermission", null);
|
||||
if (haveAllPerms)
|
||||
Miscellaneous.runMethodReflective(activityDetectionClassPath, "startActivityDetectionReceiver", null);
|
||||
// ActivityDetectionReceiver.startActivityDetectionReceiver();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);
|
||||
if(runResult instanceof Boolean)
|
||||
else
|
||||
{
|
||||
boolean isRunning = (Boolean) runResult;
|
||||
if (isRunning)
|
||||
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);
|
||||
if (runResult instanceof Boolean)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down ActivityDetectionReceiver because not used in any rule.", 4);
|
||||
Miscellaneous.runMethodReflective(activityDetectionClassPath, "stopActivityDetectionReceiver", null);
|
||||
boolean isRunning = (Boolean) runResult;
|
||||
if (isRunning)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "LocationProvider", "Shutting down ActivityDetectionReceiver because not used in any rule.", 4);
|
||||
Miscellaneous.runMethodReflective(activityDetectionClassPath, "stopActivityDetectionReceiver", null);
|
||||
// ActivityDetectionReceiver.stopActivityDetectionReceiver();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@ public class Settings implements SharedPreferences
|
||||
public final static int lockSoundChangesInterval = 15;
|
||||
public static final int newsPollEveryXDays = 3;
|
||||
public static final int newsDisplayForXDays = 3;
|
||||
public static final int updateCheckFrequencyDays = 7;
|
||||
public static final String folderName = "Automation";
|
||||
public static final String zipFileName = "automation.zip";
|
||||
|
||||
@@ -59,12 +60,16 @@ public class Settings implements SharedPreferences
|
||||
public static int activityDetectionRequiredProbability;
|
||||
public static boolean privacyLocationing;
|
||||
public static int startScreen;
|
||||
public static int tabsPlacement;
|
||||
public static boolean executeRulesAndProfilesWithSingleClick;
|
||||
public static boolean displayNewsOnMainScreen;
|
||||
public static boolean automaticUpdateCheck;
|
||||
|
||||
public static boolean lockSoundChanges;
|
||||
public static boolean noticeAndroid9MicrophoneShown;
|
||||
public static boolean noticeAndroid10WifiShown;
|
||||
public static long lastNewsPolltime;
|
||||
public static long lastUpdateCheck;
|
||||
|
||||
public static ArrayList<String> whatHasBeenDone;
|
||||
|
||||
@@ -112,10 +117,13 @@ public class Settings implements SharedPreferences
|
||||
protected static final int default_activityDetectionRequiredProbability = 75;
|
||||
protected static final boolean default_privacyLocationing = false;
|
||||
protected static final int default_startScreen = 0;
|
||||
protected static final int default_tabsPlacement = 0;
|
||||
protected static final boolean default_executeRulesAndProfilesWithSingleClick = false;
|
||||
protected static final boolean default_displayNewsOnMainScreen = false;
|
||||
protected static final boolean default_automaticUpdateCheck = false;
|
||||
protected static final boolean default_lockSoundChanges = false;
|
||||
protected static final long default_lastNewsPolltime = -1;
|
||||
protected static final long default_lastUpdateCheck = -1;
|
||||
|
||||
@Override
|
||||
public boolean contains(String arg0)
|
||||
@@ -247,8 +255,10 @@ public class Settings implements SharedPreferences
|
||||
|
||||
privacyLocationing = prefs.getBoolean("privacyLocationing", default_privacyLocationing);
|
||||
startScreen = Integer.parseInt(prefs.getString("startScreen", String.valueOf(default_startScreen)));
|
||||
tabsPlacement = Integer.parseInt(prefs.getString("tabsPlacement", String.valueOf(default_tabsPlacement)));
|
||||
|
||||
executeRulesAndProfilesWithSingleClick = prefs.getBoolean("executeRulesAndProfilesWithSingleClick", default_executeRulesAndProfilesWithSingleClick);
|
||||
automaticUpdateCheck = prefs.getBoolean("automaticUpdateCheck", default_automaticUpdateCheck);
|
||||
displayNewsOnMainScreen = prefs.getBoolean("displayNewsOnMainScreen", default_displayNewsOnMainScreen);
|
||||
|
||||
lockSoundChanges = prefs.getBoolean("lockSoundChanges", default_lockSoundChanges);
|
||||
@@ -256,6 +266,7 @@ public class Settings implements SharedPreferences
|
||||
noticeAndroid10WifiShown = prefs.getBoolean("noticeAndroid10WifiShown", false);
|
||||
|
||||
lastNewsPolltime = prefs.getLong("lastNewsPolltime", default_lastNewsPolltime);
|
||||
lastUpdateCheck = prefs.getLong("lastUpdateCheck", default_lastUpdateCheck);
|
||||
|
||||
String whbdString = prefs.getString("whatHasBeenDone", "");
|
||||
if(whbdString != null && whbdString.length() > 0)
|
||||
@@ -432,9 +443,15 @@ public class Settings implements SharedPreferences
|
||||
if(!prefs.contains("startScreen") | force)
|
||||
editor.putString("startScreen", String.valueOf(default_startScreen));
|
||||
|
||||
if(!prefs.contains("tabsPlacement") | force)
|
||||
editor.putString("tabsPlacement", String.valueOf(default_tabsPlacement));
|
||||
|
||||
if(!prefs.contains("executeRulesAndProfilesWithSingleClick") | force)
|
||||
editor.putBoolean("executeRulesAndProfilesWithSingleClick", default_executeRulesAndProfilesWithSingleClick);
|
||||
|
||||
if(!prefs.contains("automaticUpdateCheck") | force)
|
||||
editor.putBoolean("automaticUpdateCheck", default_automaticUpdateCheck);
|
||||
|
||||
if(!prefs.contains("displayNewsOnMainScreen") | force)
|
||||
editor.putBoolean("displayNewsOnMainScreen", default_displayNewsOnMainScreen);
|
||||
|
||||
@@ -447,6 +464,9 @@ public class Settings implements SharedPreferences
|
||||
if(!prefs.contains("lastNewsPolltime") | force)
|
||||
editor.putLong("lastNewsPolltime", default_lastNewsPolltime);
|
||||
|
||||
if(!prefs.contains("lastUpdateCheck") | force)
|
||||
editor.putLong("lastUpdateCheck", default_lastUpdateCheck);
|
||||
|
||||
if(!prefs.contains("whatHasBeenDone") | force)
|
||||
editor.putString("whatHasBeenDone", "");
|
||||
|
||||
@@ -510,7 +530,9 @@ public class Settings implements SharedPreferences
|
||||
editor.putString("activityDetectionRequiredProbability", String.valueOf(activityDetectionRequiredProbability));
|
||||
editor.putBoolean("privacyLocationing", privacyLocationing);
|
||||
editor.putString("startScreen", String.valueOf(startScreen));
|
||||
editor.putString("tabsPlacement", String.valueOf(tabsPlacement));
|
||||
editor.putBoolean("executeRulesAndProfilesWithSingleClick", executeRulesAndProfilesWithSingleClick);
|
||||
editor.putBoolean("automaticUpdateCheck", automaticUpdateCheck);
|
||||
editor.putBoolean("displayNewsOnMainScreen", displayNewsOnMainScreen);
|
||||
|
||||
editor.putBoolean("lockSoundChanges", lockSoundChanges);
|
||||
@@ -518,6 +540,7 @@ public class Settings implements SharedPreferences
|
||||
editor.putBoolean("noticeAndroid10WifiShown", noticeAndroid10WifiShown);
|
||||
|
||||
editor.putLong("lastNewsPolltime", lastNewsPolltime);
|
||||
editor.putLong("lastUpdateCheck", lastUpdateCheck);
|
||||
|
||||
editor.putString("whatHasBeenDone", Miscellaneous.explode(";", whatHasBeenDone));
|
||||
|
||||
@@ -559,4 +582,4 @@ public class Settings implements SharedPreferences
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -77,10 +77,17 @@ public class Trigger
|
||||
private PointOfInterest pointOfInterest = null;
|
||||
private TimeFrame timeFrame;
|
||||
|
||||
public static String triggerPhoneCallStateRinging = "ringing";
|
||||
public static String triggerPhoneCallStateStarted = "started";
|
||||
public static String triggerPhoneCallStateStopped = "stopped";
|
||||
public static String triggerPhoneCallDirectionIncoming = "incoming";
|
||||
public static String triggerPhoneCallDirectionOutgoing = "outgoing";
|
||||
public static String triggerPhoneCallDirectionAny = "any";
|
||||
public static String triggerPhoneCallNumberAny = "any";
|
||||
|
||||
private double speed; //km/h
|
||||
private long noiseLevelDb;
|
||||
private String wifiName = "";
|
||||
private String processName = null;
|
||||
private String processName = null;
|
||||
private int batteryLevel;
|
||||
private int phoneDirection = 0; // 0=any, 1=incoming, 2=outgoing
|
||||
private String phoneNumber = null;
|
||||
@@ -306,10 +313,10 @@ public class Trigger
|
||||
break;
|
||||
case wifiConnection:
|
||||
String wifiDisplayName = "";
|
||||
if(this.getWifiName().length() == 0)
|
||||
if(this.getTriggerParameter2().length() == 0)
|
||||
wifiDisplayName += Miscellaneous.getAnyContext().getResources().getString(R.string.anyWifi);
|
||||
else
|
||||
wifiDisplayName += this.getWifiName();
|
||||
wifiDisplayName += this.getTriggerParameter2();
|
||||
|
||||
if(getTriggerParameter())
|
||||
returnString.append(String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.connectedToWifi), wifiDisplayName));
|
||||
@@ -339,21 +346,45 @@ public class Trigger
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.roaming));
|
||||
break;
|
||||
case phoneCall:
|
||||
if(getPhoneDirection() == 1)
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.incomingAdjective) + " ");
|
||||
else if(getPhoneDirection() == 2)
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingAdjective) + " ");
|
||||
String[] elements = triggerParameter2.split(triggerParameter2Split);
|
||||
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.phoneCall));
|
||||
if(phoneNumber != null && !phoneNumber.equals("any"))
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.with) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.number) + " " + phoneNumber);
|
||||
|
||||
returnString.append(" ");
|
||||
|
||||
if(elements[1].equals(triggerPhoneCallDirectionAny))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.with));
|
||||
else if(elements[1].equals(triggerPhoneCallDirectionIncoming))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.from));
|
||||
else if(elements[1].equals(triggerPhoneCallDirectionOutgoing))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.to));
|
||||
|
||||
returnString.append(" ");
|
||||
|
||||
if(elements[2].equals(Trigger.triggerPhoneCallNumberAny))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.any) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.number));
|
||||
else
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.with) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.anyNumber));
|
||||
|
||||
if(getTriggerParameter())
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.started));
|
||||
else
|
||||
returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.stopped));
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.number) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.matching) + " " + elements[2]);
|
||||
|
||||
returnString.append(" ");
|
||||
|
||||
if(elements[0].equals(Trigger.triggerPhoneCallStateRinging))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.ringing));
|
||||
else if(elements[0].equals(Trigger.triggerPhoneCallStateStarted))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.started));
|
||||
else if(elements[0].equals(Trigger.triggerPhoneCallStateStopped))
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.stopped));
|
||||
|
||||
// returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.phoneCall));
|
||||
// if(phoneNumber != null && !phoneNumber.equals("any"))
|
||||
// returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.with) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.number) + " " + phoneNumber);
|
||||
// else
|
||||
// returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.with) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.anyNumber));
|
||||
//
|
||||
// if(getTriggerParameter())
|
||||
// returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.started));
|
||||
// else
|
||||
// returnString.append(" " + Miscellaneous.getAnyContext().getResources().getString(R.string.stopped));
|
||||
break;
|
||||
case nfcTag:
|
||||
// This type doesn't have an activate/deactivate equivalent
|
||||
@@ -572,15 +603,6 @@ public class Trigger
|
||||
return (String[])triggerTypesList.toArray(new String[triggerTypesList.size()]);
|
||||
}
|
||||
|
||||
public String getWifiName()
|
||||
{
|
||||
return wifiName;
|
||||
}
|
||||
|
||||
public void setWifiName(String wifiName)
|
||||
{
|
||||
this.wifiName = wifiName;
|
||||
}
|
||||
public void setBluetoothEvent(String string)
|
||||
{
|
||||
this.bluetoothEvent = string;
|
||||
|
||||
@@ -23,6 +23,8 @@ import java.security.GeneralSecurityException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
import static com.jens.automation2.Trigger.triggerParameter2Split;
|
||||
|
||||
public class XmlFileInterface
|
||||
{
|
||||
public static String settingsFileName = "Automation_settings.xml";
|
||||
@@ -91,7 +93,7 @@ public class XmlFileInterface
|
||||
{
|
||||
//start a tag called "root"
|
||||
serializer.startTag(null, "PointOfInterest");
|
||||
|
||||
|
||||
//i indent code just to have a view similar to xml-tree
|
||||
serializer.startTag(null, "name");
|
||||
serializer.text(PointOfInterest.getPointOfInterestCollection().get(i).getName());
|
||||
@@ -253,13 +255,13 @@ public class XmlFileInterface
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.noiseLevel)
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getNoiseLevelDb()));
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.wifiConnection)
|
||||
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getWifiName());
|
||||
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerParameter2());
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.process_started_stopped)
|
||||
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getProcessName());
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.batteryLevel)
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getBatteryLevel()));
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.phoneCall)
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getPhoneDirection()) + "," + String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getPhoneNumber()));
|
||||
// else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.phoneCall)
|
||||
// serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getPhoneDirection()) + "," + String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getPhoneNumber()));
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.nfcTag)
|
||||
serializer.text(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getNfcTagId());
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.activityDetection)
|
||||
@@ -273,6 +275,8 @@ public class XmlFileInterface
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getHeadphoneType()));
|
||||
else if(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerType() == Trigger_Enum.notification)
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerParameter2()));
|
||||
else
|
||||
serializer.text(String.valueOf(Rule.getRuleCollection().get(i).getTriggerSet().get(j).getTriggerParameter2()));
|
||||
serializer.endTag(null, "TriggerParameter2");
|
||||
serializer.endTag(null, "Trigger");
|
||||
}
|
||||
@@ -861,45 +865,11 @@ public class XmlFileInterface
|
||||
if (name.equals("TriggerEvent"))
|
||||
{
|
||||
String triggerEventString = readTag(parser, "TriggerEvent");
|
||||
// if(triggerEventString.equals("pointOfInterest"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.pointOfInterest);
|
||||
// else if(triggerEventString.equals("timeFrame"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.timeFrame);
|
||||
// else if(triggerEventString.equals("charging"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.charging);
|
||||
// else if(triggerEventString.equals("usb_host_connection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.usb_host_connection);
|
||||
// else if(triggerEventString.equals("batteryLevel"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.batteryLevel);
|
||||
// else if(triggerEventString.equals("speed"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.speed);
|
||||
// else if(triggerEventString.equals("noiseLevel"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.noiseLevel);
|
||||
// else if(triggerEventString.equals("wifiConnection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.wifiConnection);
|
||||
// else
|
||||
if(triggerEventString.equals("process_started_stopped") | triggerEventString.equals("process_running"))
|
||||
|
||||
if(triggerEventString.equals("process_started_stopped") | triggerEventString.equals("process_running"))
|
||||
newTrigger.setTriggerType(Trigger_Enum.process_started_stopped);
|
||||
// else if(triggerEventString.equals("airplaneMode"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.airplaneMode);
|
||||
// else if(triggerEventString.equals("roaming"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.roaming);
|
||||
// else if(triggerEventString.equals("phoneCall"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.phoneCall);
|
||||
// else if(triggerEventString.equals("nfcTag"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.nfcTag);
|
||||
// else if(triggerEventString.equals("notification"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.notification);
|
||||
// else if(triggerEventString.equals("activityDetection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.activityDetection);
|
||||
// else if(triggerEventString.equals("bluetoothConnection"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.bluetoothConnection);
|
||||
// else if(triggerEventString.equals("headsetPlugged"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.headsetPlugged);
|
||||
// else if(triggerEventString.equals("notification"))
|
||||
// newTrigger.setTriggerType(Trigger_Enum.notification);
|
||||
else
|
||||
newTrigger.setTriggerType(Trigger_Enum.valueOf(triggerEventString));
|
||||
newTrigger.setTriggerType(Trigger_Enum.valueOf(triggerEventString));
|
||||
}
|
||||
else if (name.equals("TriggerParameter1"))
|
||||
{
|
||||
@@ -922,42 +892,91 @@ public class XmlFileInterface
|
||||
Miscellaneous.logEvent("e", "XmlFileInterface", Log.getStackTraceString(e), 2);
|
||||
Toast.makeText(context, "Error while writing file: " + Log.getStackTraceString(e), Toast.LENGTH_LONG).show();
|
||||
}
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.timeFrame)
|
||||
{
|
||||
newTrigger.setTimeFrame(new TimeFrame(triggerParameter2));
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.batteryLevel)
|
||||
{
|
||||
newTrigger.setBatteryLevel(Integer.parseInt(triggerParameter2));
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.speed)
|
||||
{
|
||||
newTrigger.setSpeed(Double.parseDouble(triggerParameter2));
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.noiseLevel)
|
||||
{
|
||||
newTrigger.setNoiseLevelDb(Long.parseLong(triggerParameter2));
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.wifiConnection)
|
||||
{
|
||||
newTrigger.setWifiName(triggerParameter2);
|
||||
// newTrigger.setWifiName(triggerParameter2);
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.process_started_stopped)
|
||||
{
|
||||
newTrigger.setProcessName(triggerParameter2);
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.phoneCall)
|
||||
{
|
||||
// 0/1/2,number
|
||||
int direction = Integer.parseInt(triggerParameter2.substring(0, 1));
|
||||
String number = triggerParameter2.substring(2);
|
||||
newTrigger.setPhoneDirection(direction);
|
||||
newTrigger.setPhoneNumber(number);
|
||||
String[] elements = triggerParameter2.split(",");
|
||||
if(elements.length == 2) //old format
|
||||
{
|
||||
// 0/1/2,number
|
||||
int direction = Integer.parseInt(elements[0]);
|
||||
|
||||
String number = elements[1];
|
||||
newTrigger.setPhoneDirection(direction);
|
||||
newTrigger.setPhoneNumber(number);
|
||||
|
||||
String tp2String = "";
|
||||
|
||||
if(newTrigger.getTriggerParameter())
|
||||
tp2String+= Trigger.triggerPhoneCallStateStarted;
|
||||
else
|
||||
tp2String+= Trigger.triggerPhoneCallStateStopped;
|
||||
|
||||
tp2String += triggerParameter2Split;
|
||||
|
||||
switch(direction)
|
||||
{
|
||||
case 0:
|
||||
tp2String += Trigger.triggerPhoneCallDirectionAny;
|
||||
break;
|
||||
case 1:
|
||||
tp2String += Trigger.triggerPhoneCallDirectionIncoming;
|
||||
break;
|
||||
case 2:
|
||||
tp2String += Trigger.triggerPhoneCallDirectionOutgoing;
|
||||
break;
|
||||
}
|
||||
|
||||
tp2String += triggerParameter2Split;
|
||||
|
||||
tp2String += number;
|
||||
|
||||
newTrigger.setTriggerParameter2(tp2String);
|
||||
}
|
||||
/*else // new format
|
||||
{
|
||||
//tp1 is now irrelevant
|
||||
elements = triggerParameter2.split(Trigger.triggerParameter2Split);
|
||||
// state/direction/number
|
||||
}*/
|
||||
else
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.nfcTag)
|
||||
{
|
||||
newTrigger.setNfcTagId(triggerParameter2);
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.activityDetection)
|
||||
{
|
||||
@@ -969,6 +988,7 @@ public class XmlFileInterface
|
||||
{
|
||||
newTrigger.setActivityDetectionType(0);
|
||||
}
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.bluetoothConnection)
|
||||
{
|
||||
@@ -978,6 +998,7 @@ public class XmlFileInterface
|
||||
newTrigger.setBluetoothEvent(substrings[0]);
|
||||
newTrigger.setBluetoothDeviceAddress(substrings[1]);
|
||||
}
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else if(newTrigger.getTriggerType() == Trigger_Enum.headsetPlugged)
|
||||
{
|
||||
@@ -989,9 +1010,10 @@ public class XmlFileInterface
|
||||
{
|
||||
newTrigger.setHeadphoneType(-1);
|
||||
}
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
else
|
||||
newTrigger.setTriggerParameter2(triggerParameter2);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -1079,17 +1101,6 @@ public class XmlFileInterface
|
||||
{
|
||||
String actionNameString = readTag(parser, "ActionName");
|
||||
|
||||
// if(actionNameString.equals("setWifi"))
|
||||
// newAction.setAction(Action_Enum.setWifi);
|
||||
// else if(actionNameString.equals("setBluetooth"))
|
||||
// newAction.setAction(Action_Enum.setBluetooth);
|
||||
// else if(actionNameString.equals("setUsbTethering"))
|
||||
// newAction.setAction(Action_Enum.setUsbTethering);
|
||||
// else if(actionNameString.equals("setWifiTethering"))
|
||||
// newAction.setAction(Action_Enum.setWifiTethering);
|
||||
// else if(actionNameString.equals("setDisplayRotation"))
|
||||
// newAction.setAction(Action_Enum.setDisplayRotation);
|
||||
|
||||
// *** deprecated
|
||||
//else
|
||||
if(actionNameString.equals("turnWifiOn"))
|
||||
@@ -1113,29 +1124,7 @@ public class XmlFileInterface
|
||||
else if(actionNameString.equals("disableScreenRotation"))
|
||||
newAction.setAction(Action_Enum.disableScreenRotation);
|
||||
// *** deprecated
|
||||
|
||||
// else if(actionNameString.equals("triggerUrl"))
|
||||
// newAction.setAction(Action_Enum.triggerUrl);
|
||||
// else if(actionNameString.equals("changeSoundProfile"))
|
||||
// newAction.setAction(Action_Enum.changeSoundProfile);
|
||||
// else if(actionNameString.equals("startOtherActivity"))
|
||||
// newAction.setAction(Action_Enum.startOtherActivity);
|
||||
// else if(actionNameString.equals("waitBeforeNextAction"))
|
||||
// newAction.setAction(Action_Enum.waitBeforeNextAction);
|
||||
// else if(actionNameString.equals("wakeupDevice"))
|
||||
// newAction.setAction(Action_Enum.wakeupDevice);
|
||||
// else if(actionNameString.equals("setAirplaneMode"))
|
||||
// newAction.setAction(Action_Enum.setAirplaneMode);
|
||||
// else if(actionNameString.equals("setDataConnection"))
|
||||
// newAction.setAction(Action_Enum.setDataConnection);
|
||||
// else if(actionNameString.equals("speakText"))
|
||||
// newAction.setAction(Action_Enum.speakText);
|
||||
// else if(actionNameString.equals("sendTextMessage"))
|
||||
// newAction.setAction(Action_Enum.sendTextMessage);
|
||||
// else if(actionNameString.equals("playMusic"))
|
||||
// newAction.setAction(Action_Enum.playMusic);
|
||||
// else if(actionNameString.equals("setScreenBrightness"))
|
||||
// newAction.setAction(Action_Enum.setScreenBrightness);
|
||||
|
||||
else
|
||||
newAction.setAction(Action_Enum.valueOf(actionNameString));
|
||||
}
|
||||
@@ -1223,8 +1212,43 @@ public class XmlFileInterface
|
||||
{
|
||||
newAction.setParameter2(tag);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
androidx.security.crypto.MasterKey.Builder
|
||||
|
||||
MasterKey mainKey = new MasterKey.Builder(context)
|
||||
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
|
||||
.build();
|
||||
*/
|
||||
}
|
||||
}
|
||||
else if(newAction.getAction().equals(Action_Enum.startOtherActivity)) // separator has been changed, convert in old files
|
||||
{
|
||||
String newTag;
|
||||
|
||||
if(tag.contains(Action.intentPairSeperator)) // already has new format
|
||||
newTag = tag;
|
||||
else
|
||||
newTag = tag.replace("/", Action.intentPairSeperator);
|
||||
|
||||
String[] newTagPieces = newTag.split(";");
|
||||
|
||||
if(newTagPieces.length < 2 || (!newTagPieces[0].contains(Actions.dummyPackageString) && newTagPieces[1].contains(Action.intentPairSeperator)))
|
||||
{
|
||||
newTag = Actions.dummyPackageString + ";" + newTag;
|
||||
newTagPieces = newTag.split(";");
|
||||
}
|
||||
|
||||
if(newTagPieces.length < 3)
|
||||
newTag += ";" + ActivityManageActionStartActivity.startByActivityString;
|
||||
else if(newTagPieces.length >= 3)
|
||||
{
|
||||
if(newTagPieces[2].contains(Action.intentPairSeperator))
|
||||
newTag = newTagPieces[0] + ";" + newTagPieces[1] + ";" + ActivityManageActionStartActivity.startByActivityString + ";" + newTagPieces[2];
|
||||
}
|
||||
|
||||
newAction.setParameter2(newTag);
|
||||
}
|
||||
else
|
||||
newAction.setParameter2(tag);
|
||||
}
|
||||
|
||||
+19
@@ -0,0 +1,19 @@
|
||||
package com.jens.automation2.actions.wifi_router;
|
||||
|
||||
/*
|
||||
Class taken from here:
|
||||
https://github.com/aegis1980/WifiHotSpot
|
||||
*/
|
||||
|
||||
public abstract class MyOnStartTetheringCallback
|
||||
{
|
||||
/**
|
||||
* Called when tethering has been successfully started.
|
||||
*/
|
||||
public abstract void onTetheringStarted();
|
||||
|
||||
/**
|
||||
* Called when starting tethering failed.
|
||||
*/
|
||||
public abstract void onTetheringFailed();
|
||||
}
|
||||
@@ -0,0 +1,205 @@
|
||||
package com.jens.automation2.actions.wifi_router;
|
||||
|
||||
/*
|
||||
Class taken from here:
|
||||
https://github.com/aegis1980/WifiHotSpot
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.wifi.WifiConfiguration;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.Handler;
|
||||
import android.util.Log;
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.android.dx.stock.ProxyBuilder;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
|
||||
import java.io.File;
|
||||
import java.lang.reflect.InvocationHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
* Created by jonro on 19/03/2018.
|
||||
*/
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||
public class MyOreoWifiManager
|
||||
{
|
||||
private static final String TAG = MyOreoWifiManager.class.getSimpleName();
|
||||
|
||||
private Context mContext;
|
||||
private WifiManager mWifiManager;
|
||||
private ConnectivityManager mConnectivityManager;
|
||||
|
||||
public MyOreoWifiManager(Context c)
|
||||
{
|
||||
mContext = c;
|
||||
mWifiManager = (WifiManager) mContext.getSystemService(Context.WIFI_SERVICE);
|
||||
mConnectivityManager = (ConnectivityManager) mContext.getSystemService(ConnectivityManager.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* This sets the Wifi SSID and password
|
||||
* Call this before {@code startTethering} if app is a system/privileged app
|
||||
* Requires: android.permission.TETHER_PRIVILEGED which is only granted to system apps
|
||||
*/
|
||||
public void configureHotspot(String name, String password)
|
||||
{
|
||||
WifiConfiguration apConfig = new WifiConfiguration();
|
||||
apConfig.SSID = name;
|
||||
apConfig.preSharedKey = password;
|
||||
apConfig.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
|
||||
try
|
||||
{
|
||||
Method setConfigMethod = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
|
||||
boolean status = (boolean) setConfigMethod.invoke(mWifiManager, apConfig);
|
||||
Miscellaneous.logEvent("i", "configureHotspot()", "setWifiApConfiguration - success? " + status, 2);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "configureHotspot()", "Error in configureHotspot: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks where tethering is on.
|
||||
* This is determined by the getTetheredIfaces() method,
|
||||
* that will return an empty array if not devices are tethered
|
||||
*
|
||||
* @return true if a tethered device is found, false if not found
|
||||
*/
|
||||
public boolean isTetherActive()
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method = mConnectivityManager.getClass().getDeclaredMethod("getTetheredIfaces");
|
||||
if (method == null)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "getTetheredIfaces()", "getTetheredIfaces is null", 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
String res[] = (String []) method.invoke(mConnectivityManager, null);
|
||||
Miscellaneous.logEvent("i", "isTetherActive()", "getTetheredIfaces invoked", 5);
|
||||
Miscellaneous.logEvent("i", "isTetherActive()", Arrays.toString(res), 4);
|
||||
|
||||
if (res.length > 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "isTetherActive()", "Error in getTetheredIfaces: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* This enables tethering using the ssid/password defined in Settings App>Hotspot & tethering
|
||||
* Does not require app to have system/privileged access
|
||||
* Credit: Vishal Sharma - https://stackoverflow.com/a/52219887
|
||||
*/
|
||||
public boolean startTethering(final MyOnStartTetheringCallback callback)
|
||||
{
|
||||
// On Pie if we try to start tethering while it is already on, it will
|
||||
// be disabled. This is needed when startTethering() is called programmatically.
|
||||
if (isTetherActive())
|
||||
{
|
||||
Miscellaneous.logEvent("i", "startTethering()", "Tether already active, returning", 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
File outputDir = mContext.getCodeCacheDir();
|
||||
Object proxy;
|
||||
try
|
||||
{
|
||||
proxy = ProxyBuilder.forClass(OnStartTetheringCallbackClass())
|
||||
.dexCache(outputDir).handler(new InvocationHandler()
|
||||
{
|
||||
@Override
|
||||
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
|
||||
{
|
||||
switch (method.getName())
|
||||
{
|
||||
case "onTetheringStarted":
|
||||
callback.onTetheringStarted();
|
||||
break;
|
||||
case "onTetheringFailed":
|
||||
callback.onTetheringFailed();
|
||||
break;
|
||||
default:
|
||||
ProxyBuilder.callSuper(proxy, method, args);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}).build();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "startTethering()", "Error in enableTethering ProxyBuilder", 2);
|
||||
return false;
|
||||
}
|
||||
|
||||
Method method = null;
|
||||
try
|
||||
{
|
||||
method = mConnectivityManager.getClass().getDeclaredMethod("startTethering", int.class, boolean.class, OnStartTetheringCallbackClass(), Handler.class);
|
||||
if (method == null)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "startTethering()", "startTetheringMethod is null", 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE, false, proxy, null);
|
||||
Miscellaneous.logEvent("i", "startTethering()", "startTethering invoked", 5);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "startTethering()", "Error in enableTethering: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void stopTethering()
|
||||
{
|
||||
try
|
||||
{
|
||||
Method method = mConnectivityManager.getClass().getDeclaredMethod("stopTethering", int.class);
|
||||
if (method == null)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "stopTethering", "stopTetheringMethod is null", 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
method.invoke(mConnectivityManager, ConnectivityManager.TYPE_MOBILE);
|
||||
Miscellaneous.logEvent("i", "stopTethering", "stopTethering invoked", 5);
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "stopTethering", "stopTethering error: " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
|
||||
private Class OnStartTetheringCallbackClass()
|
||||
{
|
||||
try
|
||||
{
|
||||
return Class.forName("android.net.ConnectivityManager$OnStartTetheringCallback");
|
||||
}
|
||||
catch (ClassNotFoundException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "OnStartTetheringCallbackClass()", "OnStartTetheringCallbackClass error: " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -144,8 +144,33 @@ public class LocationProvider
|
||||
}
|
||||
else
|
||||
{
|
||||
speedCalculation:
|
||||
if (locationList.size() >= 2)
|
||||
{
|
||||
while (locationList.size() > 2)
|
||||
{
|
||||
// Remove all entries except for the last 2
|
||||
Miscellaneous.logEvent("i", "Speed", "About to delete oldest position record until only 2 left. Currently have " + String.valueOf(locationList.size()) + " records.", 4);
|
||||
locationList.remove(0);
|
||||
}
|
||||
|
||||
/*
|
||||
The two most recent locations in the list must have a usable accuracy.
|
||||
*/
|
||||
for(int i = 0; i < 2; i++)
|
||||
{
|
||||
if
|
||||
(
|
||||
(locationList.get(i).getProvider().equals(LocationManager.GPS_PROVIDER) && locationList.get(i).getAccuracy() > Settings.satisfactoryAccuracyGps)
|
||||
||
|
||||
(locationList.get(i).getProvider().equals(LocationManager.NETWORK_PROVIDER) && locationList.get(i).getAccuracy() > Settings.satisfactoryAccuracyNetwork)
|
||||
)
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Speed", "Not using 2 most recent locations for speed calculation because at least one does not have a satisfactory accuracy: " + locationList.get(i).toString(), 4);
|
||||
break speedCalculation;
|
||||
}
|
||||
}
|
||||
|
||||
Miscellaneous.logEvent("i", "Speed", "Trying to calculate speed based on the last locations.", 4);
|
||||
|
||||
double currentSpeed;
|
||||
@@ -184,14 +209,6 @@ public class LocationProvider
|
||||
}
|
||||
else
|
||||
Miscellaneous.logEvent("i", "Speed", "Last two locations are too far apart in terms of time. Cannot use them for speed calculation.", 4);
|
||||
|
||||
|
||||
while (locationList.size() > 2)
|
||||
{
|
||||
// Remove all entries except for the last 2
|
||||
Miscellaneous.logEvent("i", "Speed", "About to delete oldest position record until only 2 left. Currently have " + String.valueOf(locationList.size()) + " records.", 4);
|
||||
locationList.remove(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -489,18 +506,10 @@ public class LocationProvider
|
||||
{
|
||||
// time is up, no cell location updates since x minutes, start accelerometer
|
||||
String text = "Timer triggered. Based on the last location and speed we may be at a POI. Forcing location update in case CellLocationChangedReceiver didn\'t fire.";
|
||||
// Miscellaneous.logEvent("i", "AccelerometerHandler", text, 5);
|
||||
// CellLocationChangedReceiver.stopCellLocationChangedReceiver();
|
||||
// startAccelerometerReceiver();
|
||||
|
||||
Location currentLocation = CellLocationChangedReceiver.getInstance().getLocation("coarse");
|
||||
AutomationService.getInstance().getLocationProvider().setCurrentLocation(currentLocation, false);
|
||||
}
|
||||
/*else if(msg.what == 0)
|
||||
{
|
||||
String text = "Abort command received, deactivating SpeedReceiver";
|
||||
Miscellaneous.logEvent("i", "SpeedHandler", text, 4);
|
||||
stopAccelerometerReceiver();
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import android.net.NetworkInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.util.Log;
|
||||
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
import com.jens.automation2.PointOfInterest;
|
||||
import com.jens.automation2.R;
|
||||
@@ -28,9 +29,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
protected static WifiBroadcastReceiver wifiBrInstance;
|
||||
protected static IntentFilter wifiListenerIntentFilter;
|
||||
protected static boolean wifiListenerActive=false;
|
||||
|
||||
|
||||
|
||||
|
||||
public static String getLastWifiSsid()
|
||||
{
|
||||
return lastWifiSsid;
|
||||
@@ -103,7 +102,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
Miscellaneous.logEvent("i", "WifiReceiver", context.getResources().getString(R.string.poiHasNoWifiNotStoppingCellLocationListener), 2);
|
||||
}
|
||||
|
||||
findRules(parentLocationProvider);
|
||||
findRules(AutomationService.getInstance());
|
||||
}
|
||||
else if(myWifi.isConnectedOrConnecting()) // first time connect from wifi-listener-perspective
|
||||
{
|
||||
@@ -115,7 +114,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
String ssid = myWifiManager.getConnectionInfo().getSSID();
|
||||
setLastWifiSsid(ssid);
|
||||
lastConnectedState = true;
|
||||
findRules(parentLocationProvider);
|
||||
findRules(AutomationService.getInstance());
|
||||
}
|
||||
else if(!myWifi.isConnectedOrConnecting()) // really disconnected? because sometimes also fires on connect
|
||||
{
|
||||
@@ -128,7 +127,7 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
mayCellLocationChangedReceiverBeActivatedFromWifiPointOfWifi = true;
|
||||
CellLocationChangedReceiver.startCellLocationChangedReceiver();
|
||||
lastConnectedState = false;
|
||||
findRules(parentLocationProvider);
|
||||
findRules(AutomationService.getInstance());
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@@ -143,13 +142,13 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
|
||||
}
|
||||
}
|
||||
|
||||
public static void findRules(LocationProvider parentLocationProvider)
|
||||
public static void findRules(AutomationService automationServiceInstance)
|
||||
{
|
||||
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByWifiConnection();
|
||||
for(Rule oneRule : ruleCandidates)
|
||||
{
|
||||
if(oneRule.applies(parentLocationProvider.parentService))
|
||||
oneRule.activate(parentLocationProvider.parentService, false);
|
||||
if(oneRule.applies(automationServiceInstance))
|
||||
oneRule.activate(automationServiceInstance, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -161,7 +161,7 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
|
||||
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
|
||||
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
|
||||
WifiBroadcastReceiver.setLastWifiSsid(wifiInfo.getSSID());
|
||||
WifiBroadcastReceiver.findRules(automationServiceRef.getLocationProvider());
|
||||
| ||||