Compare commits

..

26 Commits

Author SHA1 Message Date
666129de16 New release 2021-06-02 22:29:07 +02:00
becdbd6546 Hunting crash in Fdroid version 2021-06-02 17:12:33 +02:00
d292988737 Hunting crash in Fdroid version 2021-06-01 20:07:15 +02:00
21ee06e9b1 Wifi tethering without root above Oreo works again. 2021-05-30 20:03:30 +02:00
f22e4854ee Merge branch 'WifiRouter' into development
# Conflicts:
#	app/src/main/res/values-es/strings.xml
2021-05-30 12:28:59 +02:00
7182698b8a Wifi tethering without root above Oreo works again. 2021-05-30 12:27:27 +02:00
7fd8d1cfd0 Translation 2021-05-26 19:55:21 +02:00
943928089b Translation 2021-05-22 23:12:40 +02:00
f70e45701f Wifirouter 2021-05-22 02:51:31 +02:00
9b33f13f66 Italian translation updated 2021-05-21 19:52:36 +02:00
2f3a33b1b8 Translation 2021-05-20 23:11:16 +02:00
6c8ca59e3f Spanish translation 2021-05-19 21:06:15 +02:00
5ffb36a87f Added read_phone_state for action setDataConnection 2021-05-18 22:30:01 +02:00
1560fd3343 SuperSu related changes. 2021-05-18 20:02:45 +02:00
a0ff8c80f0 Spanish translation 2021-05-16 22:51:03 +02:00
1ea3bdaea3 Permissions constants used. 2021-05-16 19:57:05 +02:00
f325b30917 Permissions constants used. 2021-05-16 19:51:22 +02:00
8ce2a09b3b Wifi trigger mgmt change 2021-05-16 14:27:54 +02:00
4a18a6ed19 Wifi trigger mgmt change 2021-05-16 02:32:31 +02:00
9a8519d3e3 Phone Listener changed. 2021-05-15 19:55:48 +02:00
0a0399c2b0 Phone Listener changed. 2021-05-15 14:22:43 +02:00
3844079781 Phone Listener changed. 2021-05-15 02:27:59 +02:00
191ad904a3 Phone Listener changed. 2021-05-14 20:07:46 +02:00
e988cedf7c Phone Listener changed. 2021-05-14 13:00:25 +02:00
9a7f66fa22 PhoneCallTrigger 2021-05-13 23:50:14 +02:00
c926c85dd0 Phone Listener changed. 2021-05-13 18:37:34 +02:00
78 changed files with 6395 additions and 2443 deletions

View File

@ -11,8 +11,8 @@ android {
compileSdkVersion 29
buildToolsVersion '29.0.2'
useLibrary 'org.apache.http.legacy'
versionCode 104
versionName "1.6.33"
versionCode 105
versionName "1.6.34"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
@ -70,6 +70,9 @@ dependencies {
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
apkFlavorImplementation 'com.google.android.gms:play-services-location:17.1.0'
implementation 'com.linkedin.dexmaker:dexmaker:2.25.0'
implementation 'androidx.appcompat:appcompat:1.2.0'
implementation 'com.google.android.material:material:1.3.0'
testImplementation 'junit:junit:4.+'

View File

@ -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" />
@ -142,7 +143,7 @@
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityTriggerPhoneCall" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityHelp" />
<activity
@ -188,9 +189,10 @@
<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"
@ -202,6 +204,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"
@ -210,13 +219,6 @@
<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"/>

View File

@ -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;
@ -220,7 +221,7 @@ public class Rule implements Comparable<Rule>
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 +416,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 +549,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 +602,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 +639,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))
{
@ -916,7 +936,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 +1089,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,7 +1360,7 @@ 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>();
@ -1351,7 +1371,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

View File

@ -140,7 +140,7 @@
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityTriggerPhoneCall" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityHelp" />
<activity
@ -185,16 +185,9 @@
<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>
<!-- 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" />
<service
@ -207,6 +200,12 @@
</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
android:name=".FileShareProvider"
android:authorities="com.jens.automation2"

View File

@ -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;
@ -217,7 +218,7 @@ public class Rule implements Comparable<Rule>
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 +413,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 +546,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 +599,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 +636,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 +792,7 @@ public class Rule implements Comparable<Rule>
}
foundMatch = true;
break;
}
}
@ -883,7 +904,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)
@ -1036,7 +1057,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,7 +1328,7 @@ 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>();
@ -1318,7 +1339,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

View File

@ -134,7 +134,7 @@
<activity android:name=".ActivityManageActionPlaySound" />
<activity android:name=".ActivityManageTriggerTimeFrame" />
<activity android:name=".ActivityMaintenance" />
<activity android:name=".ActivityTriggerPhoneCall" />
<activity android:name=".ActivityManageTriggerPhoneCall" />
<activity android:name=".ActivityManageActionBrightnessSetting" />
<activity android:name=".ActivityHelp" />
<activity
@ -180,9 +180,10 @@
<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"
@ -194,6 +195,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"
@ -202,13 +210,6 @@
<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"/>

View File

@ -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;
@ -219,7 +220,7 @@ public class Rule implements Comparable<Rule>
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 +415,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 +548,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 +601,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 +638,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))
{
@ -915,7 +935,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 +1088,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,7 +1359,7 @@ 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>();
@ -1350,7 +1370,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

View File

@ -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;
@ -460,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);
}
}

View File

@ -1,5 +1,6 @@
package com.jens.automation2;
import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.PendingIntent;
@ -20,9 +21,12 @@ import android.telephony.SmsManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.view.View;
import android.view.WindowManager;
import android.widget.Toast;
import com.jens.automation2.actions.wifi_router.MyOnStartTetheringCallback;
import com.jens.automation2.actions.wifi_router.MyOreoWifiManager;
import com.jens.automation2.location.WifiBroadcastReceiver;
import com.jens.automation2.receivers.ConnectivityReceiver;
@ -51,6 +55,7 @@ public class Actions
{
public static AutomationService autoMationServerRef;
public static Context context;
public static Context rootetcontext;
private static Intent playMusicIntent;
private static boolean suAvailable = false;
private static String suVersion = null;
@ -67,24 +72,24 @@ public class Actions
{
Miscellaneous.logEvent("i", "Wifi", "Changing Wifi to " + String.valueOf(desiredState), 4);
if(desiredState && Settings.useWifiForPositioning)
if (desiredState && Settings.useWifiForPositioning)
WifiBroadcastReceiver.startWifiReceiver(autoMationServerRef.getLocationProvider());
WifiManager myWifi = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiManager myWifi = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
// toggle
if(toggleActionIfPossible)
if (toggleActionIfPossible)
{
Toast.makeText(context, context.getResources().getString(R.string.toggling) + " " + context.getResources().getString(R.string.wifi), Toast.LENGTH_LONG).show();
desiredState = !myWifi.isWifiEnabled();
}
// Only perform action if necessary
if((!myWifi.isWifiEnabled() && desiredState) | (myWifi.isWifiEnabled() && !desiredState))
if ((!myWifi.isWifiEnabled() && desiredState) | (myWifi.isWifiEnabled() && !desiredState))
{
String wifiString = "";
if(desiredState)
if (desiredState)
{
wifiString = context.getResources().getString(R.string.activating) + " " + context.getResources().getString(R.string.wifi);
}
@ -96,7 +101,7 @@ public class Actions
Toast.makeText(context, wifiString, Toast.LENGTH_LONG).show();
boolean returnValue = myWifi.setWifiEnabled(desiredState);
if(!returnValue)
if (!returnValue)
Miscellaneous.logEvent("i", "Wifi", "Error changing Wifi to " + String.valueOf(desiredState), 2);
else
Miscellaneous.logEvent("i", "Wifi", "Wifi changed to " + String.valueOf(desiredState), 2);
@ -112,19 +117,19 @@ public class Actions
Miscellaneous.logEvent("i", "ScreenRotation", "Changing ScreenRotation to " + String.valueOf(desiredState), 4);
try
{
if(toggleActionIfPossible)
if (toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.toggling), 2);
boolean currentStatus = android.provider.Settings.System.getInt(myContext.getContentResolver(),android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 0;
if(currentStatus)
boolean currentStatus = android.provider.Settings.System.getInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 0;
if (currentStatus)
desiredState = !currentStatus;
}
if(desiredState)
if (desiredState)
{
if(android.provider.Settings.System.getInt(myContext.getContentResolver(),android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 0)
if (android.provider.Settings.System.getInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 0)
{
android.provider.Settings.System.putInt(myContext.getContentResolver(),android.provider.Settings.System.ACCELEROMETER_ROTATION, 1);
android.provider.Settings.System.putInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 1);
Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.screenRotationEnabled), 2);
}
else
@ -132,16 +137,16 @@ public class Actions
}
else
{
if(android.provider.Settings.System.getInt(myContext.getContentResolver(),android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 1)
if (android.provider.Settings.System.getInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0) == 1)
{
android.provider.Settings.System.putInt(myContext.getContentResolver(),android.provider.Settings.System.ACCELEROMETER_ROTATION, 0);
android.provider.Settings.System.putInt(myContext.getContentResolver(), android.provider.Settings.System.ACCELEROMETER_ROTATION, 0);
Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.screenRotationDisabled), 2);
}
else
Miscellaneous.logEvent("i", "setScreenRotation", myContext.getResources().getString(R.string.screenRotationAlreadyDisabled), 2);
}
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("e", "setScreenRotation", myContext.getResources().getString(R.string.errorChangingScreenRotation) + ": " + Log.getStackTraceString(e), 2);
}
@ -149,25 +154,25 @@ public class Actions
private static boolean isWifiApEnabled(Context context)
{
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
boolean currentlyEnabled = false;
Method[] methods = wifiManager.getClass().getDeclaredMethods();
for(Method method : methods)
for (Method method : methods)
{
if(method.getName().equals("isWifiApEnabled"))
if (method.getName().equals("isWifiApEnabled"))
{
try
{
Object returnObject = method.invoke(wifiManager);
currentlyEnabled = Boolean.valueOf(returnObject.toString());
if(currentlyEnabled)
if (currentlyEnabled)
Miscellaneous.logEvent("i", "isWifiApEnabled", "true", 5);
else
Miscellaneous.logEvent("i", "isWifiApEnabled", "false", 5);
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("i", "isWifiApEnabled", context.getResources().getString(R.string.errorDeterminingWifiApState) + ": " + e.getMessage(), 4);
}
@ -175,59 +180,86 @@ public class Actions
}
return currentlyEnabled;
}
public static Boolean setWifiTethering(Context context, Boolean desiredState, boolean toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "WifiTethering", "Changing WifiTethering to " + String.valueOf(desiredState), 4);
boolean state = Actions.isWifiApEnabled(context);
if(toggleActionIfPossible)
if (toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "WifiAp", context.getResources().getString(R.string.toggling), 2);
desiredState = !state;
}
if(((state && !desiredState) || (!state && desiredState)))
if (((state && !desiredState) || (!state && desiredState)))
{
WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.O)
{
WifiManager wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
Method[] methods = wifiManager.getClass().getDeclaredMethods();
for(Method method : methods)
for (Method method : methods)
{
// Miscellaneous.logEvent("i", "WifiAp", "Trying to find appropriate method... " + method.getName());
if(method.getName().equals("setWifiApEnabled"))
Miscellaneous.logEvent("i", "WifiAp", "Trying to find appropriate method... " + method.getName(), 5);
if (method.getName().equals("setWifiApEnabled"))
{
try
{
String desiredString = "";
if(desiredState)
if (desiredState)
desiredString = "activate";
else
desiredString = "deactivate";
if(!toggleActionIfPossible)
if (!toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "WifiAp", "Trying to " + desiredString + " wifi ap...", 2);
if(!method.isAccessible())
if (!method.isAccessible())
method.setAccessible(true);
method.invoke(wifiManager, null, desiredState);
}
else
{
Miscellaneous.logEvent("i", "WifiAp", "Trying to " + context.getResources().getString(R.string.toggle) + " wifi ap...", 2);
if(!method.isAccessible())
if (!method.isAccessible())
method.setAccessible(true);
method.invoke(wifiManager, null, !state);
}
Miscellaneous.logEvent("i", "WifiAp", "Wifi ap " + desiredString + "d.", 2);
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("i", "WifiAp", context.getResources().getString(R.string.errorActivatingWifiAp) + ". " + e.getMessage(), 2);
}
}
}
}
else
{
MyOnStartTetheringCallback cb = new MyOnStartTetheringCallback()
{
@Override
public void onTetheringStarted()
{
Log.i("Tether", "Läuft");
}
@Override
public void onTetheringFailed()
{
Log.i("Tether", "Doof");
}
};
MyOreoWifiManager mowm = new MyOreoWifiManager(context);
if (desiredState)
mowm.startTethering(cb);
else
mowm.stopTethering();
}
}
return true;
}
@ -244,9 +276,9 @@ public class Actions
try
{
connectivityServiceObject = context.getSystemService(Context.CONNECTIVITY_SERVICE);
connMgr = (ConnectivityManager)connectivityServiceObject;
connMgr = (ConnectivityManager) connectivityServiceObject;
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("e", "UsbTethering", context2.getResources().getString(R.string.logErrorGettingConnectionManagerService), 2);
return false;
@ -254,18 +286,18 @@ public class Actions
try
{
if((state && !desiredState) || (!state && desiredState))
if ((state && !desiredState) || (!state && desiredState))
{
try
{
Method method = connectivityServiceObject.getClass().getDeclaredMethod("getTetheredIfaces");
if(!method.isAccessible())
if (!method.isAccessible())
method.setAccessible(true);
String[] tetheredInterfaces = (String[]) method.invoke(connectivityServiceObject);
if(tetheredInterfaces.length > 0)
if (tetheredInterfaces.length > 0)
state = true;
}
catch(NoSuchMethodException e)
catch (NoSuchMethodException e)
{
// System doesn't have that method, try another way
@ -277,22 +309,22 @@ public class Actions
}
}
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("w", "UsbTethering", context2.getResources().getString(R.string.logErrorDeterminingCurrentUsbTetheringState), 3);
}
if(toggleActionIfPossible)
if (toggleActionIfPossible)
{
Miscellaneous.logEvent("w", "UsbTethering", context2.getResources().getString(R.string.toggling), 3);
desiredState = !state;
}
if((state && !desiredState) || (!state && desiredState))
if ((state && !desiredState) || (!state && desiredState))
{
String desiredString = "";
if(desiredState)
if (desiredState)
desiredString = "activate";
else
desiredString = "deactivate";
@ -301,22 +333,22 @@ public class Actions
{
Method method = null;
for(Method m : connectivityServiceObject.getClass().getDeclaredMethods())
for (Method m : connectivityServiceObject.getClass().getDeclaredMethods())
{
if(desiredState && m.getName().equals("tether"))
if (desiredState && m.getName().equals("tether"))
{
method = m;
break;
}
if(!desiredState && m.getName().equals("untether"))
if (!desiredState && m.getName().equals("untether"))
{
method = m;
break;
}
}
if(method == null)
if (method == null)
throw new NoSuchMethodException();
@ -332,13 +364,13 @@ public class Actions
Miscellaneous.logEvent("i", "UsbTethering", context2.getResources().getString(R.string.logDetectingTetherableUsbInterface), 4);
String[] available = null;
Method[] wmMethods = connMgr.getClass().getDeclaredMethods();
for(Method getMethod: wmMethods)
for (Method getMethod : wmMethods)
{
if(getMethod.getName().equals("getTetherableUsbRegexs"))
if (getMethod.getName().equals("getTetherableUsbRegexs"))
{
try
{
if(!method.isAccessible())
if (!method.isAccessible())
method.setAccessible(true);
available = (String[]) getMethod.invoke(connMgr);
// break;
@ -352,16 +384,16 @@ public class Actions
// DETECT INTERFACE NAME
if(available.length > 0)
if (available.length > 0)
{
for(String interfaceName : available)
for (String interfaceName : available)
{
Miscellaneous.logEvent("i", "UsbTethering", "Detected " + String.valueOf(available.length) + " tetherable usb interfaces.", 5);
Miscellaneous.logEvent("i", "UsbTethering", "Trying to " + desiredString + " UsbTethering on interface " + interfaceName + "...", 5);
if(!method.isAccessible())
if (!method.isAccessible())
method.setAccessible(true);
Integer returnCode = (Integer)method.invoke(connectivityServiceObject, interfaceName);
if(returnCode == 0)
Integer returnCode = (Integer) method.invoke(connectivityServiceObject, interfaceName);
if (returnCode == 0)
{
Miscellaneous.logEvent("i", "UsbTethering", "UsbTethering " + desiredString + "d.", 5);
return true;
@ -377,7 +409,7 @@ public class Actions
{
Miscellaneous.logEvent("w", "UsbTethering", "Error while trying to " + desiredString + " UsbTethering. This kind of error may indicate we are above Android 2.3: " + Log.getStackTraceString(e), 3);
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("w", "UsbTethering", "Error while trying to " + desiredString + " UsbTethering. " + Log.getStackTraceString(e), 3);
}
@ -394,14 +426,14 @@ public class Actions
BluetoothAdapter myBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// toggle
if(toggleActionIfPossible)
if (toggleActionIfPossible)
{
Miscellaneous.logEvent("e", "SetBluetooth", context.getResources().getString(R.string.toggling), 2);
desiredState = !myBluetoothAdapter.isEnabled();
}
// activate
if(!myBluetoothAdapter.isEnabled() && desiredState)
if (!myBluetoothAdapter.isEnabled() && desiredState)
{
Toast.makeText(context, context.getResources().getString(R.string.activating) + " Bluetooth.", Toast.LENGTH_LONG).show();
myBluetoothAdapter.enable();
@ -409,14 +441,14 @@ public class Actions
}
// deactivate
if(myBluetoothAdapter.isEnabled() && !desiredState)
if (myBluetoothAdapter.isEnabled() && !desiredState)
{
Toast.makeText(context, context.getResources().getString(R.string.deactivating) + " Bluetooth.", Toast.LENGTH_LONG).show();
myBluetoothAdapter.disable();
return true;
}
}
catch(NullPointerException e)
catch (NullPointerException e)
{
Miscellaneous.logEvent("e", "SetBluetooth", context.getResources().getString(R.string.failedToTriggerBluetooth), 2);
Toast.makeText(context, context.getResources().getString(R.string.bluetoothFailed), Toast.LENGTH_LONG).show();
@ -429,7 +461,7 @@ public class Actions
{
Miscellaneous.logEvent("i", context.getResources().getString(R.string.soundSettings), "Changing sound to " + String.valueOf(soundSetting), 4);
AudioManager myAudioManager = (AudioManager)context.getSystemService(Context.AUDIO_SERVICE);
AudioManager myAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
myAudioManager.setRingerMode(soundSetting);
}
@ -475,13 +507,13 @@ public class Actions
public static void playSound(boolean alwaysPlay, String soundFileLocation)
{
if(alwaysPlay || ((AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE)).getRingerMode() == AudioManager.RINGER_MODE_NORMAL)
if (alwaysPlay || ((AudioManager) Miscellaneous.getAnyContext().getSystemService(Context.AUDIO_SERVICE)).getRingerMode() == AudioManager.RINGER_MODE_NORMAL)
{
MediaPlayer mp = new MediaPlayer();
try
{
File file = new File(soundFileLocation);
if(file.exists())
if (file.exists())
{
Uri fileUri = Uri.parse(soundFileLocation);
mp.setLooping(false);
@ -581,7 +613,7 @@ public class Actions
int paramsStartIndex;
if(!startByAction)
if (!startByAction)
{
// selected by activity
@ -602,7 +634,7 @@ public class Actions
// else
externalActivityIntent.setClassName(packageName, className);
if(!Miscellaneous.doesActivityExist(externalActivityIntent, Miscellaneous.getAnyContext()))
if (!Miscellaneous.doesActivityExist(externalActivityIntent, Miscellaneous.getAnyContext()))
Miscellaneous.logEvent("w", "StartOtherApp", "Activity not found: " + className, 2);
}
else
@ -612,7 +644,7 @@ public class Actions
externalActivityIntent = new Intent();
if(!params[0].equals(dummyPackageString))
if (!params[0].equals(dummyPackageString))
externalActivityIntent.setPackage(params[0]);
externalActivityIntent.setAction(params[1]);
@ -682,7 +714,7 @@ public class Actions
}
else if (singleParam[0].equals("Uri"))
{
if(singleParam[1].equalsIgnoreCase("IntentData"))
if (singleParam[1].equalsIgnoreCase("IntentData"))
{
Miscellaneous.logEvent("i", "StartOtherApp", "Adding parameter of type " + singleParam[0] + " with value " + singleParam[2] + " as standard data parameter.", 3);
externalActivityIntent.setData(Uri.parse(singleParam[2]));
@ -702,12 +734,12 @@ public class Actions
Miscellaneous.logEvent("w", "StartOtherApp", "Unknown type of parameter " + singleParam[0] + " found. Name " + singleParam[1] + " and value " + singleParam[2], 3);
}
if(params[2].equals(ActivityManageActionStartActivity.startByActivityString))
if (params[2].equals(ActivityManageActionStartActivity.startByActivityString))
autoMationServerRef.startActivity(externalActivityIntent);
else
autoMationServerRef.sendBroadcast(externalActivityIntent);
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("e", "StartOtherApp", autoMationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + Log.getStackTraceString(e), 2);
Toast.makeText(autoMationServerRef, autoMationServerRef.getResources().getString(R.string.errorStartingOtherActivity) + ": " + e.getMessage(), Toast.LENGTH_LONG).show();
@ -731,12 +763,12 @@ public class Actions
public static void wakeupDevice(Long awakeTime)
{
String duration = "default";
if(awakeTime > 0)
if (awakeTime > 0)
duration = String.valueOf(awakeTime) + " milliseconds";
Miscellaneous.logEvent("i", "wakeupDevice", "wakeupDevice for " + String.valueOf(duration) + ".", 4);
if(awakeTime > 0)
if (awakeTime > 0)
{
/*
* This action needs to be performed in a separate thread. If it ran in the same one
@ -769,7 +801,7 @@ public class Actions
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(phoneNumber, null, message, pi, null);
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("e", Miscellaneous.getAnyContext().getString(R.string.sendTextMessage), "Error in sendTextMessage: " + Log.getStackTraceString(e), 3);
}
@ -809,8 +841,13 @@ public class Actions
@SuppressLint("NewApi")
public static boolean setAirplaneMode(boolean desiredState, boolean toggleActionIfPossible)
{
// Beginning from SDK Version 17 this may not work anymore.
// Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, value is unchanged.
/*
Beginning from SDK Version 17 this may not work anymore.
Setting airplane_mode_on has moved from android.provider.Settings.System to android.provider.Settings.Global, value is unchanged.
https://stackoverflow.com/questions/22349928/permission-denial-not-allowed-to-send-broadcast-android-intent-action-airplane
https://stackoverflow.com/questions/7066427/turn-off-airplane-mode-in-android
*/
boolean returnValue = false;
@ -818,31 +855,37 @@ public class Actions
{
boolean isEnabled = ConnectivityReceiver.isAirplaneMode(autoMationServerRef);
if(isEnabled)
if (isEnabled)
Miscellaneous.logEvent("i", "Airplane mode", "Current status is enabled.", 4);
else
Miscellaneous.logEvent("i", "Airplane mode", "Current status is disabled.", 4);
if(toggleActionIfPossible)
if (toggleActionIfPossible)
{
Miscellaneous.logEvent("i", "Airplane mode", context.getResources().getString(R.string.toggling), 4);
desiredState = !isEnabled;
}
if(isEnabled != desiredState)
if (isEnabled != desiredState)
{
int desiredValueInt = 0;
if(desiredState)
if (desiredState)
desiredValueInt = 1;
if(Build.VERSION.SDK_INT < 17)
if (Build.VERSION.SDK_INT < 17 || ActivityPermissions.havePermission(Manifest.permission.WRITE_SECURE_SETTINGS, context))
{
returnValue = android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, desiredValueInt);
//returnValue = android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, desiredValueInt);
returnValue = android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.Global.AIRPLANE_MODE_ON, desiredValueInt);
// Intent airplaneIntent = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
// airplaneIntent.putExtra("state", desiredState);
// context.sendBroadcast(airplaneIntent);
}
else
{
if(desiredState)
if (desiredState)
{
String[] commands = new String[]
{
@ -853,7 +896,6 @@ public class Actions
}
else
{
String[] commands = new String[]
{
"settings put global airplane_mode_on 0",
@ -873,7 +915,7 @@ public class Actions
else
Miscellaneous.logEvent("i", "Airplane mode", "Airplane mode is already in status " + String.valueOf(desiredState) + ". Nothing to do.", 3);
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("e", "Airplane mode", Log.getStackTraceString(e), 2);
}
@ -888,7 +930,7 @@ public class Actions
public static boolean setNetworkType(int desiredType)
{
Miscellaneous.logEvent("i", "setNetworkType", "Asked to set network type to: " + String.valueOf(desiredType), 3);
if(desiredType > 0)
if (desiredType > 0)
{
try
{
@ -896,7 +938,7 @@ public class Actions
// TelephonyManager.NETWORK_TYPE_EDGE
if(connManager.getNetworkPreference() == desiredType)
if (connManager.getNetworkPreference() == desiredType)
{
Miscellaneous.logEvent("i", "setNetworkType", "Desired networkType already set. Not doing anything.", 4);
}
@ -907,7 +949,7 @@ public class Actions
}
return true;
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("e", "setNetworkType", "Error changing network type: " + Log.getStackTraceString(e), 2);
return false;
@ -927,7 +969,7 @@ public class Actions
String textToSpeak = Miscellaneous.replaceVariablesInText(parameter2, context);
autoMationServerRef.speak(textToSpeak, true);
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("e", "Speak text", "Error in speak text: " + Log.getStackTraceString(e), 3);
}
@ -947,7 +989,7 @@ public class Actions
/*
* Fix for Samsung devices: http://stackoverflow.com/questions/12532207/open-music-player-on-galaxy-s3
*/
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 | deviceName.contains("SM-"))
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1 | deviceName.contains("SM-"))
playMusicIntent = new Intent(Intent.CATEGORY_APP_MUSIC);
else
playMusicIntent = new Intent(MediaStore.INTENT_ACTION_MUSIC_PLAYER);
@ -973,13 +1015,13 @@ public class Actions
// return false;
}
catch(ActivityNotFoundException e)
catch (ActivityNotFoundException e)
{
Toast.makeText(context, "Error: No music player found.", Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("e", "Play music", "Error in playerMusic(): No music player found. " + Log.getStackTraceString(e), 3);
return false;
}
catch(Exception e)
catch (Exception e)
{
Toast.makeText(context, "Error starting music player.", Toast.LENGTH_LONG).show();
Miscellaneous.logEvent("e", "Play music", "Error in playerMusic(): " + Log.getStackTraceString(e), 3);
@ -1039,9 +1081,12 @@ public class Actions
public static class MobileDataStuff
{
// https://stackoverflow.com/questions/31120082/latest-update-on-enabling-and-disabling-mobile-data-programmatically
/**
* Turns data on and off.
* Requires root permissions from lollipop on.
*
* @param toggleActionIfPossible
*/
public static boolean setDataConnection(boolean desiredState, boolean toggleActionIfPossible)
@ -1059,17 +1104,15 @@ public class Actions
Boolean isEnabled = isMobileDataEnabled();
if(toggleActionIfPossible)
if (toggleActionIfPossible)
{
context.getResources().getString(R.string.toggling);
desiredState = !isEnabled;
}
// if(isEnabled != desiredState)
// {
if(Build.VERSION.SDK_INT <= 20)
if (Build.VERSION.SDK_INT <= 20)
{
for(Method m : iConnectivityManagerClass.getDeclaredMethods())
for (Method m : iConnectivityManagerClass.getDeclaredMethods())
{
Miscellaneous.logEvent("i", "method", m.getName(), 5);
}
@ -1083,15 +1126,10 @@ public class Actions
{
return setDataConnectionWithRoot(desiredState);
}
// }
// else
// {
// Miscellaneous.logEvent("i", "setData", "Data already set to " + String.valueOf(desiredState) + ". Not doing anything.", 4);
// }
return true;
}
catch(Exception e)
catch (Exception e)
{
Miscellaneous.logEvent("e", "setData", "Error changing network type: " + Log.getStackTraceString(e), 2);
return false;
@ -1103,10 +1141,10 @@ public class Actions
try
{
int desiredState = 0;
if(enable)
if (enable)
desiredState = 1;
if(MobileDataStuff.setMobileNetworkFromLollipop(desiredState, autoMationServerRef))
if (MobileDataStuff.setMobileNetworkFromLollipop(desiredState, autoMationServerRef))
{
Miscellaneous.logEvent("i", "setDataConnectionWithRoot()", Miscellaneous.getAnyContext().getResources().getString(R.string.dataConWithRootSuccess), 2);
return true;
@ -1117,10 +1155,10 @@ public class Actions
return false;
}
}
catch(Exception e)
catch (Exception e)
{
String rootString;
if(Miscellaneous.isPhoneRooted())
if (Miscellaneous.isPhoneRooted())
rootString = Miscellaneous.getAnyContext().getResources().getString(R.string.phoneIsRooted);
else
rootString = Miscellaneous.getAnyContext().getResources().getString(R.string.phoneIsNotRooted);
@ -1157,7 +1195,7 @@ public class Actions
// mobile network for a subscription service.
command = "service call phone " + transactionCode + " i32 " + subscriptionId + " i32 " + desiredState;
Miscellaneous.logEvent("i", "setDataConnectionWithRoot()", "Running command: " + command.toString(), 5);
return executeCommandViaSu(new String[] { command });
return executeCommandViaSu(new String[]{command});
}
}
}
@ -1168,11 +1206,11 @@ public class Actions
{
// Execute the command via `su` to turn off mobile network.
command = "service call phone " + transactionCode + " i32 " + desiredState;
return executeCommandViaSu(new String[] { command });
return executeCommandViaSu(new String[]{command});
}
}
}
catch(Exception e)
catch (Exception e)
{
// Oops! Something went wrong, so we throw the exception here.
throw e;
@ -1186,7 +1224,7 @@ public class Actions
{
boolean isEnabled = false;
if(Build.VERSION.SDK_INT <= 20)
if (Build.VERSION.SDK_INT <= 20)
{
try
{
@ -1198,10 +1236,10 @@ public class Actions
final Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
Method getMobileDataEnabledMethod = null;
for(Method m : iConnectivityManagerClass.getDeclaredMethods())
for (Method m : iConnectivityManagerClass.getDeclaredMethods())
{
Miscellaneous.logEvent("i", "Methods", m.getName(), 5);
if(m.getName().equals("getMobileDataEnabled"))
if (m.getName().equals("getMobileDataEnabled"))
{
getMobileDataEnabledMethod = m;
break;
@ -1264,7 +1302,7 @@ public class Actions
suVersionInternal = Shell.SU.version(true);
suResult = Shell.SU.run(commands);
if(suResult != null)
if (suResult != null)
success = true;
}
}
@ -1278,12 +1316,24 @@ public class Actions
public static void setScreenBrightness(boolean autoBrightness, int brightnessValue)
{
if(autoBrightness)
if (autoBrightness)
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE, android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC);
else
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE, android.provider.Settings.System.SCREEN_BRIGHTNESS_MODE_MANUAL);
int actualBrightnessValue = (int)((float)brightnessValue / 100.0 * 255.0);
int actualBrightnessValue = (int) ((float) brightnessValue / 100.0 * 255.0);
android.provider.Settings.System.putInt(context.getContentResolver(), android.provider.Settings.System.SCREEN_BRIGHTNESS, actualBrightnessValue);
}
public boolean isAirplaneModeOn(Context context)
{
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1)
{
return android.provider.Settings.System.getInt(context.getContentResolver(), android.provider.Settings.System.AIRPLANE_MODE_ON, 0) != 0;
}
else
{
return android.provider.Settings.Global.getInt(context.getContentResolver(), android.provider.Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
}
}
}

View File

@ -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);
}

View File

@ -1,5 +1,6 @@
package com.jens.automation2;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.PendingIntent;
@ -323,9 +324,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

View File

@ -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);
@ -145,16 +146,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);
startActivityForResult(intent, requestCodeGetContact);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
if(requestCode == 1000)
if(requestCode == requestCodeGetContact)
{
if(resultCode == Activity.RESULT_OK)
{

View File

@ -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);

View File

@ -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);

View File

@ -47,7 +47,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);
@ -172,7 +172,8 @@ public class ActivityManagePoi extends Activity
double variance = locationGps.distanceTo(locationNetwork);
String text = getResources().getString(R.string.distanceBetween) + " " + String.valueOf(Math.round(variance)) + " " + getResources().getString(R.string.radiusSuggestion);
String text = String.format(getResources().getString(R.string.distanceBetween), Math.round(variance));
// 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)

View File

@ -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);

View File

@ -99,6 +99,10 @@ 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;
public static ActivityManageRule getInstance()
{
@ -256,6 +260,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;
}
@ -305,31 +322,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;
@ -552,7 +548,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 +571,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
@ -826,7 +836,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 +1143,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 +1199,6 @@ public class ActivityManageRule extends Activity
//add notification
if(resultCode == RESULT_OK)
{
//newTrigger.setNfcTagId(ActivityManageNfc.generatedId);
ruleToEdit.getTriggerSet().add(newTrigger);
newTrigger.setTriggerParameter2(
@ -1182,8 +1210,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 +1219,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)
@ -1396,12 +1439,15 @@ 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()))
{
newAction.setAction(Action_Enum.setWifiTethering);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1)
Miscellaneous.messageBox(context.getResources().getString(R.string.warning), context.getResources().getString(R.string.wifiTetheringFailForAboveNougat), context).show();
else
getActionParameter1Dialog(ActivityManageRule.this).show();
}
else if(Action.getActionTypesAsArray()[which].toString().equals(Action_Enum.setDisplayRotation.toString()))
@ -1437,13 +1483,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()))
{

View File

@ -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);

View File

@ -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);
@ -393,7 +394,5 @@ public class ActivityManageTriggerNotification extends Activity
progressDialog.dismiss();
getActionStartActivityDialog1().show();
}
}
}

View File

@ -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();
}
}
}
}
}
}

View File

@ -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);

View File

@ -0,0 +1,163 @@
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.WifiConfiguration;
import android.net.wifi.WifiManager;
import android.os.Bundle;
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);
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()
{
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();
}
@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;
}
}
}

View File

@ -1,5 +1,6 @@
package com.jens.automation2;
import android.Manifest;
import android.app.Activity;
import android.app.NotificationManager;
import android.content.ComponentName;
@ -47,16 +48,9 @@ public class ActivityPermissions extends Activity
TextView tvPermissionsExplanation, tvPermissionsExplanationSystemSettings, tvPermissionsExplanationLong;
static ActivityPermissions instance = null;
public static final String writeSystemSettingsPermissionName = "android.permission.WRITE_SETTINGS";
public static final String writeExternalStoragePermissionName = "android.permission.WRITE_EXTERNAL_STORAGE";
public static final String accessNotificationPolicyPermissionName = "android.permission.ACCESS_NOTIFICATION_POLICY";
public static final String permissionNameLocationFine = "android.permission.ACCESS_FINE_LOCATION";
public static final String permissionNameLocationCoarse = "android.permission.ACCESS_COARSE_LOCATION";
public static final String permissionNameLocationBackground = "android.permission.ACCESS_BACKGROUND_LOCATION";
public static final String permissionNameCall = "android.permission.PROCESS_OUTGOING_CALLS";
public static final String permissionNameStartService = "android.permission.FOREGROUND_SERVICE";
public static final String permissionNameReadNotifications = "android.permission.BIND_NOTIFICATION_LISTENER_SERVICE";
public static final String permissionNameWireguard = "com.wireguard.android.permission.CONTROL_TUNNELS";
public final static String permissionNameWireguard = "com.wireguard.android.permission.CONTROL_TUNNELS";
public final static String permissionNameGoogleActivityDetection = "com.google.android.gms.permission.ACTIVITY_RECOGNITION";
public final static String permissionNameSuperuser = "android.permission.ACCESS_SUPERUSER";
public static ActivityPermissions getInstance()
{
@ -168,7 +162,7 @@ public class ActivityPermissions extends Activity
/*
Filter location permission and only name it once
*/
if(s.equals(permissionNameLocationCoarse) | s.equals(permissionNameLocationFine))
if(s.equals(Manifest.permission.ACCESS_COARSE_LOCATION) | s.equals(Manifest.permission.ACCESS_FINE_LOCATION))
{
if(!locationPermissionExplained)
{
@ -213,7 +207,7 @@ public class ActivityPermissions extends Activity
for(String s : requiredPerms)
{
if (s.equalsIgnoreCase(writeSystemSettingsPermissionName))
if (s.equalsIgnoreCase(Manifest.permission.WRITE_SETTINGS))
{
if (requiredPerms.length == 1)
tvPermissionsExplanationSystemSettings.setText(getResources().getString(R.string.systemSettingsNote1));
@ -225,8 +219,16 @@ public class ActivityPermissions extends Activity
}
ActivityMainScreen.updateMainScreen();
try
{
ActivityMainRules.getInstance().updateListView();
}
catch (IllegalStateException e)
{
// Activity may not have been loaded, yet.
}
}
protected static void addToArrayListUnique(String value, ArrayList<String> list)
{
@ -241,18 +243,18 @@ public class ActivityPermissions extends Activity
for (String s : getRequiredPermissions(false))
{
if(
s.equalsIgnoreCase(permissionNameLocationBackground)
s.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
||
s.equalsIgnoreCase(permissionNameLocationFine)
s.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
||
s.equalsIgnoreCase(permissionNameLocationCoarse)
s.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
)
{
if (!Miscellaneous.googleToBlameForLocation(true))
if (!havePermission(s, context))
return true;
}
else if(s.equalsIgnoreCase("android.permission.ACTIVITY_RECOGNITION") || s.equalsIgnoreCase("com.google.android.gms.permission.ACTIVITY_RECOGNITION"))
else if(s.equalsIgnoreCase(Manifest.permission.ACTIVITY_RECOGNITION) || s.equalsIgnoreCase(permissionNameGoogleActivityDetection))
{
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
if (!havePermission(s, context))
@ -271,9 +273,9 @@ public class ActivityPermissions extends Activity
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
{
if(s.equals(writeSystemSettingsPermissionName))
if(s.equals(Manifest.permission.WRITE_SETTINGS))
return android.provider.Settings.System.canWrite(context);
else if (s.equals(accessNotificationPolicyPermissionName))
else if (s.equals(Manifest.permission.ACCESS_NOTIFICATION_POLICY))
{
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
{
@ -283,7 +285,7 @@ public class ActivityPermissions extends Activity
else
return true;
}
else if (s.equals(permissionNameReadNotifications))
else if (s.equals(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE))
{
return verifyNotificationPermission();
}
@ -316,13 +318,13 @@ public class ActivityPermissions extends Activity
// if (!havePermission(ActivityPermissions.writeExternalStoragePermissionName, workingContext))
// addToArrayListUnique(ActivityPermissions.writeExternalStoragePermissionName, requiredPermissions);
if(!havePermission(writeSystemSettingsPermissionName, workingContext))
if(!havePermission(Manifest.permission.WRITE_SETTINGS, workingContext))
{
for (Profile profile : Profile.getProfileCollection())
{
if (profile.changeIncomingCallsRingtone)
{
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
}
}
}
@ -336,17 +338,17 @@ public class ActivityPermissions extends Activity
{
if(
singlePermission.equalsIgnoreCase(permissionNameLocationBackground)
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
||
singlePermission.equalsIgnoreCase(permissionNameLocationFine)
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_FINE_LOCATION)
||
singlePermission.equalsIgnoreCase(permissionNameLocationCoarse)
singlePermission.equalsIgnoreCase(Manifest.permission.ACCESS_COARSE_LOCATION)
)
{
if (!Miscellaneous.googleToBlameForLocation(true))
addToArrayListUnique(singlePermission, requiredPermissions);
}
else if(singlePermission.equalsIgnoreCase("android.permission.ACTIVITY_RECOGNITION") || singlePermission.equalsIgnoreCase("com.google.android.gms.permission.ACTIVITY_RECOGNITION"))
else if(singlePermission.equalsIgnoreCase(Manifest.permission.ACTIVITY_RECOGNITION) || singlePermission.equalsIgnoreCase(permissionNameGoogleActivityDetection))
{
if(!BuildConfig.FLAVOR.equalsIgnoreCase("fdroidFlavor"))
addToArrayListUnique(singlePermission, requiredPermissions);
@ -404,80 +406,80 @@ public class ActivityPermissions extends Activity
switch (trigger.getTriggerType())
{
case activityDetection:
addToArrayListUnique("com.google.android.gms.permission.ACTIVITY_RECOGNITION", requiredPermissions);
addToArrayListUnique("android.permission.ACTIVITY_RECOGNITION", requiredPermissions);
addToArrayListUnique(permissionNameGoogleActivityDetection, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACTIVITY_RECOGNITION, requiredPermissions);
break;
case airplaneMode:
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case batteryLevel:
// addToArrayListUnique("android.permission.READ_PHONE_STATE", requiredPermissions);
// addToArrayListUnique("android.permission.BATTERY_STATS", requiredPermissions);
// addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
// addToArrayListUnique(Manifest.permission.BATTERY_STATS, requiredPermissions);
break;
case bluetoothConnection:
addToArrayListUnique("android.permission.BLUETOOTH_ADMIN", requiredPermissions);
addToArrayListUnique("android.permission.BLUETOOTH", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case charging:
addToArrayListUnique("android.permission.READ_PHONE_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
// addToArrayListUnique("android.permission.BATTERY_STATS", requiredPermissions);
break;
case headsetPlugged:
addToArrayListUnique("android.permission.READ_PHONE_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
break;
case nfcTag:
addToArrayListUnique("android.permission.NFC", requiredPermissions);
addToArrayListUnique(Manifest.permission.NFC, requiredPermissions);
break;
case noiseLevel:
addToArrayListUnique("android.permission.RECORD_AUDIO", requiredPermissions);
addToArrayListUnique(Manifest.permission.RECORD_AUDIO, requiredPermissions);
break;
case phoneCall:
addToArrayListUnique("android.permission.READ_PHONE_STATE", requiredPermissions);
addToArrayListUnique(permissionNameCall, requiredPermissions);
addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.PROCESS_OUTGOING_CALLS, requiredPermissions);
break;
case pointOfInterest:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
addToArrayListUnique(permissionNameLocationBackground, requiredPermissions);
addToArrayListUnique(permissionNameLocationFine, requiredPermissions);
addToArrayListUnique(permissionNameLocationCoarse, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_BACKGROUND_LOCATION, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_FINE_LOCATION, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_COARSE_LOCATION, requiredPermissions);
}
else
{
addToArrayListUnique(permissionNameLocationFine, requiredPermissions);
addToArrayListUnique(permissionNameLocationCoarse, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_FINE_LOCATION, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_COARSE_LOCATION, requiredPermissions);
}
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.INTERNET", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_WIFI_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_WIFI_STATE, requiredPermissions);
break;
case process_started_stopped:
addToArrayListUnique("android.permission.GET_TASKS", requiredPermissions);
addToArrayListUnique(Manifest.permission.GET_TASKS, requiredPermissions);
break;
case roaming:
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case speed:
addToArrayListUnique(permissionNameLocationFine, requiredPermissions);
addToArrayListUnique(permissionNameLocationCoarse, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_FINE_LOCATION, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_COARSE_LOCATION, requiredPermissions);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
addToArrayListUnique(permissionNameLocationBackground, requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.INTERNET", requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_BACKGROUND_LOCATION, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
break;
case timeFrame:
break;
case usb_host_connection:
addToArrayListUnique("android.permission.READ_PHONE_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
// addToArrayListUnique("android.permission.BATTERY_STATS", requiredPermissions);
break;
case wifiConnection:
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_WIFI_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_WIFI_STATE, requiredPermissions);
break;
case notification:
addToArrayListUnique(permissionNameReadNotifications, requiredPermissions);
addToArrayListUnique(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, requiredPermissions);
break;
default:
break;
@ -489,57 +491,69 @@ public class ActivityPermissions extends Activity
switch (action.getAction())
{
case changeSoundProfile:
addToArrayListUnique("android.permission.MODIFY_AUDIO_SETTINGS", requiredPermissions);
addToArrayListUnique(Manifest.permission.MODIFY_AUDIO_SETTINGS, requiredPermissions);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.N)
addToArrayListUnique(accessNotificationPolicyPermissionName, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NOTIFICATION_POLICY, requiredPermissions);
break;
case disableScreenRotation:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case enableScreenRotation:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case playMusic:
break;
case sendTextMessage:
addToArrayListUnique("android.permission.SEND_SMS", requiredPermissions);
addToArrayListUnique(Manifest.permission.SEND_SMS, requiredPermissions);
checkPermissionsInVariableUse(action.getParameter2(), requiredPermissions);
break;
case setAirplaneMode:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_SUPERUSER", requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
/* Permission was not required anymore, even before Android 6: https://su.chainfire.eu/#updates-permission
addToArrayListUnique(permissionNameSuperuser, requiredPermissions);*/
break;
case setBluetooth:
addToArrayListUnique("android.permission.BLUETOOTH_ADMIN", requiredPermissions);
addToArrayListUnique("android.permission.BLUETOOTH", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case setDataConnection:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_SUPERUSER", requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, requiredPermissions);
/* Permission was not required anymore, even before Android 6: https://su.chainfire.eu/#updates-permission
addToArrayListUnique(permissionNameSuperuser, requiredPermissions);*/
break;
case setDisplayRotation:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
break;
case setUsbTethering:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
break;
case setWifi:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case setWifiTethering:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
/*
https://stackoverflow.com/questions/46284914/how-to-enable-android-o-wifi-hotspot-programmatically
Unfortunately when requesting this permission it will be rejected automatically.
*/
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
// addToArrayListUnique("android.permission.TETHER_PRIVILEGED", requiredPermissions);
break;
case speakText:
checkPermissionsInVariableUse(action.getParameter2(), requiredPermissions);
break;
case startOtherActivity:
if(
@ -558,57 +572,56 @@ public class ActivityPermissions extends Activity
// addToArrayListUnique("net.kollnig.missioncontrol.permission.ADMIN", requiredPermissions);
break;
case triggerUrl:
addToArrayListUnique("android.permission.INTERNET", requiredPermissions);
// Hier m<EFBFBD><EFBFBD>te ein Hinweis kommen, da<EFBFBD> nur die Variablen verwendet werden k<EFBFBD>nnen, f<EFBFBD>r die es Rechte gibt.
addToArrayListUnique(Manifest.permission.INTERNET, requiredPermissions);
checkPermissionsInVariableUse(action.getParameter2(), requiredPermissions);
break;
case turnBluetoothOff:
addToArrayListUnique("android.permission.BLUETOOTH_ADMIN", requiredPermissions);
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.BLUETOOTH", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnBluetoothOn:
addToArrayListUnique("android.permission.BLUETOOTH_ADMIN", requiredPermissions);
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.BLUETOOTH", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH_ADMIN, requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.BLUETOOTH, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnUsbTetheringOff:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
break;
case turnUsbTetheringOn:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
break;
case turnWifiOff:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnWifiOn:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnWifiTetheringOff:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case turnWifiTetheringOn:
addToArrayListUnique(writeSystemSettingsPermissionName, requiredPermissions);
addToArrayListUnique("android.permission.CHANGE_NETWORK_STATE", requiredPermissions);
addToArrayListUnique("android.permission.ACCESS_NETWORK_STATE", requiredPermissions);
addToArrayListUnique(Manifest.permission.WRITE_SETTINGS, requiredPermissions);
addToArrayListUnique(Manifest.permission.CHANGE_NETWORK_STATE, requiredPermissions);
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, requiredPermissions);
break;
case waitBeforeNextAction:
break;
case wakeupDevice:
addToArrayListUnique("android.permission.WAKE_LOCK", requiredPermissions);
addToArrayListUnique(Manifest.permission.WAKE_LOCK, requiredPermissions);
break;
default:
break;
}
}
}
@ -660,31 +673,31 @@ public class ActivityPermissions extends Activity
switch(permission)
{
case "android.permission.RECEIVE_BOOT_COMPLETED":
case Manifest.permission.RECEIVE_BOOT_COMPLETED:
usingElements.add(getResources().getString(R.string.startAtSystemBoot));
break;
case accessNotificationPolicyPermissionName:
case Manifest.permission.ACCESS_NOTIFICATION_POLICY:
usingElements.add(getResources().getString(R.string.actionChangeSoundProfile));
break;
case "android.permission.WRITE_EXTERNAL_STORAGE":
case Manifest.permission.WRITE_EXTERNAL_STORAGE:
usingElements.add(getResources().getString(R.string.storeSettings));
break;
case permissionNameReadNotifications:
case Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.notification))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "com.google.android.gms.permission.ACTIVITY_RECOGNITION":
case permissionNameGoogleActivityDetection:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.activityDetection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.ACTIVITY_RECOGNITION":
case Manifest.permission.ACTIVITY_RECOGNITION:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.activityDetection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case permissionNameLocationCoarse:
case Manifest.permission.ACCESS_COARSE_LOCATION:
// usingElements.add(getResources().getString(R.string.android_permission_ACCESS_COARSE_LOCATION));
usingElements.add(getResources().getString(R.string.manageLocations));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
@ -692,21 +705,21 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case permissionNameLocationFine:
case Manifest.permission.ACCESS_FINE_LOCATION:
usingElements.add(getResources().getString(R.string.manageLocations));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case permissionNameLocationBackground:
case Manifest.permission.ACCESS_BACKGROUND_LOCATION:
usingElements.add(getResources().getString(R.string.googleLocationChicanery));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.ACCESS_NETWORK_STATE":
case Manifest.permission.ACCESS_NETWORK_STATE:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.airplaneMode))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection))
@ -742,7 +755,7 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Action.Action_Enum.turnWifiTetheringOn))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.ACCESS_WIFI_STATE":
case Manifest.permission.ACCESS_WIFI_STATE:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.wifiConnection))
@ -756,7 +769,7 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.usb_host_connection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;*/
case "android.permission.BLUETOOTH_ADMIN":
case Manifest.permission.BLUETOOTH_ADMIN:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setBluetooth))
@ -766,7 +779,7 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Action.Action_Enum.turnBluetoothOn))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.BLUETOOTH":
case Manifest.permission.BLUETOOTH:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.bluetoothConnection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Action.Action_Enum.setBluetooth))
@ -776,11 +789,11 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Action.Action_Enum.turnBluetoothOn))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.GET_TASKS":
case Manifest.permission.GET_TASKS:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.process_started_stopped))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.INTERNET":
case Manifest.permission.INTERNET:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.pointOfInterest))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.speed))
@ -788,15 +801,15 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Action.Action_Enum.triggerUrl))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.NFC":
case Manifest.permission.NFC:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.nfcTag))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case permissionNameCall:
case Manifest.permission.PROCESS_OUTGOING_CALLS:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.phoneCall))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.READ_PHONE_STATE":
case Manifest.permission.READ_PHONE_STATE:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.batteryLevel))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.charging))
@ -808,15 +821,15 @@ public class ActivityPermissions extends Activity
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.usb_host_connection))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.RECORD_AUDIO":
case Manifest.permission.RECORD_AUDIO:
for(String ruleName : getRulesUsing(Trigger.Trigger_Enum.noiseLevel))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.SEND_SMS":
case Manifest.permission.SEND_SMS:
for(String ruleName : getRulesUsing(Action.Action_Enum.sendTextMessage))
usingElements.add(String.format(getResources().getString(R.string.ruleXrequiresThis), ruleName));
break;
case "android.permission.FOREGROUND_SERVICE":
case Manifest.permission.FOREGROUND_SERVICE:
usingElements.add(getResources().getString(R.string.startAutomationAsService));
break;
}
@ -858,7 +871,7 @@ public class ActivityPermissions extends Activity
}
if (requestCode == requestCodeForPermissionsNotifications)
if(havePermission(permissionNameReadNotifications, ActivityPermissions.this))
if(havePermission(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, ActivityPermissions.this))
requestPermissions(cachedPermissionsToRequest, true);
}
}
@ -868,16 +881,16 @@ public class ActivityPermissions extends Activity
ArrayList<String> permissionList = new ArrayList<String>();
for(String permission : permissionNames)
{
if(permissionNames.equals(permissionNameCall))
if(permissionNames.equals(Manifest.permission.PROCESS_OUTGOING_CALLS))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), permissionNameCall) && !Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext()))
if(ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.PROCESS_OUTGOING_CALLS) && !Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext()))
{
permissionList.add(permission);
}
}
else if(permissionNames.equals("android.permission.SEND_SMS"))
else if(permissionNames.equals(Manifest.permission.SEND_SMS))
{
if(ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), "android.permission.SEND_SMS") && !Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext()))
if(ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS) && !Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext()))
{
permissionList.add(permission);
}
@ -901,7 +914,7 @@ public class ActivityPermissions extends Activity
{
for (String s : requiredPermissions)
{
if (s.equalsIgnoreCase(writeSystemSettingsPermissionName))
if (s.equalsIgnoreCase(Manifest.permission.WRITE_SETTINGS))
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
@ -910,7 +923,7 @@ public class ActivityPermissions extends Activity
startActivityForResult(intent, requestCodeForPermissionsWriteSettings);
return;
}
else if (s.equalsIgnoreCase(accessNotificationPolicyPermissionName))
else if (s.equalsIgnoreCase(Manifest.permission.ACCESS_NOTIFICATION_POLICY))
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
@ -919,7 +932,7 @@ public class ActivityPermissions extends Activity
startActivityForResult(intent, requestCodeForPermissionsNotificationPolicy);
return;
}
else if (s.equalsIgnoreCase(permissionNameReadNotifications))
else if (s.equalsIgnoreCase(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE))
{
requiredPermissions.remove(s);
cachedPermissionsToRequest = requiredPermissions;
@ -941,25 +954,25 @@ public class ActivityPermissions extends Activity
if(requiredPermissions.size() > 0)
{
if(requiredPermissions.contains(permissionNameCall))
if(requiredPermissions.contains(Manifest.permission.PROCESS_OUTGOING_CALLS))
{
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), "android.permission.SEND_SMS")
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
&&
Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
)
{
requiredPermissions.remove(permissionNameCall);
requiredPermissions.remove(Manifest.permission.PROCESS_OUTGOING_CALLS);
Miscellaneous.messageBox("Problem", getResources().getString(R.string.googleSarcasm), ActivityPermissions.this).show();
}
}
if(requiredPermissions.contains("android.permission.SEND_SMS"))
if(requiredPermissions.contains(Manifest.permission.SEND_SMS))
{
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), "android.permission.SEND_SMS")
if(!ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), Manifest.permission.SEND_SMS)
&&
Miscellaneous.isGooglePlayInstalled(Miscellaneous.getAnyContext())
)
{
requiredPermissions.remove("android.permission.SEND_SMS");
requiredPermissions.remove(Manifest.permission.SEND_SMS);
Miscellaneous.messageBox("Problem", getResources().getString(R.string.googleSarcasm), ActivityPermissions.this).show();
}
}
@ -1005,7 +1018,7 @@ public class ActivityPermissions extends Activity
for (int i=0; i < grantResults.length; i++)
{
if(permissions[i].equalsIgnoreCase(writeExternalStoragePermissionName) && grantResults[i] == PackageManager.PERMISSION_GRANTED)
if(permissions[i].equalsIgnoreCase(Manifest.permission.WRITE_EXTERNAL_STORAGE) && grantResults[i] == PackageManager.PERMISSION_GRANTED)
{
// We just got permission to read the config file. Read again.
try
@ -1081,6 +1094,64 @@ public class ActivityPermissions extends Activity
}
}
static ArrayList<String> checkPermissionsInVariableUse(String text, ArrayList<String> permsList)
{
/*
[uniqueid]
[serialnr]
[latitude]
[longitude]
[phonenr]
[d]
[m]
[Y]
[h]
[H]
[i]
[s]
[ms]
[notificationTitle]
[notificationText]
*/
if(text.contains("[uniqueid]"))
{
}
else if(text.contains("[serialnr]"))
{
}
else if(text.contains("[latitude]") || text.contains("[longitude]"))
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
{
addToArrayListUnique(Manifest.permission.ACCESS_BACKGROUND_LOCATION, permsList);
addToArrayListUnique(Manifest.permission.ACCESS_FINE_LOCATION, permsList);
addToArrayListUnique(Manifest.permission.ACCESS_COARSE_LOCATION, permsList);
}
else
{
addToArrayListUnique(Manifest.permission.ACCESS_FINE_LOCATION, permsList);
addToArrayListUnique(Manifest.permission.ACCESS_COARSE_LOCATION, permsList);
}
addToArrayListUnique(Manifest.permission.ACCESS_NETWORK_STATE, permsList);
addToArrayListUnique(Manifest.permission.INTERNET, permsList);
addToArrayListUnique(Manifest.permission.ACCESS_WIFI_STATE, permsList);
}
else if(text.contains("[phonenr]"))
{
addToArrayListUnique(Manifest.permission.READ_PHONE_STATE, permsList);
addToArrayListUnique(Manifest.permission.PROCESS_OUTGOING_CALLS, permsList);
}
else if(text.contains("[notificationTitle]") || text.contains("[notificationTitle]"))
{
addToArrayListUnique(Manifest.permission.BIND_NOTIFICATION_LISTENER_SERVICE, permsList);
}
return permsList;
}
private void setHaveAllPermissions()
{
setResult(RESULT_OK);
@ -1088,7 +1159,16 @@ public class ActivityPermissions extends Activity
NotificationManager mNotificationManager = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
mNotificationManager.cancel(notificationIdPermissions);
ActivityMainScreen.updateMainScreen();
try
{
ActivityMainRules.getInstance().updateListView();
}
catch (IllegalStateException e)
{
// Activity may not have been loaded, yet.
}
this.finish();
}
@ -1147,104 +1227,106 @@ public class ActivityPermissions extends Activity
protected static void fillPermissionMaps()
{
mapGeneralPermissions = new HashMap<String, String>();
mapGeneralPermissions.put("general", "android.permission.RECEIVE_BOOT_COMPLETED");
mapGeneralPermissions.put("general", "android.permission.WRITE_EXTERNAL_STORAGE");
mapGeneralPermissions.put("general", Manifest.permission.RECEIVE_BOOT_COMPLETED);
mapGeneralPermissions.put("general", Manifest.permission.WRITE_EXTERNAL_STORAGE);
mapTriggerPermissions = new HashMap<String, String>();
mapTriggerPermissions.put("activityDetection", "com.google.android.gms.permission.ACTIVITY_RECOGNITION");
mapTriggerPermissions.put("activityDetection", "android.permission.ACTIVITY_RECOGNITION");
mapTriggerPermissions.put("airplaneMode", "android.permission.ACCESS_NETWORK_STATE");
mapTriggerPermissions.put("batteryLevel", "android.permission.READ_PHONE_STATE");
mapTriggerPermissions.put("batteryLevel", "android.permission.BATTERY_STATS");
mapTriggerPermissions.put("bluetoothConnection", "android.permission.BLUETOOTH_ADMIN");
mapTriggerPermissions.put("bluetoothConnection", "android.permission.BLUETOOTH");
mapTriggerPermissions.put("bluetoothConnection", "android.permission.ACCESS_NETWORK_STATE");
mapTriggerPermissions.put("charging", "android.permission.READ_PHONE_STATE");
mapTriggerPermissions.put("charging", "android.permission.BATTERY_STATS");
mapTriggerPermissions.put("headsetPlugged", "android.permission.READ_PHONE_STATE");
mapTriggerPermissions.put("nfcTag", "android.permission.NFC");
mapTriggerPermissions.put("noiseLevel", "android.permission.RECORD_AUDIO");
mapTriggerPermissions.put("phoneCall", "android.permission.READ_PHONE_STATE");
mapTriggerPermissions.put("phoneCall", permissionNameCall);
mapTriggerPermissions.put("pointOfInterest", permissionNameLocationFine);
mapTriggerPermissions.put("pointOfInterest", permissionNameLocationCoarse);
mapTriggerPermissions.put("activityDetection", permissionNameGoogleActivityDetection);
mapTriggerPermissions.put("activityDetection", Manifest.permission.ACTIVITY_RECOGNITION);
mapTriggerPermissions.put("airplaneMode", Manifest.permission.ACCESS_NETWORK_STATE);
mapTriggerPermissions.put("batteryLevel", Manifest.permission.READ_PHONE_STATE);
mapTriggerPermissions.put("batteryLevel", Manifest.permission.BATTERY_STATS);
mapTriggerPermissions.put("bluetoothConnection", Manifest.permission.BLUETOOTH_ADMIN);
mapTriggerPermissions.put("bluetoothConnection", Manifest.permission.BLUETOOTH);
mapTriggerPermissions.put("bluetoothConnection", Manifest.permission.ACCESS_NETWORK_STATE);
mapTriggerPermissions.put("charging", Manifest.permission.READ_PHONE_STATE);
mapTriggerPermissions.put("charging", Manifest.permission.BATTERY_STATS);
mapTriggerPermissions.put("headsetPlugged", Manifest.permission.READ_PHONE_STATE);
mapTriggerPermissions.put("nfcTag", Manifest.permission.NFC);
mapTriggerPermissions.put("noiseLevel", Manifest.permission.RECORD_AUDIO);
mapTriggerPermissions.put("phoneCall", Manifest.permission.READ_PHONE_STATE);
mapTriggerPermissions.put("phoneCall", Manifest.permission.PROCESS_OUTGOING_CALLS);
mapTriggerPermissions.put("pointOfInterest", Manifest.permission.ACCESS_FINE_LOCATION);
mapTriggerPermissions.put("pointOfInterest", Manifest.permission.ACCESS_COARSE_LOCATION);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
mapTriggerPermissions.put("pointOfInterest", permissionNameLocationBackground);
mapTriggerPermissions.put("pointOfInterest", "android.permission.ACCESS_NETWORK_STATE");
mapTriggerPermissions.put("pointOfInterest", "android.permission.INTERNET");
mapTriggerPermissions.put("pointOfInterest", "android.permission.ACCESS_WIFI_STATE");
mapTriggerPermissions.put("process_started_stopped", "android.permission.GET_TASKS");
mapTriggerPermissions.put("roaming", "android.permission.ACCESS_NETWORK_STATE");
mapTriggerPermissions.put("speed", permissionNameLocationFine);
mapTriggerPermissions.put("speed", permissionNameLocationCoarse);
mapTriggerPermissions.put("pointOfInterest", Manifest.permission.ACCESS_BACKGROUND_LOCATION);
mapTriggerPermissions.put("pointOfInterest", Manifest.permission.ACCESS_NETWORK_STATE);
mapTriggerPermissions.put("pointOfInterest", Manifest.permission.INTERNET);
mapTriggerPermissions.put("pointOfInterest", Manifest.permission.ACCESS_WIFI_STATE);
mapTriggerPermissions.put("process_started_stopped", Manifest.permission.GET_TASKS);
mapTriggerPermissions.put("roaming", Manifest.permission.ACCESS_NETWORK_STATE);
mapTriggerPermissions.put("speed", Manifest.permission.ACCESS_FINE_LOCATION);
mapTriggerPermissions.put("speed", Manifest.permission.ACCESS_COARSE_LOCATION);
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
mapTriggerPermissions.put("speed", permissionNameLocationBackground);
mapTriggerPermissions.put("speed", "android.permission.ACCESS_NETWORK_STATE");
mapTriggerPermissions.put("speed", "android.permission.INTERNET");
mapTriggerPermissions.put("speed", Manifest.permission.ACCESS_BACKGROUND_LOCATION);
mapTriggerPermissions.put("speed", Manifest.permission.ACCESS_NETWORK_STATE);
mapTriggerPermissions.put("speed", Manifest.permission.INTERNET);
// map.put("timeFrame", "");
mapTriggerPermissions.put("usb_host_connection", "android.permission.READ_PHONE_STATE");
mapTriggerPermissions.put("usb_host_connection", "android.permission.BATTERY_STATS");
mapTriggerPermissions.put("wifiConnection", "android.permission.ACCESS_NETWORK_STATE");
mapTriggerPermissions.put("wifiConnection", "android.permission.ACCESS_WIFI_STATE");
mapTriggerPermissions.put("usb_host_connection", Manifest.permission.READ_PHONE_STATE);
mapTriggerPermissions.put("usb_host_connection", Manifest.permission.BATTERY_STATS);
mapTriggerPermissions.put("wifiConnection", Manifest.permission.ACCESS_NETWORK_STATE);
mapTriggerPermissions.put("wifiConnection", Manifest.permission.ACCESS_WIFI_STATE);
mapActionPermissions = new HashMap<String, String>();
mapActionPermissions.put("changeSoundProfile", "android.permission.MODIFY_AUDIO_SETTINGS");
mapActionPermissions.put("changeSoundProfile", accessNotificationPolicyPermissionName);
mapActionPermissions.put("disableScreenRotation", writeSystemSettingsPermissionName);
mapActionPermissions.put("enableScreenRotation", writeSystemSettingsPermissionName);
mapActionPermissions.put("changeSoundProfile", Manifest.permission.MODIFY_AUDIO_SETTINGS);
mapActionPermissions.put("changeSoundProfile", Manifest.permission.ACCESS_NOTIFICATION_POLICY);
mapActionPermissions.put("disableScreenRotation", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("enableScreenRotation", Manifest.permission.WRITE_SETTINGS);
// mapActionPermissions.put("playMusic", "");
mapActionPermissions.put("sendTextMessage", "android.permission.SEND_SMS");
mapActionPermissions.put("setAirplaneMode", writeSystemSettingsPermissionName);
mapActionPermissions.put("setAirplaneMode", "android.permission.ACCESS_NETWORK_STATE");
mapActionPermissions.put("setAirplaneMode", "android.permission.ACCESS_SUPERUSER");
mapActionPermissions.put("setAirplaneMode", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("setBluetooth", "android.permission.BLUETOOTH_ADMIN");
mapActionPermissions.put("setBluetooth", "android.permission.BLUETOOTH");
mapActionPermissions.put("setBluetooth", "android.permission.ACCESS_NETWORK_STATE");
mapActionPermissions.put("setBluetooth", writeSystemSettingsPermissionName);
mapActionPermissions.put("setDataConnection", writeSystemSettingsPermissionName);
mapActionPermissions.put("setDataConnection", "android.permission.ACCESS_NETWORK_STATE");
mapActionPermissions.put("setDataConnection", "android.permission.ACCESS_SUPERUSER");
mapActionPermissions.put("setDataConnection", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("setDisplayRotation", writeSystemSettingsPermissionName);
mapActionPermissions.put("setUsbTethering", writeSystemSettingsPermissionName);
mapActionPermissions.put("setUsbTethering", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("setWifi", writeSystemSettingsPermissionName);
mapActionPermissions.put("setWifi", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("setWifi", "android.permission.ACCESS_NETWORK_STATE");
mapActionPermissions.put("setWifiTethering", writeSystemSettingsPermissionName);
mapActionPermissions.put("setWifiTethering", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("setWifiTethering", "android.permission.ACCESS_NETWORK_STATE");
// mapActionPermissions.put("speakText", accessNotificationPolicyPermissionName);
mapActionPermissions.put("sendTextMessage", Manifest.permission.SEND_SMS);
mapActionPermissions.put("setAirplaneMode", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("setAirplaneMode", Manifest.permission.ACCESS_NETWORK_STATE);
/* Permission was not required anymore, even before Android 6: https://su.chainfire.eu/#updates-permission
mapActionPermissions.put("setAirplaneMode", permissionNameSuperuser);*/
mapActionPermissions.put("setAirplaneMode", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("setBluetooth", Manifest.permission.BLUETOOTH_ADMIN);
mapActionPermissions.put("setBluetooth", Manifest.permission.BLUETOOTH);
mapActionPermissions.put("setBluetooth", Manifest.permission.ACCESS_NETWORK_STATE);
mapActionPermissions.put("setBluetooth", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("setDataConnection", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("setDataConnection", Manifest.permission.ACCESS_NETWORK_STATE);
/* Permission was not required anymore, even before Android 6: https://su.chainfire.eu/#updates-permission
mapActionPermissions.put("setDataConnection", permissionNameSuperuser);*/
mapActionPermissions.put("setDataConnection", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("setDisplayRotation", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("setUsbTethering", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("setUsbTethering", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("setWifi", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("setWifi", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("setWifi", Manifest.permission.ACCESS_NETWORK_STATE);
mapActionPermissions.put("setWifiTethering", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("setWifiTethering", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("setWifiTethering", Manifest.permission.ACCESS_NETWORK_STATE);
// mapActionPermissions.put("speakText", Manifest.permission.ACCESS_NOTIFICATION_POLICY);
// mapActionPermissions.put("startOtherActivity", "");
mapActionPermissions.put("triggerUrl", "android.permission.INTERNET");
mapActionPermissions.put("triggerUrl", Manifest.permission.INTERNET);
// Hier müßte ein Hinweis kommen, daß nur die Variablen verwendet werden können, für die es Rechte gibt.
mapActionPermissions.put("turnBluetoothOff", "android.permission.BLUETOOTH_ADMIN");
mapActionPermissions.put("turnBluetoothOff", "android.permission.BLUETOOTH");
mapActionPermissions.put("turnBluetoothOff", "android.permission.ACCESS_NETWORK_STATE");
mapActionPermissions.put("turnBluetoothOff", writeSystemSettingsPermissionName);
mapActionPermissions.put("turnBluetoothOn", "android.permission.BLUETOOTH_ADMIN");
mapActionPermissions.put("turnBluetoothOn", "android.permission.BLUETOOTH");
mapActionPermissions.put("turnBluetoothOn", "android.permission.ACCESS_NETWORK_STATE");
mapActionPermissions.put("turnBluetoothOn", writeSystemSettingsPermissionName);
mapActionPermissions.put("turnUsbTetheringOff", writeSystemSettingsPermissionName);
mapActionPermissions.put("turnUsbTetheringOff", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("turnUsbTetheringOn", writeSystemSettingsPermissionName);
mapActionPermissions.put("turnUsbTetheringOn", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("turnWifiOff", writeSystemSettingsPermissionName);
mapActionPermissions.put("turnWifiOff", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("turnWifiOff", "android.permission.ACCESS_NETWORK_STATE");
mapActionPermissions.put("turnWifiOn", writeSystemSettingsPermissionName);
mapActionPermissions.put("turnWifiOn", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("turnWifiOn", "android.permission.ACCESS_NETWORK_STATE");
mapActionPermissions.put("turnWifiTetheringOff", writeSystemSettingsPermissionName);
mapActionPermissions.put("turnWifiTetheringOff", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("turnWifiTetheringOff", "android.permission.ACCESS_NETWORK_STATE");
mapActionPermissions.put("turnWifiTetheringOn", writeSystemSettingsPermissionName);
mapActionPermissions.put("turnWifiTetheringOn", "android.permission.CHANGE_NETWORK_STATE");
mapActionPermissions.put("turnWifiTetheringOn", "android.permission.ACCESS_NETWORK_STATE");
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.BLUETOOTH_ADMIN);
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.BLUETOOTH);
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.ACCESS_NETWORK_STATE);
mapActionPermissions.put("turnBluetoothOff", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("turnBluetoothOn", Manifest.permission.BLUETOOTH_ADMIN);
mapActionPermissions.put("turnBluetoothOn", Manifest.permission.BLUETOOTH);
mapActionPermissions.put("turnBluetoothOn", Manifest.permission.ACCESS_NETWORK_STATE);
mapActionPermissions.put("turnBluetoothOn", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("turnUsbTetheringOff", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("turnUsbTetheringOff", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("turnUsbTetheringOn", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("turnUsbTetheringOn", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("turnWifiOff", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("turnWifiOff", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("turnWifiOff", Manifest.permission.ACCESS_NETWORK_STATE);
mapActionPermissions.put("turnWifiOn", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("turnWifiOn", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("turnWifiOn", Manifest.permission.ACCESS_NETWORK_STATE);
mapActionPermissions.put("turnWifiTetheringOff", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("turnWifiTetheringOff", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("turnWifiTetheringOff", Manifest.permission.ACCESS_NETWORK_STATE);
mapActionPermissions.put("turnWifiTetheringOn", Manifest.permission.WRITE_SETTINGS);
mapActionPermissions.put("turnWifiTetheringOn", Manifest.permission.CHANGE_NETWORK_STATE);
mapActionPermissions.put("turnWifiTetheringOn", Manifest.permission.ACCESS_NETWORK_STATE);
// mapActionPermissions.put("waitBeforeNextAction", "");
mapActionPermissions.put("wakeupDevice", "android.permission.WAKE_LOCK");
mapActionPermissions.put("wakeupDevice", Manifest.permission.WAKE_LOCK);
}
/*

View File

@ -1,16 +0,0 @@
package com.jens.automation2;
import android.app.Activity;
import android.os.Bundle;
import androidx.annotation.Nullable;
public class ActivityTriggerPhoneCall extends Activity
{
@Override
protected void onCreate(@Nullable Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.trigger_phone_call);
}
}

View File

@ -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;
}
}
@ -445,7 +446,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();
@ -593,9 +595,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

View File

@ -1,5 +1,6 @@
package com.jens.automation2;
import android.Manifest;
import android.annotation.SuppressLint;
import android.app.AlertDialog;
import android.app.Notification;
@ -21,6 +22,8 @@ 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;
@ -334,7 +337,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.
@ -1471,4 +1474,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);
}
}

View File

@ -490,11 +490,19 @@ public class PointOfInterest implements Comparable<PointOfInterest>
{
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;
}
@ -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;
}

View File

@ -271,10 +271,13 @@ 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))
{
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);
if (runResult instanceof Boolean)
{
boolean isRunning = (Boolean) runResult;
if (isRunning)
@ -298,7 +301,7 @@ public class ReceiverCoordinator
else
{
Object runResult = Miscellaneous.runMethodReflective(activityDetectionClassPath, "isActivityDetectionReceiverRunning", null);
if(runResult instanceof Boolean)
if (runResult instanceof Boolean)
{
boolean isRunning = (Boolean) runResult;
if (isRunning)
@ -309,6 +312,7 @@ public class ReceiverCoordinator
}
}
}
}
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.bluetoothConnection))
{

View File

@ -77,9 +77,16 @@ 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 int batteryLevel;
private int phoneDirection = 0; // 0=any, 1=incoming, 2=outgoing
@ -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);
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));
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.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;

View File

@ -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";
@ -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");
}
@ -888,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)
{
String[] elements = triggerParameter2.split(",");
if(elements.length == 2) //old format
{
// 0/1/2,number
int direction = Integer.parseInt(triggerParameter2.substring(0, 1));
String number = triggerParameter2.substring(2);
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)
{
@ -935,6 +988,7 @@ public class XmlFileInterface
{
newTrigger.setActivityDetectionType(0);
}
newTrigger.setTriggerParameter2(triggerParameter2);
}
else if(newTrigger.getTriggerType() == Trigger_Enum.bluetoothConnection)
{
@ -944,6 +998,7 @@ public class XmlFileInterface
newTrigger.setBluetoothEvent(substrings[0]);
newTrigger.setBluetoothDeviceAddress(substrings[1]);
}
newTrigger.setTriggerParameter2(triggerParameter2);
}
else if(newTrigger.getTriggerType() == Trigger_Enum.headsetPlugged)
{
@ -955,8 +1010,9 @@ public class XmlFileInterface
{
newTrigger.setHeadphoneType(-1);
}
newTrigger.setTriggerParameter2(triggerParameter2);
}
else
newTrigger.setTriggerParameter2(triggerParameter2);
}
else

View File

@ -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();
}

View File

@ -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;
}
}

View File

@ -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;
@ -29,8 +30,6 @@ public class WifiBroadcastReceiver extends BroadcastReceiver
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);
}
}

View File

@ -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());
WifiBroadcastReceiver.findRules(automationServiceRef);
break;
case ConnectivityManager.TYPE_MOBILE:
boolean isRoaming = isRoaming(context);
@ -219,7 +219,7 @@ public class ConnectivityReceiver extends BroadcastReceiver implements Automatio
// This will serve as a disconnected event. Happens if wifi is connected, then module deactivated.
Miscellaneous.logEvent("i", "Connectivity", "Wifi deactivated while having been connected before.", 4);
WifiBroadcastReceiver.lastConnectedState = false;
WifiBroadcastReceiver.findRules(automationServiceRef.getLocationProvider());
WifiBroadcastReceiver.findRules(automationServiceRef);
}
}
}

View File

@ -1,5 +1,7 @@
package com.jens.automation2.receivers;
import android.Manifest;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@ -13,16 +15,18 @@ import com.jens.automation2.AutomationService;
import com.jens.automation2.Miscellaneous;
import com.jens.automation2.R;
import com.jens.automation2.Rule;
import com.jens.automation2.Trigger;
import com.jens.automation2.Trigger.Trigger_Enum;
import java.util.ArrayList;
public class PhoneStatusListener implements AutomationListenerInterface
{
protected static int currentStateIncoming = -1;
protected static int currentStateOutgoing = -1;
// protected static int currentStateIncoming = -1;
// protected static int currentStateOutgoing = -1;
protected static String lastPhoneNumber="";
protected static int lastPhoneDirection = -1; //0=incoming, 1=outgoing
protected static int currentState = -1;
protected static boolean incomingCallsReceiverActive = false;
protected static boolean outgoingCallsReceiverActive = false;
@ -31,7 +35,6 @@ public class PhoneStatusListener implements AutomationListenerInterface
protected static IncomingCallsReceiver incomingCallsReceiverInstance;
protected static BroadcastReceiver outgoingCallsReceiverInstance;
public static boolean isIncomingCallsReceiverActive()
{
return incomingCallsReceiverActive;
@ -59,6 +62,16 @@ public class PhoneStatusListener implements AutomationListenerInterface
return lastPhoneNumber;
}
public static void setCurrentState(int currentState)
{
PhoneStatusListener.currentState = currentState;
}
public static int getCurrentState()
{
return currentState;
}
public static class IncomingCallsReceiver extends PhoneStateListener
{
@Override
@ -66,6 +79,20 @@ public class PhoneStatusListener implements AutomationListenerInterface
{
// Miscellaneous.logEvent("i", "Call state", "New call state: " + String.valueOf(state), 4);
/*
Unfortunately receivers for incoming and outgoing calls behave pretty differently:
The Outgoing-Receiver is called when starting a call (ringing)
It is not called when that outgoing call ends however, only the incoming receiver.
If the last call was outgoing the state has not changed to idle this is kind of a fake alert.
*/
if(lastPhoneDirection == 2 && currentState != TelephonyManager.CALL_STATE_IDLE)
{
// This status update is actually for an outgoing call
setCurrentState(state);
if(incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
setLastPhoneNumber(incomingNumber);
@ -73,167 +100,105 @@ public class PhoneStatusListener implements AutomationListenerInterface
{
case TelephonyManager.CALL_STATE_IDLE:
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
if(currentStateIncoming == TelephonyManager.CALL_STATE_OFFHOOK)
setCurrentStateIncoming(state);
else if(currentStateOutgoing == TelephonyManager.CALL_STATE_OFFHOOK)
setCurrentStateOutgoing(state);
else
currentStateIncoming = state;
currentStateOutgoing = state;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
if(currentStateIncoming == TelephonyManager.CALL_STATE_RINGING)
setCurrentStateIncoming(state);
else if(currentStateOutgoing == TelephonyManager.CALL_STATE_RINGING)
setCurrentStateOutgoing(state);
break;
case TelephonyManager.CALL_STATE_RINGING:
String number = "unknown";
if(incomingNumber != null && incomingNumber.length() > 0)
number = incomingNumber;
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.incomingCallFrom), number), 4);
setCurrentStateIncoming(state);
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), incomingNumber), 4);
break;
}
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(Trigger.triggerPhoneCallDirectionOutgoing);
for(int i=0; i<ruleCandidates.size(); i++)
{
AutomationService asInstance = AutomationService.getInstance();
if(asInstance != null)
if(ruleCandidates.get(i).applies(asInstance))
ruleCandidates.get(i).activate(asInstance, false);
}
}
else
{
// state != TelephonyManager.CALL_STATE_IDLE &&
setCurrentState(state);
setLastPhoneDirection(1);
if (incomingNumber != null && incomingNumber.length() > 0) // check for null in case call comes in with suppressed number.
setLastPhoneNumber(incomingNumber);
switch (state)
{
case TelephonyManager.CALL_STATE_IDLE:
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_IDLE", 4);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Miscellaneous.logEvent("i", "Call state", "New call state: CALL_STATE_OFFHOOK", 4);
break;
case TelephonyManager.CALL_STATE_RINGING:
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.incomingCallFrom), incomingNumber), 4);
break;
}
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(Trigger.triggerPhoneCallDirectionIncoming);
for (int i = 0; i < ruleCandidates.size(); i++)
{
AutomationService asInstance = AutomationService.getInstance();
if (asInstance != null)
if (ruleCandidates.get(i).applies(asInstance))
ruleCandidates.get(i).activate(asInstance, false);
}
}
}
}
static void setLastPhoneDirection(int i)
{
lastPhoneDirection = i;
}
public static class OutgoingCallsReceiver extends BroadcastReceiver
{
@Override
public void onReceive(Context context, Intent intent)
{
setCurrentStateOutgoing(2);
setLastPhoneNumber(intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallFrom), getLastPhoneNumber()), 4);
/*
This receiver is ONLY triggered when outgoing calls ring, not when that call is established or ends.
*/
setLastPhoneDirection(2);
// TelephonyManager tm = (TelephonyManager)context.getSystemService(Service.TELEPHONY_SERVICE);
// int newState = tm.getCallState();
// setCurrentState(newState);
setCurrentState(TelephonyManager.CALL_STATE_RINGING);
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
setLastPhoneNumber(phoneNumber);
Miscellaneous.logEvent("i", "Call state", String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.outgoingCallTo), getLastPhoneNumber()), 4);
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(Trigger.triggerPhoneCallDirectionOutgoing);
for(int i=0; i<ruleCandidates.size(); i++)
{
AutomationService asInstance = AutomationService.getInstance();
if(asInstance != null)
if(ruleCandidates.get(i).applies(asInstance))
ruleCandidates.get(i).activate(asInstance, false);
}
}
}
public static boolean isInACall()
{
if(isInIncomingCall() | isInOutgoingCall())
return true;
return false;
return getCurrentState() != TelephonyManager.CALL_STATE_IDLE;
}
public static boolean isInIncomingCall()
{
// Miscellaneous.logEvent("i", "Incoming call state", String.valueOf(currentStateIncoming), 5);
switch(currentStateIncoming)
{
// case -1:
// return false;
// case 0:
// return false;
// case 1:
// return true;
case 2:
return true;
// case 3:
// return true;
// case 4:
// return true;
// default:
// return false;
}
return false;
}
public static boolean isInOutgoingCall()
{
// Miscellaneous.logEvent("i", "Outgoing call state", String.valueOf(currentStateOutgoing), 5);
switch(currentStateOutgoing)
{
// case -1:
// return false;
// case 0:
// return false;
// case 1:
// return true;
case 2:
return true;
// case 3:
// return true;
// case 4:
// return true;
// default:
// return false;
}
return false;
}
private static void setCurrentStateIncoming(int state)
{
// Miscellaneous.logEvent("i", "Call state", "New incoming call state: " + String.valueOf(state), 4);
if(currentStateIncoming != state)
{
if(lastPhoneDirection != 1)
lastPhoneDirection = 1;
if(
(state == 0 && currentStateIncoming == 2)
|
(state == 2 && (currentStateIncoming == 0 | currentStateIncoming == 1))
)
{
currentStateIncoming = state;
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(isInIncomingCall());
for(int i=0; i<ruleCandidates.size(); i++)
{
AutomationService asInstance = AutomationService.getInstance();
if(asInstance != null)
if(ruleCandidates.get(i).applies(asInstance))
ruleCandidates.get(i).activate(asInstance, false);
}
}
else
currentStateIncoming = state;
}
}
public static int getCurrentStateIncoming()
{
return currentStateIncoming;
}
public static void setCurrentStateOutgoing(int state)
{
if(currentStateOutgoing != state)
{
if(lastPhoneDirection != 2)
lastPhoneDirection = 2;
if(
(state == 0 && currentStateOutgoing == 2)
|
(state == 2 && (currentStateOutgoing == 0 | currentStateOutgoing == 1)))
{
PhoneStatusListener.currentStateOutgoing = state;
ArrayList<Rule> ruleCandidates = Rule.findRuleCandidatesByPhoneCall(isInOutgoingCall());
for(int i=0; i<ruleCandidates.size(); i++)
{
AutomationService asInstance = AutomationService.getInstance();
if(asInstance != null)
if(ruleCandidates.get(i).applies(asInstance))
ruleCandidates.get(i).activate(asInstance, false);
}
}
else
PhoneStatusListener.currentStateOutgoing = state;
}
}
public static int getCurrentStateOutgoing()
{
return currentStateOutgoing;
}
/*
Future remark:
Apps that redirect outgoing calls should use the android.telecom.CallRedirectionService API.
Apps that perform call screening should use the android.telecom.CallScreeningService API.
*/
public static void startPhoneStatusListener(AutomationService automationService)
{
@ -312,9 +277,9 @@ public class PhoneStatusListener implements AutomationListenerInterface
public static boolean haveAllPermission()
{
return
ActivityPermissions.havePermission("android.permission.READ_PHONE_STATE", Miscellaneous.getAnyContext())
ActivityPermissions.havePermission(Manifest.permission.READ_PHONE_STATE, Miscellaneous.getAnyContext())
&&
ActivityPermissions.havePermission(ActivityPermissions.permissionNameCall, Miscellaneous.getAnyContext());
ActivityPermissions.havePermission(Manifest.permission.PROCESS_OUTGOING_CALLS, Miscellaneous.getAnyContext());
}
@Override

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2014 Jorrit "Chainfire" Jongma
* Copyright (C) 2012-2019 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -20,10 +20,15 @@ import android.content.Context;
import android.os.Handler;
import android.widget.Toast;
import androidx.annotation.AnyThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
/**
* Base application class to extend from, solving some issues with
* toasts and AsyncTasks you are likely to run into
*/
@SuppressWarnings("WeakerAccess")
public class Application extends android.app.Application {
/**
* Shows a toast message
@ -31,7 +36,8 @@ public class Application extends android.app.Application {
* @param context Any context belonging to this application
* @param message The message to show
*/
public static void toast(Context context, String message) {
@AnyThread
public static void toast(@Nullable Context context, @NonNull String message) {
// this is a static method so it is easier to call,
// as the context checking and casting is done for you
@ -45,7 +51,7 @@ public class Application extends android.app.Application {
final Context c = context;
final String m = message;
((Application)context).runInApplicationThread(new Runnable() {
((Application) context).runInApplicationThread(new Runnable() {
@Override
public void run() {
Toast.makeText(c, m, Toast.LENGTH_LONG).show();
@ -54,14 +60,15 @@ public class Application extends android.app.Application {
}
}
private static Handler mApplicationHandler = new Handler();
private static final Handler mApplicationHandler = new Handler();
/**
* Run a runnable in the main application thread
*
* @param r Runnable to run
*/
public void runInApplicationThread(Runnable r) {
@AnyThread
public void runInApplicationThread(@NonNull Runnable r) {
mApplicationHandler.post(r);
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2014 Jorrit "Chainfire" Jongma
* Copyright (C) 2012-2019 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -18,12 +18,19 @@ package eu.chainfire.libsuperuser;
import android.os.Looper;
import android.util.Log;
import android.os.Process;
import androidx.annotation.AnyThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.jens.automation2.BuildConfig;
/**
* Utility class for logging and debug features that (by default) does nothing when not in debug mode
*/
@SuppressWarnings({"WeakerAccess", "UnusedReturnValue", "unused"})
@AnyThread
public class Debug {
// ----- DEBUGGING -----
@ -63,12 +70,14 @@ public class Debug {
public static final int LOG_GENERAL = 0x0001;
public static final int LOG_COMMAND = 0x0002;
public static final int LOG_OUTPUT = 0x0004;
public static final int LOG_POOL = 0x0008;
public static final int LOG_NONE = 0x0000;
public static final int LOG_ALL = 0xFFFF;
private static int logTypes = LOG_ALL;
@Nullable
private static OnLogListener logListener = null;
/**
@ -81,7 +90,7 @@ public class Debug {
* @param typeIndicator String indicator for message type
* @param message The message to log
*/
private static void logCommon(int type, String typeIndicator, String message) {
private static void logCommon(int type, @NonNull String typeIndicator, @NonNull String message) {
if (debug && ((logTypes & type) == type)) {
if (logListener != null) {
logListener.onLog(type, typeIndicator, message);
@ -98,7 +107,7 @@ public class Debug {
*
* @param message The message to log
*/
public static void log(String message) {
public static void log(@NonNull String message) {
logCommon(LOG_GENERAL, "G", message);
}
@ -109,7 +118,7 @@ public class Debug {
*
* @param message The message to log
*/
public static void logCommand(String message) {
public static void logCommand(@NonNull String message) {
logCommon(LOG_COMMAND, "C", message);
}
@ -120,10 +129,19 @@ public class Debug {
*
* @param message The message to log
*/
public static void logOutput(String message) {
public static void logOutput(@NonNull String message) {
logCommon(LOG_OUTPUT, "O", message);
}
/**
* <p>Log pool event</p>
*
* @param message The message to log
*/
public static void logPool(@NonNull String message) {
logCommon(LOG_POOL, "P", message);
}
/**
* <p>Enable or disable logging specific types of message</p>
*
@ -151,6 +169,7 @@ public class Debug {
* to occur.</p>
*
* @param type LOG_* constants
* @return enabled?
*/
public static boolean getLogTypeEnabled(int type) {
return ((logTypes & type) == type);
@ -164,6 +183,7 @@ public class Debug {
* debug mode into account for the result.</p>
*
* @param type LOG_* constants
* @return enabled and in debug mode?
*/
public static boolean getLogTypeEnabledEffective(int type) {
return getDebug() && getLogTypeEnabled(type);
@ -178,7 +198,7 @@ public class Debug {
*
* @param onLogListener Custom log listener or NULL to revert to default
*/
public static void setOnLogListener(OnLogListener onLogListener) {
public static void setOnLogListener(@Nullable OnLogListener onLogListener) {
logListener = onLogListener;
}
@ -187,6 +207,7 @@ public class Debug {
*
* @return Current custom log handler or NULL if none is present
*/
@Nullable
public static OnLogListener getOnLogListener() {
return logListener;
}
@ -236,7 +257,7 @@ public class Debug {
* @return Running on main thread ?
*/
public static boolean onMainThread() {
return ((Looper.myLooper() != null) && (Looper.myLooper() == Looper.getMainLooper()));
return ((Looper.myLooper() != null) && (Looper.myLooper() == Looper.getMainLooper()) && (Process.myUid() != 0));
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2014 Jorrit "Chainfire" Jongma
* Copyright (C) 2012-2019 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -37,6 +37,7 @@ import android.content.Intent;
* window possibly obscuring SuperSU dialogs".
* </p>
*/
@SuppressWarnings({"unused"})
public abstract class HideOverlaysReceiver extends BroadcastReceiver {
public static final String ACTION_HIDE_OVERLAYS = "eu.chainfire.supersu.action.HIDE_OVERLAYS";
public static final String CATEGORY_HIDE_OVERLAYS = Intent.CATEGORY_INFO;
@ -45,7 +46,7 @@ public abstract class HideOverlaysReceiver extends BroadcastReceiver {
@Override
public final void onReceive(Context context, Intent intent) {
if (intent.hasExtra(EXTRA_HIDE_OVERLAYS)) {
onHideOverlays(intent.getBooleanExtra(EXTRA_HIDE_OVERLAYS, false));
onHideOverlays(context, intent, intent.getBooleanExtra(EXTRA_HIDE_OVERLAYS, false));
}
}
@ -53,7 +54,9 @@ public abstract class HideOverlaysReceiver extends BroadcastReceiver {
* Called when overlays <em>should</em> be hidden or <em>may</em> be shown
* again.
*
* @param context App context
* @param intent Received intent
* @param hide Should overlays be hidden?
*/
public abstract void onHideOverlays(boolean hide);
public abstract void onHideOverlays(Context context, Intent intent, boolean hide);
}

View File

@ -0,0 +1,186 @@
/*
* Copyright (C) 2012-2019 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.chainfire.libsuperuser;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import androidx.annotation.AnyThread;
import androidx.annotation.NonNull;
import androidx.annotation.WorkerThread;
@SuppressWarnings("WeakerAccess")
@AnyThread
public class MarkerInputStream extends InputStream {
private static final String EXCEPTION_EOF = "EOF encountered, shell probably died";
@NonNull
private final StreamGobbler gobbler;
private final InputStream inputStream;
private final byte[] marker;
private final int markerLength;
private final int markerMaxLength;
private final byte[] read1 = new byte[1];
private final byte[] buffer = new byte[65536];
private int bufferUsed = 0;
private volatile boolean eof = false;
private volatile boolean done = false;
public MarkerInputStream(@NonNull StreamGobbler gobbler, @NonNull String marker) throws UnsupportedEncodingException {
this.gobbler = gobbler;
this.gobbler.suspendGobbling();
this.inputStream = gobbler.getInputStream();
this.marker = marker.getBytes("UTF-8");
this.markerLength = marker.length();
this.markerMaxLength = marker.length() + 5; // marker + space + exitCode(max(3)) + \n
}
@Override
public int read() throws IOException {
while (true) {
int r = read(read1, 0, 1);
if (r < 0) return -1;
if (r == 0) {
// wait for data to become available
try {
Thread.sleep(16);
} catch (InterruptedException e) {
// no action
}
continue;
}
return (int)read1[0] & 0xFF;
}
}
@Override
public int read(@NonNull byte[] b) throws IOException {
return read(b, 0, b.length);
}
private void fill(int safeSizeToWaitFor) {
// fill up our own buffer
if (isEOF()) return;
try {
int a;
while (((a = inputStream.available()) > 0) || (safeSizeToWaitFor > 0)) {
int left = buffer.length - bufferUsed;
if (left == 0) return;
int r = inputStream.read(buffer, bufferUsed, Math.max(safeSizeToWaitFor, Math.min(a, left)));
if (r >= 0) {
bufferUsed += r;
safeSizeToWaitFor -= r;
} else {
// This shouldn't happen *unless* we have both the full content and the end
// marker, otherwise the shell was interrupted/died. An IOException is raised
// in read() below if that is the case.
setEOF();
break;
}
}
} catch (IOException e) {
setEOF();
}
}
@Override
public synchronized int read(@NonNull byte[] b, int off, int len) throws IOException {
if (done) return -1;
fill(markerLength - bufferUsed);
// we need our buffer to be big enough to detect the marker
if (bufferUsed < markerLength) return 0;
// see if we have our marker
int match = -1;
for (int i = Math.max(0, bufferUsed - markerMaxLength); i < bufferUsed - markerLength; i++) {
boolean found = true;
for (int j = 0; j < markerLength; j++) {
if (buffer[i + j] != marker[j]) {
found = false;
break;
}
}
if (found) {
match = i;
break;
}
}
if (match == 0) {
// marker is at the front of the buffer
while (buffer[bufferUsed -1] != (byte)'\n') {
if (isEOF()) throw new IOException(EXCEPTION_EOF);
fill(1);
}
if (gobbler.getOnLineListener() != null) gobbler.getOnLineListener().onLine(new String(buffer, 0, bufferUsed - 1, "UTF-8"));
done = true;
return -1;
} else {
int ret;
if (match == -1) {
if (isEOF()) throw new IOException(EXCEPTION_EOF);
// marker isn't in the buffer, drain as far as possible while keeping some space
// leftover so we can still find the marker if its read is split between two fill()
// calls
ret = Math.min(len, bufferUsed - markerMaxLength);
} else {
// even if eof, it is possibly we have both the content and the end marker, which
// counts as a completed command, so we don't throw IOException here
// marker found, max drain up to marker, this will eventually cause the marker to be
// at the front of the buffer
ret = Math.min(len, match);
}
if (ret > 0) {
System.arraycopy(buffer, 0, b, off, ret);
bufferUsed -= ret;
System.arraycopy(buffer, ret, buffer, 0, bufferUsed);
} else {
try {
// prevent 100% CPU on reading from for example /dev/random
Thread.sleep(4);
} catch (Exception e) {
// no action
}
}
return ret;
}
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public synchronized void close() throws IOException {
if (!isEOF() && !done) {
// drain
byte[] buffer = new byte[1024];
while (read(buffer) >= 0) {
}
}
}
public synchronized boolean isEOF() {
return eof;
}
public synchronized void setEOF() {
eof = true;
}
}

View File

@ -0,0 +1,243 @@
/*
* Copyright (C) 2012-2019 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.chainfire.libsuperuser;
import java.util.ArrayList;
import java.util.List;
import androidx.annotation.AnyThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
/**
* Helper class for modifying SELinux policies, reducing the number of calls to a minimum.
*
* Example usage:
*
* <pre>
* <code>
*
* private class Policy extends eu.chainfire.libsuperuser.Policy {
* {@literal @}Override protected String[] getPolicies() {
* return new String[] {
* "allow sdcardd unlabeled dir { append create execute write relabelfrom link unlink ioctl getattr setattr read rename lock mounton quotaon swapon rmdir audit_access remove_name add_name reparent execmod search open }",
* "allow sdcardd unlabeled file { append create write relabelfrom link unlink ioctl getattr setattr read rename lock mounton quotaon swapon audit_access open }",
* "allow unlabeled unlabeled filesystem associate"
* };
* }
* };
* private Policy policy = new Policy();
*
* public void someFunctionNotCalledOnMainThread() {
* policy.inject();
* }
*
* </code>
* </pre>
*/
@SuppressWarnings({"WeakerAccess", "UnusedReturnValue", "unused"})
public abstract class Policy {
/**
* supolicy should be called as little as possible. We batch policies together. The command
* line is guaranteed to be able to take 4096 characters. Reduce by a bit for supolicy itself.
*/
private static final int MAX_POLICY_LENGTH = 4096 - 32;
private static final Object synchronizer = new Object();
@Nullable
private static volatile Boolean canInject = null;
private static volatile boolean injected = false;
/**
* @return Have we injected our policies already?
*/
@AnyThread
public static boolean haveInjected() {
return injected;
}
/**
* Reset policies-have-been-injected state, if you really need to inject them again. Extremely
* rare, you will probably never need this.
*/
@AnyThread
public static void resetInjected() {
synchronized (synchronizer) {
injected = false;
}
}
/**
* Override this method to return a array of strings containing the policies you want to inject.
*
* @return Policies to inject
*/
@NonNull
protected abstract String[] getPolicies();
/**
* Detects availability of the supolicy tool. Only useful if Shell.SU.isSELinuxEnforcing()
* returns true. Caches return value, can safely be called from the UI thread <b>if</b> a
* a cached value exists.
*
* @see #resetCanInject()
*
* @return canInject?
*/
@SuppressWarnings({"deprecation", "ConstantConditions"})
@WorkerThread // first call only
public static boolean canInject() {
synchronized (synchronizer) {
if (canInject != null) return canInject;
canInject = false;
// We are making the assumption here that if supolicy is called without parameters,
// it will return output (such as a usage notice) on STDOUT (not STDERR) that contains
// at least the word "supolicy". This is true at least for SuperSU.
List<String> result = Shell.run("sh", new String[] { "supolicy" }, null, false);
if (result != null) {
for (String line : result) {
if (line.contains("supolicy")) {
canInject = true;
break;
}
}
}
return canInject;
}
}
/**
* Reset cached can-inject state and force redetection on nect canInject() call
*/
@AnyThread
public static void resetCanInject() {
synchronized (synchronizer) {
canInject = null;
}
}
/**
* Transform the policies defined by getPolicies() into a set of shell commands
*
* @return Possibly empty List of commands, or null
*/
@Nullable
protected List<String> getInjectCommands() {
return getInjectCommands(true);
}
/**
* Transform the policies defined by getPolicies() into a set of shell commands
*
* @param allowBlocking allow method to perform blocking I/O for extra checks
* @return Possibly empty List of commands, or null
*/
@Nullable
@SuppressWarnings("all")
@WorkerThread // if allowBlocking
protected List<String> getInjectCommands(boolean allowBlocking) {
synchronized (synchronizer) {
// No reason to bother if we're in permissive mode
if (!Shell.SU.isSELinuxEnforcing()) return null;
// If we can't inject, no use continuing
if (allowBlocking && !canInject()) return null;
// Been there, done that
if (injected) return null;
// Retrieve policies
String[] policies = getPolicies();
if ((policies != null) && (policies.length > 0)) {
List<String> commands = new ArrayList<String>();
// Combine the policies into a minimal number of commands
String command = "";
for (String policy : policies) {
if ((command.length() == 0) || (command.length() + policy.length() + 3 < MAX_POLICY_LENGTH)) {
command = command + " \"" + policy + "\"";
} else {
commands.add("supolicy --live" + command);
command = "";
}
}
if (command.length() > 0) {
commands.add("supolicy --live" + command);
}
return commands;
}
// No policies
return null;
}
}
/**
* Inject the policies defined by getPolicies(). Throws an exception if called from
* the main thread in debug mode.
*/
@SuppressWarnings({"deprecation"})
@WorkerThread
public void inject() {
synchronized (synchronizer) {
// Get commands that inject our policies
List<String> commands = getInjectCommands();
// Execute them, if any
if ((commands != null) && (commands.size() > 0)) {
Shell.SU.run(commands);
}
// We survived without throwing
injected = true;
}
}
/**
* Inject the policies defined by getPolicies(). Throws an exception if called from
* the main thread in debug mode if waitForIdle is true. If waitForIdle is false
* however, it cannot be guaranteed the command was executed and the policies injected
* upon return.
*
* @param shell Interactive shell to execute commands on
* @param waitForIdle wait for the command to complete before returning?
*/
@WorkerThread // if waitForIdle
public void inject(@NonNull Shell.Interactive shell, boolean waitForIdle) {
synchronized (synchronizer) {
// Get commands that inject our policies
List<String> commands = getInjectCommands(waitForIdle);
// Execute them, if any
if ((commands != null) && (commands.size() > 0)) {
shell.addCommand(commands);
if (waitForIdle) {
shell.waitForIdle();
}
}
// We survived without throwing
injected = true;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2012-2014 Jorrit "Chainfire" Jongma
* Copyright (C) 2012-2019 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@ -21,11 +21,27 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.List;
import java.util.Locale;
import androidx.annotation.AnyThread;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
/**
* Thread utility class continuously reading from an InputStream
*/
@SuppressWarnings({"WeakerAccess"})
public class StreamGobbler extends Thread {
private static int threadCounter = 0;
private static int incThreadCounter() {
synchronized (StreamGobbler.class) {
int ret = threadCounter;
threadCounter++;
return ret;
}
}
/**
* Line callback interface
*/
@ -42,10 +58,30 @@ public class StreamGobbler extends Thread {
void onLine(String line);
}
private String shell = null;
private BufferedReader reader = null;
private List<String> writer = null;
private OnLineListener listener = null;
/**
* Stream closed callback interface
*/
public interface OnStreamClosedListener {
/**
* <p>Stream closed callback</p>
*/
void onStreamClosed();
}
@NonNull
private final String shell;
@NonNull
private final InputStream inputStream;
@NonNull
private final BufferedReader reader;
@Nullable
private final List<String> writer;
@Nullable
private final OnLineListener lineListener;
@Nullable
private final OnStreamClosedListener streamClosedListener;
private volatile boolean active = true;
private volatile boolean calledOnClose = false;
/**
* <p>StreamGobbler constructor</p>
@ -56,12 +92,17 @@ public class StreamGobbler extends Thread {
*
* @param shell Name of the shell
* @param inputStream InputStream to read from
* @param outputList List<String> to write to, or null
* @param outputList {@literal List<String>} to write to, or null
*/
public StreamGobbler(String shell, InputStream inputStream, List<String> outputList) {
@AnyThread
public StreamGobbler(@NonNull String shell, @NonNull InputStream inputStream, @Nullable List<String> outputList) {
super("Gobbler#" + incThreadCounter());
this.shell = shell;
this.inputStream = inputStream;
reader = new BufferedReader(new InputStreamReader(inputStream));
writer = outputList;
lineListener = null;
streamClosedListener = null;
}
/**
@ -74,25 +115,45 @@ public class StreamGobbler extends Thread {
* @param shell Name of the shell
* @param inputStream InputStream to read from
* @param onLineListener OnLineListener callback
* @param onStreamClosedListener OnStreamClosedListener callback
*/
public StreamGobbler(String shell, InputStream inputStream, OnLineListener onLineListener) {
@AnyThread
public StreamGobbler(@NonNull String shell, @NonNull InputStream inputStream, @Nullable OnLineListener onLineListener, @Nullable OnStreamClosedListener onStreamClosedListener) {
super("Gobbler#" + incThreadCounter());
this.shell = shell;
this.inputStream = inputStream;
reader = new BufferedReader(new InputStreamReader(inputStream));
listener = onLineListener;
lineListener = onLineListener;
streamClosedListener = onStreamClosedListener;
writer = null;
}
@Override
public void run() {
// keep reading the InputStream until it ends (or an error occurs)
// optionally pausing when a command is executed that consumes the InputStream itself
try {
String line;
while ((line = reader.readLine()) != null) {
Debug.logOutput(String.format("[%s] %s", shell, line));
Debug.logOutput(String.format(Locale.ENGLISH, "[%s] %s", shell, line));
if (writer != null) writer.add(line);
if (listener != null) listener.onLine(line);
if (lineListener != null) lineListener.onLine(line);
while (!active) {
synchronized (this) {
try {
this.wait(128);
} catch (InterruptedException e) {
// no action
}
}
}
}
} catch (IOException e) {
// reader probably closed, expected exit condition
if (streamClosedListener != null) {
calledOnClose = true;
streamClosedListener.onStreamClosed();
}
}
// make sure our stream is closed and resources will be freed
@ -101,5 +162,96 @@ public class StreamGobbler extends Thread {
} catch (IOException e) {
// read already closed
}
if (!calledOnClose) {
if (streamClosedListener != null) {
calledOnClose = true;
streamClosedListener.onStreamClosed();
}
}
}
/**
* <p>Resume consuming the input from the stream</p>
*/
@AnyThread
public void resumeGobbling() {
if (!active) {
synchronized (this) {
active = true;
this.notifyAll();
}
}
}
/**
* <p>Suspend gobbling, so other code may read from the InputStream instead</p>
*
* <p>This should <i>only</i> be called from the OnLineListener callback!</p>
*/
@AnyThread
public void suspendGobbling() {
synchronized (this) {
active = false;
this.notifyAll();
}
}
/**
* <p>Wait for gobbling to be suspended</p>
*
* <p>Obviously this cannot be called from the same thread as {@link #suspendGobbling()}</p>
*/
@WorkerThread
public void waitForSuspend() {
synchronized (this) {
while (active) {
try {
this.wait(32);
} catch (InterruptedException e) {
// no action
}
}
}
}
/**
* <p>Is gobbling suspended ?</p>
*
* @return is gobbling suspended?
*/
@AnyThread
public boolean isSuspended() {
synchronized (this) {
return !active;
}
}
/**
* <p>Get current source InputStream</p>
*
* @return source InputStream
*/
@NonNull
@AnyThread
public InputStream getInputStream() {
return inputStream;
}
/**
* <p>Get current OnLineListener</p>
*
* @return OnLineListener
*/
@Nullable
@AnyThread
public OnLineListener getOnLineListener() {
return lineListener;
}
void conditionalJoin() throws InterruptedException {
if (calledOnClose) return; // deadlock from callback, we're inside exit procedure
if (Thread.currentThread() == this) return; // can't join self
join();
}
}

View File

@ -0,0 +1,122 @@
/*
* Copyright (C) 2012-2019 Jorrit "Chainfire" Jongma
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.chainfire.libsuperuser;
import android.os.Build;
import java.util.List;
import java.util.Locale;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
/**
* Utility class to decide between toolbox and toybox calls on M.
* Note that some calls (such as 'ls') are present in both, this
* class will favor toybox variants.
*
* This may not be what you want, as both syntax and output may
* differ between the variants.
*
* Very specific warning, the 'mount' included with toybox tends
* to segfault, at least on the first few 6.0 firmwares.
*/
@SuppressWarnings({"unused", "WeakerAccess", "deprecation"})
public class Toolbox {
private static final int TOYBOX_SDK = 23;
private static final Object synchronizer = new Object();
@Nullable
private static volatile String toybox = null;
/**
* Initialize. Asks toybox which commands it supports. Throws an exception if called from
* the main thread in debug mode.
*/
@SuppressWarnings("all")
@WorkerThread
public static void init() {
// already inited ?
if (toybox != null) return;
// toybox is M+
if (Build.VERSION.SDK_INT < TOYBOX_SDK) {
toybox = "";
} else {
if (Debug.getSanityChecksEnabledEffective() && Debug.onMainThread()) {
Debug.log(Shell.ShellOnMainThreadException.EXCEPTION_TOOLBOX);
throw new Shell.ShellOnMainThreadException(Shell.ShellOnMainThreadException.EXCEPTION_TOOLBOX);
}
// ask toybox which commands it has, and store the info
synchronized (synchronizer) {
toybox = "";
List<String> output = Shell.SH.run("toybox");
if (output != null) {
toybox = " ";
for (String line : output) {
toybox = toybox + line.trim() + " ";
}
}
}
}
}
/**
* Format a command string, deciding on toolbox or toybox for its execution
*
* If init() has not already been called, it is called for you, which may throw an exception
* if we're in the main thread.
*
* Example:
* Toolbox.command("chmod 0.0 %s", "/some/file/somewhere");
*
* Output:
* &lt; M: "toolbox chmod 0.0 /some/file/somewhere"
* M+ : "toybox chmod 0.0 /some/file/somewhere"
*
* @param format String to format. First word is the applet name.
* @param args Arguments passed to String.format
* @return Formatted String prefixed with either toolbox or toybox
*/
@SuppressWarnings("ConstantConditions")
@WorkerThread // if init() not yet called
public static String command(@NonNull String format, Object... args) {
if (Build.VERSION.SDK_INT < TOYBOX_SDK) {
return String.format(Locale.ENGLISH, "toolbox " + format, args);
}
if (toybox == null) init();
format = format.trim();
String applet;
int p = format.indexOf(' ');
if (p >= 0) {
applet = format.substring(0, p);
} else {
applet = format;
}
if (toybox.contains(" " + applet + " ")) {
return String.format(Locale.ENGLISH, "toybox " + format, args);
} else {
return String.format(Locale.ENGLISH, "toolbox " + format, args);
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

After

Width:  |  Height:  |  Size: 4.2 KiB

View File

@ -2,17 +2,24 @@
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:layout_margin="10dp" >
android:layout_margin="@dimen/default_margin" >
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/urlToTriggerExplanation"
android:layout_marginBottom="@dimen/default_margin"/>
<TextView
android:id="@+id/tvRuleTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textStyle="bold"
android:text="@string/urlToTrigger" />
<EditText

View File

@ -0,0 +1,193 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="@dimen/default_margin" >
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical" >
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:text="@string/phoneCall" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="1"
android:stretchColumns="1" >
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/state" />
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/rbTriggerPhoneCallStateRinging"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/ringing" />
<RadioButton
android:id="@+id/rbTriggerPhoneCallStateStarted"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/started" />
<RadioButton
android:id="@+id/rbTriggerPhoneCallStateStopped"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/stopped" />
</RadioGroup>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_span="2"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:background="#aa000000" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/phoneDirection" />
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:id="@+id/rbTriggerPhoneCallDirectionAny"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/any" />
<RadioButton
android:id="@+id/rbTriggerPhoneCallDirectionIncoming"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/incoming" />
<RadioButton
android:id="@+id/rbTriggerPhoneCallDirectionOutgoing"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/outgoing" />
</RadioGroup>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:layout_span="2"
android:layout_width="match_parent"
android:layout_height="1dp"
android:layout_margin="10dp"
android:background="#aa000000" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:text="@string/phoneNumber" />
<EditText
android:id="@+id/etTriggerPhoneCallPhoneNumber"
android:inputType="text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:text="@string/phoneNumberExplanation" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:layout_span="2"
android:text="@string/urlRegex" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:id="@+id/bTriggerPhoneCallImportFromContacts"
android:layout_marginVertical="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_span="2"
android:text="@string/importNumberFromContacts" />
</TableRow>
</TableLayout>
<Button
android:id="@+id/bSaveTriggerPhoneCall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</androidx.appcompat.widget.LinearLayoutCompat>
</ScrollView>

View File

@ -0,0 +1,90 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_margin="@dimen/default_margin">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/wifiConnection"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:layout_marginBottom="@dimen/default_margin" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="1"
android:stretchColumns="1" >
<TableRow>
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingRight="@dimen/default_margin"
android:text="@string/state"/>
<RadioGroup
android:layout_height="wrap_content"
android:layout_width="match_parent">
<RadioButton
android:id="@+id/rbTriggerWifiConnected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:checked="true"
android:text="@string/connected" />
<RadioButton
android:id="@+id/rbTriggerWifiDisconnected"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="@string/disconnected" />
</RadioGroup>
</TableRow>
<TableRow>
<TextView
android:layout_height="wrap_content"
android:layout_width="match_parent"
android:paddingRight="@dimen/default_margin"
android:text="@string/name"/>
<EditText
android:id="@+id/etTriggerWifiName"
android:layout_height="wrap_content"
android:layout_width="match_parent" />
</TableRow>
<TableRow>
<Button
android:id="@+id/bLoadWifiList"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/loadWifiList" />
<Spinner
android:id="@+id/spinnerWifiList"
android:enabled="false"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</TableRow>
</TableLayout>
<Button
android:id="@+id/btriggerWifiSave"
android:layout_marginTop="@dimen/default_margin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/save" />
</androidx.appcompat.widget.LinearLayoutCompat>

View File

@ -1,19 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<TabHost xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@android:id/tabhost"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
android:layout_width="match_parent"
android:layout_height="match_parent">
<TabWidget
android:id="@android:id/tabs"
android:layout_width="fill_parent"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<FrameLayout
android:id="@android:id/tabcontent"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</LinearLayout>
</TabHost>

View File

@ -1,113 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_margin="@dimen/default_margin"
android:orientation="vertical"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAppearance="@style/TextAppearance.AppCompat.Headline"
android:text="@string/phoneCall" />
<TableLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:shrinkColumns="1"
android:stretchColumns="1" >
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/state" />
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/started" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/stopped" />
</RadioGroup>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/phoneDirection" />
<RadioGroup
android:layout_width="wrap_content"
android:layout_height="wrap_content" >
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/incoming" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/outgoing" />
</RadioGroup>
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/phoneNumber" />
<EditText
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/phoneNumberExplanation" />
</TableRow>
<TableRow
android:layout_width="match_parent"
android:layout_height="wrap_content" >
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/importNumberFromContacts" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/phoneNumberExplanation" />
</TableRow>
</TableLayout>
</androidx.appcompat.widget.LinearLayoutCompat>

View File

@ -1,6 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Automation</string>
<string name="ruleActivate">Aktiviere Regel %1$s</string>
<string name="profileActivate">Aktiviere Profil %1$s</string>
<string name="ruleActivateToggle">Aktiviere Regel %1$s im Umschaltmodus</string>
@ -14,28 +13,16 @@
<string name="serviceWontStart">Weder Orte noch Regeln sind definitiv. Dienst wird nicht starten.</string>
<string name="serviceStarted">Automations-Dienst gestarted.</string>
<string name="version">Version %1$s.</string>
<string name="logServiceStarting">Dienst wird gestartet.</string>
<string name="logNotAllMeasurings">Es stehen noch nicht alle Messwerte zur Verfügung. Es kann noch kein Vergleich vorgenommen werden.</string>
<string name="distanceBetween">Der Abstand zwischen GPS- und Mobilfunk-Position beträgt</string>
<string name="radiusSuggestion">Meter. Dies +1 sollte der minimale Radius sein.</string>
<string name="distanceBetween">Der Abstand zwischen GPS- und Mobilfunk-Position beträgt %1$d m. Dies +1 sollte der minimale Radius sein.</string>
<string name="comparing">Sowohl Netzwerk- als auch GPS Position sind bekannt. Vergleiche...</string>
<string name="logNoSuitableProvider">Kein brauchbarer Positionsanbieter verfügbar.</string>
<string name="positioningWindowNotice">Falls Sie in einem Gebäude sind wird empfohlen das Gerät in die Nähe eines Fensters zu bringen bis eine Position ermittelt werden konnte. Andernfalls kann es sehr lange dauern oder es funktioniert gar nicht.</string>
<string name="gettingPosition">Position wird ermittelt. Bitte warten...</string>
<string name="logGettingPositionWithProvider">Position wird ermittelt mit Anbieter:</string>
<string name="yes">Ja</string>
<string name="no">Nein</string>
<string name="logGotGpsUpdate">GPS Position erhalten. Genauigkeit:</string>
<string name="logGotNetworkUpdate">Netzwerk Position erhalten. Genauigkeit:</string>
<string name="pleaseEnterValidLatitude">Bitte geben Sie einen gültigen Breitengrad an.</string>
<string name="pleaseEnterValidLongitude">Bitte geben Sie einen gültigen Längengrad an.</string>
<string name="pleaseEnterValidRadius">Bitte geben Sie einen gültigen positiven Radius an.</string>
<string name="selectOneDay">Bitte wählen Sie wenigstens einen Tag aus.</string>
<string name="logAttemptingToBindToService">Versuche zum Dienst zu verbinden... </string>
<string name="logAttemptingToUnbindFromService">Versuche vom Dienst zu trennen... </string>
<string name="logBoundToService">Zum Dienst verbunden.</string>
<string name="logUnboundFromService">Vom Dienst getrennt.</string>
<string name="logServiceAlreadyRunning">Befehl zum Starten des Dienstes, aber er läuft bereits.</string>
<string name="whatToDoWithRule">Was soll mit der Regel gemacht werden?</string>
<string name="whatToDoWithPoi">Was soll mit dem Ort gemacht werden?</string>
<string name="whatToDoWithProfile">Was soll mit dem Profil gemacht werden?</string>
@ -121,14 +108,14 @@
<string name="gpsAccuracy">GPS Genauigkeit [m]</string>
<string name="satisfactoryAccuracyNetwork">Genauigkeit für Mobilfunk Änderungen in Metern</string>
<string name="networkAccuracy">Mobilfunk Genauigkeit [m]</string>
<string name="minimumTimeForLocationUpdates">Minimale Zeitänderung in Sekunden für Positionsupdates</string>
<string name="minimumTimeForLocationUpdates">Minimale Zeitänderung in Millisekunden für Positionsupdates</string>
<string name="timeForUpdate">Zeit für Updates [millisek]</string>
<string name="soundSettings">Ton Einstellungen</string>
<string name="showHelp">Hilfe</string>
<string name="rules">Regeln</string>
<string name="helpTextRules">Alle Auslöser sind UND-verknüpft. D.h. die Regel wird nur zutreffen, wenn alle Bedingungen erfüllt sind. Wenn Sie eine ODER-Verknüpfung möchten, müssen Sie eine weitere Regel erstellen.</string>
<string name="timeframes">Zeiträume</string>
<string name="helpTextTimeFrame">Wenn Sie eine Regel mit einem oder mehreren Zeiträumen erstellen, haben Sie zwei Möglichkeiten. Sie können wählen, ob der Auslöser besagt, daß der Zeitraum entweder verlassen ODER betreten wird. In jedem Fall wird die Regel nur einmal ausgelöst.\nWenn eine Regel z.B. besagt \"betrete timeframe xyz\" und das Klingeltonprofil in Vibration ändert, bedeutet das NICHT, daß das Gerät hinterher automatisch wieder zum normalen Klingelprofil zurückschaltet. Wenn das erwünscht ist, muß eine weitere Regel mit einem Folgezeitraum erstellen werden.</string>
<string name="helpTextTimeFrame">Wenn Sie eine Regel mit einem Zeitraum erstellen, haben Sie zwei Möglichkeiten. Sie können wählen, ob der Auslöser besagt, daß der Zeitraum entweder verlassen ODER betreten wird. In jedem Fall wird die Regel nur einmal ausgelöst. Wenn eine Regel z.B. besagt \"betrete timeframe xyz\" und das Klingeltonprofil in Vibration ändert, bedeutet das NICHT, daß das Gerät hinterher automatisch wieder zum normalen Klingelprofil zurückschaltet. Wenn das erwünscht ist, muß eine weitere Regel mit einem Folgezeitraum erstellen werden.</string>
<string name="helpTextSound">Auf dem Hauptbildschirm können Sie die Funktion Tonänderunugen sperren benutzen, um vorrübergehend regelbasierte Tonänderungen zu deaktivieren. Z.B. könnten Sie in einer Situation oder an einem Ort sein, wo Klingeltöne normalerweise in Ordnung sind, aber dieses eine Mal würde es stören. Die Funktion wird automatisch wieder deaktiviert nachdem die eingestellte Zeit abgelaufen ist. Klicken Sie den + Knopf, um die angezeigte Zeit zur Frist hinzuzufügen. Sobald es aktiv ist, können Sie es mit dem Schalter rechts wieder abschalten (und so regelbasierte Tonänderungen wieder ermöglichen).</string>
<string name="toggableRules">Umkehrbare Regeln</string>
<string name="helpTextToggable">Regeln haben eine Einstellung namens \"Umschaltbar\". Das bedeutet: Wurde eine Regel ausgeführt und anschließend treten dieselben Auslöser wieder ein, wird die Regel nochmal in umgekehrter Weise ausgeführt, wo es möglich ist. Gegenwärtig funktioniert das nur im Zusammenspiel mit NFC Tags. Wenn Sie einen Tag zwei Mal berühren und es eine umschaltbare Regel zu diesem Tag gibt, wird das Programm das Gegenteil von gegenwärtigen Zustand tun, z.B. WLAN ausschalten, wenn es gegenwärtig eingeschaltet ist.</string>
@ -146,7 +133,7 @@
<string name="lengthOfNoiseLevelMeasurementsTitle">Länge einer Lautstärkemessung in Sekunden</string>
<string name="referenceValueForNoiseLevelMeasurementsSummary">Physikalischer Referenzwert für Lautstärkemessungen</string>
<string name="referenceValueForNoiseLevelMeasurementsTitle">Referenz für Lautstärkemessungen</string>
<string name="logLevelSummary">Protokollierungsgrad (1=minimum, 5=maximum)</string>
<string name="logLevelSummary">Protokollierungsgrad (1=Minimum, 5=Maximum)</string>
<string name="logLevelTitle">Protokollierungsgrad</string>
<string name="ruleActive">Regel aktiv</string>
<string name="triggerPointOfInterest">Ort</string>
@ -189,7 +176,6 @@
<string name="general">Allgemein</string>
<string name="generalText">Um dieses Programm zu benutzen, müssen Sie Regeln anlegen. Diese enthalten Auslöser (z.B. ob Sie ein bestimmtes Gebiet betreten oder eine bestimmte Zeitspanne beginnt). Nachdem Sie dies erledigt haben, klicken Sie auf den Ein/Aus Schalter auf dem Hauptbildschirm.</string>
<string name="unknownActionSpecified">Unbekannte Aktion definiert.</string>
<string name="errorTriggeringUrl">Fehler beim Aufrufen der URL</string>
<string name="errorChangingScreenRotation">Fehler beim Ändern der Bildschirmrotation</string>
<string name="errorDeterminingWifiApState">Fehler bei der Statusprüfung des WLAN Routers</string>
<string name="errorActivatingWifiAp">Fehler beim Aktivieren des WLAN Routers</string>
@ -210,16 +196,6 @@
<string name="wifiName">WLAN name</string>
<string name="enterWifiName">Geben Sie den Namen des WLANs ein (SSID). Leer lassen für irgendein WLAN.</string>
<string name="cancel">Abbrechen</string>
<string name="ruleDoesntApplyWeAreSlowerThan">Regel trifft nicht zu. Wir sind langsamer als</string>
<string name="ruleDoesntApplyWeAreFasterThan">Regel trifft nicht zu. Wir sind schneller als</string>
<string name="ruleDoesntApplyItsQuieterThan">Regel trifft nicht zu. Es ist ruhiger als</string>
<string name="ruleDoesntApplyItsLouderThan">Regel trifft nicht zu. Es ist lauter als</string>
<string name="ruleDoesntApplyBatteryLowerThan">Regel trifft nicht zu. Akkustand ist niedriger als</string>
<string name="ruleDoesntApplyBatteryHigherThan">Regel trifft nicht zu. Akkustand ist höher als</string>
<string name="ruleDoesntApplyNotTheCorrectSsid">Regel trifft nicht zu. Nicht die korrekte SSID (gefordert: \"%1$s\", gegeben: \"%2$s\").</string>
<string name="ruleDoesntApplyNoTagLabel">Regel trifft nicht zu. Keine Tag Bezeichnung oder kein Tag.</string>
<string name="ruleDoesntApplyWrongTagLabel">Regel trifft nicht zu. Falsche Tag Bezeichnung.</string>
<string name="ruleIsDeactivatedCantApply">Regel %1$s ist deaktiviert, kann nicht zutreffen.</string>
<string name="starting">starte</string>
<string name="stopping">stoppe</string>
<string name="connecting">verbinde</string>
@ -242,12 +218,8 @@
<string name="runManually">Manuell ausführen</string>
<string name="serviceHasToRunForThat">Der Dienst muß dafür laufen.</string>
<string name="gpsComparison">GPS Vergleich</string>
<string name="gpsComparisonTimeoutStop">Stoppe GPS Vergleichsmessung, Zeitlimit überschritten.</string>
<string name="timeoutForGpsComparisonsTitle">GPS Zeitlimit [sek]</string>
<string name="timeoutForGpsComparisonsSummary">Zeitlimit in Sekunden wie lange versucht wird eine GPS Vergleichsposition zu finden. Danach wird die letzte bekannte Position übernommen.</string>
<string name="startingGpsTimeout">Starting GPS timeout.</string>
<string name="forcedLocationUpdate">Erzwungenes Positionsupdate</string>
<string name="forcedLocationUpdateLong">Da Zeitlimit für Vergleichsmessung überschritten wird jetzt die letzte bekannte Position übernommen.</string>
<string name="rememberLastActivePoiSummary">Wenn Sie an einem Ort sind, Ihr Gerät oder die Anwendung neustarten und den Ort verlassen wird die Anwendung beim nächsten Start Regeln ausführen, die für das Verlassen des Orts definiert sind.</string>
<string name="rememberLastActivePoiTitle">Merke den zuletzt aktiven Ort</string>
<string name="muteTextToSpeechDuringCallsTitle">Während Telefonaten stumm</string>
@ -263,35 +235,14 @@
<string name="settingsCategoryProcessMonitoring">Prozess Überwachung</string>
<string name="timeBetweenProcessMonitoringsTitle">Sekunden zwischen Prozess-Überwachungen</string>
<string name="timeBetweenProcessMonitoringsSummary">Je niedriger desto höher der Akkuverbrauch</string>
<string name="refreshingProcessList">Refreshing process list.</string>
<string name="processes">Processes</string>
<string name="startingPeriodicProcessMonitoringEngine">Starting periodic process monitoring engine.</string>
<string name="processMonitoring">Prozessüberwachung</string>
<string name="periodicProcessMonitoringIsAlreadyRunning">Periodische Prozessüberwachung läuft bereits. Kann sie nicht nochmal starten.</string>
<string name="stoppingPeriodicProcessMonitoringEngine">Stoppe Prozessüberwachungs-Dienst.</string>
<string name="periodicProcessMonitoringIsNotActive">Prozessüberwachung läuft nicht. Kann sie nicht stoppen.</string>
<string name="periodicProcessMonitoringStarted">Prozessüberwachung gestarted.</string>
<string name="periodicProcessMonitoringStopped">Prozessüberwachung gestopped.</string>
<string name="rearmingProcessMonitoringMessage">Prozessüberwachung wird erneut scharf geschaltet.</string>
<string name="notRearmingProcessMonitoringMessageStopRequested">Schalte Prozessüberwachung nicht erneut scharf, Stop angefragt.</string>
<string name="messageReceivedStatingProcessMonitoringIsComplete">Nachricht erhalten, die besagt, daß Prozessüberwachung fertig ist.</string>
<string name="appStarted">App gestarted.</string>
<string name="appStopped">App gestopped.</string>
<string name="runningApp">Laufende app</string>
<string name="errorWritingSettingsToPersistentMemory">Fehler beim Speichern der Einstellungen.</string>
<string name="settings">Einstellungen</string>
<string name="writingSettingsToPersistentMemory">Einstellungen werden gespeichert.</string>
<string name="refreshingSettingsFromFileToMemory">Einstellungen werden neu geladen.</string>
<string name="errorReadingSettings">Fehler beim Lesen der Einstellungen.</string>
<string name="invalidStuffStoredInSettingsErasing">Ungültige Daten in den Einstellungen gefunden. Einstellungen werden gelöscht.</string>
<string name="initializingSettingsToPersistentMemory">Einstellungen werden in nicht flüchtigen Speicher initialisiert.</string>
<string name="errorInitializingSettingsToPersistentMemory">Fehler beim Initialisieren der Einstellungen.</string>
<string name="settingsErased">Einstellungen gelöscht.</string>
<string name="settingsSetToDefault">Einstellungen auf Standardwerte gesetzt.</string>
<string name="batteryLevel">Akkustand</string>
<string name="selectSpeed">Geschwindigkeit wählen</string>
<string name="selectBattery">Akkustand wählen</string>
<string name="applyingSettingsAndRules">Aktualisiere Einstellungen, Regeln und Orte.</string>
<string name="privacy">Datenschutzerklärung</string>
<string name="privacyConfirmationText">Ein Browser wird nun geöffnet und die Datenschutzerklärung von der Webseite des Entwicklers laden.</string>
<string name="waitBeforeNextAction">Vor der nächsten Aktion warten</string>
@ -303,9 +254,6 @@
<string name="moveDown">Herunterschieben</string>
<string name="cantMoveUp">Das Objekt kann nicht weiter hochgeschoben werden.</string>
<string name="cantMoveDown">Das Objekt kann nicht weiter heruntergeschoben werden.</string>
<string name="wifiNameSpecifiedCheckingThat">WLAN SSID angegeben, überprüfe...</string>
<string name="wifiNameMatchesRuleWillApply">WLAN SSID stimmt überein. Regel trifft zu.</string>
<string name="noWifiNameSpecifiedAnyWillDo">Keine WLAN SSID angegeben. Jedes WLAN trifft zu.</string>
<string name="ruleCheckOf">RuleCheck von %1$s</string>
<string name="airplaneMode">Flugmodus</string>
<string name="activate">Aktivieren</string>
@ -364,7 +312,6 @@
<string name="nfcNoNdefIntentBut">Kein NFC NDEF intent, sondern</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC wird in dieser Android Version noch nicht unterstützt.</string>
<string name="cantRunRule">Regeln können nicht ausgeführt werden.</string>
<string name="cantDownloadTooFewRequestsInSettings">Kann nichts runterladen. Menge an erlaubten Versuchen ist in den Einstellungen auf weniger als 1 gesetzt.</string>
<string name="nfcApplyTagToRule">Aktuellen Tag in Regel übernehmen</string>
<string name="nfcTagReadSuccessfully">Tag erfolgreich gelesen.</string>
<string name="nfcValueNotSuitable">Gepspeicherter Wert nicht geeignet.</string>
@ -401,8 +348,6 @@
<string name="detectedActivityWalking">Gehen</string>
<string name="detectedActivityRunning">Laufen</string>
<string name="detectedActivityInvalidStatus">Ungültige Tätigkeit</string>
<string name="ruleDoesntApplyActivityGivenButTooLowProbability">Regel trifft nicht zu. Erkannte Tätigkeit %1$s gegebenem, aber mit zu niedriger Wahrscheinlichkeit (%2$s %%), gefordert %3$s %%.</string>
<string name="ruleDoesntApplyActivityNotPresent">Regel trifft nicht zu. Geforderte Tätigkeit %1$s passiert gerade nicht.</string>
<string name="selectTypeOfActivity">Art der Tätigkeit auswählen</string>
<string name="triggerOnlyAvailableIfPlayServicesInstalled">Dieser Auslöser kann nur verwendet werden, wenn die Google Play Dienste installiert sind.</string>
<string name="activityDetectionFrequencyTitle">Frequenz für Aktivitätserkennung [sek]</string>
@ -410,7 +355,7 @@
<string name="activityDetectionRequiredProbabilityTitle">Wahrscheinlichkeit für Aktivitätserkennungen</string>
<string name="activityDetectionRequiredProbabilitySummary">Wahrscheinlichkeit, ab der eine Aktivität als gegeben gilt.</string>
<string name="incomingCallFrom">Eingehender Telefonanruf von %1$s.</string>
<string name="outgoingCallFrom">Ausgehender Telefonanruf von %1$s.</string>
<string name="outgoingCallTo">Ausgehender Telefonanruf von %1$s.</string>
<string name="actionSpeakText">Text sprechen</string>
<string name="textToSpeak">Zu sprechender Text</string>
<string name="toggleNotAllowed">Die Umschaltfunktion ist momentan nur für Regeln erlaubt, die NFC Tags als Auslöser haben. Für weitere Informationen lesen Sie die Hilfe.</string>
@ -442,22 +387,12 @@
<string name="headphoneMicrophone">Mikrofon</string>
<string name="headphoneAny">Egal</string>
<string name="headphoneSelectType">Kopfhörer Typ auswählen</string>
<string name="ruleDoesntApplyWrongHeadphoneType">Regel trifft nicht zu. Falscher Kopfhörertyp.</string>
<string name="ignoringActivityDetectionUpdateTooSoon">Ignoriere Aktivitätserkennungsupdate. Kam früher rein als %1$s Sekunden.</string>
<string name="whatsThis">Was ist das?</string>
<string name="atLeastRuleXisUsingY">Mindestens Regel \"%1$s\" nutzt einen Auslöser vom Typ \"%2$s\".</string>
<string name="privacyLocationingTitle">Private Ortung verwenden</string>
<string name="privacyLocationingSummary">Ortungsmethoden vermeiden, die Ihre Position dazu an einen Anbieter übermitteln, z.B. Google. Dies wird nur GPS verwenden und daher langsam sein oder nicht ausreichend zuverlässig funktionieren.</string>
<string name="enforcingGps">Private Ortung aktiviert, erzwinge GPS Verwendung.</string>
<string name="notEnforcingGps">Private Ortung nicht aktiviert, verwende reguläre Anbieterauswahl.</string>
<string name="gpsMeasurement">GPS Messung</string>
<string name="gpsMeasurementTimeout">GPS Messung aufgrund Timeout gestoppt.</string>
<string name="cellMastChanged">Mobilfunkmast geändert: %1$s</string>
<string name="noiseDetectionHint">Wenn Sie denken die Lautstärkeerkennung arbeitet nicht korrekt (abhängig von dem Wert, den Sie angeben), bedenken Sie bitte, daß jedes Telefon unterschiedlich ist. In den Einstellungen können Sie daher die \"Referenz für Lautstärkemessungen\" ändern. Für weitere Informationen siehe http://de.wikipedia.org/wiki/Schalldruckpegel. Sie können den Lautstärkentester vom Hauptbildschirm aus aufrufen, um Ihr Gerät zu kalibrieren.</string>
<string name="hint">Hinweis</string>
<string name="selectNoiseLevel">Lautstärkepegel auswählen</string>
<string name="poiHasWifiStoppingCellLocationListener">Ort hat WLAN. Stoppe CellLocationListener.</string>
<string name="poiHasNoWifiNotStoppingCellLocationListener">Ort hat kein WLAN. Stoppe CellLocationListener nicht.</string>
<string name="showOnMap">Auf Karte zeigen</string>
<string name="noMapsApplicationFound">Auf Ihrem Gerät konnte keine Kartenanwendung gefunden werden.</string>
<string name="locationEngineNotActive">Positionsbestimmung nicht aktiv.</string>
@ -503,10 +438,6 @@
<string name="volumeTest">Lautstärkentest</string>
<string name="volumeTesterExplanation">Um einen dB Wert für die Lautstärkemessung zu berechnen müssen Sie einen sogenannten physikalischen Referenzwert angeben. Bitte lesen Sie bei Wikipedia nach, um mehr zu erfahren. Dieser Wert wird höchstwahrscheinlich für jedes Smartphone oder Tablet anders sein, deshalb diese Testanwendung. Verschieben Sie den Regler, um den gegenwärtig definierten Wert zu ändern. Je höher der Referenzwert desto niedriger wird der dB Wert. Es werden alle paar %1$s Sekunden neue Messungen vorgenommen und das Ergebnis unten angezeigt. Drücken Sie den zurück-Button, wenn Sie einen passenden Wert gefunden haben.</string>
<string name="settingsWillTakeTime">Manche Einstellungen können nicht übernommen werden bevor der Dienst neu gestartet wird.</string>
<string name="phoneIsRooted">Das Gerät ist gerootet.</string>
<string name="phoneIsNotRooted">Das Gerät ist nicht gerootet.</string>
<string name="dataConWithRootSuccess">Die Datenverbindung wurde mit superUser Rechten erfolgreich geändert.</string>
<string name="dataConWithRootFail">Die Datenverbindung konnte mit superUser Rechten nicht geändert werden.</string>
<string name="rootExplanation">Sie müssen Ihr Telefon rooten, damit diese Funktion funktionieren kann. Danach müssen Sie "Regel manuell ausführen", um den SuperUser Berechtigungsdialog zu zeigen. Wenn dieser erscheint, müssen Sie den Haken setzen, der es immer erlaubt. Ansonsten kann die Regel nicht funktionieren, wenn Sie das Telefon gerade nicht benutzen und demnach den nächsten Dialog nicht genehmigen können.</string>
<string name="errorWritingConfig">Fehler beim Schreiben der Konfiguration. Gibt es einen beschreibbaren Speicher, und wurde alle Berechtigungen gegeben?</string>
<string name="phoneNrReplacementError">Die letzte Telefonnummer konnte nicht in die Variable integriert werden. Sie liegt mir nicht vor.</string>
@ -592,7 +523,7 @@
<string name="manageLocations">Orte anlegen oder ändern</string>
<string name="publishedOn">veröffentlicht am</string>
<string name="filesHaveBeenMovedTo">Automation benutzt jetzt ein anderes Verzeichnis, um Ihre Daten zu speichern. Alle Ihre Automation-Dateien wurden hierhin verschoben: \"%s\". Die Berechtigung für den externen Speicher wird nun nicht mehr benötigt; Sie können Sie entfernen. In einer künftigen Version wird sie entfernt werden.</string>
<string name="locationEngineDisabledShort">Die Position kann nicht mehr bestimmt werden.</string>
<string name="locationEngineDisabledShort">Die Position kann nicht mehr im Hintergrund bestimmt werden. Klicken Sie hier für mehr Infos.</string>
<string name="locationEngineDisabledLong">Leider kann die Position nicht mehr bestimmt werden. Großer Dank dafür geht an Google für seine unendliche Weisheit und Großzügigkeit.\\n\\nBeginnend mit Android 10 wurde eine neue Berechtigung eingeführt, die benötigt wird, um als App die Position auch im Hintergrund bestimmen zu können, was, für eine App wie diese, natürlich notwendig ist.\\n\\nWährend ich das grundsätzlich für eine gute Idee halte, gilt das nicht für die Schikanen, die man Entwicklern damit zumutet.\\n\\nWenn man eine App entwickelt, kann man versuchen sich für diese Berechtigung zu qualifizieren, indem man einen Katalog von Bedingungen erfüllt. Leider wurden neue Versionen meiner Anwendung über einen Zeitraum von drei Monaten immer wieder abgelehnt.\\n\\nDas lief auf die immer gleiche Art ab:\\n\\nIch habe eine neue Version eingereicht, die all diese Anforderungen erfüllt hat.\\n\\nGoogles miserabler Entwickler-Support behauptete ich würde sie nicht einhalten.\\n\\nIch habe Beweise geliefert, daß ich alles einhalte.<br />Ich bekam eine Antwort wie "Ich kann Ihnen nicht weiterhelfen.\\n\\nIrgendwann habe ich aufgegeben.\\n\\nDie Folge davon ist nun, daß die Google Play Version keine Positionsbestimmung mehr im Hintergrund durchführen kann. Meine einzige Alternative wäre es gewesen, daß die ganze Anwendung aus dem Store fliegt.\\n\\nDas tut mir sehr leid, aber ich habe mein Bestes gegeben mit einem Kunden\"dienst\" zu diskutieren, der mehrfach beim Turing-Test durchgefallen ist.\\n\\nDie gute Nachricht: Die Anwendung kann es immer noch!\\n\\nAutomation ist nun Open Source Software und kann ab sofort bei F-Droid heruntergeladen werden. F-Droid ist ein freier Appstore, der Ihre Privatsphäre respektiert - statt nur so zu tun wie Google das macht.\\n\\nSichern Sie Ihre Konfiguratinsdatei, deinstallieren Sie dazu diese Anwendung, installieren sie von F-Droid neu, Konfigurationsdatei zurückspielen und fertig.\\n\\nKlicken Sie hier, um mehr herauszufinden:</string>
<string name="filesStoredAt">Konfigurations- und Logdateien werden hier gespeichert: %1$s. Klicken Sie hier auf diesen Text, um dieses Verzeichnis in einem Datei-Explorer zu öffnen. Leider funktioniert das nur auf gerooteten Geräten.\n\nFür alle anderen Geräte: Benutzen Sie einfach den Export Button, wenn Sie eine Sicherung anlegen wollen.</string>
<string name="directionStringEquals">ist gleich</string>
@ -630,7 +561,6 @@
<string name="shareConfigAndLogFilesWithDev">Konfigurations- und Logdatei mit Entwickler teilen (via email).</string>
<string name="shareConfigAndLogExplanation">Dies wird eine neue Email öffnen mit Konfigurations- und Logdateien als Zip-Anhang. Sie wird nicht automatisch versendet. D.h. Sie können so z.B. auch den Adressaten zu sich selbst ändern.</string>
<string name="notificationTriggerExplanation">Dieser Auslöser reagiert auf Benachrichtigungen anderer Anwendung im Benachrichtigungsbereich von Android (oder wenn diese geschlossen werden). Sie können eine bestimmte Anwendung festlegen, von die Nachricht stammen muß. Wenn nicht, zählt jede Benachrichtigung. Sie können auch Zeichenketten für Titel oder Nachrichteninhalt festlegen, die enthalten sein müssen. Die Groß-/Kleinschreibung wird hierbei nicht berücksichtigt.</string>
<string name="ruleActivationComplete">Regel \"%1$s\" wurde fertig ausgeführt.</string>
<string name="addParameters">Parameter hinzufügen</string>
<string name="errorRunningRule">Fehler beim Ausführen einer Regel.</string>
<string name="startAppChoiceNote">Hier haben Sie 2 grundsätzliche Optionen:\n\n1. Sie können ein Programm starten, indem Sie eine Activity auswählen.\nStellen Sie sich das so vor, daß Sie ein bestimmtes Fenster einer Anwendung vorauswählen, in das man direkt springt. Behalten Sie im Kopf, daß das nicht immer funktionieren wird. Das liegt daran, daß die Fenster einer Anwendung miteinander interagieren können, sich u.U. Parameter übergeben. Wenn man jetzt ganz kalt in ein bestimmtes Fenster springt, könnte dieses zum Start z.B. bestimmte Parameter erwarten - die fehlen. So könnte es passieren, daß das Fenster zwar versucht zu öffnen, das aber nicht klappt und es somit nie wirlich sichtbar wird. Versuchen Sie\'s trotzdem!\nSie können den Pfad manuell eingeben, sollten aber den Auswählen-Knopf benutzen. Wenn Sie es dennoch manuell eingeben, geben Sie den PackageName ins obere Feld ein und den vollen Pfad der Activity ins untere.\n\n2. Auswahl per Action\nIm Gegensatz zur Auswahl eines bestimmten Fensters, können Sie ein Programm auch über eine Action starten lassen. Stellen Sie sich das so vor als würden Sie in den Wald rufen \"Ich hätte gerne XYZ\" und falls eine Anwendung installiert ist, die das liefern kann, wird sie gestartet. Ein gutes Beispiel wäre zum Beispiel "Browser starten" - es könnten sogar mehrere installiert sein, die das können (aber normalerweise gibts eine, die als Standard eingestellt ist).\nDiese Action müssen Sie manuell eingeben. Der PackageName ist hier optional. Behalten Sie dabei im Auge, daß mögliche Variablen nicht aufgelöst werden. Beispielsweise werden Sie häufig im Internet finden, daß man die Kamera über die Action \"MediaStore.ACTION_IMAGE_CAPTURE\" starten kann. Das ist grundsätzlich nicht richtig, wird aber nicht direkt funktionieren, denn das ist nur eine Variable. Sie müssen dann einen Blick in die Android Dokumentation werfen, wo Sie sehen werden, daß sich hinter dieser Variable eigentlich der Wert \"android.media.action.IMAGE_CAPTURE\" verbirgt. Gibt man diesen in das Feld ein, wird\'s funktionieren.</string>
@ -653,7 +583,7 @@
<string name="noFilesImported">Keine Dateien konnten importiert werden.</string>
<string name="notAllFilesImported">Nicht alle passenden Dateien konnten importiert werden.</string>
<string name="openExamplesPage">Webseite mit Beispielen öffnen</string>
<string name="phoneNumberExplanation">Sie können eine bestimmte Nummer eingeben, aber müssen nicht. Wenn Sie eine angeben wollen, können Sie auch eine aus dem Adressbuch auswählen.</string>
<string name="phoneNumberExplanation">Sie können eine bestimmte Nummer eingeben, aber müssen nicht. Wenn Sie eine angeben wollen, können Sie auch eine aus dem Adressbuch auswählen. Außerdem können Sie reguläre Audrücke verwenden. Zum Testen selbiger mag ich die Seite:</string>
<string name="prefsImportError">Fehler beim Importieren der Einstellungen.</string>
<string name="rulesImportedSuccessfully">Regeln und Orte wurden erfolgreich importiert.</string>
<string name="rulesImportError">Fehler beim Importieren der Regeln.</string>
@ -665,4 +595,13 @@
<string name="android.permission.ACTIVITY_RECOGNITION">Aktivitätserkennung</string>
<string name="packageName">Paketname</string>
<string name="activityOrActionName">Acitivity/Action name</string>
<string name="warning">Warnung</string>
<string name="ringing">klingelt</string>
<string name="from">von</string>
<string name="to">an</string>
<string name="matching">übereinstimmend</string>
<string name="loadWifiList">WLAN Liste laden</string>
<string name="noKnownWifis">Es gibt keine bekannten WLANs auf Ihrem Gerät.</string>
<string name="needLocationPermForWifiList">Die Liste von WLANs auf Ihrem Gerät könnte verwendet werden, um zu ermitteln, an welchen Orten Sie waren. Deshalb ist die Positions-Berechtigung nötig, um die Liste dieser WLANs zu laden. Wenn Sie eines aus der Liste auswählen möchten, müssen Sie diese Berechtigung gewähren. Wenn nicht, können Sie immer noch eines manuell eingeben.</string>
<string name="urlToTriggerExplanation">Diese Funktion öffnet NICHT den Browser, sondern löst die HTTP Anfrage im Hintergrund aus. Sie können das z.B. benutzen, um Befehle an Ihre Heimautomatisierung zu schicken.</string>
</resources>

View File

@ -1,131 +1,115 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Automation</string>
<string name="ruleActivate">Estoy activando regla %1$s</string>
<string name="ruleActivate">Estoy activando norma %1$s</string>
<string name="profileActivate">Estoy activando perfil %1$s</string>
<string name="ruleActivateToggle">Estoy activando regla %1$s in el modo del inventir</string>
<string name="addPoi">Crear lugar</string>
<string name="addRule">Crear regla</string>
<string name="poiList">Listo de lugares:</string>
<string name="ruleList">Lista de reglas:</string>
<string name="pleaseEnterValidName">Inserta un nombre válido, por favor.</string>
<string name="pleaseSpecifiyTrigger">Inserta al menos un disparador, por favor.</string>
<string name="pleaseSpecifiyAction">Inserta al menos un acción, por favor.</string>
<string name="serviceWontStart">No rules defined. Service won\'t start.</string>
<string name="serviceStarted">Automation service ha inicializado.</string>
<string name="ruleActivateToggle">Estoy activando norma %1$s en el modo del invertir</string>
<string name="addPoi">Crear sitio</string>
<string name="addRule">Crear norma</string>
<string name="poiList">Lista de sitios:</string>
<string name="ruleList">Lista de normas:</string>
<string name="pleaseEnterValidName">Inserte un nombre válido, por favor.</string>
<string name="pleaseSpecifiyTrigger">Inserta al menos una condición, por favor.</string>
<string name="pleaseSpecifiyAction">Inserta al menos una acción, por favor.</string>
<string name="serviceWontStart">No hay normas definidas. Servicio no enciende.</string>
<string name="serviceStarted">Automation servicio ha iniciado.</string>
<string name="version">Versión %1$s.</string>
<string name="logServiceStarting">Inicializando servicio.</string>
<string name="logNotAllMeasurings">Todavia no tengo todo los ensayos des lugares. No puedo hacer comparación.</string>
<string name="distanceBetween">Distancia entre GPS lugar y network lugar esta</string>
<string name="radiusSuggestion">metros. Este +1 habia de estar el minimo.</string>
<string name="comparing">Tengo tanto network como gps lugar. Estoy comparando...</string>
<string name="logNoSuitableProvider">No ha encontrado una adecuada compañía de lugares.</string>
<string name="positioningWindowNotice">Si estas en un edificaión vaya cerca de una ventana hasta una posición ha sido encontrado. Si no podria durar mucho tiempo si es posible en absoluto.</string>
<string name="gettingPosition">Buscando posición. Esperaria, por favor...</string>
<string name="logGettingPositionWithProvider">Busco el posición de la compañía:</string>
<string name="distanceBetween">Distancia entre el sitio GPS y el sitio red está %1$d metros. Este +1m debe ser el minimo.</string>
<string name="comparing">Tengo tanto sitio red como sitio gps. Estoy comparando...</string>
<string name="positioningWindowNotice">Si está en una edificación vaya cerca de una ventana hasta que una posición haya sido encontrada. Sino podria durar mucho tiempo o no seria posible.</string>
<string name="gettingPosition">Buscando posición. Espere, por favor...</string>
<string name="yes">Si</string>
<string name="no">No</string>
<string name="logGotGpsUpdate">He recibido una posición de GPS. Precisión:</string>
<string name="logGotNetworkUpdate">He recibido una posición de network. Precisión:</string>
<string name="monday">Lunes</string>
<string name="tuesday">Martes</string>
<string name="wednesday">Miercoles</string>
<string name="wednesday">Miércoles</string>
<string name="thursday">Jueves</string>
<string name="friday">Viernes</string>
<string name="saturday">Sabado</string>
<string name="saturday">Sábado</string>
<string name="headphoneMicrophone">Microfóno</string>
<string name="whatsThis">Que es eso?</string>
<string name="privacyLocationingTitle">Solo usar localización privada</string>
<string name="privacyLocationingSummary">Avoid locationing methods that may send your location to a provider, e.g. Google. This will use GPS only and may therefore be slow or not work reliably.</string>
<string name="enforcingGps">Private Locationing enabled, enforcing GPS use.</string>
<string name="notEnforcingGps">Private Locationing not enabled, using regular provider search.</string>
<string name="volumeAlarms">Alarmas</string>
<string name="change">modificar</string>
<string name="soundModeNormal">Normal</string>
<string name="soundModeVibrate">Vibración</string>
<string name="soundModeSilent">Silencio</string>
<string name="enterAname">Enter a name!</string>
<string name="noChangeSelectedProfileDoesntMakeSense">No change selected. Profile doesn\'t make sense.</string>
<string name="username">Nombre de usuario</string>
<string name="ok">Ok</string>
<string name="continueText">continuar</string>
<string name="rule">Regla</string>
<string name="android.permission.SEND_SMS">Enviar mensajes SMS</string>
<string name="android.permission.READ_CONTACTS">Read contact data</string>
<string name="ruleXrequiresThis">Regla \"%1$s\" requires this.</string>
<string name="android.permission.READ_CONTACTS">Leer directorio</string>
<string name="ruleXrequiresThis">Regla \"%1$s\" lo necesita.</string>
<string name="sendTextMessage">Enviar mensaje SMS</string>
<string name="importNumberFromContacts">Import number from contacts</string>
<string name="edit">Edit</string>
<string name="importNumberFromContacts">Importar número del directorio</string>
<string name="edit">Editar</string>
<string name="textToSend">Texto de enviar</string>
<string name="password">Contraseña</string>
<string name="showOnMap">Monstrar en una mapa</string>
<string name="headphoneAny">Igual</string>
<string name="sunday">Domingo</string>
<string name="pleaseEnterValidLatitude">Por favor inserte un grado de latitud válido.</string>
<string name="pleaseEnterValidLongitude">Por favor inserte un grade de longitud válido.</string>
<string name="pleaseEnterValidLongitude">Por favor inserte un grado de longitud válido.</string>
<string name="pleaseEnterValidRadius">Por favor inserte un radio válido.</string>
<string name="selectOneDay">Por favor selectar al menos un dia.</string>
<string name="logAttemptingToBindToService">Intentando de connectar al servicio...</string>
<string name="logAttemptingToUnbindFromService">Intentando de disconnectar del servicio...</string>
<string name="logBoundToService">Connectado al servicio.</string>
<string name="logUnboundFromService">Separado del servicio.</string>
<string name="whatToDoWithRule">Hacer que con la regla?</string>
<string name="whatToDoWithPoi">Hacer que con el lugar?</string>
<string name="selectOneDay">Por favor seleccione al menos un dia.</string>
<string name="whatToDoWithRule">Hacer que con la norma?</string>
<string name="whatToDoWithPoi">Hacer que con el sitio?</string>
<string name="whatToDoWithProfile">Hacer que con el perfil?</string>
<string name="delete">borrar</string>
<string name="deleteCapital">Borrar</string>
<string name="delete">eliminar</string>
<string name="deleteCapital">Eliminar</string>
<string name="serviceStopped">Servicio automation terminado.</string>
<string name="logServiceStopping">Terminando servicio.</string>
<string name="stillGettingPosition">Todavia buscando posición</string>
<string name="lastRule">Ultima regla:</string>
<string name="at">al</string>
<string name="lastRule">Última norma:</string>
<string name="at">el</string>
<string name="service">Servicio:</string>
<string name="getCurrentPosition">Buscar positión actual</string>
<string name="savePoi">Guardar lugar</string>
<string name="deletePoi">Borrar posición</string>
<string name="getCurrentPosition">Buscar posición actual</string>
<string name="savePoi">Guardar sitio</string>
<string name="deletePoi">Eliminar posición</string>
<string name="latitude">Latitud</string>
<string name="longitude">Longitud</string>
<string name="ruleName">Nombre de regla</string>
<string name="triggers">Disparador(es)</string>
<string name="triggersComment">y-connectado (todo tienen que applicar al mismo tiempo)</string>
<string name="addTrigger">Añadir disparador</string>
<string name="ruleName">Nombre de la norma</string>
<string name="triggers">Condición(es)</string>
<string name="triggersComment">y-conectado (todo tiene que aplicar al mismo tiempo)</string>
<string name="addTrigger">Añadir condición</string>
<string name="actions">Acción(es)</string>
<string name="actionsComment">(ejecutado in esta orden)</string>
<string name="actionsComment">(ejecutado en esta orden)</string>
<string name="addAction">Añadir acción</string>
<string name="saveRule">Guardar regla</string>
<string name="saveRule">Guardar norma</string>
<string name="start">Inicio</string>
<string name="end">Final</string>
<string name="save">Guardar</string>
<string name="urlToTrigger">URL para ejecutar</string>
<string name="wifi">wifi</string>
<string name="activating">Estoy activando</string>
<string name="deactivating">Estoy desctivando</string>
<string name="activating">Activando</string>
<string name="deactivating">Desactivando</string>
<string name="entering">entrando</string>
<string name="leaving">saliendo</string>
<string name="noPoisSpecified">Al primer tienes que crear lugares.</string>
<string name="selectPoi">Seleccionar lugar</string>
<string name="selectTypeOfAction">Selecte tipo the acción</string>
<string name="noPoisSpecified">Primero tiene que crear sitios.</string>
<string name="selectPoi">Seleccionar sitio</string>
<string name="selectTypeOfAction">Seleccione tipo de la acción</string>
<string name="connected">connectado</string>
<string name="stopped">terminado</string>
<string name="started">Commencado</string>
<string name="disconnected">separado</string>
<string name="selectSoundProfile">Selecte perfil de sonido</string>
<string name="whatToDoWithTrigger">Hacer que con el disparador?</string>
<string name="started">Comenzado</string>
<string name="disconnected">desconectado</string>
<string name="selectSoundProfile">Seleccione perfil de sonido</string>
<string name="whatToDoWithTrigger">Hacer que con la condición?</string>
<string name="whatToDoWithAction">Hacer que con la acción?</string>
<string name="radiusHasToBePositive">Radio tiene que ser un numero positivo.</string>
<string name="poiStillReferenced">Todavia hay reglas cuales usan este lugar (%1$s). No puedo borrar el.</string>
<string name="generalSettings">Reglajes generales.</string>
<string name="startAtSystemBoot">Inicializar al boot.</string>
<string name="writeLogFile">Guardar un archivo protocolo</string>
<string name="radiusHasToBePositive">Radio tiene que ser un número positivo.</string>
<string name="poiStillReferenced">Todavia hay normas que usan este sitio (%1$s). No puedo eliminarlo.</string>
<string name="generalSettings">Configuración general.</string>
<string name="startAtSystemBoot">Iniciar al boot.</string>
<string name="writeLogFile">Escribir un archivo protocolo</string>
<string name="wifiState">Estado wifi</string>
<string name="showHelp">Descripción</string>
<string name="rules">Reglas</string>
<string name="rules">Normas</string>
<string name="timeframes">Intervalo</string>
<string name="helpTitleEnergySaving">Configuración de ahorro de energia</string>
<string name="speedMaximumTime">Tiempo en minutos</string>
<string name="exceeds">exede</string>
<string name="dropsBelow">es menos que</string>
<string name="triggerPointOfInterest">Lugar</string>
<string name="triggerPointOfInterest">sitio</string>
<string name="triggerTimeFrame">Intervalo</string>
<string name="triggerSpeed">Velocidad</string>
<string name="actionSetWifi">Wifi</string>
@ -144,8 +128,8 @@
<string name="actionTurnWifiTetheringOff">desactivar enrutador wifi</string>
<string name="actionTurnAirplaneModeOn">encender modo de vuelo</string>
<string name="actionTurnAirplaneModeOff">desactivar modo de vuelo</string>
<string name="activePoi">Lugar activo</string>
<string name="closestPoi">Lugar mas cerca</string>
<string name="activePoi">sitio activo</string>
<string name="closestPoi">sitio mas cerca</string>
<string name="poi">Posición</string>
<string name="pois">posiciónes</string>
<string name="serviceNotRunning">Servicio not esta activo</string>
@ -158,9 +142,9 @@
<string name="exceeding">exedendo</string>
<string name="droppingBelow">estendo menos que</string>
<string name="anyWifi">algun wifi</string>
<string name="selectApplication">Elega la app</string>
<string name="selectPackageOfApplication">Elega el paquete de la app</string>
<string name="selectActivityToBeStarted">Elega la actividad de la app</string>
<string name="selectApplication">Elija la app</string>
<string name="selectPackageOfApplication">Elija el paquete de la app</string>
<string name="selectActivityToBeStarted">Elija la actividad de la app</string>
<string name="errorStartingOtherActivity">Error encendiendo otra app</string>
<string name="startAppBySendBroadcast">con sendBroadcast()</string>
<string name="startAppByStartActivity">con startActivity()</string>
@ -178,7 +162,7 @@
<string name="alwaysPlay">siempre tocar</string>
<string name="playSound">Tocar sonido</string>
<string name="direction">dirección</string>
<string name="anyApp">alguna app</string>
<string name="anyApp">cualquier app</string>
<string name="directionStringNotEquals">no es igual a</string>
<string name="directionStringStartsWith">comenza con</string>
<string name="directionStringEndsWith">termina con</string>
@ -190,10 +174,10 @@
<string name="locationDisabled">Localización desactivado</string>
<string name="error">Error</string>
<string name="android.permission.ACCESS_BACKGROUND_LOCATION">Determinar su posición en el contexto</string>
<string name="manageLocations">Crear p editar lugares</string>
<string name="manageLocations">Crear p editar sitios</string>
<string name="startScreen">Ventana incial</string>
<string name="positioningEngine">Metodo de localización</string>
<string name="deviceDoesNotHaveBluetooth">Este móvil no tiene Bluetooth. Puede continuar pero probablemente no va a funciónar.</string>
<string name="deviceDoesNotHaveBluetooth">Este dispositivo no tiene Bluetooth. Puede continuar pero probablemente no va a funciónar.</string>
<string name="android.permission.READ_CALL_LOG">Leer protocolo de teléfono</string>
<string name="android.permission.READ_CALENDAR">Leer calendario</string>
<string name="android.permission.ACCESS_FINE_LOCATION">Determinar la posición exacta</string>
@ -205,15 +189,15 @@
<string name="android.permission.MODIFY_AUDIO_SETTINGS">Modificar la configuración sonida</string>
<string name="android.permission.RECORD_AUDIO">Grabar audio</string>
<string name="android.permission.PROCESS_OUTGOING_CALLS">Detecar llamados saliendos</string>
<string name="android.permission.READ_PHONE_STATE">Detecar el estado del móvil</string>
<string name="android.permission.READ_PHONE_STATE">Detecar el estado del dispositivo</string>
<string name="android.permission.READ_EXTERNAL_STORAGE">Leer la memoria</string>
<string name="android.permission.WRITE_EXTERNAL_STORAGE">Escribir a la memoria</string>
<string name="android.permission.WRITE_SETTINGS">Modificar la configuración del móvil</string>
<string name="android.permission.WRITE_SETTINGS">Modificar la configuración del dispositivo</string>
<string name="android.permission.BATTERY_STATS">Determinar el estado de la batteria</string>
<string name="android.permission.CHANGE_BACKGROUND_DATA_SETTING">Modificar la conexión internet</string>
<string name="android.permission.ACCESS_NOTIFICATION_POLICY">Exeder configuración no molestar</string>
<string name="android.permission.WRITE_SECURE_SETTINGS">Escribir a la memoria</string>
<string name="apply">aceptar</string>
<string name="apply">acplicar</string>
<string name="publishedOn">publicitado el</string>
<string name="postsNotification">%1$s crea notificación</string>
<string name="removedNotification">notificación de %1$s removido</string>
@ -226,7 +210,7 @@
<string name="configurationExportedSuccessfully">Exportación completada con éxito</string>
<string name="noFileManageInstalled">No mánager archivo esta instalada</string>
<string name="cantFindSoundFile">No puedo buscar el archivo sonido %1$s, por eso no puedo tocar lo.</string>
<string name="ruleActive">Regla activa</string>
<string name="ruleActive">Norma activa</string>
<string name="triggerCharging">Batteria esta cargando</string>
<string name="triggerUsb_host_connection">USB conexión a un computador</string>
<string name="actionSetDisplayRotation">Girar monitor</string>
@ -236,14 +220,13 @@
<string name="enterWifiName">Inserta el nombre del wifi. Deje vacio para applicar a todos wifis.</string>
<string name="startOtherActivity">Iniciar otra app</string>
<string name="settings">Ajustes</string>
<string name="errorReadingSettings">Error leer ajustes.</string>
<string name="bluetoothConnection">Bluetooth conexión</string>
<string name="bluetoothConnectionTo">Bluetooth conexión to %1$s</string>
<string name="anyDevice">algun aparato</string>
<string name="noDevice">no aparato</string>
<string name="anyDevice">cualquier dispositivo</string>
<string name="noDevice">no dispositivo</string>
<string name="actionPlayMusic">Abrir jugador musica</string>
<string name="profiles">Perfiles</string>
<string name="ruleHistory">Historia de reglas (más ultimas al primero)</string>
<string name="ruleHistory">Historia de normas (más ultimas al primero)</string>
<string name="lockSoundChanges">Bloquerar modificaciónes sonidas</string>
<string name="status">Estado</string>
<string name="android.permission.ACCESS_NETWORK_STATE">Determinar el estado de la red</string>
@ -254,7 +237,7 @@
<string name="invalidProfileName">Nombre invalido</string>
<string name="anotherProfileByThatName">Hay otro perfil con lo mismo nombre.</string>
<string name="errorActivatingProfile">Error activando perfil:</string>
<string name="executeRulesAndProfilesWithSingleClickTitle">Activar reglas/perfiles con 1 clic</string>
<string name="executeRulesAndProfilesWithSingleClickTitle">Activar normas/perfiles con 1 clic</string>
<string name="name">Nombre</string>
<string name="useAuthentication">Usar verificación de la autenticidad</string>
<string name="radiusWithUnit">Radio [m]</string>
@ -263,25 +246,25 @@
<string name="notificationRingtone">Sonido polifónico para notificaciónes</string>
<string name="incomingCallsRingtone">Sonido polifónico para llamadas</string>
<string name="batteryLevel">NIvel de la bateria</string>
<string name="selectBattery">Elegir nivel de la bateria</string>
<string name="selectBattery">Elija nivel de la bateria</string>
<string name="triggerNoiseLevel">Nivel del rudio fondo</string>
<string name="anotherAppIsRunning">Otra app esta enciendo/terminado</string>
<string name="airplaneMode">Modo vuelo</string>
<string name="triggerHeadsetPlugged">Auriculares conectado</string>
<string name="headsetConnected">Auriculares (tipo: %1$s) conectado</string>
<string name="headsetDisconnected">Auriculares (tipo: %1$s) desconectado</string>
<string name="phoneCall">Llamado</string>
<string name="anotherAppIsRunning">Otra app esta encienda/terminada</string>
<string name="airplaneMode">Modo avión</string>
<string name="triggerHeadsetPlugged">Auriculares conectados</string>
<string name="headsetConnected">Auriculares (tipo: %1$s) conectados</string>
<string name="headsetDisconnected">Auriculares (tipo: %1$s) desconectados</string>
<string name="phoneCall">Llamada</string>
<string name="phoneNumber">Número de teléfono</string>
<string name="enterPhoneNumber">Inserte numbero de teléfono. Vacio para algun número</string>
<string name="phoneDirection">Direción de llamada</string>
<string name="enterPhoneNumber">Inserte numero de teléfono. Vacio para algun número.</string>
<string name="phoneDirection">Elija llamada entrante o saliente</string>
<string name="headphoneSimple">Auriculares</string>
<string name="headphoneSelectType">Elegir tipo de los auriculares</string>
<string name="accelerometer">" Acelerómetro "</string>
<string name="accelerometer">" Acelerómetro"</string>
<string name="gpsAccuracy">GPS exactitud [m]</string>
<string name="soundSettings">Ajustes sonidos</string>
<string name="soundSettings">Configuración de sonido</string>
<string name="settingsCategoryNoiseLevelMeasurements">Medición de ruido fondo</string>
<string name="waitBeforeNextAction">Esperar antes de la ación próxima</string>
<string name="wakeupDevice">Desperatar móvil</string>
<string name="waitBeforeNextAction">Esperar antes de la acción próxima</string>
<string name="wakeupDevice">Despertar dispositivo</string>
<string name="textToSpeak">Text para hablar</string>
<string name="state">Estado</string>
<string name="setScreenBrightness">Poner luminosidad del monitor</string>
@ -292,15 +275,15 @@
<string name="autoBrightnessNotice">Si usa luminosidad automatica el valor probablemente no va a durar mucho tiempo.</string>
<string name="actionDataConnection">Datos móviles</string>
<string name="actionSpeakText">Hablar texto</string>
<string name="selectToggleDirection">Activar o desactivar</string>
<string name="selectToggleDirection">Activar o desactivar?</string>
<string name="activated">activado</string>
<string name="activate">Activar</string>
<string name="deactivate">Desactivar</string>
<string name="deactivated">desactivado</string>
<string name="selectNoiseLevel">Elija nivel del ruido fondo</string>
<string name="selectSpeed">Elegir velocidad</string>
<string name="selectSpeed">Elija velocidad</string>
<string name="selectTypeOfActivity">Elija tipo de actividad</string>
<string name="selectTypeOfTrigger">Elija tipo de disparador</string>
<string name="selectTypeOfTrigger">Elija tipo de condición</string>
<string name="startAppStartType">Elija tipo de comienzo</string>
<string name="android.permission.BLUETOOTH">Cambiar ajusted Bluetooth</string>
<string name="android.permission.BLUETOOTH_ADMIN">Cambiar ajusted Bluetooth</string>
@ -312,4 +295,198 @@
<string name="parameterValue">Valor del parámetro</string>
<string name="addIntentValue">Añadir pareja intento</string>
<string name="parameterType">Tipo del parámetro</string>
<string name="phoneNumberExplanation">Puedes entrar un número, pero es opciónal. Si quieres usar un puedes elegir un de su directorio o entrar un manualmente. Adiciónalmente puedes usar expresiónes regulares. Para testar esos me gusta la pagina:</string>
<string name="screenRotationEnabled">Rotación del monitor activado.</string>
<string name="screenRotationDisabled">Rotación del monitor desactivado.</string>
<string name="noPoisDefinedShort">No hay sitios.</string>
<string name="starting">inciendo</string>
<string name="stopping">terminando</string>
<string name="connecting">conectando</string>
<string name="disconnecting">desconectando</string>
<string name="connectedToWifi">conectado a wifi \"%1$s\"</string>
<string name="disconnectedFromWifi">desconectado a wifi \"%1$s\"</string>
<string name="cantStopIt">No puedo terminarlo.</string>
<string name="httpAcceptAllCertificatesTitle">Aceptar todo los certificados</string>
<string name="httpAcceptAllCertificatesSummary">Omitir comprobar el validez de certificados (no es una bien idea)</string>
<string name="httpAttemptsTimeoutTitle">Timeout [sec]</string>
<string name="httpAttemptsTitle">Número de pruebas HTTP</string>
<string name="httpAttemptsTimeoutSummary">Timeout de HTTP requests [segundos]</string>
<string name="httpAttemptGapTitle">Pausa [sec]</string>
<string name="runManually">Encender manualmente</string>
<string name="serviceHasToRunForThat">Para este ación el servicio tiene que estar activo</string>
<string name="gpsComparison">Comparación GPS</string>
<string name="timeoutForGpsComparisonsTitle">GPS timeout [sec]</string>
<string name="muteTextToSpeechDuringCallsTitle">Silencio durante llamadas</string>
<string name="anotherRuleByThatName">Ya existe otra norma con el mismo nombre.</string>
<string name="settingsCategoryProcessMonitoring">Monitoreo de procesos</string>
<string name="timeBetweenProcessMonitoringsTitle">Segundos inter monitoreos de procesos</string>
<string name="processes">Procesos</string>
<string name="processMonitoring">Monitoreo de procesos</string>
<string name="privacy">Política de privacidad</string>
<string name="moveUp">Desplazar a arriba</string>
<string name="moveDown">Desplazar a abajo</string>
<string name="warning">Alerta</string>
<string name="ringing">soniendo</string>
<string name="from">de</string>
<string name="to">a</string>
<string name="matching">concordiando</string>
<string name="loadWifiList">Cargar listo de wifis</string>
<string name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">Leer notificaciónes del systema</string>
<string name="bluetoothFailed">No pude activar o desactivar Bluetooth. Tiene el dispositvo Bluetooth?</string>
<string name="urlTooShort">El url tiene que tener mínimo 10 caracteres.</string>
<string name="textTooShort">El texto tiene que tener mínimo 10 caracteres.</string>
<string name="onOff">On/Off</string>
<string name="useTextToSpeechOnNormalSummary">Usar TextToSpeech en un perfil normal</string>
<string name="useTextToSpeechOnVibrateSummary">Usar TextToSpeech en un perfil vibración</string>
<string name="useTextToSpeechOnSilentSummary">Usar TextToSpeech en un perfil silencioso</string>
<string name="useTextToSpeechOnNormalTitle">TTS en normal</string>
<string name="useTextToSpeechOnVibrateTitle">TTS en vibración</string>
<string name="useTextToSpeechOnSilentTitle">TTS en silencioso</string>
<string name="positioningSettings">Configuración de buscar posición</string>
<string name="listenToWifiState">Observar estado de wifi cuando es posible</string>
<string name="listenToAccelerometerState">Observar movimiento del dispositivo cuando wifi no está disponible</string>
<string name="accelerometerTimer">Usar acelerómetro despues x minutos sin cambio de torre telefónica</string>
<string name="cellMastIdleTime">Tiempo inactivo de las torres telefónicas</string>
<string name="accelerometerThresholdDescription">Valor limite para movimientos acelerómetro</string>
<string name="accelerometerThreshold">Valor acelerómetro</string>
<string name="positioningThresholds">Posicionando valores</string>
<string name="minimumDistanceChangeForGpsLocationUpdates">Minima distancia para cambio de GPS</string>
<string name="distanceForGpsUpdate">Minimo cambio GPS [m]</string>
<string name="minimumDistanceChangeForNetworkLocationUpdates">Minima distancia para cambio de red telefonica</string>
<string name="distanceForNetworkUpdate">Minimo cambio red [m]</string>
<string name="satisfactoryAccuracyGps">Exactitud necesaria para GPS en metros.</string>
<string name="satisfactoryAccuracyNetwork">Exactitud necesaria para red en metros.</string>
<string name="networkAccuracy">Red exactitud [m]</string>
<string name="minimumTimeForLocationUpdates">Tiempo minimo para cambio en milisegundos para actualizar posición</string>
<string name="timeForUpdate">Tiempo de actualizar [milisegundos]</string>
<string name="urlLegend">Variables: Puede usar esas variables. Mientras ejecuta van a sustituir con los valores correspondientes en su dispositivo.
Incluya las paréntecis en su texto.\n\n[uniqueid] - el número único de su dispositivo\n[serialnr] - el número de serie de su dispositivo\n[latitude] - su latitud\n[longitude] - su longitud\n[phonenr] - Ùltimo número de llamada realizada tanto de salida como entrante\n[d] - Dia del mes, 2 digitos con cero al comienzo\n[m] - número del mes, 2 digitos con cero al comienzo\n[Y] - Número del año, 4 digitos\n[h] - Hora, formato 12 horas con cero al comienzo\n[H] - Hora, formato 24 horas con cero al comienzo\n[i] - Minutos con cero al comienzo\n[s] - Segundos con cero al comienzo\n[ms] - milisegundos\n[notificationTitle] - Título de la última notificación\n[notificationText] - Texto de la última notificación</string>
<string name="screenRotationAlreadyEnabled">Rotación del monitor todavia esta activado.</string>
<string name="screenRotationAlreadyDisabled">Rotación del monitor todavia esta desactivado.</string>
<string name="needLocationPermForWifiList">Se puede usar la lista de wifis conocidos para determinar los sitios a cuales estuve. Por eso el permiso locación esta necesaria para cargar la lista de wifis. Si quiere elegir un de la lista tiene que conceder el permiso. En caso contrario todavia puede entrar un nombre wifi manualmente.</string>
<string name="com.wireguard.android.permission.CONTROL_TUNNELS">Controlar conexiones de la app wireguard</string>
<string name="shareConfigAndLogFilesWithDev">Enviar configuración y procotolo al developer (via email).</string>
<string name="rootExplanation">Necesita permiso root para este functión. Después encenda la función \"ejecutar norma manualmente\" para presentar el permiso superuser dialogo. Es necesita elegir \"siempre permitir root para esta app\". En caso contrario la norma no puede funcionar al fondo.</string>
<string name="helpTextRules">Todos las condiciones estan y-conectado. La norma solo va a aplicarse cuando todos las condiciones sus aplican. Si quiere O cree otra norma.</string>
<string name="timeBetweenNoiseLevelMeasurementsSummary">Segundos inter dos ensayos de nivel de ruido</string>
<string name="timeBetweenNoiseLevelMeasurementsTitle">Segundos inter dos ensayos de nivel de ruido</string>
<string name="lengthOfNoiseLevelMeasurementsSummary">Duración en segundos para un ensayos de nivel de ruido</string>
<string name="lengthOfNoiseLevelMeasurementsTitle">Duración en segundos para un ensayos de nivel de ruido</string>
<string name="referenceValueForNoiseLevelMeasurementsSummary">Referencia fisicalo para ensayo de nivel ruido</string>
<string name="referenceValueForNoiseLevelMeasurementsTitle">Referencia fisicalo para ensayo de nivel ruido</string>
<string name="logLevelSummary">Nivel del registro (1=minimo, 5=maximo)</string>
<string name="logLevelTitle">Nivel del registro</string>
<string name="unknownActionSpecified">Ación inconocido especicado</string>
<string name="errorChangingScreenRotation">Error cambiando rotación del monitor</string>
<string name="failedToTriggerBluetooth">Error cambiando Bluetooth. El dispositivo tiene Bluetooth?</string>
<string name="settingsCategoryHttp">Pedido HTTP</string>
<string name="httpAttemptsSummary">Cantidad de los pruebos en caso pedidos HTTP fallan por razones de conexißon</string>
<string name="httpAttemptGapSummary">Pausa antes de otra prueba [segundos]</string>
<string name="timeoutForGpsComparisonsSummary">Tiempo maximo en segundos</string>
<string name="rememberLastActivePoiSummary">Se esta en un sitio reinicie su dispositivo o la aplicaión y salga el sitio la aplicaión va a procesar normas que incluyan saliendo este sitio.</string>
<string name="rememberLastActivePoiTitle">Memorar ultimom sitio activo.</string>
<string name="settingsErased">Configuración borrado.</string>
<string name="settingsSetToDefault">Configuración reajustado al predeterminado.</string>
<string name="privacyConfirmationText">Voy a abrir un browser y cargar la politica de privacidad de la pagina del desarrolador.</string>
<string name="waitBeforeNextActionEnterValue">Inserte un valor en milisegundos por cuánto tiempo esperar antes de la proxima acción.</string>
<string name="wakeupDeviceValue">Inserte un valor en milisegundos por cuánto tiempo el dispositivo se tiene que quedar activo. 0 para usar el valor predeterminado.</string>
<string name="enterAPositiveValidNonDecimalNumber">Inserte un numero positivo no-decimal.</string>
<string name="cantMoveUp">No puedo mover objeto arriba. Ya está en el maximo.</string>
<string name="cantMoveDown">No puedo mover objeto abajo. Todavia está en el minimo.</string>
<string name="timeFrameWhichDays">En cuales dias?</string>
<string name="insideOrOutsideTimeFrames">Dentro o fuera de esos periodos?</string>
<string name="roaming">Roaming</string>
<string name="until">hasta</string>
<string name="application">Aplicación</string>
<string name="is">está</string>
<string name="with">con</string>
<string name="any">cualquier</string>
<string name="incoming">recibiendo</string>
<string name="outgoing">saliendo</string>
<string name="noKnownWifis">No hay wifis conociendos en su disparador.</string>
<string name="helpTextTimeFrame">Si crea una norma con un periodo tiene dos opciones. Puede elegir entre entrar o salir de un periodo. En todo caso la norma será ejecutada solo una vez. Si crea una norma con una condición \"entrar periodo xyz\" y por ejemplo la acción \"poner el dispositivo en vibración\", el dispositivo NO va a cambiar a sonido de llamada automaticamente despues del periodo. Si desea esto tiene que crear otra norma con otro periodo.</string>
<string name="toggableRules">Normas reversibles</string>
<string name="helpTextPoi">Un sitio consiste de coordinadas GPS y un radio. Porque la localización via red móvil terrestre es relativamente imprecisa (pero rápido y barato) no especifiqué el radio demasiado corto. La applicación va a sugerir un radio minimo cuando cree nuevo sitio.</string>
<string name="generalText">Para usar este programa tiene que crear normas. Ellos tienen condiciones, por ejemplo \"está en un sitio\" o \"está en un periodo\". Despues cliquee el on/off boton en la pantalla principal.</string>
<string name="muteTextToSpeechDuringCallsSummary">Poner TextToSpeech en muto mientras dura las llamadas</string>
<string name="anotherPoiByThatName">Ya existe otro sitio con el mismo nombre.</string>
<string name="timeBetweenProcessMonitoringsSummary">Cuanto mas bajo tanto mas se utiliza la bateria</string>
<string name="airplaneModeSdk17Warning">A partir de Android version 4.2 esta función solo functiona si su dispositivo esta rooted.</string>
<string name="selectTypeOfIntentPair">"Elija un tipo pareja intent. "</string>
<string name="enterNameForIntentPair">Inserte nombre para pareja intent.</string>
<string name="enterValueForIntentPair">Inserte valor para pareja intent.</string>
<string name="whatToDoWithIntentPair">Hacer que con pareja?</string>
<string name="gettingListOfInstalledApplications">Determinando lista de aplicaciones instaladas...</string>
<string name="actionSetDataConnectionOn">activar datos móviles</string>
<string name="actionSetDataConnectionOff">desactivar datos móviles</string>
<string name="incomingAdjective">recibiendo</string>
<string name="outgoingAdjective">saliendo</string>
<string name="anyNumber">cualquier número</string>
<string name="number">número</string>
<string name="nfcTag">tag NFC</string>
<string name="closeTo">cerca de</string>
<string name="withLabel">con etiqueta</string>
<string name="deviceDoesNotHaveNfc">Parece que este dispositivo no tiene NFC.</string>
<string name="nfcReadTag">Leer ID de tag.</string>
<string name="nfcWriteTag">Escribir tag</string>
<string name="nfcEnterValidIdentifier">Inserte una etiqueta valida para el tag (como \"Puerta de casa\").</string>
<string name="nfcTagWrittenSuccessfully">Tag escrita con exito.</string>
<string name="nfcTagWriteError">Error escribiendo tag. Esta el tag cerca?</string>
<string name="nfcTagDiscovered">Tag encontrado.</string>
<string name="nfcBringTagIntoRange">Traiga un tag cerca.</string>
<string name="nfcTagFoundWithText">Tag encontrado con etiqueta:</string>
<string name="nfcUnsupportedEncoding">No hay soporte para este codigo:</string>
<string name="nfcNoNdefIntentBut">No NFC NDEF intent, pero</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC sin soporto en esta version Android, todavia no.</string>
<string name="cantRunRule">No puedo ejecutar normas.</string>
<string name="nfcApplyTagToRule">Aplicar este tag a norma</string>
<string name="nfcTagReadSuccessfully">Tag escritoso con exito.</string>
<string name="nfcValueNotSuitable">Valor guardado no valido.</string>
<string name="nfcNoTag">No tag presente.</string>
<string name="newNfcId">Escrbir nueve ID NFC</string>
<string name="newId">Nueve ID:</string>
<string name="currentId">Actual ID:</string>
<string name="nfcTagDataNotUsable">Tag no esta utilizable, escribir de nueve.</string>
<string name="none">ningún</string>
<string name="anyLocation">cualquier sitio</string>
<string name="eraseSettings">Borrar configuración</string>
<string name="defaultSettings">Configuración standard</string>
<string name="areYouSure">Está seguro?</string>
<string name="detectedActivityOnBicycle">En bicicleta</string>
<string name="detectedActivityOnFoot">En pie</string>
<string name="detectedActivityInVehicle">En vehiculo (auto/autobus)</string>
<string name="detectedActivityWalking">Andante</string>
<string name="detectedActivityRunning">jogging</string>
<string name="detectedActivityInvalidStatus">Acción no válida</string>
<string name="detectedActivityTilting">Inclinando</string>
<string name="detectedActivityStill">No movimiento</string>
<string name="detectedActivityUnknown">desconocido</string>
<string name="triggerOnlyAvailableIfPlayServicesInstalled">Esta condición solo esta disponsible si Google Play Services estan instalado.</string>
<string name="activityDetectionFrequencyTitle">Frequencia de reconocimiento de actividad [seg]</string>
<string name="activityDetectionFrequencySummary">Segundos entre pruebas de reconocimientos de actividad.</string>
<string name="activityDetectionRequiredProbabilityTitle">Probabilidad de reconocimiento de actividad.</string>
<string name="activityDetectionRequiredProbabilitySummary">Certeza necesario con cuelas resultatods de reconocimiento de actividad seran aceptandos.</string>
<string name="selectDeviceFromList">un de la lista</string>
<string name="connectionToDevice">conexión a dispositivo</string>
<string name="disconnectionFromDevice">desconexión de dispositivo</string>
<string name="privacyLocationingSummary">Evitar usar methodos de localización cueles envian su posición a un provedor, por ejemplo Google. Eso so va a usar GPS solo. Por eso puede trajabar lento o poco fiable.</string>
<string name="locationEngineNotActive">Ingenio de localización no esta activo.</string>
<string name="noMapsApplicationFound">Parece no hay una aplicaión de mapa en su dispositivo.</string>
<string name="soundMode">Modo de sonido de llamada.</string>
<string name="showIcon">Monstrar icono</string>
<string name="showIconWhenServiceIsRunning">Monstrar icono cuando el servicio esta activo (ocultando solo funciona antes Android 7)</string>
<string name="currentVolume">Volumen actual</string>
<string name="volumeTest">Prueba de volumen</string>
<string name="permissionsTitle">Permisos necesarios</string>
<string name="disabledFeatures">Funcionas desactivadas</string>
<string name="invalidDevice">Dispositivo no valido.</string>
<string name="android.permission.ACCESS_WIFI_STATE">Determinar estado de wifi</string>
<string name="android.permission.WAKE_LOCK">Tener dispositivo despierto</string>
<string name="android.permission.MODIFY_PHONE_STATE">Cambiar ajustes del dispositivo</string>
<string name="android.permission.GET_TASKS">Determinar procesos activados</string>
<string name="android.permission.RECEIVE_BOOT_COMPLETED">Detectar reinicio del dispositivo</string>
<string name="helpTextActivityDetection">Esta función puede detecar su estado de movimiento (en pie, en bicicleta, en vehiculo). La función no es un parte de Automation, pero de Google Play Services. Técnicamente no da un si/no resultado, pero una certeza con que el estado es probable. Puede configurar el percentaje del cual Automation va a aceptar un resultado. Dos comentarios: 1) Mas de un estado se puede aplicar al mismo tiempo. Por ejemplo puede esta en pie en un autobus. 2) Esta sensor es relativamente caro (bateria). Si posible considere alternativas, por ejemplo bluetooth conexción a tu coche en vez de \"en vehiculo\".</string>
<string name="textMessageAnnotations">Puede insertar un numero de llamada. Alternativamente puede importar un numero de su directorio. Pero tenga en cuenta: El numero va a serar guardado, no el contacto. Si cambias el numero en su directoria tiene que cambiar la normal tambien.</string>
<string name="startAutomationAsService">Encender automation como un servicio</string>
<string name="startScreenSummary">Elija la pantalla con que automation enciende.</string>
</resources>

View File

@ -1,11 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:ns1="urn:oasis:names:tc:xliff:document:1.2">
<string name="ConfigurationExportError">There was an error while exporting the configuration.</string>
<string name="accelerometer">Accelerometro</string>
<string name="accelerometerThreshold">Soglia accelerometro</string>
<string name="accelerometerThresholdDescription">Soglia per i movimenti dell\'accelerometro</string>
<string name="accelerometerTimer">Usa l\'accelerometro dopo x minuti senza lunghi cambiamento della cella radiomobile</string>
<string name="accelerometerTimer">Usa l\'accelerometro dopo x minuti senza lunghi cambiamenti delripetitore</string>
<string name="actionChangeSoundProfile">Cambia il profilo sonoro</string>
<string name="actionDataConnection">Connessione di rete</string>
<string name="actionDataConnection">Connessione dati mobile</string>
<string name="actionDisableScreenRotation">disabilita la rotazione dello schermo</string>
<string name="actionEnableScreenRotation">abilita la rotazione dello schermo</string>
<string name="actionPlayMusic">Apri il lettore musicale</string>
@ -16,42 +17,50 @@
<string name="actionSetUsbTethering">Tethering USB</string>
<string name="actionSetWifi">Wifi</string>
<string name="actionSetWifiTethering">Wifi Tethering</string>
<string name="actionSpeakText">Pronuncia</string>
<string name="actionTriggerUrl">Apri URL</string>
<string name="actionTurnAirplaneModeOff">termina la modalità aeroplano</string>
<string name="actionTurnAirplaneModeOn">passa a modalità aeroplano</string>
<string name="actionSpeakText">Pronuncia testo</string>
<string name="actionTriggerUrl">Apri indirizzo</string>
<string name="actionTurnAirplaneModeOff">termina la modalità aereo</string>
<string name="actionTurnAirplaneModeOn">passa a modalità aereo</string>
<string name="actionTurnBluetoothOff">attiva Bluetooth</string>
<string name="actionTurnBluetoothOn">disattiva il Bluetooth</string>
<string name="actionTurnBluetoothOn">disattiva Bluetooth</string>
<string name="actionTurnUsbTetheringOff">disattiva Tethering USB</string>
<string name="actionTurnUsbTetheringOn">attiva Tethering USB</string>
<string name="actionTurnWifiOff">disattiva Wifi</string>
<string name="actionTurnWifiOn">attiva Wifi</string>
<string name="actionTurnWifiTetheringOff">disattiva Tethering Wifi</string>
<string name="actionTurnWifiTetheringOn">attiva Tethering Wifi</string>
<string name="actions">Azioni(e)</string>
<string name="actions">Azione(i)</string>
<string name="actionsComment">(saranno eseguite in quest\'ordine)</string>
<string name="activate">Attivazione</string>
<string name="activate">Attiva</string>
<string name="activated">attivo</string>
<string name="activating">Sto attivando</string>
<string name="activePoi">Posizione attiva:</string>
<string name="activityDetection">Rilevamento di attività</string>
<string name="activityDetectionFrequencySummary">Secondi tra i tentativi di rilevazione dell\'attività.</string>
<string name="activityDetectionFrequencyTitle">Frequenza di rilevazione [sec]</string>
<string name="activityDetectionRequiredProbabilitySummary">L\'attendibilità dellesecuzione delle attività.</string>
<string name="activityDetectionRequiredProbabilityTitle">Rilevazione di probabile attività</string>
<string name="activityDetection">Rilevamento dell\'attività</string>
<string name="activityDetectionFrequencySummary">Secondi tra i tentativi di rilevamento dell\'attività.</string>
<string name="activityDetectionFrequencyTitle">Frequenza di rilevamento [sec]</string>
<string name="activityDetectionRequiredProbabilitySummary">Attendibilità alla quale esecuzione delle attività è considerata corretta.</string>
<string name="activityDetectionRequiredProbabilityTitle">Probabilità di rilevamento dell\'attività</string>
<string name="activityOrActionName">Nome attività/azione</string>
<string name="addAction">Aggiungi azione</string>
<string name="addIntentValue">Aggiungi una coppia di Intent</string>
<string name="addIntentValue">Aggiungi una coppia di intenzioni</string>
<string name="addParameters">Aggiungi parametri</string>
<string name="addPoi">Aggiungi posizione</string>
<string name="addProfile">Aggiungi profilo</string>
<string name="addRule">Aggiugni regola</string>
<string name="addTrigger">Aggiungi evento</string>
<string name="airplaneMode">Modalità aeroplano</string>
<string name="airplaneModeSdk17Warning">A partire dalla versione Android 4.2 questa funzione è disponibile solo se il dispositivo è rootato.</string>
<string name="addTrigger">Aggiungi evento di attivazione</string>
<string name="airplaneMode">Modalità aereo</string>
<string name="airplaneModeSdk17Warning">A partire dalla versione Android 4.2 questa funzione è disponibile solo se il dispositivo ha accesso root.</string>
<string name="alwaysPlay">riproduci sempre</string>
<string name="alwaysPlayExplanation">Se questa impostazione è attiva, il suono sarà sempre riprodotto. Se questa è disattivata, la riproduzione avverrà quando il telefono non è nè in mute, nè in vibrazione. Comunque, quando attiva, non avrà effetto sul volume. Quindi, per esempio, se la il telefono ha la suoneria attivata, questa opzione non aumenterà il volume di riproduzione multimediale. E di conseguenza, se il volume del suono di riproduzione multimediale è in mute, non potrai ascoltare nulla.</string>
<string name="android.permission.ACCESS_BACKGROUND_LOCATION">Leggi posizione in secondo piano.</string>
<string name="android.permission.ACCESS_COARSE_LOCATION">Leggi posizione approssimativa</string>
<string name="android.permission.ACCESS_FINE_LOCATION">Leggi posizione precisa</string>
<string name="android.permission.ACCESS_NETWORK_STATE">Leggi lo stato della rete mobile</string>
<string name="android.permission.ACCESS_NOTIFICATION_POLICY">Ignore la politica di "non disturbare"</string>
<string name="android.permission.ACCESS_WIFI_STATE">Leggi lo stato della rete wifi</string>
<string name="android.permission.ACTIVITY_RECOGNITION">Identificazione attività</string>
<string name="android.permission.BATTERY_STATS">Leggere lo stato della batteria</string>
<string name="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">Leggere le notifiche di sistema</string>
<string name="android.permission.BLUETOOTH">Cambia le impostazioni Bluetooth</string>
<string name="android.permission.BLUETOOTH_ADMIN">Cambia le impostazioni Bluetooth</string>
<string name="android.permission.CHANGE_BACKGROUND_DATA_SETTING">Cambia la connessione dati</string>
@ -60,184 +69,200 @@
<string name="android.permission.MODIFY_AUDIO_SETTINGS">Cambia le impostazioni audio</string>
<string name="android.permission.MODIFY_PHONE_STATE">Cambia le impostazioni del dispositivo</string>
<string name="android.permission.NFC">Usa il modulo NFC</string>
<string name="android.permission.PROCESS_OUTGOING_CALLS">Rileva chiamata in uscita</string>
<string name="android.permission.READ_CALENDAR">Legge gli appuntamenti dal calendario</string>
<string name="android.permission.READ_CALL_LOG">Legge il registro chiamate</string>
<string name="android.permission.PROCESS_OUTGOING_CALLS">Rileva chiamate in uscita</string>
<string name="android.permission.READ_CALENDAR">Leggere gli appuntamenti dal calendario</string>
<string name="android.permission.READ_CALL_LOG">Leggere il registro chiamate</string>
<string name="android.permission.READ_CONTACTS">Leggere informazioni dai Contatti</string>
<string name="android.permission.READ_EXTERNAL_STORAGE">Legge la memoria esterna</string>
<string name="android.permission.READ_PHONE_STATE">Rileva lo stato del telefono</string>
<string name="android.permission.RECEIVE_BOOT_COMPLETED">Rileva che il dispositivo è stato riavviato</string>
<string name="android.permission.RECORD_AUDIO">Registra l\'audio</string>
<string name="android.permission.VIBRATE">Fa vibrare il telefono</string>
<string name="android.permission.RECEIVE_BOOT_COMPLETED">Rileva riavvio del dispositivo</string>
<string name="android.permission.RECORD_AUDIO">Registra audio</string>
<string name="android.permission.SEND_SMS">Invia messaggio di testo</string>
<string name="android.permission.VIBRATE">Attiva vibrazione</string>
<string name="android.permission.WAKE_LOCK">Mantiene attivo il dispositivo</string>
<string name="android.permission.WRITE_EXTERNAL_STORAGE">Scrive su SD</string>
<string name="android.permission.WRITE_EXTERNAL_STORAGE">Scrive sulla SD</string>
<string name="android.permission.WRITE_SECURE_SETTINGS">Cambia le impostazioni del dispositivo</string>
<string name="android.permission.WRITE_SETTINGS">Cambia le impostazioni del dispositivo</string>
<string name="android10WifiToggleNotice">Sfortunatamente, Google ha deciso di rimuovere questa funzione in Android 10. Applicazioni normali non hanno più accesso alla accensione o spegnimento della connessione wifi on. Questo significa che questa azione non avrà effetto su questo dispositivo.</string>
<string name="android9RecordAudioNotice">Se si sta usando il livello di rumore come evento di attivazione: sfortunatamente, a partire da Android 9 (Pie), Google ha deciso di non permettere l\'accesso al microfono da parte di applicazioni attive in secondo piano. Pertanto questo evento non ha più effetto e non attiverà nessuna azione.</string>
<string name="anotherAppIsRunning">Si è avviata/fermata un\'altra app</string>
<string name="anotherPoiByThatName">Nome già usato per un\'altra posizione.</string>
<string name="anotherProfileByThatName">Nome già usato per un altro profilo.</string>
<string name="anotherRuleByThatName">Nome già usato per un\'altra regola.</string>
<string name="any">qualsiaisi</string>
<string name="anyApp">Qualsiasi applicazione</string>
<string name="anyDevice">qualsiasi dispositivo</string>
<string name="anyLocation">qualsiasi posizione</string>
<string name="anyNumber">qualsiasi numero</string>
<string name="anyWifi">qualsiasi wifi</string>
<string name="appRequiresPermissiontoAccessExternalStorage">Automation richiede lautorizzazione per archiviare e leggere le impostazioni e le regole.</string>
<string name="featuresDisabled">L\'applicazione è in esecuzione in modalità limitata a causa di autorizzazioni mancanti.</string>
<string name="appStarted">App avviata.</string>
<string name="appStopped">App terminata.</string>
<string name="app_name">Automation</string>
<string name="appRequiresPermissiontoAccessExternalStorage">Automation richiede accesso alla memoria esterna per leggere le proprie impostazioni e regole.</string>
<string name="application">Applicazione</string>
<string name="applicationHasBeenUpdated">L\'applicazione è stata aggiornata.</string>
<string name="applyingSettingsAndRules">Applicazione delle impostazioni, regole e posizioni.</string>
<string name="areYouSure">Sicuro?</string>
<string name="at">il</string>
<string name="atLeastRuleXisUsingY">Almeno una regola ( \"%1$s\" ) sta usando una condizione di tipo \"%2$s\".</string>
<string name="logAttemptingDownloadOf">Tentativo di dowload di</string>
<string name="logAttemptingToBindToService">Tentativo di attivare il servizio... </string>
<string name="logAttemptingToUnbindFromService">Tentativo di disattivare il servizio... </string>
<string name="audibleSelection">Audio alla selezione di cambio schermo</string>
<string name="apply">applica</string>
<string name="areYouSure">Sei sicuro?</string>
<string name="at">al</string>
<string name="audibleSelection">Audio abilitato quando si seleziona lo schermo</string>
<string name="autoBrightness">Abilitare luminosità automatica</string>
<string name="autoBrightnessNotice">Se usi la luminosità automatica, il valore di luminosità scelto a seguito non sarà probabilmente in use per molto.</string>
<string name="batteryLevel">livello della batteria</string>
<string name="bluetoothConnection">Connessione Bluetooth</string>
<string name="bluetoothConnectionTo">Connessione Bluetooth fra %1$s</string>
<string name="bluetoothConnectionTo">Connessione Bluetooth con %1$s</string>
<string name="bluetoothDeviceInRange">Dispositivo Bluetooth %1$s rilevato.</string>
<string name="bluetoothDeviceOutOfRange">Dispositivo Bluetooth %1$s non raggiungibile.</string>
<string name="bluetoothDisconnectFrom">Bluetooth connection to %1$s torn</string>
<string name="bluetoothDisconnectFrom">Connessione Bluetooth con %1$s interrotta</string>
<string name="bluetoothFailed">Impossibile attivare il Bluetooth. Questo dispositivo è dotato di Bluetooth?</string>
<string name="logBoundToService">Servizio impegnato.</string>
<string name="cancel">Abbandona</string>
<string name="cantDownloadTooFewRequestsInSettings">Non è possibile scaricare nulla. La quantità di richieste HTTP è impostata inferiore a 1.</string>
<string name="cantMoveDown">Non posso abbassare l\'item. E\' già l\'ultimo.</string>
<string name="cantMoveUp">Non posso alzare l\'item. E\' già il primo.</string>
<string name="cantRunRule">Queste regole non possono essere eseguite.</string>
<string name="brightnessAuto">luminosità automatica</string>
<string name="brightnessManual">luminosità manuale</string>
<string name="cancel">Annulla</string>
<string name="cantFindSoundFile">Impossibile trovate il file audio %1$s e riprodurlo.</string>
<string name="cantMoveDown">Non posso spostare giù l\'elemento. E\' già l\'ultimo.</string>
<string name="cantMoveUp">Non posso spostare su l\'elemento. E\' già il primo.</string>
<string name="cantRunRule">Impossibile eseguire le regole.</string>
<string name="cantStopIt">Non posso fermarla.</string>
<string name="cellMastChanged">Devi cambiare la cella: %1$s</string>
<string name="cellMastIdleTime">Massimo tempo di inattività della cella</string>
<string name="change">Abilita modifiche</string>
<string name="logClearingBothLocationListeners">Cancello la posizione sia come rete che come GPS</string>
<string name="closeTo">chiuso in</string>
<string name="closestPoi">Posizione precedente:</string>
<string name="cellMastIdleTime">Massimo tempo di inattività del ripetitore</string>
<string name="change">Modifica</string>
<string name="chooseActivityHint">In questa ultima selezione dovrai selezionare una attività specifica. Praticamente, questa è come una finestra dell\'applicazione desiderata. Se non sai qual è, si raccomanda scegliere quella che ha \"main\" o \"launcher\" nel suo nome.</string>
<string name="clickAndHoldForOptions">Clicca e mantieni premuto un elemento per vedere le opzioni.</string>
<string name="closeTo">vicino a</string>
<string name="closestPoi">Posizione più vicina:</string>
<string name="com.wireguard.android.permission.CONTROL_TUNNELS">Controlla i tunnels dell\'applicazione wireguard</string>
<string name="comparing">Ho la posizione sia dalla rete che dal GPS e le sto confrontando...</string>
<string name="configurationExportedSuccessfully">Configurazione esportata con successo.</string>
<string name="configurationImportedSuccessfully">Configurazione esportata con successo.</string>
<string name="connected">connesso</string>
<string name="connectedToWifi">connesso a wifi \"%1$s</string>
<string name="connectedToWifi">connesso al wifi \"%1$s</string>
<string name="connecting">connessione in corso</string>
<string name="connectionToDevice">connessione al dispositivo</string>
<string name="continueText">Continua</string>
<string name="continueText">continua</string>
<string name="currentId">ID corrente:</string>
<string name="currentVolume">Volume attuale</string>
<string name="dataConWithRootFail">Il dato non può essere cambiato usando i permessi superuser.</string>
<string name="dataConWithRootSuccess">La connessione è stata cambiata usando i permessi superuser. </string>
<string name="deactivate">Disattivazione</string>
<string name="deactivated">non attivo</string>
<string name="deactivating">Disattivazione in corso</string>
<string name="defaultSettings">Ripristino impostazioni di default</string>
<string name="delete">cancella</string>
<string name="deleteCapital">Cancella</string>
<string name="delete">rimuovi</string>
<string name="deleteCapital">Rimuovi</string>
<string name="deletePoi">Cancella posizione</string>
<string name="detectedActivity">Cancella attività:</string>
<string name="detectedActivity">Attività rilevata:</string>
<string name="detectedActivityInVehicle">In un veicolo (auto, bus,...)</string>
<string name="detectedActivityInvalidStatus">Attività non valida</string>
<string name="detectedActivityOnBicycle">In bicicletta</string>
<string name="detectedActivityOnFoot">A piedi</string>
<string name="detectedActivityRunning">Di corsa</string>
<string name="detectedActivityStill">Fermo</string>
<string name="detectedActivityTilting">Pendenza</string>
<string name="detectedActivityTilting">Ribaltando</string>
<string name="detectedActivityUnknown">Sconosciuto</string>
<string name="detectedActivityWalking">Passeggio</string>
<string name="logDetectingTetherableUsbInterface">Individuata interfaccia USB con tethering.</string>
<string name="deviceDoesNotHaveNfc">Sembra che il dispositivo non sia NFC.</string>
<string name="detectedActivityWalking">Camminando</string>
<string name="deviceDoesNotHaveBluetooth">Questo dispositivo non sembra avere bluetooth. Puoi comunque configurare questa opzione, ma non avrà probabilmente nessun effetto.</string>
<string name="deviceDoesNotHaveNfc">Sembra che il dispositivo non abbia la funzione NFC.</string>
<string name="deviceInRange">dispositivo visibile</string>
<string name="deviceOutOfRange">dispositivo fuori portata</string>
<string name="direction">Direzione</string>
<string name="directionStringContains">contiene</string>
<string name="directionStringEndsWith">finisce in</string>
<string name="directionStringEquals">uguale a</string>
<string name="directionStringNotEquals">non uguale a</string>
<string name="directionStringStartsWith">comincia con</string>
<string name="disabledFeatures">Funzioni disabilitate</string>
<string name="disconnected">disconnesso</string>
<string name="disconnectedFromWifi">disconnesso dal wifi \"%1$s</string>
<string name="disconnectedFromWifi">disconnesso dalla rete wifi \"%1$s</string>
<string name="disconnecting">disconnessione in corso</string>
<string name="disconnectionFromDevice">disconnesso dal dispositivo</string>
<string name="distanceBetween">La distanza tra la posizione GPS e la posizione di rete è</string>
<string name="displayNewsOnMainScreen">Visualizza le novità dell\'applicazione sullo schermo principale</string>
<string name="displayNewsOnMainScreenDescription">Novità relative solo a questa applicazione, stiamo parlando di un paio per anno, non di più.</string>
<string name="distanceBetween">La distanza tra la posizione GPS e la posizione di rete è di %1$d metri. Il raggio minimo è +1 metro.</string>
<string name="distanceForGpsUpdate">Distanza per l\'aggiornamento del GPS [m]</string>
<string name="distanceForNetworkUpdate">Distanza per l\'aggiornamento della rete [m]</string>
<string name="droppingBelow">inferiore a</string>
<string name="droppingBelow">sta andando sotto</string>
<string name="dropsBelow">inferiore</string>
<string name="edit">Modifica</string>
<string name="end">Fine</string>
<string name="enforcingGps">Impedisce la localizzazione del provider e forza il GPS</string>
<string name="enterAPositiveValidNonDecimalNumber">Inserire un numero intero positivo</string>
<string name="enterAname">Inserisci un nome</string>
<string name="enterNameForIntentPair">Definisci un nome per la coppia di Intent</string>
<string name="enterPhoneNumber">Inserisci un numero di telefono. Lascia vuoto per qualsiasi numero.</string>
<string name="enterValidReferenceValue">Inserire un valore di riferimento valido.</string>
<string name="enterValueForIntentPair">Definisci un valore per la coppia di Intent.</string>
<string name="enterWifiName">Inserire un nome per la wifi. Se vuoto varrà per qualsiasi wifi.</string>
<string name="enterAname">Inserisci un nome!</string>
<string name="enterNameForIntentPair">Definisci un nome per la coppia di intenzioni</string>
<string name="enterPackageName">Inserisci un nome di pacchetto che sia valido.</string>
<string name="enterPhoneNumber">Inserisci un numero di telefono. Lascia vuoto per accettare qualsiasi numero.</string>
<string name="enterValidAction">Inserisci una azione valida</string>
<string name="enterValidReferenceValue">Inserisci un valore di riferimento valido.</string>
<string name="enterValueForIntentPair">Definisci un valore per la coppia di Intenzioni.</string>
<string name="enterWifiName">Inserire un nome per la wifi. Se vuoto sarà valido per qualsiasi wifi.</string>
<string name="entering">entrando in</string>
<string name="eraseSettings">Azzera le impostazioni</string>
<string name="error">Errore</string>
<string name="errorActivatingProfile">Errore nell\'attivazione del profilo:</string>
<string name="errorActivatingWifiAp">Errore nell\'attivazione del wifi</string>
<string name="errorChangingScreenRotation">Errore nella rotazione dello schermo</string>
<string name="logErrorDeterminingCurrentUsbTetheringState">Errore nel riconsocimento di UsbTethering.</string>
<string name="errorDeterminingWifiApState">Errore nel riconoscimento wifi</string>
<string name="logErrorGettingConnectionManagerService">Errore del connectionManager. Il Tethering USB non risponde.</string>
<string name="errorInitializingSettingsToPersistentMemory">Errore nello scrivere le impostazioni nella memoria di massa.</string>
<string name="errorActivatingWifiAp">Errore nell\'attivazione del punto di accesso wifi</string>
<string name="errorChangingScreenRotation">Errore nel ruotare lo schermo</string>
<string name="errorDeterminingWifiApState">Errore nel riconoscimento del punto di accesso wifi</string>
<string name="errorReadingPoisAndRulesFromFile">Errore nella lettura di regole e posizioni dal file.</string>
<string name="errorReadingSettings">Errore nel leggere le impostazioni</string>
<string name="errorRunningRule">C\'è stato un errore cercando di eseguire una regola.</string>
<string name="errorStartingOtherActivity">Errore nel\'avvio dell\'altra attività</string>
<string name="errorTriggeringUrl">Errore di indirizzamento</string>
<string name="errorWritingConfig">Errore nello scrivere la configurazione. La memoria è accessibile?</string>
<string name="errorWritingConfig">Errore nello scrivere la configurazione. È la memoria in sola lettura?</string>
<string name="errorWritingFile">Errore nella scrittura delle impostazioni.</string>
<string name="errorWritingSettingsToPersistentMemory">Errore nella memorizzazione delle impostazioni.</string>
<string name="exceeding">superiore a</string>
<string name="exceeds">superiore</string>
<string name="exceeding">sta sorpassando</string>
<string name="exceeds">è superiore</string>
<string name="executeRulesAndProfilesWithSingleClickTitle">Esegui regole/profili con un singolo click.</string>
<string name="exportConfiguration">Esporta la configurazione</string>
<string name="failedToTriggerBluetooth">Non riesco ad attivare il Bluetooth. Questo dispositivo ha il Bluetooth?</string>
<string name="featureNotInFdroidVersion">Questa funzione sfrutta software non basato su codice aperto. Pertanto non è disponibile nella versione F-Droid.</string>
<string name="featuresDisabled">L\'applicazione è in esecuzione in modalità limitata a causa di autorizzazioni mancanti.</string>
<string name="fileDoesNotExist">Il file non esiste.</string>
<string name="filesHaveBeenMovedTo">Automation usa adesso un percorso nuovo per salvare i tuoi files. Tutti i files di Automation sono stati mossi qui: \"%s\". I permessi di accesso alla memoria esterna non sono più necessari e si possono revocare. Questo verrà permanentemente rimosso in una versione futura.</string>
<string name="filesStoredAt">I files di configurazione e log sono salvati nella cartella %1$s. Clicca su questo testo per aprire l\'esploratore di files. Sfortunatamente, questo solo funziona su un dispositivo con accesso root.\n\nPER TUTTI GLI ALTRI DISPOSITIVI: basta usare il bottone \'esporta\' per fare un backup.</string>
<string name="forcedLocationUpdate">Aggiornamento forzato della posizione</string>
<string name="forcedLocationUpdateLong">Essendo scaduto il timeout della misura sarà considerata valida l\'ultima posizione rilevata.</string>
<string name="forcedLocationUpdateLong">Avendo raggiunto il timeout comparando le misure, sarà considerata valida l\'ultima posizione rilevata.</string>
<string name="friday">Venerdì</string>
<string name="general">Descrizione della regola</string>
<string name="from">da</string>
<string name="general">Generale</string>
<string name="generalSettings">Impostazioni globali</string>
<string name="generalText">Per utilizzare questo programma è necessario impostare delle regole. Le regole contengono eventi, per esempio l\'arrivare in una determinata zona o essere in un intervallo temporale. Dopo che è stato fatto clic sul pulsante ON / OFF nella home-page.
</string>
<string name="generalText">Per utilizzare questo programma è necessario impostare delle regole. Le regole contengono eventi, per esempio l\'arrivare in una determinata zona o essere in un intervallo temporale. Dopo che è stato fatto, fare clic sul pulsante ON / OFF nella home-page.</string>
<string name="getCurrentPosition">Rileva la posizione attuale</string>
<string name="gettingListOfInstalledApplications">Sto cercando le applicazioni installate … </string>
<string name="gettingPosition">Sto rilevando la posizione. Attendere prego ...</string>
<string name="logGettingPositionWithProvider">Richiesta posizione dal provider:</string>
<string name="googleLocationChicanery">Questa applicazione accumula dati di localizzazione per abilitare regole basate sulla posizione insieme al rilevamento della velocità anche quando l\'applicazione è chiusa o non in uso.</string>
<string name="googleLocationChicaneryOld">Questa applicazione accumula dati di localizzazione per determinare se sei attualmente ad una delle posizioni che hai creato. Inoltre, questa funzione è usata per determinare la tua velocità attuale se tale evento è stato attivato nelle regole. Questi rilevamenti sono effettuati anche quando l\'applicazione è chiusa o non in uso (ma solo se il servizio è attivato).</string>
<string name="googleSarcasm">Grazie alla infinita sapienza di Google e continui sforzi per proteggere la privacy di ognuno di noi, nelle regole che possano inviare SMS o coinvolgere lo stato del telefono, sono state rimossi eventi ed azioni rilevanti.</string>
<string name="google_app_id">id della tua app</string>
<string name="logGotGpsUpdate">GPS aggiornato. Precisione:</string>
<string name="logGotNetworkUpdate">Rete aggiornata. Precisione:</string>
<string name="gpsAccuracy">Precisone del GPS [m]</string>
<string name="gpsComparison">Confronto col GPS</string>
<string name="gpsComparisonTimeoutStop">Fermata la comparazione col GPS per timeout.</string>
<string name="gpsMeasurement">Misura GPS</string>
<string name="gpsMeasurementTimeout">Misura GPS fermata per timeout.</string>
<string name="hapticFeedback">Sensazione tattile(vibrazione al tocco)</string>
<string name="gpsComparison">Comparazione GPS</string>
<string name="gpsComparisonTimeoutStop">Sto fermando la comparazione con il GPS a causa di un timeout.</string>
<string name="hapticFeedback">Sensazione tattile (vibrazione al tocco)</string>
<string name="headphoneAny">Oppure</string>
<string name="headphoneMicrophone">Microfono</string>
<string name="headphoneSelectType">Seleziona il tipo di auricolare</string>
<string name="headphoneSimple">Auricolari</string>
<string name="headsetConnected">Connesso auricolari (type: %1$s) </string>
<string name="headsetDisconnected">Disconnesso auticolari (type: %1$s) </string>
<string name="helpTextPoi">Una posizione è composta da una zona con un raggio intorno a un punto specificato dalle coordinate GPS. ll posizionamento è realizzato appoggianodosi alle coordinate dei ripetitori del tuo gestore. E\' leggermente impreciso, ma veloce e consuma poca batteria. Pertanto è bene non specificare un raggio troppo piccolo. L\'applicazione suggerisce un raggio minimo quando si crea una nuova posizione.</string>
<string name="helpTextProcessMonitoring">Se si specifica una regola che controlli l\'esecuzione di un processo Automation eseguirà la verifica ogni x secondi (con x selezionabile nelle impostazioni). Va infatti considerato che un monitoraggio costante provocherebbe un rapido esaurimento della batteria e non esistono segnalazioni di questo tipo nel sistema operativo.</string>
<string name="helpTextRules">Tutti gli eventi di una regola sono efficaci se si verificano nella loro totalità. Basta che un evento non sia verificato è la regola non si attiverà. Per avere invece una funzionalità alternativa bisogna creare più regole.</string>
<string name="helpTextTimeFrame">Se si specifica una regola con un intervallo temporale si hanno due scelte. È possibile scegliere se si desidera attivare la regola all\'interno o all\'esterno dell\'intervallo di tempo. In entrambi i casi l\'azione verrà eseguita una sola volta.
Quindi, se si crea una regola che imposta il profilo su vibrazione nell\'intervallo temporale xyz, il telefono, passato allo stato vibrazione, rimarrà definitivamente in tale stato anche dopo lo scadere dell\'intervallo di tempo. Se si desidera che ciò avvenga è necessario specificare un\'altra regola con un altro periodo di tempo.</string>
<string name="helpTextToggable">Alcune regole hanno una bandiera chiamata "Reversibile". Ciò significa che, se una regola viene eseguita al verificarsi di un evento e poi quest\'ultimo si verifica una seconda volta, il comando della regola verrà eseguito una ulteriore volta in modalità inversa, se possibile. Attualmente questo avverrà solo in combinazione con i tag NFC. Se li si tocca due volte la regola associata invertirà la situazione attuale. Per esempio una regola “Reversibile” può disattivare il WiFi se attivo e viceversa attivarlo se non attivo.</string>
<string name="headsetConnected">Connesso auricolare (tipo: %1$s) </string>
<string name="headsetDisconnected">Disconnesso auticolari (tipo: %1$s) </string>
<string name="helpTextActivityDetection">Questa funzione può identificare se sei attualmente in movimento e se sei a piedi o in che tipo di veicolo (almeno con una certa precisione). Questa funzione non è completamente integrata con Automation, ma viene fornita dai servizi di Google Play. In pratica, non fornisce un risultato si/no, ma provvede una percentuale del livello di sicurezza dello stato di movimento identificato. Puoi scegliere la percentuale raggiunta la quale Automation accetterà un resultato. Nota: 1) è possibile che più di uno stato sia identificato nello stesso momento. Per esempio, potresti star CAMMINANDO dentro a un bus in movimento; 2) Questo sensor usa molta energia. Se possibile, potresti considerare delle alternative, per esempio, potresti identificare che stai guidando, forzando una connessione con il vivavoce.</string>
<string name="helpTextEnergySaving">Molti produttori di dispositive Android cercano di salvare energia limitando le attività di applicazioni eseguite in secondo piano. Sfortunatamente, questo spesso fa che tali applicazioni non funzionino correttamente e Automation è fra queste. Puoi leggere questa <a href="https://dontkillmyapp.com/">pagina web</a> per scoprire come escludere Automation da queste funzioni di risparmio energetico.</string>
<string name="helpTextPoi">Una posizione è composta da cooridinate GPS ed un raggio d\'azione. Dato che il posizionamento realizzato tramite i ripetitori del tuo gestore è piuttosto impreciso (ma veloce e consuma poca batteria), è bene non specificare un raggio troppo piccolo. L\'applicazione suggerisce un raggio minimo quando si crea una nuova posizione.</string>
<string name="helpTextProcessMonitoring">Se si specifica una regola che controlli l\'esecuzione di un processo, Automation eseguirà la verifica ogni x secondi (con x selezionabile nelle impostazioni). Bisogna considerare che un monitoraggio costante provocherebbe un rapido esaurimento della batteria e non esistono notifiche di questo tipo di attività proviste dal sistema operativo.</string>
<string name="helpTextRules">Una regola sarà eseguita quando tutti i suoi eventi risultano veri. Basta che solo un evento non sia eseguito e la regola non si attiverà. Per eseguire una regola in base a diversi eventi individuali, è sufficiente creare regole specifiche per ogni set di eventi.</string>
<string name="helpTextSound">Nello schermo principale puoi bloccare temporaneamente i cambi ai suoni per evitare l\'esecuzione di regole che facciano cambi alle attività sonore. Per esempio, potresti essere in una situatione o in un luogo dove normalmente ascoltare il suono di una suoneria è ok, ma in questa occasione bisognerebbe evitarlo. Questa funzione si disattiverà automaticamente non appena sia trascorso il tempo selezionato. Fai Click sul bottone + per raggiungere la quantità di tempo desiderata. Una volta attiva, questa si può disattivare nuovamente usando il pulsante di attivazione (e in questo modo, si riattiveranno le regole basate su cambi sonori).</string>
<string name="helpTextTimeFrame">Se si specifica una regola con un intervallo temporale si hanno due scelte. È possibile scegliere se si desidera attivare la regola all\'interno o all\'esterno dell\'intervallo di tempo. In entrambi i casi l\'azione verrà eseguita una sola volta. Quindi, se si crea una regola che imposta il profilo su vibrazione nell\'intervallo temporale xyz, il telefono, passato allo stato vibrazione, rimarrà definitivamente in tale stato anche dopo lo scadere dell\'intervallo di tempo. Se si desidera che ciò avvenga è necessario specificare un\'altra regola con un altro periodo di tempo.</string>
<string name="helpTextToggable">Le regole hanno un segno di spunta chiamato "Reversibile". Ciò significa che, se una regola viene eseguita al verificarsi di un evento e poi quest\'ultimo si verifica una seconda volta, il comando della regola verrà eseguito una ulteriore volta in modalità inversa, se possibile. Attualmente questo avverrà solo in combinazione con i tag NFC. Se li si tocca due volte la regola associata invertirà la situazione attuale. Per esempio una regola “Reversibile” può disattivare il WiFi se attivo e viceversa attivarlo se non attivo.</string>
<string name="helpTitleEnergySaving">Risparmio energetico</string>
<string name="hint">Suggerimento</string>
<string name="httpAcceptAllCertificatesSummary">Salta il controllo dei certificate SSL (si consiglia di non attivarlo)</string>
<string name="httpAcceptAllCertificatesTitle">Accetta tutti I certificati</string>
<string name="httpAttemptGapSummary">Pausa prima del successive tentativo [secondi]</string>
<string name="httpAcceptAllCertificatesSummary">Salta il controllo dei certificati SSL (si consiglia di non attivarlo)</string>
<string name="httpAcceptAllCertificatesTitle">Accetta tutti i certificati</string>
<string name="httpAttemptGapSummary">Pausa prima del tentativo successivo [secondi]</string>
<string name="httpAttemptGapTitle">Pausa [sec]</string>
<string name="httpAttemptsSummary">Numero di tentative ripetuti in caso di fallimento richiesta HTTP a causa della connessione </string>
<string name="httpAttemptsSummary">Numero di tentativi in caso le richieste HTTP falliscano a causa di problemi di connessione </string>
<string name="httpAttemptsTimeoutSummary">Timeout per richieste HTTP [secondi]</string>
<string name="httpAttemptsTimeoutTitle">Timeout [sec]</string>
<string name="httpAttemptsTitle">Numero di tentativi HTTP</string>
<string name="ignoringActivityDetectionUpdateTooSoon">Nessuna risposta. Riprovo tra %1$s secondi.</string>
<string name="incoming">ricevuta</string>
<string name="incomingAdjective">ricevuta</string>
<string name="importConfiguration">Importa configurazione</string>
<string name="importExportExplanation">Quando si clicca su importa o esporta, stai scegliendo la direzione in cui i files vengono importati o esportati. Quando si procede alla esportazione, files esistenti potrebbero essere sovrascritti.</string>
<string name="importNumberFromContacts">Importa numero dai contatti</string>
<string name="incoming">in arrivo</string>
<string name="incomingAdjective">in arrivo</string>
<string name="incomingCallFrom">Chiamata in arrivo da %1$s.</string>
<string name="incomingCallsRingtone">Suoneria per le chiamate in arrivo</string>
<string name="initializingSettingsToPersistentMemory">Impostazioni iniziali in una memoria di massa.</string>
<string name="insideOrOutsideTimeFrames">Dentro o fuori l\'intervallo?</string>
<string name="insideOrOutsideTimeFrames">Dentro o fuori questi intervalli?</string>
<string name="intentDataComment">Se il tuo parametro è di tipo Uri e usi \"IntentData\" come nome (in maiuscole o minuscole non importa), il parametro non verrà aggiunto come parametro normale con putExtra(), ma sarà aggiunto all\'intento con setData().</string>
<string name="invalidDevice">Dispositivo non valido.</string>
<string name="invalidPoiName">Nome posizione non valido.</string>
<string name="invalidProfileName">Nome profilo non valido.</string>
<string name="invalidStuffStoredInSettingsErasing">Impostazioni non tutte valide. Le sto cancellando ...</string>
<string name="is">é</string>
<string name="is">è</string>
<string name="lastRule">Ultima regola:</string>
<string name="latitude">Latitudine</string>
<string name="leaving">uscendo da</string>
@ -245,284 +270,306 @@ Quindi, se si crea una regola che imposta il profilo su vibrazione nell\'interva
<string name="lengthOfNoiseLevelMeasurementsTitle">Durata di ogni misura di livello di rumore</string>
<string name="listenToAccelerometerState">Rileva i movimenti del dispositivo dove non fosse disponibile il wifi</string>
<string name="listenToWifiState">Rileva il cambiamento di stato del wifi se disponibile</string>
<string name="loadWifiList">Carica lista wifi</string>
<string name="locationDisabled">Localizzazione disattivata</string>
<string name="locationEngineDisabledLong">Purtroppo la tua posizione non può più essere determinata. Un debito di gratitudine è dovuto a Google per la sua infinita saggezza e amabilità.\n\nVediamo di approfondire questo problema. A partire da Android 10 è stato introdotto un nuovo permesso che è necessario per determinare la vostra posizione in secondo piano (che naturalmente è necessario per un\'app come questa). Sebbene la consideri una buona idea in generale, i problemi che comporta per gli sviluppatori non lo sono.\n\nWQuando si sviluppa un\'app si può cercare di qualificarsi per questo permesso rispettando un catalogo di requisiti. Purtroppo le nuove versioni della mia app sono state rifiutate per un periodo di tre mesi. Ho soddisfatto tutti questi requisiti, mentre il merdoso supporto allo sviluppo di Google ha affermato che non l\'ho fatto. Dopo aver dato loro la prova che l\'ho fatto - ho ottenuto una risposta del tipo \"non posso più aiutarti\". Alla fine mi sono arreso.\n\nDi conseguenza, la versione di Google Play non può più usare la tua posizione come trigger. La mia unica opzione alternativa sarebbe stata quella di avere questa applicazione rimossa dal negozio interamente.\n\nNe sono molto dispiaciuto, ma ho fatto del mio meglio per discutere con un \"supporto\" che ripetutamente non ha superato il test di Turing.\n\nInfine, c\'è una buona notizia: puoi ancora avere tutto!\n\nAutomation è adesso una applicazione di codice aperto e si può trovare su F-Droid. Questo è un app store che si preoccupa davvero della tua privacy - invece che fingere di farlo. Basta fare il backup del tuo file di configurazione, disinstallare questa app, installarla di nuovo da F-Droid e ripristinare il tuo file di configurazione - fatto.\n\nClicca qui per maggiori informazioni:</string>
<string name="locationEngineDisabledShort">La localizzazione non può più essere determinata. Clicca qui per scoprirne il perché.</string>
<string name="locationEngineNotActive">Ricerca posizione non attiva.</string>
<string name="lockSoundChanges">Cambiamento dei suoni:</string>
<string name="lockSoundChanges">Blocca il cambio dei suoni:</string>
<string name="logFileMaxSizeSummary">Massima dimensione del file di log in Megabyte. Tronca quando la dimensione eccede.</string>
<string name="logFileMaxSizeTitle">Massima dimensione del file di log [Mb]</string>
<string name="logLevelSummary">Dettaglio del file di Log (1=minimo, 5=massimo)</string>
<string name="logLevelTitle">Dettaglio del file di log</string>
<string name="logServiceStopping">Arrestando il servizio.</string>
<string name="longitude">Longitudine</string>
<string name="mainScreenPermissionNote">Automation richiede ulteriori autorizzazioni. Clicca su questo testo per saperne di più e concederle.</string>
<string name="messageReceivedStatingProcessMonitoringIsComplete">Il messaggio ricevuto attesta che il monitoraggio del processo è completato.</string>
<string name="minimumDistanceChangeForGpsLocationUpdates">Minimo intervallo (im metri) per l\'aggiornamento GPS </string>
<string name="minimumDistanceChangeForNetworkLocationUpdates">Minima distanza percorsa per aggiornare la posizione della rete.</string>
<string name="minimumTimeForLocationUpdates">Intervallo minimo in secondi per aggiornare la localizzazione</string>
<string name="mainScreenPermissionNote">Automation richiede ulteriori autorizzazioni per funzionare correttamente. Clicca su questo testo per saperne di più e richiederle.</string>
<string name="manageLocations">Creare o modificare posizioni</string>
<string name="matching">abbinando</string>
<string name="messageNotShownAgain">Questo messaggio non sarà mostrato più.</string>
<string name="minimumDistanceChangeForGpsLocationUpdates">Minimo intervallo (in metri) per aggiornare le posizioni GPS </string>
<string name="minimumDistanceChangeForNetworkLocationUpdates">Minimo cambio della distanza per aggiornare la posizione dalla rete.</string>
<string name="minimumTimeForLocationUpdates">Intervallo minimo in millisecondi per aggiornare la localizzazione</string>
<string name="monday">Lunedì</string>
<string name="moreSettings">Altre impostazioni</string>
<string name="moveDown">Sposta verso il basso</string>
<string name="moveUp">Sposta versol\'alto</string>
<string name="muteTextToSpeechDuringCallsSummary">Disabilitazione del TextToSpeach durante le chiamate</string>
<string name="muteTextToSpeechDuringCallsTitle">Silenziato durante la chiamata</string>
<string name="muteTextToSpeechDuringCallsTitle">Silenziare durante le chiamate</string>
<string name="name">Nome</string>
<string name="needLocationPermForWifiList">L\'elenco delle wifi a cui il tuo dispositivo è stato connesso potrebbe essere usato per determinare i luoghi in cui sei stato. Questo è il motivo per cui il permesso di localizzazione è richiesto per caricare l\'elenco delle wifi. Se vuoi essere in grado di sceglierne una dalla lista devi concedere questo permesso. Altrimenti puoi ancora inserire il nome della tua wifi manualmente.</string>
<string name="networkAccuracy">Precisione della rete [m]</string>
<string name="newId">Nuovo ID:</string>
<string name="newNfcId">Scrivi un nuovo ID NFC</string>
<string name="newThreadRules">Nuova discussione</string>
<string name="newsOptIn">Vuoi ricevere delle notizie su questa app (solo quelle importanti) nella schermata principale? Queste vengono scaricate dal sito web dello sviluppatore. Non ci sarà nessuna notifica intrusiva, solo un testo nella schermata principale quando apri l\'app.</string>
<string name="nfcApplyTagToRule">Applicazione del tag alla regola</string>
<string name="nfcBringTagIntoRange">Portarsi nel campo d\'azione di un tag NFC.</string>
<string name="nfcBringTagIntoRangeToRead">Ricerca di un TAG da leggere.</string>
<string name="nfcEnterValidIdentifier">Inserire un nome valido per il tag (come "porta d\'ingresso di casa").</string>
<string name="nfcNoNdefIntentBut">Nessun NFC NDEF intent, ma</string>
<string name="nfcBringTagIntoRange">Portare un tag NFC nel campo d\'azione.</string>
<string name="nfcBringTagIntoRangeToRead">Avvicina il TAG da leggere.</string>
<string name="nfcEnterValidIdentifier">Inserire un nome valido per il tag (come "Porta d\'ingresso di casa").</string>
<string name="nfcNoNdefIntentBut">Nessun intento NFC NDEF , ma</string>
<string name="nfcNoTag">Nessun tag rilevato.</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC non è ancora supportato in questa versione di Android.</string>
<string name="nfcReadTag">Lettura ID da un tag</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC non ancora supportato in questa versione di Android.</string>
<string name="nfcReadTag">Lettura ID dal tag</string>
<string name="nfcTag">Tag NFC</string>
<string name="nfcTagDataNotUsable">Dato del tag inadatto, riscrivere.</string>
<string name="nfcTagDataNotUsable">Dati del tag non leggibili, si prega di riscriverli.</string>
<string name="nfcTagDiscovered">Tag rilevato</string>
<string name="nfcTagFoundWithText">Trovatao Tag con scritto:</string>
<string name="nfcTagReadSuccessfully">Tag letto.</string>
<string name="nfcTagWriteError">Errore di scrittura sul tag. E\' in visibilità?</string>
<string name="nfcTagWrittenSuccessfully">Scrittura Tag verificata.</string>
<string name="nfcTagFoundWithText">Trovato Tag con testo:</string>
<string name="nfcTagReadSuccessfully">Tag letto con successo.</string>
<string name="nfcTagWriteError">Errore di scrittura sul tag. È sufficientemente vicino?</string>
<string name="nfcTagWrittenSuccessfully">Scrittura Tag eseguita con successo.</string>
<string name="nfcUnsupportedEncoding">Codifica non supportata:</string>
<string name="nfcValueNotSuitable">Valore memorizzato non adatto.</string>
<string name="nfcWriteTag">Scrittura tag</string>
<string name="no">No</string>
<string name="noApplicableFilesFoundInDirectory">Nessun file adatto è stato trovato in quella directory.</string>
<string name="noChangeSelectedProfileDoesntMakeSense">Nessun cambiamento selezionato. Questo profilo non ha senso.</string>
<string name="noDataChangedReadingAnyway">Sembra che non siano state salvate le modifiche. Tuttavia ci possono essere stati cambiamenti nella memoria che devono essere recuperati. Devo ricaricare il file.</string>
<string name="noDataChangedReadingAnyway">Sembra che non siano state salvate le modifiche. Tuttavia ci possono essere stati cambiamenti in memoria che devono essere rimossi. Devo ricaricare il file.</string>
<string name="noDevice">nessun dispositivo</string>
<string name="noFileManageInstalled">Nessun esploratore di files installato.</string>
<string name="noFilesImported">Non è stato possibile importare nessun file.</string>
<string name="noKnownWifis">Non c\'è nessuna wifi conosciuta sul tuo dispositivo.</string>
<string name="noMapsApplicationFound">Non trovo un navigatore installato.</string>
<string name="noOverLap">Nessuna duplicazione di posizioni rilevata.</string>
<string name="noPoiInRelevantRange">Nessuna posizione in un range significativo.</string>
<string name="noPoisDefinedShort">Nessuna posizione inidcata.</string>
<string name="noPoisSpecified">Non hai specificato nessuna posizione. E\' necessario.</string>
<string name="noProfileChangeSoundLocked">Il profilo non può essere attivato. Rimane attivo l\'ultimo profilo attivato.</string>
<string name="noProfilesCreateOneFirst">Non è specificato nessun profilo nella tua configurazione. Devi farlo prima.</string>
<string name="logNoSuitableProvider">Non posso localizzare attraverso il provider.</string>
<string name="noWifiNameSpecifiedAnyWillDo">Nessun SSID (nome della wifi) specificato; devi inserirne uno.</string>
<string name="noWritableFolderFound">Nessun folder disponibile per salvare il file di configurazione.</string>
<string name="noiseDetectionHint">Se pensi che la rilevazione del rumore non funzioni correttamente (in base al valore specificato) considera che ogni telefono è diverso. Quindi puoi tarare il "riferimento per la misurazione del rumore" nelle impostazioni. Consulta http://en.wikipedia.org/wiki/Decibel per maggiori informazioni. È possibile utilizzare la “Taratura audio” della schermata principale per calibrare il dispositivo.</string>
<string name="noPoiInRelevantRange">Nessuna posizione nel raggio specificato.</string>
<string name="noPoisDefinedShort">Nessuna posizione indicata.</string>
<string name="noPoisSpecified">Non hai specificato nessuna posizione. È necessario.</string>
<string name="noProfileChangeSoundLocked">Il profilo non può essere attivato. L\'ultimo profilo attivato è bloccato.</string>
<string name="noProfilesCreateOneFirst">Non è specificato nessun profilo nella tua configurazione. Prima di tutto, creane uno.</string>
<string name="noWifiNameSpecifiedAnyWillDo">Nessun nome della wifi specificato; devi inserirne uno.</string>
<string name="noWritableFolderFound">Nessuna cartella scrivibile trovata che permetta salvare il file di configurazione.</string>
<string name="noiseDetectionHint">Se pensi che la rilevazione del rumore non funzioni correttamente (in base al valore specificato) considera che ogni telefono è diverso. Quindi puoi tarare il "riferimento per la misurazione del rumore" nelle impostazioni. Consulta http://en.wikipedia.org/wiki/Decibel per maggiori informazioni. È possibile utilizzare la \"Taratura audio\" dalla schermata principale per calibrare il dispositivo.</string>
<string name="none">nessuno</string>
<string name="logNotAllMeasurings">P</string>
<string name="notEnforcingGps">Permette la localizzazione da terzi e la normale ricerca del provider.</string>
<string name="notRearmingProcessMonitoringMessageStopRequested">Messaggio di mancato avvio del monitoraggio, è riciesto l\arresto.</string>
<string name="logNotStartingServiceAfterAppUpdate">Nessun servizio attivo dopo laggiornamento dellApp.</string>
<string name="logNotStartingServiceAtPhoneBoot">Nessun servizio attivo allavvio del telefono.</string>
<string name="notAllFilesImported">Non è stato possibile importare tutti i file rilevanti.</string>
<string name="notification">Notifica</string>
<string name="notificationAppears">La notifica appare</string>
<string name="notificationDisappears">La notifica non appare</string>
<string name="notificationRingtone">Tono di notifica</string>
<string name="notificationTriggerExplanation">Questo evento risponderà ad altre applicazioni che aprono notifiche nell\'area apposita (o che vengono chiuse). Puoi specificare un\'altra applicazione da cui la notifica deve provenire. Se non lo fai, saranno incluse le notifiche da qualsiasi altra applicazione. Puoi anche specificare le stringhe che devono o non devono essere presenti nel titolo o nel corpo della notifica. Il confronto fatto non è sensibile alle maiuscole e alle minuscole.</string>
<string name="number">numero</string>
<string name="ok">Ok</string>
<string name="onOff">On/Off</string>
<string name="onOff">Acceso/Spento</string>
<string name="openExamplesPage">Apri la pagina web con gli esempi</string>
<string name="outgoing">effettuata</string>
<string name="outgoingAdjective">effettuata</string>
<string name="outgoingCallFrom">Ultima chiamata effettuata %1$s fa.</string>
<string name="outgoingCallTo">Ultima chiamata effettuata %1$s fa.</string>
<string name="overlapBetweenPois">Rilevata sovrapposizione della posizione %1$s. Ridurre il raggio almeno di %2$s metri.</string>
<string name="overview">Panoramica</string>
<string name="packageName">Nome del pacchetto</string>
<string name="parameterName">Nome parametro</string>
<string name="parameterType">Tipo parametro</string>
<string name="parameterValue">Valore</string>
<string name="password">Password</string>
<string name="periodicProcessMonitoringIsAlreadyRunning">Non posso avviare il processo ciclico di monitoraggio perché é già attivo.</string>
<string name="periodicProcessMonitoringIsNotActive">Non posso fermare il processo ciclico di monitoraggio perchè non è attivo.</string>
<string name="periodicProcessMonitoringStarted">Processo ciclico di monitoraggio avviato.</string>
<string name="periodicProcessMonitoringStopped">Processo ciclico di monitoraggio terminato.</string>
<string name="permissionsExplanation">Spiegazione delle autorizzazioni richieste</string>
<string name="permissionsExplanationGeneric">L\'applicazione è in esecuzione in modalità risparmio energetico ed ha pertanto disattivato alcune caratteristiche. Per funzionare appieno richiede ulteriori autorizzazioni. Se si desidera utilizzare tutte le funzionalità è necessario concedere le autorizzazioni indicate o alcune regole non potranno essere eseguite. Per ogni autorizzazione è esplicitato il motivo.
Selezionare su “Continua” quando si è pronti a procedere.</string>
<string name="permissionsExplanationSmall">Per attivare la funzione che hai tentato di utilizzare, necessitano ulteriori autorizzazioni. Seleziona “Continua” per richiederle.</string>
<string name="permissionsTitle">Occorrono le autorizzazioni.</string>
<string name="permissionsExplanationGeneric">L\'applicazione sta venendo attualmente eseguita in modalità limitata ed ha pertanto disattivato alcune funzioni. Per funzionare appieno richiede ulteriori permessi. Se vuoi utilizzare tutte le funzionalità è necessario concedere i permessi nelle successive finestre o alcune regole non potranno essere eseguite. Di seguito ti viene data una spiegazione dei permessi richiesti. Clicca su \"Continua\" quando sei pronto a procedere.</string>
<string name="permissionsExplanationSmall">Per attivare la funzione che hai appena tentato di utilizzare, sono necessari ulteriori permessi. Clicca \"Continua\" per richiederli.</string>
<string name="permissionsTitle">Permessi necessari</string>
<string name="phoneCall">Chiamata</string>
<string name="phoneDirection">Seleziona se entrante o uscente</string>
<string name="phoneIsNotRooted">Il telefono non è rootato.</string>
<string name="phoneIsRooted">Il telefono è rootato.</string>
<string name="phoneNrReplacementError">Non ho l\'ultimo numero di telefono e quindi non posso inserirlo nella variabile.</string>
<string name="phoneNumber">Numero di telefono</string>
<string name="phoneNumberExplanation">È possibile inserire un numero di telefono specifico, ma non è necessario. Se vuoi specificarne uno, puoi sceglierlo dalla tua rubrica o inserirlo manualmente. Inoltre puoi usare espressioni regolari. Per testare un\'espressione regolare mi piace questa pagina:</string>
<string name="playSound">Esegui suono</string>
<string name="pleaseEnterValidLatitude">Inserisci una latitudine valida.</string>
<string name="pleaseEnterValidLongitude">Inserisci una longitudine valida.</string>
<string name="pleaseEnterValidName">Inserisci un nome valido.</string>
<string name="pleaseEnterValidRadius">Inserisci un raggio positivo e valido.</string>
<string name="pleaseSpecifiyAction">Indica almeno un\'azione.</string>
<string name="pleaseSpecifiyTrigger">Indica almeno una consizione.</string>
<string name="pleaseSpecifiyTrigger">Indica almeno un evento.</string>
<string name="poi">Posizione</string>
<string name="poiCouldBeInRange">Almeno la posizione %1$s potrebbe essere in zona, se non in sovrapposizione.</string>
<string name="poiHasNoWifiNotStoppingCellLocationListener">La posizione non ha la connessione wifi. Continuo CellLocationListener.</string>
<string name="poiHasWifiStoppingCellLocationListener">La posizione ha la connessione wifi. Termino CellLocationListener.</string>
<string name="poiList">Elenco alfabetico delle posizioni:</string>
<string name="poiStillReferenced">Ci sono ancora regole che fanno riferimento alla posizione (%1$s). Quindi non posso cancellare.</string>
<string name="poiCouldBeInRange">Almeno la posizione %1$s potrebbe essere in zona, se non ne esistono altre in aggiunta.</string>
<string name="poiList">Elenco delle posizioni:</string>
<string name="poiStillReferenced">Ci sono ancora regole che fanno riferimento a questa posizione (%1$s). Quindi non posso cancellarla ancora.</string>
<string name="pois">Posizioni</string>
<string name="positioningEngine">Modulo di posizionamento</string>
<string name="positioningSettings">Impostazioni del posizionamento</string>
<string name="positioningThresholds">Soglia del posizionamento</string>
<string name="positioningWindowNotice">Se sei all\' interno di un edificio è fortemente consigliato accostarsi ad una finestra fino a quando è stata trovata una posizione. Diversamente la ricerca può richiedere molto tempo.</string>
<string name="privacy">Info Privacy</string>
<string name="positioningThresholds">Soglie del posizionamento</string>
<string name="positioningWindowNotice">Se sei all\' interno di un edificio è fortemente consigliato avvicinarsi ad una finestra fino a quando è stata trovata una posizione. Diversamente la ricerca potrebbe richiedere molto tempo o non riuscire a trovare nulla.</string>
<string name="postsNotification">%1$s notifica dei messaggi</string>
<string name="prefsImportError">C\'è stato un errore nell\'importazione delle preferenze.</string>
<string name="privacy">Informativa sulla Privacy</string>
<string name="privacyConfirmationText">Sarai reindirizzato al sito dello sviluppatore per scaricare l\'informativa sulla privacy.</string>
<string name="privacyLocationingSummary">Evita i metodi di localizzazione che possono inviare la tua posizione a un provider, ad esempio Google. Userà solo il GPS. Questo può provocare rallentamenti o non funzionare correttamente.</string>
<string name="privacyLocationingTitle">Solo posizioni riservate</string>
<string name="privacyLocationingSummary">Evita i metodi di localizzazione che possono inviare la tua posizione a un provider, ad esempio Google. Userà solo il GPS e pertanto potrebbe essere lento o non funzionare correttamente.</string>
<string name="privacyLocationingTitle">Solo posizioni private</string>
<string name="processMonitoring">Controllo di un processo</string>
<string name="processes">Processi</string>
<string name="profile">Profilo</string>
<string name="profileActivate">Attivazione del profilo %1$s</string>
<string name="profiles">Profili</string>
<string name="radiusHasToBePositive">Il raggio deve avere valore positivo.</string>
<string name="radiusSuggestion">metri. Il raggio minimo è +1 ma puoi aumentare.</string>
<string name="publishedOn">pubblicato il</string>
<string name="radiusHasToBePositive">Il raggio deve essere un numero positivo.</string>
<string name="radiusWithUnit">Raggio [m]</string>
<string name="readLocation">Legge la posizione</string>
<string name="rearmingProcessMonitoringMessage">Messaggio di riavvio del monitoraggio.</string>
<string name="referenceValueForNoiseLevelMeasurementsSummary">Valore di riferimento fisico per la misura di rumore</string>
<string name="referenceValueForNoiseLevelMeasurementsTitle">Riferimento per la misura di rumore</string>
<string name="refreshingProcessList">Ricontrollo la lista dei processi.</string>
<string name="refreshingSettingsFromFileToMemory">Riprisitna in memoria le impostzioni memorizzate in un file.</string>
<string name="rememberLastActivePoiSummary">Se sei in una posizione, la memorizza in modo che al riavvio l\'applicazione eseguirà le regole associate al lasciare la posizione.</string>
<string name="rememberLastActivePoiTitle">Ricorda la posizione dell\'ultima attività</string>
<string name="rememberLastActivePoiSummary">Se sei in una posizione, riavvia il tuo dispositivo o l\'applicazione e lascia la posizione. L\'applicazione eseguirà le regole associate alla uscita dal luogo al suo prossimo avvio.</string>
<string name="rememberLastActivePoiTitle">Ricorda la ultima posizione attiva</string>
<string name="removedNotification">la notifica da %1$s rimossa</string>
<string name="ringing">squillando</string>
<string name="roaming">Roaming</string>
<string name="rootExplanation">È necessario rootare il telefono per utilizzare questa funzione. Una volta rootato il telefono devi "eseguire la regola manualmente" per attivare la richiesta di autorizzazione come superuser. E\' necessario autorizzare l\'applicazione a utilizzare il profilo superuser sempre. In caso contrario, la regola non può funzionare quando il telefono è inattivo.</string>
<string name="rootExplanation">È necessario avere permessi di root per utilizzare questa funzione. Una volta abilitato l\'accesso root, dovrai \"eseguire la regola manualmente\" per attivare la richiesta di autorizzazione come superuser. Quando la finestra di superuser appare, bisognerà autorizzare l\'applicazione a utilizzare superuser sempre. In caso contrario, la regola non potrà funzionare quando il telefono è inattivo.</string>
<string name="rule">Regola</string>
<string name="ruleActivate">Esecuzione di %1$s</string>
<string name="ruleActivateToggle">Esecuzione di %1$s come Toggle</string>
<string name="ruleActive">Attiva</string>
<string name="ruleActivate">Attivando la regola %1$s</string>
<string name="ruleActivateToggle">Attivando la regola %1$s in modalità reversibile</string>
<string name="ruleActive">Regola attiva</string>
<string name="ruleCheckOf">Controllo della regola %1$s</string>
<string name="ruleDoesntApplyActivityGivenButTooLowProbability">Regola inapplicabile. Attività %1$s rilevata, ma con una probabilità insufficente (%2$s %%), occorre almeno il %3$s %%.</string>
<string name="ruleDoesntApplyActivityNotPresent">Regola inapplicabile. Serve l\'attività %1$s non disponibile.</string>
<string name="ruleDoesntApplyBatteryHigherThan">Regola inapplicabile: Livello della batteria superiore a</string>
<string name="ruleDoesntApplyBatteryLowerThan">Regola inapplicabile: livello della batteria inferiore a</string>
<string name="ruleDoesntApplyDeviceInRangeButShouldNotBe">Regola inapplicabile. Incoerente il range del dispositivo</string>
<string name="ruleDoesntApplyItsLouderThan">Regola inapplicabile. E\' più forte di</string>
<string name="ruleDoesntApplyItsQuieterThan">Regola inapplicabile. E\' inferiore a</string>
<string name="ruleDoesntApplyNoTagLabel">Regola inapplicabile. Non vi è alcuna etichetta tag o nessun tag. </string>
<string name="ruleDoesntApplyNotTheCorrectDeviceAddress">Regola inapplicabile. Indirizzo dispositivo bluetooth errato.</string>
<string name="ruleDoesntApplyNotTheCorrectDeviceName">Regola inapplicabile. Nome dispositivo bluetooth errato.</string>
<string name="ruleDoesntApplyNotTheCorrectSsid">Regola inapplicabile. SSID errato (demanded: \"%1$s\", given: \"%2$s\").</string>
<string name="ruleDoesntApplyStateNotCorrect">Regola inapplicabile. Stato errato</string>
<string name="ruleDoesntApplyWeAreFasterThan">Regola inapplicabile. Velocità superiore a</string>
<string name="ruleDoesntApplyWeAreSlowerThan">Regola inapplicabile. Velocità inferiore a</string>
<string name="ruleDoesntApplyWrongHeadphoneType">Regola inapplicabile. Tipo di auricolare errato.</string>
<string name="ruleDoesntApplyWrongTagLabel">Regola inapplicabile. Etichetta Tag errata.</string>
<string name="ruleDoesntApplyBatteryHigherThan">Impossibile applicare la regola: Livello della batteria superiore a</string>
<string name="ruleDoesntApplyBatteryLowerThan">Impossibile applicare la regola: livello della batteria inferiore a</string>
<string name="ruleDoesntApplyDeviceInRangeButShouldNotBe">Impossibile applicare la regola. Il dispositivo è in portata, ma non dovrebbe esserlo</string>
<string name="ruleDoesntApplyItsLouderThan">Impossibile applicare la regola. È più forte di</string>
<string name="ruleDoesntApplyItsQuieterThan">Impossibile applicare la regola. È inferiore a</string>
<string name="ruleDoesntApplyNoTagLabel">Impossibile applicare la regola. Non vi è alcuna etichetta tag o nessun tag. </string>
<string name="ruleDoesntApplyNotTheCorrectDeviceAddress">Impossibile applicare la regola. Indirizzo dispositivo bluetooth errato.</string>
<string name="ruleDoesntApplyNotTheCorrectDeviceName">Impossibile applicare la regola. Nome dispositivo bluetooth errato.</string>
<string name="ruleDoesntApplyNotTheCorrectSsid">Impossibile applicare la regola. SSID errato (richiesto: \"%1$s\", ottenuto: \"%2$s\").</string>
<string name="ruleDoesntApplyStateNotCorrect">Impossibile applicare la regola. Stato errato</string>
<string name="ruleDoesntApplyWeAreFasterThan">Impossibile applicare la regola. Velocità superiore a</string>
<string name="ruleDoesntApplyWeAreSlowerThan">Impossibile applicare la regola. Velocità inferiore a</string>
<string name="ruleDoesntApplyWrongTagLabel">Impossibile applicare la regola. Etichetta Tag errata.</string>
<string name="ruleHistory">Cronologia delle regole (dalla più recente):</string>
<string name="ruleIsDeactivatedCantApply">La regola %1$s é disattiva e non posso applicarla.</string>
<string name="ruleLegend">Verde = attiva, Rosso = inattiva, Giallo = necessita ulterori autorizzazioni Android.</string>
<string name="ruleList">Elenco alfabetico delle regole:</string>
<string name="ruleIsDeactivatedCantApply">La regola %1$s è disabilitata e non posso applicarla.</string>
<string name="ruleLegend">Verde = abilitata, Rosso = disabilitata, Giallo = necessita ulteriori permessi</string>
<string name="ruleList">Elenco delle regole:</string>
<string name="ruleName">Nome della regola</string>
<string name="ruleNotToggable">La regola %1$s non è Reversibile.</string>
<string name="ruleToggable">La regola %1$s é Reversibile.</string>
<string name="ruleXrequiresThis">Lo richiede la regola \"%1$s\".</string>
<string name="ruleNotToggable">La regola %1$s non è adatta ad essere Reversibile.</string>
<string name="ruleToggable">La regola %1$s è adatta per essere Reversibile.</string>
<string name="ruleXrequiresThis">La regola \"%1$s\" ne ha bisogno.</string>
<string name="rules">Regole</string>
<string name="rulesImportError">C\'è stato un errore nell\'importazione di regole e posizioni</string>
<string name="rulesImportedSuccessfully">Le regole e le posizioni sono state importate con successo.</string>
<string name="runManually">Esecuzione manuale</string>
<string name="runningApp">App in esecuzione</string>
<string name="satisfactoryAccuracyGps">precisione minima in metri quando la posizione è individuata via GPS</string>
<string name="satisfactoryAccuracyNetwork">Precisione minima quando la localizzazione è effettuata in metri attraverso le celle radiomobile </string>
<string name="satisfactoryAccuracyGps">Precisione minima in metri quando la posizione è individuata via GPS</string>
<string name="satisfactoryAccuracyNetwork">Precisione minima quando la localizzazione è effettuata in metri attraverso i ripetitori</string>
<string name="saturday">Sabato</string>
<string name="save">Salva</string>
<string name="savePoi">Salva posizione</string>
<string name="saveRule">Conferma</string>
<string name="saveRule">Salva Regola</string>
<string name="screenLockSoundNotice">I suoni di blocco dello schermo non possono più essere modificati automaticamente sui dispositivi con Android versione 6.0 o superiore. Qualunque cosa tu abbia impostato qui, non funzionerà in nessuna direzione.</string>
<string name="screenLockUnlockSound">Suono di blocco/sblocco schermo</string>
<string name="screenRotationAlreadyDisabled">Rotazione schermo già disattiva.</string>
<string name="screenRotationAlreadyDisabled">Rotazione schermo già disattivata.</string>
<string name="screenRotationAlreadyEnabled">Rotazione schermo già attiva.</string>
<string name="screenRotationDisabled">Rotazione schermo disabilitata.</string>
<string name="screenRotationEnabled">Rotazione schermo attivata.</string>
<string name="selectActivityToBeStarted">Seleziona l\'attività del pacchetto scelto</string>
<string name="selectApplication">Aggiungi App</string>
<string name="selectApplication">Scegli App</string>
<string name="selectBattery">Seleziona il livello di batteria</string>
<string name="selectConnectionOption">Seleziona una opzione di connessione.</string>
<string name="selectDeviceFromList">uno della lista</string>
<string name="selectDeviceOption">Seleziona una opzione del dispositivo</string>
<string name="selectDeviceFromList">uno dalla lista</string>
<string name="selectDeviceOption">Seleziona una opzione di dispositivo</string>
<string name="selectNoiseLevel">Seleziona il livello di rumore</string>
<string name="selectOneDay">Seleziona almeno un giorno</string>
<string name="selectPackageOfApplication">Seleziona quale attività</string>
<string name="selectPackageOfApplication">Seleziona il pacchetto dell\'applicazione</string>
<string name="selectPoi">Seleziona la posizione</string>
<string name="selectSoundFile">Select sound file</string>
<string name="selectSoundProfile">Seleziona il profilo audio</string>
<string name="selectSpeed">Seleziona la velocità</string>
<string name="selectToggleDirection">Seleziona</string>
<string name="selectToggleDirection">Seleziona acceso o spento?</string>
<string name="selectTypeOfAction">Seleziona il tipo di azione</string>
<string name="selectTypeOfActivity">Seleziona il tipo di attività</string>
<string name="selectTypeOfIntentPair">Seleziona il tipo per la coppia di Intent</string>
<string name="selectTypeOfIntentPair">Seleziona il tipo per la coppia di Intenzioni</string>
<string name="selectTypeOfTrigger">Seleziona il tipo di evento</string>
<string name="service">Stato:</string>
<string name="logServiceAlreadyRunning">Richiesta di attivazione sul servizio già attivo.</string>
<string name="sendTextMessage">Invia messaggio di testo</string>
<string name="service">Servizio:</string>
<string name="serviceHasToRunForThat">Devi attivare il servizio.</string>
<string name="serviceNotRunning">Servizio non attivo.</string>
<string name="serviceStarted">Automation attivata.</string>
<string name="version">Versione %1$s.</string>
<string name="logServiceStarting">Avvio del servizio</string>
<string name="serviceStopped">Attività di Automation terminata.</string>
<string name="logServiceStopping">Arresto attività.</string>
<string name="serviceWontStart">Non c\'è nessuna regola. L\'attività non può iniziare.</string>
<string name="serviceStarted">Il servizio di Automation è attivo.</string>
<string name="serviceStopped">Il servizio di Automation è stato fermato.</string>
<string name="serviceWontStart">Nessuna regola definita. Il servizio non può iniziare.</string>
<string name="setScreenBrightness">Impostare la luminosità dello schermo</string>
<string name="setScreenBrightnessEnterValue">Digitare la luminosità desiderata (da 0 a 100).</string>
<string name="settings">Impostazioni</string>
<string name="settingsCategoryHttp">Richieste HTTP(s)</string>
<string name="settingsCategoryNoiseLevelMeasurements">Misura del livello di rumore</string>
<string name="settingsCategoryProcessMonitoring">Controllo di processo</string>
<string name="settingsCategoryProcessMonitoring">Monitoraggio del processo</string>
<string name="settingsErased">Impostazioni cancellate.</string>
<string name="settingsSetToDefault">Impostazioni di default ripristinate.</string>
<string name="settingsWillTakeTime">Per rendere efficaci alcune impostazioni è necessario il riavvio o la modifica delle posizioni.</string>
<string name="showHelp">Descrizione</string>
<string name="settingsReferringToRestrictedFeatures">Le tue impostazioni e/o regole si riferiscono attualmente a funzioni non coperte da una licenza aperta e che pertanto non possono essere fornite nella versione F-Droid. Questo include il rilevamento della tua attuale attività fisica.</string>
<string name="settingsSetToDefault">Impostazioni predefinite ripristinate.</string>
<string name="settingsWillTakeTime">Alcune impostazioni non saranno applicate prima che alcune impostazioni contestuali cambino o che il servizio venga riavviato.</string>
<string name="shareConfigAndLogExplanation">Questo creerà una email con la tua configurazione e i file di log allegati come file zip. Non sarà inviata automaticamente, dovrai premere \"invia\". Puoi anche cambiare il destinatario con te stesso, per esempio.</string>
<string name="shareConfigAndLogFilesWithDev">Condividere i file di configurazione e di registro con lo sviluppatore (via e-mail).</string>
<string name="showHelp">Mostra Aiuto</string>
<string name="showIcon">Mostra icona</string>
<string name="showIconWhenServiceIsRunning">Mostra una icona quando attiva (nascondere funziona solo sotto Android 7)</string>
<string name="showIconWhenServiceIsRunning">Mostra una icona quando il servizio è attivo (nasconderla funziona solo in versioni inferiori ad Android 7)</string>
<string name="showOnMap">Mostra sulla mappa</string>
<string name="someOptionsNotAvailableYet">Alcune opzioni sono disabilitate in quanto non ancora implementate. Saranno introdotte in una versione successiva.</string>
<string name="soundMode">Sonoro</string>
<string name="soundMode">Modalità sonora</string>
<string name="soundModeNormal">Normale</string>
<string name="soundModeSilent">Silenziato</string>
<string name="soundModeSilent">Silenziosa</string>
<string name="soundModeVibrate">Vibrazione</string>
<string name="soundSettings">Impostazioni del sonoro</string>
<string name="soundSettings">Impostazioni del suono</string>
<string name="speedMaximumTime">Tempo in minuti</string>
<string name="speedMaximumTimeBetweenLocations">Tempo massimo tra la rilevazione di due posizioni per determinare la velocità.</string>
<string name="speedMaximumTimeBetweenLocations">Tempo massimo tra la rilevazione di due posizioni per determinarne la velocità.</string>
<string name="start">Inizio</string>
<string name="startAtSystemBoot">Avvio automatic al boot</string>
<string name="startNewThreadForRuleExecution">Nuovo tentativo di attivazione della regola.</string>
<string name="startAppByAction">per azione</string>
<string name="startAppByActivity">per attività</string>
<string name="startAppBySendBroadcast">per sendBroadcast()</string>
<string name="startAppByStartActivity">per startActivity()</string>
<string name="startAppChoiceNote">Qui hai 2 opzioni generali: 1. Puoi avviare un programma selezionando un\'attività. Immagina questo come la preselezione di una specifica schermata/finestra di un\'applicazione. Tieni a mente che questo potrebbe non funzionare sempre. Questo perché le finestre di un\'applicazione potrebbero interagire tra loro, ad esempio per passarsi dei parametri. Quando si avvia direttamente una schermata specifica la cui interazione non è ancora avvenuta, la finestra potrebbe chiudersi istantaneamente (quindi non verrà mai mostrata). Ma puoi provare comunque! Inserisci un percorso di attività manualmente, ma si raccomanda di usare il pulsante \"Seleziona\". Se decidi di inserirlo manualmente, digita il nome del pacchetto dell\'applicazione nel campo superiore e il percorso completo dell\'attività in quello inferiore. 2. Selezione per azione. Invece che selezionare una specifica finestra puoi anche avviare un programma per mezzo di un\'azione. Questo è come gridare "Vorrei xyz" e se c\'è un\'applicazione installata che è registrata con quella funzione, verrà avviata. Un buon esempio sarebbe avviare un navigatore - potresti anche averne più di uno installato (ma uno è di solito quello di default). Devi inserire questo manualmente, mentre PackageName è opzionale qui. Tieni a mente che nessuna variabile sarà risolta. Se vuoi avviare la fotocamera per esempio usando \"MediaStore.ACTION_IMAGE_CAPTURE\" non funzionerà. Devi dare un\'occhiata alla documentazione di Android e usare invece il valore effettivo di questa variabile che in questo esempio sarebbe \"android.media.action.IMAGE_CAPTURE\".</string>
<string name="startAppSelectionType">Metodo per\nselezionare l\'applicazione</string>
<string name="startAppStartType">Seleziona tipo di avvio</string>
<string name="startAtSystemBoot">Avvio automatico al boot</string>
<string name="startAutomationAsService">Avvia Automation come un servizio</string>
<string name="startNewThreadForRuleExecution">Iniziata nuova esecuzione per l\'attivazione della regola.</string>
<string name="startOtherActivity">Inizia una nuova app</string>
<string name="startServiceAfterAppUpdate">Riavvia automaticamente l\'app dopo un aggiornamento se era già in esecuzione.</string>
<string name="startServiceAfterAppUpdateShort">Riavvio dopo aggiornamento</string>
<string name="started">avviando</string>
<string name="starting">avvio</string>
<string name="startingGpsTimeout">In attesa del GPS</string>
<string name="startingPeriodicProcessMonitoringEngine">Avviare il processo ciclico di monitoraggio.</string>
<string name="logStartingServiceAfterAppUpdate">Inizio attività dopo l\'aggiornamento.</string>
<string name="logStartingServiceAtPhoneBoot">Starting service at phone boot.</string>
<string name="status">Riepilogo</string>
<string name="stillGettingPosition">In attesa</string>
<string name="stopped">terminando</string>
<string name="stopping">quando finisce</string>
<string name="stoppingPeriodicProcessMonitoringEngine">Fermare il processo ciclico di monitoraggio engine.</string>
<string name="storeSettings">Scrivere e/o leggere le impostazioni</string>
<string name="startScreen">Schermo di Avvio</string>
<string name="startScreenSummary">Seleziona la schermata con cui le applicazioni si aprono all\'inizio.</string>
<string name="startServiceAfterAppUpdate">Riavvia automaticamente il servizio se era già in esecuzione, dopo che l\'applicazione venga aggiornata.</string>
<string name="startServiceAfterAppUpdateShort">Riavvio del servizio dopo l\'aggiornamento</string>
<string name="started">avviato</string>
<string name="starting">avviando</string>
<string name="startingGpsTimeout">Avviando timeout GPS</string>
<string name="status">Stato</string>
<string name="stillGettingPosition">Ancora in attesa della posizione</string>
<string name="stopped">terminatoo</string>
<string name="stopping">terminando</string>
<string name="storeSettings">Leggere e scrivere le impostazioni</string>
<string name="stringNotAllowed">La stringa %1$s non è permessa.</string>
<string name="sunday">Domenica</string>
<string name="systemSettingsNote1">E\' necessaria labilitazione a modificare alcune impostazioni del sistema operativo (anche cose semplici come accendere il Bluetooth o ilm Wifi). Dopo aver selezionato "Continua" si aprirà un popup per abilitare Automation. Premi il tasto "back" per tornare.</string>
<string name="systemSettingsNote1">Il permesso di cambiare alcune impostazioni del sistema operativo è necessario (anche per cose semplici come attivare il bluetooth o il wifi). Dopo aver cliccato su \"continua\" si aprirà una finestra dove dovrai abilitare questo per Automation. Poi premi il tasto \"indietro\".</string>
<string name="systemSettingsNote2">Ulteriori autorizzazioni verranno richieste in una seconda finestra.</string>
<string name="textToSpeak">Text to speak</string>
<string name="text">Testo</string>
<string name="textMessageAnnotations">Puoi inserire direttamente un numero di telefono. In alternativa usa l\'opzione contatti per sceglierne uno. Ma tieni presente che il numero verrà memorizzato qui, non nel contatto. Se cambi il numero di telefono di un contatto, dovrai aggiornarlo nella questa regola. Non si aggiorna da solo.</string>
<string name="textToSend">Testo da inviare</string>
<string name="textToSpeak">Testo da leggere</string>
<string name="textTooShort">Il testo deve avere almeno 10 caratteri.</string>
<string name="theFollowingPermissionsHaveBeenDenied">Sono state negate le seguenti autorizzazioni:</string>
<string name="theseAreThePermissionsRequired">Necessitano le seguenti autorizzazioni:</string>
<string name="theseAreThePermissionsRequired">Queste sono le autorizzazioni necessarie:</string>
<string name="thursday">Giovedì</string>
<string name="timeBetweenNoiseLevelMeasurementsSummary">Secondi tra misure di livello di rumore</string>
<string name="timeBetweenNoiseLevelMeasurementsTitle">Secondi tra misure di livello di rumore</string>
<string name="timeBetweenProcessMonitoringsSummary">Più è basso e più alto sarà il consume della batteria</string>
<string name="timeBetweenProcessMonitoringsSummary">Più è basso e più sarà alto il consumo della batteria</string>
<string name="timeBetweenProcessMonitoringsTitle">Secondi tra un monitoraggio e l\'altro</string>
<string name="timeForUpdate">Intervallo di aggiornamento [millisecondi]</string>
<string name="timeFrameWhichDays">Che giorno?</string>
<string name="timeFrameWhichDays">In che giorni?</string>
<string name="timeframes">Intervalli</string>
<string name="timeoutForGpsComparisonsSummary">Massimo tempo in secondi per cercare di individuare la posizione GPS per confront. Allo scadere sarà assunta valida l\'ultima localizzazione rilevata.</string>
<string name="timeoutForGpsComparisonsTitle">GPS timeout [sec]</string>
<string name="toggableRules">Regole “Reversibili”</string>
<string name="toggle">toggle</string>
<string name="toggleNotAllowed">La reversibilità al momento è disponibile solo per le regole che hanno come evento un tag NFC. Consulta l\'help per i dettagli.</string>
<string name="toggleRule">Reversibile</string>
<string name="toggling">Inversione</string>
<string name="triggerCharging">Carica della Batteria</string>
<string name="triggerHeadsetPlugged">Inserimento auricolari</string>
<string name="timeoutForGpsComparisonsSummary">Massimo tempo in secondi per cercare di individuare la posizione GPS per la comparazione. Allo scadere sarà assunta valida l\'ultima localizzazione rilevata.</string>
<string name="timeoutForGpsComparisonsTitle">Timeout del GPS [sec]</string>
<string name="title">Titolo</string>
<string name="to">a</string>
<string name="toggableRules">Regole \"Reversibili\"</string>
<string name="toggle">reversibile</string>
<string name="toggleNotAllowed">La reversibilità al momento è disponibile solo per le regole che hanno come evento un tag NFC. Consulta l\'aiuto per i dettagli.</string>
<string name="toggleRule">Regola Reversibile</string>
<string name="toggling">Attivando</string>
<string name="triggerCharging">Batteria sotto carica</string>
<string name="triggerHeadsetPlugged">Connessione Auricolari</string>
<string name="triggerNoiseLevel">Livello del rumore di fondo</string>
<string name="triggerOnlyAvailableIfPlayServicesInstalled">Questa evento è valida solo se Google play service è installato.</string>
<string name="triggerOnlyAvailableIfPlayServicesInstalled">Questa evento è valido solo se Google play service è installato.</string>
<string name="triggerPointOfInterest">Posizione</string>
<string name="triggerSpeed">Velocità</string>
<string name="triggerTimeFrame">Intervallo</string>
<string name="triggerUrlReplacementPositionError">Hai chiesto di aggiungere una posizione alla tua URL. Purtroppo non ho ancora alcuna posizione.</string>
<string name="triggerUrlReplacementPositionError">Hai chiesto di aggiungere una posizione alla tua URL. Purtroppo non ho ancora ricevuto nessuna posizione.</string>
<string name="triggerUsb_host_connection">connessione al computer (USB)</string>
<string name="triggers">evento(i)</string>
<string name="triggersComment">(le attive saranno applicate in AND)</string>
<string name="triggers">Evento(i)</string>
<string name="triggersComment">(tutti gli eventi devono essere validi allo stesso tempo)</string>
<string name="tuesday">Martedì</string>
<string name="logUnboundFromService">Servizio disimpegnato.</string>
<string name="unknownActionSpecified">Azione non riconosciuta.</string>
<string name="unknownError">Errore indeterminato.</string>
<string name="until">finchè</string>
<string name="urlLegend">Variabili:\n È possibile utilizzare le seguenti variabili. All\'innesco saranno sostituite con il valore corrispondente sul dispositivo. Includi le parentesi nella tuo testo.\n\n[uniqueid] - L\'imei del tuo dispositivo\n[serialnr] - Il serial number del tuo dispositivio\n[latitude] - La latitudine del tuo dispositivo\n[longitude] - La longitudine del tuo dispositivo\n[phonenr] - Nr ultima chiamata (entrante o uscente)\n[d] - Il giorno del mese, sempre 2 cifre\n[m] - Mese in formato numerico, sempre 2 cifre\n[Y] - Lanno, sempre 4 cifre\n[h] - Ore in formato 12 ore, sempre 2 cifre con due punti\n[H] - Ore in formato 24 ore, sempre 2 cifre con due punti\n[i] - Minuti, sempre 2 cifre\n[s] - Secondi, sempre 2 cifre\n[ms] - millisecondi, sempre 3 cifre
</string>
<string name="urlLegend">Variabili:\n È possibile utilizzare le seguenti variabili. All\'attivazione saranno sostituite con il valore corrispondente sul dispositivo. Includi le parentesi nel tuo testo.\n\n[uniqueid] - Il numero di serie del tuo dispositivo\n[serialnr] - Il serial number del tuo dispositivio\n[latitude] - La latitudine del tuo dispositivo\n[longitude] - La longitudine del tuo dispositivo\n[phonenr] - Numero dell\'ultima chiamata (entrante o uscente)\n[d] - Il giorno del mese, sempre 2 cifre\n[m] - Mese in formato numerico, sempre 2 cifre\n[Y] - L\anno, sempre 4 cifre\n[h] - Ore in formato 12 ore, sempre 2 cifre con due punti\n[H] - Ore in formato 24 ore, sempre 2 cifre con due punti\n[i] - Minuti, sempre 2 cifre\n[s] - Secondi, sempre 2 cifre\n[ms] - millisecondi, sempre 3 cifre [notificationTitle] - titolo dell\'ultima notifica [notificationText] - testo dell\'ultima notifica</string>
<string name="urlToTrigger">URL da caricare:</string>
<string name="urlTooShort">La url deve avere almeno 10 caratteri.</string>
<string name="usbTetheringFailForAboveGingerbread">Questo molto probabilmente non funziona con versioni superiori ad Android 2.3. Tuttavia è possibile utilizzare la connessione wifi tethering per attivare la regola.</string>
<string name="useAuthentication">Attiva Username e Password</string>
<string name="urlTooShort">L\'url deve avere almeno 10 caratteri.</string>
<string name="usbTetheringFailForAboveGingerbread">Questo molto probabilmente non funzionerà dato che sei su una versione superiore ad Android 2.3. Tuttavia è possibile utilizzare la connessione wifi tethering per attivare la regola se sei su una versione inferiore ad Android 7.</string>
<string name="useAuthentication">Usa l\'autenticazione</string>
<string name="useExistingTag">Utilizzo di un tag NFC esistente</string>
<string name="useTextToSpeechOnNormalSummary">Usa TextToSpeech nel modo normale</string>
<string name="useTextToSpeechOnNormalTitle">TTS in modo normale</string>
@ -530,19 +577,21 @@ Selezionare su “Continua” quando si è pronti a procedere.</string>
<string name="useTextToSpeechOnSilentTitle">TTS in modo silenzioso</string>
<string name="useTextToSpeechOnVibrateSummary">Usa TextToSpeech nel modo vibrazione</string>
<string name="useTextToSpeechOnVibrateTitle">TTS in modo vibrazione</string>
<string name="username">Username</string>
<string name="usingNewThreadForRuleExecution">Nuovo tentativo di avvio della regola.</string>
<string name="username">Nome utente</string>
<string name="usingNewThreadForRuleExecution">Iniziata nuova esecuzione per l\'attivazione della regola.</string>
<string name="version">Versione %1$s.</string>
<string name="vibrateWhenRinging">Vibrazione alla chiamata</string>
<string name="volumeAlarms">Allarmi sonori</string>
<string name="volumeMusicVideoGameMedia">Multimedia (musica, video …)</string>
<string name="volumeRingtoneNotifications">Toni e notifiche</string>
<string name="volumeTest">Taratura audio</string>
<string name="volumeTesterExplanation">Per calcolare il valore del rumore di fondo in dB è necessario specificare un valore di riferimento fisico (si prega di leggere Wikipedia per ulteriori informazioni). Questo valore è probabilmente diverso per ogni telefono. Trascinare il cursore per modificare il valore di riferimento fisico definito. Più alto è il valore di riferimento e più basso sarà il valore misurato in dB. Misurazioni costanti saranno effettuati ogni 3 secondi ed i risultati visualizzati sotto. Premere indietro quando si è trovato un valore adeguato.</string>
<string name="volumes">Livelli sonori</string>
<string name="volumeTesterExplanation">Per calcolare il valore del rumore di fondo in dB è necessario specificare un valore di riferimento fisico (si prega di leggere Wikipedia per ulteriori informazioni). Questo valore è probabilmente diverso per ogni telefono. Trascinare il cursore per modificare il valore di riferimento fisico definito. Più alto è il valore di riferimento e più basso sarà il valore misurato in dB. Misurazioni costanti saranno effettuate ogni %1$s secondi ed i risultati visualizzati sotto. Premere indietro quando hai trovato un valore adeguato.</string>
<string name="volumes">Volumi</string>
<string name="waitBeforeNextAction">Attesa prima della azione successiva</string>
<string name="waitBeforeNextActionEnterValue">Inserisci il valore della pausa tra tra un\'azione e la successiva (millisecondi).</string>
<string name="wakeupDevice">Sveglia del dispositivo</string>
<string name="wakeupDeviceValue">Inserisci per quanto tempo il dispositivo deve rimanere attivo (millisecondi). In assenza si assume 0.</string>
<string name="wakeupDevice">Sveglia il dispositivo</string>
<string name="wakeupDeviceValue">Inserisci per quanto tempo il dispositivo deve rimanere attivo (millisecondi). Usa 0 per i valori standard.</string>
<string name="warning">Attenzione</string>
<string name="wednesday">Mercoledì</string>
<string name="whatToDoWithAction">Cosa vuoi fare?</string>
<string name="whatToDoWithIntentPair">Cosa fare con la coppia?</string>
@ -554,13 +603,12 @@ Selezionare su “Continua” quando si è pronti a procedere.</string>
<string name="wifi">wifi</string>
<string name="wifiConnection">Connessione wifi</string>
<string name="wifiName">Nome wifi</string>
<string name="wifiNameMatchesRuleWillApply">Il nome della wifi combacia. La regola può è valida.</string>
<string name="wifiNameMatchesRuleWillApply">Il nome della wifi combacia. La regola si applicherà.</string>
<string name="wifiNameSpecifiedCheckingThat">Verifica della wifi indicata.</string>
<string name="wifiState">Stato Wifi</string>
<string name="wifiTetheringFailForAboveNougat">Questo non funziona più dato che sei su una versione superiore ad Android 7.</string>
<string name="with">con</string>
<string name="withLabel">con etichetta</string>
<string name="writeLogFile">Memorizza un file di log</string>
<string name="writingSettingsToPersistentMemory">Scrivo le impostazioni nella memoria di massa.</string>
<string name="yes">Si</string>
<string name="edit">Elaborare</string>
</resources>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Automation</string>
<string name="app_name" translatable="false">Automation</string>
<string name="ruleActivate">Activating rule %1$s</string>
<string name="profileActivate">Activating profile %1$s</string>
<string name="ruleActivateToggle">Activating rule %1$s in Togglemode</string>
@ -14,28 +14,27 @@
<string name="serviceWontStart">No rules defined. Service won\'t start.</string>
<string name="serviceStarted">Automation Service started.</string>
<string name="version">Version %1$s.</string>
<string name="logServiceStarting">Starting service.</string>
<string name="logNotAllMeasurings">Don\'t have all location measurings, yet. Can\'t do comparison.</string>
<string name="distanceBetween">Distance between GPS location and network location is</string>
<string name="radiusSuggestion">meters. This +1 should be the absolute minimum radius.</string>
<string name="logServiceStarting" translatable="false">Starting service.</string>
<string name="logNotAllMeasurings" translatable="false">Don\'t have all location measurings, yet. Can\'t do comparison.</string>
<string name="distanceBetween">Distance between GPS location and network location is %1$d meters. This +1m should be the absolute minimum radius.</string>
<string name="comparing">Have both network and gps location. Comparing...</string>
<string name="logNoSuitableProvider">No suitable location providers could be used.</string>
<string name="logNoSuitableProvider" translatable="false">No suitable location providers could be used.</string>
<string name="positioningWindowNotice">If you are in a building it is strongly advised to place your device next to a window until a position has been found. Otherwise it may take a very long time if it is able to find one at all.</string>
<string name="gettingPosition">Getting position. Please wait...</string>
<string name="logGettingPositionWithProvider">Requesting location using provider:</string>
<string name="logGettingPositionWithProvider" translatable="false">Requesting location using provider:</string>
<string name="yes">Yes</string>
<string name="no">No</string>
<string name="logGotGpsUpdate">Got GPS update. Accuracy:</string>
<string name="logGotNetworkUpdate">Got network update. Accuracy:</string>
<string name="logGotGpsUpdate" translatable="false">Got GPS update. Accuracy:</string>
<string name="logGotNetworkUpdate" translatable="false">Got network update. Accuracy:</string>
<string name="pleaseEnterValidLatitude">Please enter a valid latitude.</string>
<string name="pleaseEnterValidLongitude">Please enter a valid longitude.</string>
<string name="pleaseEnterValidRadius">Please enter a valid positive radius.</string>
<string name="selectOneDay">Select at least one day.</string>
<string name="logAttemptingToBindToService">Attempting to bind to service... </string>
<string name="logAttemptingToUnbindFromService">Attempting to unbind from service... </string>
<string name="logBoundToService">Bound to service.</string>
<string name="logUnboundFromService">Unbound from service.</string>
<string name="logServiceAlreadyRunning">Request to start service, but it is already running.</string>
<string name="logAttemptingToBindToService" translatable="false">Attempting to bind to service... </string>
<string name="logAttemptingToUnbindFromService" translatable="false">Attempting to unbind from service... </string>
<string name="logBoundToService" translatable="false">Bound to service.</string>
<string name="logUnboundFromService" translatable="false">Unbound from service.</string>
<string name="logServiceAlreadyRunning" translatable="false">Request to start service, but it is already running.</string>
<string name="whatToDoWithRule">Do what with rule?</string>
<string name="whatToDoWithPoi">Do what with location?</string>
<string name="whatToDoWithProfile">Do what with profile?</string>
@ -121,14 +120,14 @@
<string name="gpsAccuracy">GPS accuracy [m]</string>
<string name="satisfactoryAccuracyNetwork">Satisfactory accuracy when getting location via cell towers in meters</string>
<string name="networkAccuracy">Network accuracy [m]</string>
<string name="minimumTimeForLocationUpdates">Minimum time change in seconds for location updates</string>
<string name="minimumTimeForLocationUpdates">Minimum time change in milliseconds for location updates</string>
<string name="timeForUpdate">Time for update [milliseconds]</string>
<string name="soundSettings">Sound settings</string>
<string name="showHelp">Show help</string>
<string name="rules">Rules</string>
<string name="helpTextRules">All triggers in a rule are AND-connected. The rule will only apply if all triggers are met. If you want OR create another rule.</string>
<string name="timeframes">TimeFrames</string>
<string name="helpTextTimeFrame">If you specify a rule with a timeframe you have two choices. You can choose between entering and leaving a timeframe. Either way an action is triggered only once.\nSo if you create a rule that has \"entering timeframe xyz\" as trigger and let it change your sound profile to vibrate that does not mean that the phone will automatically go to ring if the timeframe is over. If you want that you need to specify another rule with another timeframe.</string>
<string name="helpTextTimeFrame">If you specify a rule with a timeframe you have two choices. You can choose between entering OR leaving a timeframe. Either way a rule is triggered only once. So if you create a rule that has \"entering timeframe xyz\" as trigger and let it change your sound profile to vibrate that does not mean that the phone will automatically go to ring if the timeframe is over. If you want that you need to specify another rule with another timeframe.</string>
<string name="helpTextSound">On the main screen you can use lock sound changes to temporarily avoid rule based sound changes. E.g. you may be in a situation or place where usually ringtones are ok, but this one time it would be disturbing. The feature will automatically deactivate once the configured time has elapsed. Click the + button to add the given amount of time. Once it is active you may deactivate it again using the toggle button (and that way enable rule based sound changes again).</string>
<string name="toggableRules">Toggable rules</string>
<string name="helpTextToggable">Rules have a flag called \"Toggable\". This means that if a rule is executed and afterwards the same triggers apply again the rule will be executed in an opposite mode where applicable. Currently this will only happen in conjunction with NFC tags. If you tap them twice and there\'s a toggable rule associated with it it will do the opposite of the current situation, e.g. deactivate wifi if it\'s currently activated.</string>
@ -188,38 +187,38 @@
<string name="serviceNotRunning">Service is not running.</string>
<string name="general">General</string>
<string name="generalText">To use this program you must setup rules. Those contain triggers, e.g. if you reach a specified area or you enter a certain time. After that\'s been done click the on/off button on the main screen.</string>
<string name="unknownActionSpecified">Unknown action specified</string>
<string name="errorTriggeringUrl">Error triggering URL</string>
<string name="errorChangingScreenRotation">Error changing screen rotation</string>
<string name="errorDeterminingWifiApState">Error determining wifiAp state</string>
<string name="errorActivatingWifiAp">Error activating wifiAp</string>
<string name="unknownActionSpecified" translatable="false">Unknown action specified</string>
<string name="logErrorTriggeringUrl" translatable="false">Error triggering URL</string>
<string name="errorChangingScreenRotation" translatable="false">Error changing screen rotation</string>
<string name="errorDeterminingWifiApState" translatable="false">Error determining wifiAp state</string>
<string name="errorActivatingWifiAp" translatable="false">Error activating wifiAp</string>
<string name="failedToTriggerBluetooth">Failed to trigger Bluetooth. Does this device have Bluetooth?</string>
<string name="logAttemptingDownloadOf">attempting download of</string>
<string name="logErrorGettingConnectionManagerService">Error getting connectionManager service. Not doing anything to UsbTethering.</string>
<string name="logErrorDeterminingCurrentUsbTetheringState">Error determining current UsbTethering state.</string>
<string name="logDetectingTetherableUsbInterface">Detecting tetherable usb interface.</string>
<string name="logClearingBothLocationListeners">Clearing both location listeners.</string>
<string name="logStartingServiceAfterAppUpdate">Starting service after app update.</string>
<string name="logNotStartingServiceAfterAppUpdate">Not starting service after app update.</string>
<string name="logStartingServiceAtPhoneBoot">Starting service at phone boot.</string>
<string name="logNotStartingServiceAtPhoneBoot">Not starting service at phone boot.</string>
<string name="applicationHasBeenUpdated">Application has been updated.</string>
<string name="logAttemptingDownloadOf" translatable="false">attempting download of</string>
<string name="logErrorGettingConnectionManagerService" translatable="false">Error getting connectionManager service. Not doing anything to UsbTethering.</string>
<string name="logErrorDeterminingCurrentUsbTetheringState" translatable="false">Error determining current UsbTethering state.</string>
<string name="logDetectingTetherableUsbInterface" translatable="false">Detecting tetherable usb interface.</string>
<string name="logClearingBothLocationListeners" translatable="false">Clearing both location listeners.</string>
<string name="logStartingServiceAfterAppUpdate" translatable="false">Starting service after app update.</string>
<string name="logNotStartingServiceAfterAppUpdate" translatable="false">Not starting service after app update.</string>
<string name="logStartingServiceAtPhoneBoot" translatable="false">Starting service at phone boot.</string>
<string name="logNotStartingServiceAtPhoneBoot" translatable="false">Not starting service at phone boot.</string>
<string name="applicationHasBeenUpdated" translatable="false">Application has been updated.</string>
<string name="startServiceAfterAppUpdate">Start service automatically after app update if it has been running before.</string>
<string name="startServiceAfterAppUpdateShort">Start service after update</string>
<string name="wifiConnection">Wifi connection</string>
<string name="wifiName">Wifi name</string>
<string name="enterWifiName">Enter a wifi name. Leave empty for any wifi.</string>
<string name="cancel">Cancel</string>
<string name="ruleDoesntApplyWeAreSlowerThan">Rule doesn\'t apply. We are slower than</string>
<string name="ruleDoesntApplyWeAreFasterThan">Rule doesn\'t apply. We are faster than</string>
<string name="ruleDoesntApplyItsQuieterThan">Rule doesn\'t apply. It\'s quieter than</string>
<string name="ruleDoesntApplyItsLouderThan">Rule doesn\'t apply. It\'s louder than</string>
<string name="ruleDoesntApplyBatteryLowerThan">Rule doesn\'t apply. Battery level is lower than</string>
<string name="ruleDoesntApplyBatteryHigherThan">Rule doesn\'t apply. Battery level is higher than</string>
<string name="ruleDoesntApplyNotTheCorrectSsid">Rule doesn\'t apply. Not the correct SSID (demanded: \"%1$s\", given: \"%2$s\").</string>
<string name="ruleDoesntApplyNoTagLabel">Rule doesn\'t apply. There is no tag label or not tag at all.</string>
<string name="ruleDoesntApplyWrongTagLabel">Rule doesn\'t apply. Wrong tag label.</string>
<string name="ruleIsDeactivatedCantApply">Rule %1$s is deactivated, can\'t apply.</string>
<string name="ruleDoesntApplyWeAreSlowerThan" translatable="false">Rule doesn\'t apply. We are slower than</string>
<string name="ruleDoesntApplyWeAreFasterThan" translatable="false">Rule doesn\'t apply. We are faster than</string>
<string name="ruleDoesntApplyItsQuieterThan" translatable="false">Rule doesn\'t apply. It\'s quieter than</string>
<string name="ruleDoesntApplyItsLouderThan" translatable="false">Rule doesn\'t apply. It\'s louder than</string>
<string name="ruleDoesntApplyBatteryLowerThan" translatable="false">Rule doesn\'t apply. Battery level is lower than</string>
<string name="ruleDoesntApplyBatteryHigherThan" translatable="false">Rule doesn\'t apply. Battery level is higher than</string>
<string name="ruleDoesntApplyNotTheCorrectSsid" translatable="false">Rule doesn\'t apply. Not the correct SSID (demanded: \"%1$s\", given: \"%2$s\").</string>
<string name="ruleDoesntApplyNoTagLabel" translatable="false">Rule doesn\'t apply. There is no tag label or not tag at all.</string>
<string name="ruleDoesntApplyWrongTagLabel" translatable="false">Rule doesn\'t apply. Wrong tag label.</string>
<string name="ruleIsDeactivatedCantApply" translatable="false">Rule %1$s is deactivated, can\'t apply.</string>
<string name="starting">starting</string>
<string name="stopping">stopping</string>
<string name="connecting">connecting</string>
@ -242,12 +241,12 @@
<string name="runManually">Run manually</string>
<string name="serviceHasToRunForThat">The service has to be running for that.</string>
<string name="gpsComparison">GPS comparison</string>
<string name="gpsComparisonTimeoutStop">Stopping comparison GPS measurement due to timeout.</string>
<string name="gpsComparisonTimeoutStop" translatable="false">Stopping comparison GPS measurement due to timeout.</string>
<string name="timeoutForGpsComparisonsTitle">GPS timeout [sec]</string>
<string name="timeoutForGpsComparisonsSummary">Maximum time in seconds to trying getting a GPS location for comparison. If over last known location will be applied.</string>
<string name="startingGpsTimeout">Starting GPS timeout.</string>
<string name="forcedLocationUpdate">Forced location update</string>
<string name="forcedLocationUpdateLong">Due to timeout in comparison measurement the last best location will be applied.</string>
<string name="startingGpsTimeout" translatable="false">Starting GPS timeout.</string>
<string name="forcedLocationUpdate" translatable="false">Forced location update</string>
<string name="forcedLocationUpdateLong" translatable="false">Due to timeout in comparison measurement the last best location will be applied.</string>
<string name="rememberLastActivePoiSummary">If you are at a location, restart your device or the application and leave the location the application will run rules accociated to leaving the location upon its next start.</string>
<string name="rememberLastActivePoiTitle">Remember last active location</string>
<string name="muteTextToSpeechDuringCallsTitle">Mute during calls</string>
@ -263,35 +262,35 @@
<string name="settingsCategoryProcessMonitoring">Process monitoring</string>
<string name="timeBetweenProcessMonitoringsTitle">Seconds between process monitorings</string>
<string name="timeBetweenProcessMonitoringsSummary">The lower the higher the battery usage</string>
<string name="refreshingProcessList">Refreshing process list.</string>
<string name="refreshingProcessList" translatable="false">Refreshing process list.</string>
<string name="processes">Processes</string>
<string name="startingPeriodicProcessMonitoringEngine">Starting periodic process monitoring engine.</string>
<string name="startingPeriodicProcessMonitoringEngine" translatable="false">Starting periodic process monitoring engine.</string>
<string name="processMonitoring">Process monitoring</string>
<string name="periodicProcessMonitoringIsAlreadyRunning">Periodic process monitoring is already running. Won\'t start it again.</string>
<string name="stoppingPeriodicProcessMonitoringEngine">Stopping periodic process monitoring engine.</string>
<string name="periodicProcessMonitoringIsNotActive">Periodic process monitoring is not active. Can\'t stop it.</string>
<string name="periodicProcessMonitoringStarted">Periodic process monitoring started.</string>
<string name="periodicProcessMonitoringStopped">Periodic process monitoring stopped.</string>
<string name="rearmingProcessMonitoringMessage">Rearming process monitoring message.</string>
<string name="notRearmingProcessMonitoringMessageStopRequested">Not rearming process monitoring message, stop requested.</string>
<string name="messageReceivedStatingProcessMonitoringIsComplete">Message received stating process monitoring is complete.</string>
<string name="appStarted">App started.</string>
<string name="appStopped">App stopped.</string>
<string name="runningApp">Running app</string>
<string name="errorWritingSettingsToPersistentMemory">Error writing settings to persistent memory.</string>
<string name="periodicProcessMonitoringIsAlreadyRunning" translatable="false">Periodic process monitoring is already running. Won\'t start it again.</string>
<string name="stoppingPeriodicProcessMonitoringEngine" translatable="false">Stopping periodic process monitoring engine.</string>
<string name="periodicProcessMonitoringIsNotActive" translatable="false">Periodic process monitoring is not active. Can\'t stop it.</string>
<string name="periodicProcessMonitoringStarted" translatable="false">Periodic process monitoring started.</string>
<string name="periodicProcessMonitoringStopped" translatable="false">Periodic process monitoring stopped.</string>
<string name="rearmingProcessMonitoringMessage" translatable="false">Rearming process monitoring message.</string>
<string name="notRearmingProcessMonitoringMessageStopRequested" translatable="false">Not rearming process monitoring message, stop requested.</string>
<string name="messageReceivedStatingProcessMonitoringIsComplete" translatable="false">Message received stating process monitoring is complete.</string>
<string name="appStarted" translatable="false">App started.</string>
<string name="appStopped" translatable="false">App stopped.</string>
<string name="runningApp" translatable="false">Running app</string>
<string name="errorWritingSettingsToPersistentMemory" translatable="false">Error writing settings to persistent memory.</string>
<string name="settings">Settings</string>
<string name="writingSettingsToPersistentMemory">Writing settings to persistent memory.</string>
<string name="refreshingSettingsFromFileToMemory">Refreshing settings from file to memory.</string>
<string name="errorReadingSettings">Error reading settings.</string>
<string name="invalidStuffStoredInSettingsErasing">Invalid stuff stored in settings. Erasing settings...</string>
<string name="initializingSettingsToPersistentMemory">Initializing settings to persistent memory.</string>
<string name="errorInitializingSettingsToPersistentMemory">Error initializing settings to persistent memory.</string>
<string name="writingSettingsToPersistentMemory" translatable="false">Writing settings to persistent memory.</string>
<string name="refreshingSettingsFromFileToMemory" translatable="false">Refreshing settings from file to memory.</string>
<string name="errorReadingSettings" translatable="false">Error reading settings.</string>
<string name="invalidStuffStoredInSettingsErasing" translatable="false">Invalid stuff stored in settings. Erasing settings...</string>
<string name="initializingSettingsToPersistentMemory" translatable="false">Initializing settings to persistent memory.</string>
<string name="errorInitializingSettingsToPersistentMemory" translatable="false">Error initializing settings to persistent memory.</string>
<string name="settingsErased">Settings erased.</string>
<string name="settingsSetToDefault">Settings set to default.</string>
<string name="batteryLevel">Battery level</string>
<string name="selectSpeed">Select speed</string>
<string name="selectBattery">Select battery level</string>
<string name="applyingSettingsAndRules">Applying settings, rules and locations.</string>
<string name="applyingSettingsAndRules" translatable="false">Applying settings, rules and locations.</string>
<string name="privacy">Privacy Policy</string>
<string name="privacyConfirmationText">A browser will now open on your device and load the privacy policy from the developer\'s website.</string>
<string name="waitBeforeNextAction">Wait before next action</string>
@ -303,15 +302,15 @@
<string name="moveDown">Move down</string>
<string name="cantMoveUp">Can\'t move item up. It is already at the top.</string>
<string name="cantMoveDown">Can\'t move item down. It is already at the bottom.</string>
<string name="wifiNameSpecifiedCheckingThat">Wifi name specified, checking that.</string>
<string name="wifiNameMatchesRuleWillApply">Wifi name matches. Rule will apply.</string>
<string name="noWifiNameSpecifiedAnyWillDo">No wifi name specified, any will do.</string>
<string name="ruleCheckOf">RuleCheck of %1$s</string>
<string name="wifiNameSpecifiedCheckingThat" translatable="false">Wifi name specified, checking that.</string>
<string name="wifiNameMatchesRuleWillApply" translatable="false">Wifi name matches. Rule will apply.</string>
<string name="noWifiNameSpecifiedAnyWillDo" translatable="false">No wifi name specified, any will do.</string>
<string name="ruleCheckOf" translatable="false">RuleCheck of %1$s</string>
<string name="airplaneMode">Airplane mode</string>
<string name="activate">Activate</string>
<string name="deactivate">Deactivate</string>
<string name="airplaneModeSdk17Warning">Beginning from Android version 4.2 this feature only works if your device is rooted.</string>
<string name="triggerUrlReplacementPositionError">You asked for a position to be added to your URL. Unfortunately at this point I do not have any location, yet.</string>
<string name="triggerUrlReplacementPositionError" translatable="false">You asked for a position to be added to your URL. Unfortunately at this point I do not have any location, yet.</string>
<string name="addIntentValue">Add Intent pair</string>
<string name="parameterName">Parameter name</string>
<string name="parameterValue">Parameter value</string>
@ -360,11 +359,11 @@
<string name="nfcTagDiscovered">Tag discovered.</string>
<string name="nfcBringTagIntoRange">Bring an NFC tag into range.</string>
<string name="nfcTagFoundWithText">Tag found with text:</string>
<string name="nfcUnsupportedEncoding">Unsupported Encoding:</string>
<string name="nfcUnsupportedEncoding">Unsupported encoding:</string>
<string name="nfcNoNdefIntentBut">No NFC NDEF intent, but</string>
<string name="nfcNotSupportedInThisAndroidVersionYet">NFC not supported in this Android version, yet.</string>
<string name="cantRunRule">Cannot run rules.</string>
<string name="cantDownloadTooFewRequestsInSettings">Can\'t download anything. Amount of http requests in settings is lower than 1.</string>
<string name="cantDownloadTooFewRequestsInSettings" translatable="false">Can\'t download anything. Amount of http requests in settings is lower than 1.</string>
<string name="nfcApplyTagToRule">Apply tag to rule</string>
<string name="nfcTagReadSuccessfully">Tag read successfully.</string>
<string name="nfcValueNotSuitable">Value stored not suitable.</string>
@ -388,8 +387,8 @@
<string name="eraseSettings">Erase settings</string>
<string name="defaultSettings">Default settings</string>
<string name="areYouSure">Are you sure?</string>
<string name="poiCouldBeInRange">At least location %1$s could be in range, if not others in addition.</string>
<string name="noPoiInRelevantRange">No location in relevant range.</string>
<string name="poiCouldBeInRange" translatable="false">At least location %1$s could be in range, if not others in addition.</string>
<string name="noPoiInRelevantRange" translatable="false">No location in relevant range.</string>
<string name="activityDetection">Activity detection</string>
<string name="android.permission.ACTIVITY_RECOGNITION">Activity detection</string>
<string name="detectedActivity">Detected activity:</string>
@ -402,8 +401,8 @@
<string name="detectedActivityWalking">Walking</string>
<string name="detectedActivityRunning">Running</string>
<string name="detectedActivityInvalidStatus">Invalid activity</string>
<string name="ruleDoesntApplyActivityGivenButTooLowProbability">Rule doesn\'t apply. Detected activity %1$s given, but too low probability (%2$s %%), required %3$s %%.</string>
<string name="ruleDoesntApplyActivityNotPresent">Rule doesn\'t apply. Required activity %1$s not present.</string>
<string name="ruleDoesntApplyActivityGivenButTooLowProbability" translatable="false">Rule doesn\'t apply. Detected activity %1$s given, but too low probability (%2$s %%), required %3$s %%.</string>
<string name="ruleDoesntApplyActivityNotPresent" translatable="false">Rule doesn\'t apply. Required activity %1$s not present.</string>
<string name="selectTypeOfActivity">Select type of activity</string>
<string name="triggerOnlyAvailableIfPlayServicesInstalled">This trigger is only available if Google Play Services is installed.</string>
<string name="activityDetectionFrequencyTitle">Activity detection frequency [sec]</string>
@ -411,7 +410,7 @@
<string name="activityDetectionRequiredProbabilityTitle">Activity detection probability</string>
<string name="activityDetectionRequiredProbabilitySummary">Certainty from which activities are accepted as fact.</string>
<string name="incomingCallFrom">Incoming telephone call from %1$s.</string>
<string name="outgoingCallFrom">Outgoing telephone call to %1$s.</string>
<string name="outgoingCallTo">Outgoing telephone call to %1$s.</string>
<string name="actionSpeakText">Speak text</string>
<string name="textToSpeak">Text to speak</string>
<string name="toggleNotAllowed">Toggling is currently only allowed for rules that have NFC tags as trigger. See help for further information.</string>
@ -443,22 +442,22 @@
<string name="headphoneMicrophone">Microphone</string>
<string name="headphoneAny">Either</string>
<string name="headphoneSelectType">Select type of headphone</string>
<string name="ruleDoesntApplyWrongHeadphoneType">Rule doesn\'t apply. Wrong headphone type.</string>
<string name="ignoringActivityDetectionUpdateTooSoon">Ignoring activity detection update. Came in sooner that %1$s seconds.</string>
<string name="ruleDoesntApplyWrongHeadphoneType" translatable="false">Rule doesn\'t apply. Wrong headphone type.</string>
<string name="ignoringActivityDetectionUpdateTooSoon" translatable="false">Ignoring activity detection update. Came in sooner that %1$s seconds.</string>
<string name="whatsThis">What\'s this?</string>
<string name="atLeastRuleXisUsingY">At least rule \"%1$s\" is using a trigger of type \"%2$s\".</string>
<string name="atLeastRuleXisUsingY" translatable="false">At least rule \"%1$s\" is using a trigger of type \"%2$s\".</string>
<string name="privacyLocationingTitle">Only private locationing</string>
<string name="privacyLocationingSummary">Avoid locationing methods that may send your location to a provider, e.g. Google. This will use GPS only and may therefore be slow or not work reliably.</string>
<string name="enforcingGps">Private Locationing enabled, enforcing GPS use.</string>
<string name="notEnforcingGps">Private Locationing not enabled, using regular provider search.</string>
<string name="gpsMeasurement">GPS measurement</string>
<string name="gpsMeasurementTimeout">GPS measurement stopped due to timeout.</string>
<string name="cellMastChanged">Cell mast changed: %1$s</string>
<string name="enforcingGps" translatable="false">Private Locationing enabled, enforcing GPS use.</string>
<string name="notEnforcingGps" translatable="false">Private Locationing not enabled, using regular provider search.</string>
<string name="gpsMeasurement" translatable="false">GPS measurement</string>
<string name="gpsMeasurementTimeout" translatable="false">GPS measurement stopped due to timeout.</string>
<string name="cellMastChanged" translatable="false">Cell mast changed: %1$s</string>
<string name="noiseDetectionHint">If you think the noise detection isn\'t working correctly (depending on the value you specify) please keep in mind that every phone is different. You can therefore change \"Reference for noise measurement\" in settings. See http://en.wikipedia.org/wiki/Decibel for more information. You can use the volume tester from the main screen to calibrate your device.</string>
<string name="hint">Hint</string>
<string name="selectNoiseLevel">Select noise level</string>
<string name="poiHasWifiStoppingCellLocationListener">Location has wifi. Stopping CellLocationChangedReceiver.</string>
<string name="poiHasNoWifiNotStoppingCellLocationListener">Location doesn\'t have wifi. Not stopping CellLocationChangedReceiver.</string>
<string name="poiHasWifiStoppingCellLocationListener" translatable="false">Location has wifi. Stopping CellLocationChangedReceiver.</string>
<string name="poiHasNoWifiNotStoppingCellLocationListener" translatable="false">Location doesn\'t have wifi. Not stopping CellLocationChangedReceiver.</string>
<string name="showOnMap">Show on map</string>
<string name="noMapsApplicationFound">No maps application found on your device.</string>
<string name="locationEngineNotActive">Location engine not active.</string>
@ -489,7 +488,8 @@
<string name="errorWritingFile">Error writing settings file.</string>
<string name="unknownError">Unknown error.</string>
<string name="noWritableFolderFound">No writable folder found to store config file.</string>
<string name="usbTetheringFailForAboveGingerbread">This will most likely not work as you\'re above Android 2.3. However you could use wifi tethering instead.</string>
<string name="usbTetheringFailForAboveGingerbread">This will most likely not work as you\'re above Android 2.3. If you\'re below Android 7 you could use wifi tethering instead instead.</string>
<string name="wifiTetheringFailForAboveNougat">This will not work anymore as you\'re above Android 7.</string>
<string name="usingNewThreadForRuleExecution">Using new thread for rule activation.</string>
<string name="startNewThreadForRuleExecution">Start new thread for rule activation.</string>
<string name="newThreadRules">New thread</string>
@ -504,10 +504,10 @@
<string name="volumeTest">Volume test</string>
<string name="volumeTesterExplanation">To calculate a dB value for noise monitoring you need to specify a so called physical reference value. Please read Wikipedia for further information. This value is most likely different for every phone. Drag the seekbar to change the defined physical reference value. The higher the reference value the lower the dB value will be. Constant measurings will be performed every %1$s seconds and the results displayed below. Press back when you have found a suitable value.</string>
<string name="settingsWillTakeTime">Some settings will not be applied before certain environment settings change or service is restarted.</string>
<string name="phoneIsRooted">Phone is rooted.</string>
<string name="phoneIsNotRooted">Phone is not rooted.</string>
<string name="dataConWithRootSuccess">Data connection was successfully changed using superuser permissions.</string>
<string name="dataConWithRootFail">Data could not be changed using superuser permissions.</string>
<string name="phoneIsRooted" translatable="false">Phone is rooted.</string>
<string name="phoneIsNotRooted" translatable="false">Phone is not rooted.</string>
<string name="dataConWithRootSuccess" translatable="false">Data connection was successfully changed using superuser permissions.</string>
<string name="dataConWithRootFail" translatable="false">Data could not be changed using superuser permissions.</string>
<string name="rootExplanation">You need to root your phone for this function to work. Afterwards you needs to \"run the rule manually\" to show up the superuser permission question. When the superuser popups shows up you need to always allow the application to do that. Otherwise the rule cannot function when the phone is unattended.</string>
<string name="errorWritingConfig">Error writing config. Do you have a writable memory?</string>
<string name="phoneNrReplacementError">I could not insert the last phone nr in the variable. I don\'t have it.</string>
@ -576,7 +576,7 @@
<string name="chooseActivityHint">In this final selection popup you need to select a specific activity. Simplified this is like a window of the desired application. If you do not know which one it is generally a good idea to pick one that has \"main\" or \"launcher\" in its name.</string>
<string name="edit">Edit</string>
<string name="clickAndHoldForOptions">Click and hold an item for options.</string>
<string name="ruleActivationComplete">Rule \"%1$s\" finished.</string>
<string name="ruleActivationComplete" translatable="false">Rule \"%1$s\" finished.</string>
<string name="positioningEngine">Positioning engine</string>
<string name="googleSarcasm">Thanks to Google\'s infinite whisdom and constant endeavor to protect everyone\'s privacy rules that may send sms or involve the users phone state have to be stripped off applicable triggers and actions.</string>
<string name="startAutomationAsService">Start automation as a service</string>
@ -589,7 +589,7 @@
<string name="autoBrightnessNotice">If you use auto brightness the brightness value you use below will probably not be used long.</string>
<string name="screenLockSoundNotice">Screenlock sounds cannot automatically be changed anymore on devices running Android version 6.0 or higher. Whatever you set here, it will not work in either direction.</string>
<string name="startScreen">Start screen</string>
<string name="startScreenSummary">Select the screen the applications opens withs at start.</string>
<string name="startScreenSummary">Select the screen the applications opens with at start.</string>
<string name="executeRulesAndProfilesWithSingleClickTitle">Run rules/profiles with single click.</string>
<string name="googleLocationChicanery">This app collects location data to enable location based rules and speed detection even when the app is closed or not in use.</string>
<string name="googleLocationChicaneryOld">This app collects location data to determine if you\'re currently at one of the locations you created. Furthermore it is used to determine your current speed if you are using that trigger in rules. That is done even when the app is closed or not in use (but only when the service is activated).</string>
@ -605,7 +605,7 @@
<string name="filesHaveBeenMovedTo">Automation now uses another path to store your files. All your Automation-files have been moved here: \"%s\". The external storage permission is not required anymore; you can revoke it. It will be removed in a future version.</string>
<string name="newsOptIn">Would you like to receive (only important) news about this app on the main screen? Those are downloaded from the developer\'s website. There will be no intrusive notification, just a text on the main screen when you open the app.</string>
<string name="locationDisabled">Location disabled</string>
<string name="locationEngineDisabledShort">Location cannot be determined anymore. Click here to find out why.</string>
<string name="locationEngineDisabledShort">Location cannot be determined in the background anymore. Click here to find out why.</string>
<string name="locationEngineDisabledLong">Unfortunately your location cannot be determined anymore. A debt of gratitude is owed to Google for its infinite wisdom and amiableness.\\n\\nLet me explain this further. Starting with Android 10 a new permission was introduced that is needed to determine your location in the background (which of course is required for an app like this). Whilst I consider that a good idea in general the chicanery it involves for developers is not.\\n\\nWhen developing an app you can try to qualify for this permission by abiding to a catalog of requirements. Unfortunately new versions of my app have been rejected over a period of three months. I fulfilled all those requirements, Google\'s shitty development support claimed I would not. After giving them proof that I did after all - I got a response like \"I cannot help you anymore\". Eventually I gave up. \\n\\nAs a consequence the Google Play version can NOT use your location as a trigger anymore. My only alternative option would have been to have this application removed from the store entirely.\\n\\nI\'m very sorry about that, but I\'ve tried my best arguing with a \"support\" that repeatedly failed to pass the Turing test.\\n\\nThe good news: You can still have it all!\\n\\nAutomation is now open source and can be found in F-Droid. That is an app store that really cares about your privacy - rather than just acting like that. Simply backup your config file, uninstall this app, install it again from F-Droid, restore your config file - done.\\n\\nClick here to find out more:</string>
<string name="filesStoredAt">Config and log files are stored in folder %1$s. Click on this text to open a file explorer. Unfortunately this will only work on a rooted device.\n\nFOR ALL OTHER DEVICES: Simply use the export button to make a backup.</string>
<string name="notification">Notification</string>
@ -643,7 +643,7 @@
<string name="enterValidAction">Enter a valid action</string>
<string name="enterPackageName">Enter a valid package name.</string>
<string name="state">State</string>
<string name="phoneNumberExplanation">You can enter a specific phone number, but you don\'t have to. If you want to specify one you can either pick one from your address book or enter it manually.</string>
<string name="phoneNumberExplanation">You can enter a specific phone number, but you don\'t have to. If you want to specify one you can either pick one from your address book or enter it manually. In addition you may use regular expressions. To test a regular expression I like this page:</string>
<string name="importConfiguration">Import configuration</string>
<string name="exportConfiguration">Export configuration</string>
<string name="moreSettings">More settings</string>
@ -665,5 +665,14 @@
<string name="openExamplesPage">Open webpage with examples</string>
<string name="packageName">Package name</string>
<string name="activityOrActionName">Activity/action name</string>
<!-- <string name="net.kollnig.missioncontrol.permission.ADMIN">Control the app Tracker Control</string>-->
<string name="warning">Warning</string>
<string name="ringing">ringing</string>
<string name="from">from</string>
<string name="to">to</string>
<string name="matching">matching</string>
<string name="urlRegex" translatable="false">https://regex101.com/</string>
<string name="loadWifiList">Load wifi list</string>
<string name="needLocationPermForWifiList">The list of wifis your device has been connected to could be used to determine which places you have been to. That\'s why the location permission is required to load the list of wifis. If you want to be able to pick one from the list you need to grant that permission. If not you can still enter your wifi name manually.</string>
<string name="noKnownWifis">There are no known wifis on your device.</string>
<string name="urlToTriggerExplanation">This feature does NOT open a browser, but triggers a URL in the background. You can use this e.g. to send commands to your home automation.</string>
</resources>

View File

@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:4.2.0'
classpath 'com.android.tools.build:gradle:4.2.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View File

@ -0,0 +1,7 @@
* SSID für WLANs kann nun aus Liste ausgewählt werden
* WLAN Router aktivieren benötigt keine root-Rechte mehr
* Telefonanruf-Auslöser erheblich verbessert
* Problem behoben, bei dem die Nutzung von Root-Rechten nicht funktioniert hat
* Absturz behoben, der in der F-Droid Version aufgetreten ist
* Spanische Übersetzung aktualisiert
* Italienische Übersetzung verbessert

View File

@ -42,7 +42,9 @@ Mögliche Aktionen:
Es ist ziemlich schwierig diese Anwendung über die vielen verschiedenen Geräte sowie die vielen Änderungen an Android Versionen am Laufen zu halten. Ich kann vieles im Emulator testen, aber eben nicht alles.
Wenn also eine bestimmte Funktion nicht so tut wie sie sollte - lassen Sie es mich wissen. Über die Jahre habe ich noch alle Fehler behoben, die mir vernünftig gemeldet wurden. Aber dafür bin ich auf Ihre Mithilfe angewiesen.
Spenden sind nicht die einzige Möglichkeit mich zu motivieren :-)
Wenn Sie ein Problem mit der Anwendung haben und mich dazu kontaktieren möchten, updaten Sie bitte vorher auf die neueste Version und schauen Sie, ob Ihr Problem darin auch besteht.
Spenden sind sicher eine gute, aber nicht die einzige Möglichkeit mich zu motivieren :-)
* Wer mir etwas Gutes tun will, kann die Anwendung auch im Play Store bewerten.
* Außerdem ist Hilfe bei der Übersetzung willkommen. Englisch, Spanisch und Deutsch kann ich selbst. Aber sonst ist alles gern gesehen.

View File

@ -0,0 +1,7 @@
* SSID for wifi trigger can now be picked from list
* Activate wifi tethering doesn't require root anymore
* PhoneCall trigger significantly enhanced
* Fixed a problem where usage of root permissions wasn't possible
* Fixed a frequent crash that concerned the F-Droid version
* Spanish translation updated
* Italian translation updated

View File

@ -42,8 +42,10 @@ Supported actions:
It's quite hard to keep this app working across the many different hardwares as well as the many changes Android undergoes over the versions. I can test it in the emulator, but that cannot show all bugs.
So if a certain feature is not working on your device - let me know. Over the years I have fixed almost all bugs that have been reasonably reported to me. But for that I'm dependend on your input.
Donations are not the only way to motivate me :-)
* If you want to suport me, can also review the app on Google Play.
If you have a problem and think about contacting me please update to the latest version first and see if your problem persists there, too.
Donations are certainly a good, but not the only way to motivate me :-)
* If you want to support me, can also leave a positive review for the app on Google Play.
* Furthermore I can always use help in translating the app. English, German and some Spanish are among my own skills. But everything else is more than welcome.
Explanation of the many permissions can be found here: https://server47.de/automation/permissions_en.html

View File

@ -0,0 +1,7 @@
* Se puede eligir wifi SSID de una lista
* Activar wifi tethering no mas necesita root
* PhoneCall condición mejorada
* Reparado un problema de usar permisos root no estaba posible
* Reparado un crash frequente en la version F-Droid
* Spanish traducción actualizada
* Italian traducción actualizada

View File

@ -0,0 +1,51 @@
Cree reglas que tienen disparadores y aciónes. Un buen ejemplo puede ser "Ponga el móvil muto en trabajo".
Aqui esta una lista de disparadores y aciónes:
Disparadores:
* Locación
* Dia/tiempo
* Estado de cargar
* Nivel de la bateria
* USB conexión a computador establecido
* Velocidad
* Ruido del fondo (solo hasta Android 7)
* Wifi conexión
* Otra app esta activado
* Modo de vuelo
* Estado de roaming
* NFC tags
* Bluetooth conexión
* Headset conectado
* Llamado de teléfono activo
* Notificaciónes de otras apps
Supported actions:
* Pasar de wifi
* Pasar de bluetooth
* Pasar USB rúter
* Pasar wifi rúter
* Pasar rotación automatica del monitor
* Hacer un solicitud HTTP
* Cambiar el tono de llamada / ajustes de sonido
* Encender otra app
* Esperar (inter otras aciónes)
* Desperatar móvil
* Pasar modo de vuelo
* Pasar datos móviles
* Leer texto
* Abrir reproductor de música
* Cambiar luminosidad del monitor
* Enviar mensaje
* Tocar archivo sonido
Es muy dificil mantener esta applicación functionando en todos los hardwares y versiónes de Android. Puedo probrar mucho en el emulator, pero no puedo enviar todos los errores.
Si una función no funcióna - digame. En muchos años resolvaba la mayoria de los errores que los halladores me informaron bien. Pero dependo en su ayuda.
Si tiene un problema y considera contactarme update a la ultima version al primero y probar si su problam persiste.
Donaciónes seguramente son una buena, pero no la unica posibilidad de apoyarme :-)
* Si quiere apoyarme puedes escribir un buena revisión en Google Play
* Además siempre necesito ayuda en traduciendo la app. Ingles, Aleman y Español estan en mis habilidades. Per todo lo demás es bienvenido.
Puedes leer una explicación de los permisos aqui: https://server47.de/automation/permissions_en.html

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

View File

@ -0,0 +1 @@
Automatice procesos en su móvil por creando reglas.

View File

@ -0,0 +1 @@
Automation

Binary file not shown.

After

Width:  |  Height:  |  Size: 79 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 200 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 113 KiB