Compare commits
12 Commits
Author | SHA1 | Date | |
---|---|---|---|
d4288dfc40 | |||
01f4bba995 | |||
4a2a1a0550 | |||
a693ced32e | |||
64d1aec910 | |||
221cfa4339 | |||
810b6f03aa | |||
4e51cbe36e | |||
722f9f0e6b | |||
c1f03d3395 | |||
fc71a3548c | |||
e33915b578 |
@ -11,8 +11,8 @@ android {
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.2'
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
versionCode 98
|
||||
versionName "1.6.22"
|
||||
versionCode 100
|
||||
versionName "1.6.24"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
@ -137,6 +137,7 @@
|
||||
|
||||
<activity android:name=".ActivityManageRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityDisplayLongMessage" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
|
@ -133,6 +133,7 @@
|
||||
|
||||
<activity android:name=".ActivityManageRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityDisplayLongMessage" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
|
@ -36,7 +36,6 @@
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
@ -63,15 +62,6 @@
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
|
||||
<!-- Commented out because of Google Play policy -->
|
||||
<!--
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
android:required="false" />
|
||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
-->
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
@ -137,6 +127,7 @@
|
||||
|
||||
<activity android:name=".ActivityManageRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityDisplayLongMessage" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
|
@ -3,6 +3,7 @@ package com.jens.automation2.receivers;
|
||||
import android.app.IntentService;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Intent;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
|
||||
@ -13,6 +14,7 @@ import com.google.android.gms.location.ActivityRecognition;
|
||||
import com.google.android.gms.location.ActivityRecognitionApi;
|
||||
import com.google.android.gms.location.ActivityRecognitionResult;
|
||||
import com.google.android.gms.location.DetectedActivity;
|
||||
import com.jens.automation2.ActivityDisplayLongMessage;
|
||||
import com.jens.automation2.ActivityPermissions;
|
||||
import com.jens.automation2.AutomationService;
|
||||
import com.jens.automation2.Miscellaneous;
|
||||
@ -110,6 +112,14 @@ public class ActivityDetectionReceiver extends IntentService implements Automati
|
||||
}
|
||||
public static void startActivityDetectionReceiver()
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M)
|
||||
{
|
||||
if(!ActivityPermissions.havePermission("android.permission.ACTIVITY_RECOGNITION", Miscellaneous.getAnyContext()))
|
||||
{
|
||||
Miscellaneous.logEvent("w", "Activity Detection", "Don't have android.permission.ACTIVITY_RECOGNITION. Aborting receiver start..", 2);
|
||||
return;
|
||||
}
|
||||
}
|
||||
try
|
||||
{
|
||||
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Starting ActivityDetectionReceiver", 3);
|
||||
|
@ -1,195 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="com.jens.automation2">
|
||||
|
||||
<supports-screens
|
||||
android:anyDensity="true"
|
||||
android:largeScreens="true"
|
||||
android:normalScreens="true"
|
||||
android:smallScreens="true" />
|
||||
<!-- android:xlargeScreens="true" -->
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.location"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.gps"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.location.network"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.bluetooth"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.microphone"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.wifi"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.touchscreen"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.nfc"
|
||||
android:required="false" />
|
||||
|
||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
||||
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
|
||||
<uses-permission android:name="android.permission.VIBRATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
|
||||
<uses-permission android:name="android.permission.BLUETOOTH" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
|
||||
<uses-permission android:name="android.permission.BATTERY_STATS" />
|
||||
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.RECORD_AUDIO" />
|
||||
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.GET_TASKS" />
|
||||
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
|
||||
<uses-permission android:name="android.permission.NFC" />
|
||||
<uses-permission android:name="com.google.android.gms.permission.ACTIVITY_RECOGNITION" />
|
||||
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
|
||||
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
|
||||
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" />
|
||||
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.READ_CONTACTS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
|
||||
<!-- Commented out because of Google Play policy -->
|
||||
<!--
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
android:required="false" />
|
||||
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
|
||||
<uses-permission android:name="android.permission.SEND_SMS"/>
|
||||
-->
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:allowClearUserData="true"
|
||||
android:icon="@drawable/gears"
|
||||
android:label="@string/title_activity_main"
|
||||
android:theme="@style/AppTheme"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
<meta-data
|
||||
android:name="firebase_analytics_collection_deactivated"
|
||||
android:value="true" />
|
||||
<meta-data
|
||||
android:name="google_analytics_adid_collection_enabled"
|
||||
android:value="false" />
|
||||
<meta-data
|
||||
android:name="google_analytics_ssaid_collection_enabled"
|
||||
android:value="false" />
|
||||
|
||||
<activity
|
||||
android:name=".ActivityMainScreen"
|
||||
android:label="@string/app_name"></activity>
|
||||
<activity
|
||||
android:name=".ActivityManagePoi"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
<activity
|
||||
android:name=".ActivitySettings"
|
||||
android:label="@string/title_activity_main"></activity>
|
||||
|
||||
<service
|
||||
android:name=".AutomationService"
|
||||
android:exported="false"
|
||||
android:label="@string/title_activity_main" />
|
||||
|
||||
<receiver android:name=".receivers.StartupIntentReceiver" android:enabled="true" android:exported="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.SCREEN_ON" />-->
|
||||
<!--<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />-->
|
||||
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
|
||||
<action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
<action android:name="android.intent.action.REBOOT"/>
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.PackageReplacedReceiver"
|
||||
android:enabled="true">
|
||||
<intent-filter>
|
||||
<!--<action android:name="android.intent.action.PACKAGE_ADDED"/>
|
||||
<action android:name="android.intent.action.PACKAGE_REPLACED" />
|
||||
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
|
||||
<action android:name="android.intent.action.ACTION_PACKAGE_REPLACED" />-->
|
||||
<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
|
||||
|
||||
<!--<data
|
||||
android:path="com.jens.automation2"
|
||||
android:scheme="package" />-->
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
<receiver android:name=".receivers.AlarmListener" />
|
||||
<receiver android:name=".receivers.ConnectivityReceiver" />
|
||||
<receiver android:name=".receivers.TimeZoneListener" />
|
||||
|
||||
<activity android:name=".ActivityManageRule" />
|
||||
<activity android:name=".ActivityEditTriggerUrl" />
|
||||
<activity android:name=".ActivityEditSendTextMessage" />
|
||||
<activity android:name=".ActivityManageTimeFrame" />
|
||||
<activity android:name=".ActivityManageBrightnessSetting" />
|
||||
<activity android:name=".ActivityHelp" />
|
||||
<activity
|
||||
android:name=".ActivityMainTabLayout"
|
||||
android:launchMode="singleTask">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<!-- <action android:name="android.nfc.action.TECH_DISCOVERED"/> -->
|
||||
<!-- <action android:name="android.nfc.action.TAG_DISCOVERED"/> -->
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
|
||||
<data android:mimeType="text/plain" />
|
||||
<!-- <data android:mimeType="application/com.jens.automation2" /> -->
|
||||
</intent-filter>
|
||||
|
||||
<!--
|
||||
<intent-filter>
|
||||
<action android:name="android.nfc.action.NDEF_DISCOVERED" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<data android:mimeType="application/com.jens.automation2" />
|
||||
</intent-filter>
|
||||
-->
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.jens.automation2">
|
||||
|
||||
|
||||
<!--
|
||||
<meta-data
|
||||
android:name="android.nfc.action.TECH_DISCOVERED"
|
||||
android:resource="@xml/nfc_tech_filter" />
|
||||
-->
|
||||
</activity>
|
||||
<activity android:name=".ActivityMainPoi" />
|
||||
<activity android:name=".ActivityMainRules" />
|
||||
<activity android:name=".ActivityGeneric" />
|
||||
<activity android:name=".ActivityManageStartActivity" />
|
||||
<activity android:name=".ActivityManageNfc" />
|
||||
<activity android:name=".ActivityEditSpeakText" />
|
||||
<activity android:name=".ActivityManageBluetoothTrigger" />
|
||||
<activity android:name=".ActivityMainProfiles" />
|
||||
<activity android:name=".ActivityManageProfile" />
|
||||
<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"/>
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
@ -0,0 +1,56 @@
|
||||
package com.jens.automation2;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.text.Html;
|
||||
import android.view.View;
|
||||
import android.widget.QuickContactBadge;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.text.HtmlCompat;
|
||||
|
||||
public class ActivityDisplayLongMessage extends Activity
|
||||
{
|
||||
TextView tvMessageTitle, tvLongMessage, tvMessageLink;
|
||||
|
||||
@Override
|
||||
protected void onCreate(@Nullable Bundle savedInstanceState)
|
||||
{
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_display_long_message);
|
||||
|
||||
tvMessageTitle = (TextView)findViewById(R.id.tvMessageTitle);
|
||||
tvLongMessage = (TextView)findViewById(R.id.tvLongMessage);
|
||||
tvMessageLink = (TextView)findViewById(R.id.tvMessageLink);
|
||||
|
||||
String title = getIntent().getStringExtra("messageTitle");
|
||||
String message = getIntent().getStringExtra("longMessage").replace("\\n", Miscellaneous.lineSeparator);
|
||||
|
||||
String link = null;
|
||||
if(getIntent().hasExtra("messageLink"))
|
||||
link = getIntent().getStringExtra("messageLink");
|
||||
|
||||
tvMessageTitle.setText(HtmlCompat.fromHtml(title, HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
tvLongMessage.setText(message);
|
||||
|
||||
if(link != null && link.length() > 0)
|
||||
{
|
||||
tvMessageLink.setText(HtmlCompat.fromHtml("<u>" + link + "</u>", HtmlCompat.FROM_HTML_MODE_LEGACY));
|
||||
String finalLink = link;
|
||||
tvMessageLink.setOnClickListener(new View.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View view)
|
||||
{
|
||||
Uri uriUrl = Uri.parse(finalLink);
|
||||
Intent launchBrowser = new Intent(Intent.ACTION_VIEW, uriUrl);
|
||||
startActivity(launchBrowser);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
@ -53,23 +53,25 @@ public class ActivityMainPoi extends ActivityGeneric
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
// if(!ActivityPermissions.havePermission(ActivityPermissions.writeExternalStoragePermissionName, ActivityMainPoi.this))
|
||||
// {
|
||||
// Toast.makeText(ActivityMainPoi.this, getResources().getString(R.string.appRequiresPermissiontoAccessExternalStorage), Toast.LENGTH_LONG).show();
|
||||
// return;
|
||||
// }
|
||||
|
||||
if(!ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, ActivityMainPoi.this) || !ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, ActivityMainPoi.this))
|
||||
if(Miscellaneous.googleToBlameForLocation(false))
|
||||
{
|
||||
Intent permissionIntent = new Intent(ActivityMainPoi.this, ActivityPermissions.class);
|
||||
|
||||
permissionIntent.putExtra(ActivityPermissions.intentExtraName, new String[] { ActivityPermissions.permissionNameLocationCoarse, ActivityPermissions.permissionNameLocationFine });
|
||||
|
||||
startActivityForResult(permissionIntent, requestCodeForPermission);
|
||||
ActivityMainScreen.openGoogleBlamingWindow();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
buttonAddPoi();
|
||||
if (!ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, ActivityMainPoi.this) || !ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, ActivityMainPoi.this))
|
||||
{
|
||||
Intent permissionIntent = new Intent(ActivityMainPoi.this, ActivityPermissions.class);
|
||||
|
||||
permissionIntent.putExtra(ActivityPermissions.intentExtraName, new String[]{ActivityPermissions.permissionNameLocationCoarse, ActivityPermissions.permissionNameLocationFine});
|
||||
|
||||
startActivityForResult(permissionIntent, requestCodeForPermission);
|
||||
}
|
||||
else
|
||||
{
|
||||
buttonAddPoi();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -2,13 +2,13 @@ package com.jens.automation2;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.os.StrictMode;
|
||||
import android.util.Log;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.View;
|
||||
@ -29,7 +29,6 @@ import com.jens.automation2.AutomationService.serviceCommands;
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
|
||||
import java.lang.reflect.Array;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Calendar;
|
||||
|
||||
@ -41,7 +40,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
private static ActivityMainScreen activityMainScreenInstance = null;
|
||||
private ToggleButton toggleService, tbLockSound;
|
||||
private Button bShowHelp, bPrivacy, bSettingsErase, bSettingsSetToDefault, bVolumeTest, bAddSoundLockTIme;
|
||||
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNote1, tvMainScreenNote2, tvMainScreenNote3, tvlockSoundDuration;
|
||||
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNotePermissions, tvMainScreenNoteFeaturesFromOtherFlavor, tvMainScreenNoteLocationImpossibleBlameGoogle, tvMainScreenNoteNews, tvlockSoundDuration, tvFileStoreLocation;
|
||||
|
||||
private ListView lvRuleHistory;
|
||||
private ArrayAdapter<Rule> ruleHistoryListViewAdapter;
|
||||
@ -70,10 +69,12 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
tvClosestPoi = (TextView) findViewById(R.id.tvClosestPoi);
|
||||
lvRuleHistory = (ListView) findViewById(R.id.lvRuleHistory);
|
||||
tvLastRule = (TextView) findViewById(R.id.tvTimeFrameHelpText);
|
||||
tvMainScreenNote1 = (TextView) findViewById(R.id.tvMainScreenNote1);
|
||||
tvMainScreenNote2 = (TextView) findViewById(R.id.tvMainScreenNote2);
|
||||
tvMainScreenNote3 = (TextView) findViewById(R.id.tvMainScreenNote3);
|
||||
tvMainScreenNotePermissions = (TextView) findViewById(R.id.tvMainScreenNotePermissions);
|
||||
tvMainScreenNoteFeaturesFromOtherFlavor = (TextView) findViewById(R.id.tvMainScreenNoteFeaturesFromOtherFlavor);
|
||||
tvMainScreenNoteLocationImpossibleBlameGoogle = (TextView) findViewById(R.id.tvMainScreenNoteLocationImpossibleBlameGoogle);
|
||||
tvMainScreenNoteNews = (TextView) findViewById(R.id.tvMainScreenNoteNews);
|
||||
tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
|
||||
tvFileStoreLocation = (TextView)findViewById(R.id.tvFileStoreLocation);
|
||||
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
|
||||
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
|
||||
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||
@ -95,7 +96,7 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
}
|
||||
});
|
||||
|
||||
tvMainScreenNote1.setOnClickListener(new OnClickListener()
|
||||
tvMainScreenNotePermissions.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
@ -291,24 +292,52 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
{
|
||||
if(ActivityPermissions.needMorePermissions(activityMainScreenInstance))
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNote1.setText(R.string.mainScreenPermissionNote);
|
||||
activityMainScreenInstance.tvMainScreenNote1.setVisibility(View.VISIBLE);
|
||||
activityMainScreenInstance.tvMainScreenNotePermissions.setText(R.string.mainScreenPermissionNote);
|
||||
activityMainScreenInstance.tvMainScreenNotePermissions.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNote1.setText("");
|
||||
activityMainScreenInstance.tvMainScreenNote1.setVisibility(View.GONE);
|
||||
activityMainScreenInstance.tvMainScreenNotePermissions.setText("");
|
||||
activityMainScreenInstance.tvMainScreenNotePermissions.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(Miscellaneous.restrictedFeaturesConfigured())
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNote2.setText(R.string.settingsReferringToRestrictedFeatures);
|
||||
activityMainScreenInstance.tvMainScreenNote2.setVisibility(View.VISIBLE);
|
||||
activityMainScreenInstance.tvMainScreenNoteFeaturesFromOtherFlavor.setText(R.string.settingsReferringToRestrictedFeatures);
|
||||
activityMainScreenInstance.tvMainScreenNoteFeaturesFromOtherFlavor.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNote2.setText("");
|
||||
activityMainScreenInstance.tvMainScreenNote2.setVisibility(View.GONE);
|
||||
activityMainScreenInstance.tvMainScreenNoteFeaturesFromOtherFlavor.setText("");
|
||||
activityMainScreenInstance.tvMainScreenNoteFeaturesFromOtherFlavor.setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if(Miscellaneous.googleToBlameForLocation(true))
|
||||
{
|
||||
// Intent intent = new Intent(AutomationService.this, ActivityDisplayLongMessage.class);
|
||||
// intent.putExtra("longMessage", getResources().getString(R.string.locationEngineDisabledLong));
|
||||
// PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
// Miscellaneous.createDismissableNotificationWithDelay(2200, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
// else
|
||||
// Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
|
||||
activityMainScreenInstance.tvMainScreenNoteLocationImpossibleBlameGoogle.setText(R.string.locationEngineDisabledShort);
|
||||
activityMainScreenInstance.tvMainScreenNoteLocationImpossibleBlameGoogle.setVisibility(View.VISIBLE);
|
||||
activityMainScreenInstance.tvMainScreenNoteLocationImpossibleBlameGoogle.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(View v)
|
||||
{
|
||||
openGoogleBlamingWindow();
|
||||
}
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNoteLocationImpossibleBlameGoogle.setText("");
|
||||
activityMainScreenInstance.tvMainScreenNoteLocationImpossibleBlameGoogle.setVisibility(View.GONE);
|
||||
activityMainScreenInstance.tvMainScreenNoteLocationImpossibleBlameGoogle.setOnClickListener(null);
|
||||
}
|
||||
|
||||
if (AutomationService.isMyServiceRunning(activityMainScreenInstance))
|
||||
@ -418,7 +447,56 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
Miscellaneous.logEvent("i", "ActivityMainScreen", "Activity not running. No need to update.", 5);
|
||||
|
||||
if(activityMainScreenInstance != null)
|
||||
activityMainScreenInstance.checkForNews();
|
||||
{
|
||||
if(!Settings.hasBeenDone(Settings.constNewsOptInDone))
|
||||
newsOptIn();
|
||||
else
|
||||
activityMainScreenInstance.checkForNews();
|
||||
|
||||
Settings.considerDone(Settings.constNewsOptInDone);
|
||||
Settings.writeSettings(Miscellaneous.getAnyContext());
|
||||
|
||||
String folder = Miscellaneous.getWriteableFolder();
|
||||
if(folder != null && folder.length() > 0)
|
||||
activityMainScreenInstance.tvFileStoreLocation.setText(String.format(activityMainScreenInstance.getResources().getString(R.string.filesStoredAt), folder));
|
||||
}
|
||||
}
|
||||
|
||||
public static void openGoogleBlamingWindow()
|
||||
{
|
||||
Intent intent = new Intent(Miscellaneous.getAnyContext(), ActivityDisplayLongMessage.class);
|
||||
String message = Miscellaneous.getAnyContext().getResources().getText(R.string.locationEngineDisabledLong).toString();
|
||||
intent.putExtra("messageTitle", Miscellaneous.getAnyContext().getResources().getString(R.string.locationDisabled));
|
||||
intent.putExtra("longMessage", message);
|
||||
intent.putExtra("messageLink", "https://server47.de/automation/fdroidMigration.html");
|
||||
ActivityMainScreen.getActivityMainScreenInstance().startActivity(intent);
|
||||
}
|
||||
|
||||
static void newsOptIn()
|
||||
{
|
||||
AlertDialog.Builder builder = new AlertDialog.Builder(Miscellaneous.getAnyContext());
|
||||
builder.setMessage(Miscellaneous.getAnyContext().getResources().getString(R.string.newsOptIn));
|
||||
builder.setPositiveButton(Miscellaneous.getAnyContext().getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
{
|
||||
Settings.displayNewsOnMainScreen = true;
|
||||
Settings.writeSettings(Miscellaneous.getAnyContext());
|
||||
|
||||
try
|
||||
{
|
||||
activityMainScreenInstance.checkForNews();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "NewsOptIn", "There was a problem showing the news opt-in: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
});
|
||||
builder.setNegativeButton(Miscellaneous.getAnyContext().getResources().getString(R.string.no), null);
|
||||
|
||||
builder.create().show();
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -572,57 +650,31 @@ public class ActivityMainScreen extends ActivityGeneric
|
||||
|
||||
synchronized void checkForNews()
|
||||
{
|
||||
News.AsyncTaskDownloadNews dnTask = new News.AsyncTaskDownloadNews();
|
||||
dnTask.execute(ActivityMainScreen.this);
|
||||
|
||||
// StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
|
||||
// StrictMode.setThreadPolicy(policy);
|
||||
|
||||
// Calendar now = Calendar.getInstance();
|
||||
|
||||
// if (true || Settings.lastNewsPolltime == -1 || now.getTimeInMillis() >= Settings.lastNewsPolltime + (long)(Settings.pollNewsEveryXDays * 24 * 60 * 60 * 1000))
|
||||
// {
|
||||
// ArrayList<News> newsToDisplay;
|
||||
//
|
||||
//// if(Settings.lastNewsPolltime == -1)
|
||||
// newsToDisplay = News.downloadNews(ActivityMainScreen.this);
|
||||
//// else
|
||||
//// newsToDisplay = News.downloadNews(ActivityMainScreen.this, Miscellaneous.calendarFromLong(Settings.lastNewsPolltime));
|
||||
//
|
||||
// if (newsToDisplay.size() > 0)
|
||||
// {
|
||||
// activityMainScreenInstance.tvMainScreenNote3.setText(newsToDisplay.get(0).toString());
|
||||
// activityMainScreenInstance.tvMainScreenNote3.setVisibility(View.VISIBLE);
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// activityMainScreenInstance.tvMainScreenNote3.setText("");
|
||||
// activityMainScreenInstance.tvMainScreenNote3.setVisibility(View.GONE);
|
||||
// }
|
||||
// }
|
||||
if(Settings.displayNewsOnMainScreen)
|
||||
{
|
||||
News.AsyncTaskDownloadNews dnTask = new News.AsyncTaskDownloadNews();
|
||||
dnTask.execute(ActivityMainScreen.this);
|
||||
}
|
||||
}
|
||||
|
||||
public void processNewsResult(ArrayList<News> newsToDisplay)
|
||||
{
|
||||
if(Settings.displayNewsOnMainScreen)
|
||||
try
|
||||
{
|
||||
try
|
||||
if (newsToDisplay.size() > 0)
|
||||
{
|
||||
if (newsToDisplay.size() > 0)
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNote3.setText(HtmlCompat.fromHtml(newsToDisplay.get(0).toStringHtml(), 0));
|
||||
activityMainScreenInstance.tvMainScreenNote3.setVisibility(View.VISIBLE);
|
||||
}
|
||||
else
|
||||
{
|
||||
activityMainScreenInstance.tvMainScreenNote3.setText("");
|
||||
activityMainScreenInstance.tvMainScreenNote3.setVisibility(View.GONE);
|
||||
}
|
||||
activityMainScreenInstance.tvMainScreenNoteNews.setText(HtmlCompat.fromHtml(newsToDisplay.get(0).toStringHtml(), 0));
|
||||
activityMainScreenInstance.tvMainScreenNoteNews.setVisibility(View.VISIBLE);
|
||||
}
|
||||
catch(Exception e)
|
||||
else
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Error displaying news", Log.getStackTraceString(e), 3);
|
||||
activityMainScreenInstance.tvMainScreenNoteNews.setText("");
|
||||
activityMainScreenInstance.tvMainScreenNoteNews.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "Error displaying news", Log.getStackTraceString(e), 3);
|
||||
}
|
||||
}
|
||||
}
|
@ -165,7 +165,7 @@ public class ActivityManageRule extends Activity
|
||||
hideKeyboard();
|
||||
getActionTypeDialog().show();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
cmdSaveRule.setOnClickListener(new OnClickListener()
|
||||
{
|
||||
@ -502,12 +502,20 @@ public class ActivityManageRule extends Activity
|
||||
String[] booleanChoices = null;
|
||||
if(triggerType == Trigger_Enum.pointOfInterest)
|
||||
{
|
||||
if(PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
|
||||
booleanChoices = new String[]{getResources().getString(R.string.entering), getResources().getString(R.string.leaving)};
|
||||
if(Miscellaneous.googleToBlameForLocation(false))
|
||||
{
|
||||
ActivityMainScreen.openGoogleBlamingWindow();
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
Toast.makeText(myContext, getResources().getString(R.string.noPoisSpecified), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
if (PointOfInterest.getPointOfInterestCollection() != null && PointOfInterest.getPointOfInterestCollection().size() > 0)
|
||||
booleanChoices = new String[]{getResources().getString(R.string.entering), getResources().getString(R.string.leaving)};
|
||||
else
|
||||
{
|
||||
Toast.makeText(myContext, getResources().getString(R.string.noPoisSpecified), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if(triggerType == Trigger_Enum.timeFrame)
|
||||
|
@ -231,8 +231,9 @@ public class ActivityPermissions extends Activity
|
||||
{
|
||||
for (String s : getRequiredPermissions(false))
|
||||
{
|
||||
if (!havePermission(s, context))
|
||||
return true;
|
||||
if(!s.equalsIgnoreCase(permissionNameLocationBackground) && !s.equalsIgnoreCase(permissionNameLocationFine) && !s.equalsIgnoreCase(permissionNameLocationCoarse) && Miscellaneous.googleToBlameForLocation(true))
|
||||
if (!havePermission(s, context))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@ -298,7 +299,10 @@ public class ActivityPermissions extends Activity
|
||||
{
|
||||
for (String singlePermission : getPermissionsForRule(rule))
|
||||
if (!havePermission(singlePermission, workingContext))
|
||||
addToArrayListUnique(singlePermission, requiredPermissions);
|
||||
{
|
||||
if(!singlePermission.equalsIgnoreCase(permissionNameLocationBackground) && !singlePermission.equalsIgnoreCase(permissionNameLocationFine) && !singlePermission.equalsIgnoreCase(permissionNameLocationCoarse) && Miscellaneous.googleToBlameForLocation(true))
|
||||
addToArrayListUnique(singlePermission, requiredPermissions);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -977,7 +981,7 @@ public class ActivityPermissions extends Activity
|
||||
and simply disable features while keeping the notification alive. The user may dismiss it anyway.
|
||||
*/
|
||||
|
||||
Miscellaneous.logEvent("w", "Denied permissions", getResources().getString(R.string.theFollowingPermissionsHaveBeenDenied) + Miscellaneous.explode(deniedPermissions), 3);
|
||||
Miscellaneous.logEvent("w", "Denied permissions", getResources().getString(R.string.theFollowingPermissionsHaveBeenDenied) + Miscellaneous.explode(", ", deniedPermissions), 3);
|
||||
// this.finish();
|
||||
}
|
||||
else
|
||||
|
@ -37,9 +37,10 @@ public class AutomationService extends Service implements OnInitListener
|
||||
protected TextToSpeech ttsEngine = null;
|
||||
protected final static int notificationId = 1000;
|
||||
protected final static int notificationIdRestrictions = 1005;
|
||||
protected final static int notificationIdLocationRestriction = 1006;
|
||||
|
||||
final static String NOTIFICATION_CHANNEL_ID = "com.jens.automation2";
|
||||
final static String channelName = "Automation notifications";
|
||||
final static String channelName = "Service notification";
|
||||
|
||||
protected static Notification myNotification;
|
||||
protected static NotificationCompat.Builder notificationBuilder = null;
|
||||
@ -154,7 +155,8 @@ public class AutomationService extends Service implements OnInitListener
|
||||
{
|
||||
Miscellaneous.logEvent("w", "AutoStart", "Service is started via boot. Settingsfile not available because storage is not mounted, yet. Waiting for 3 seconds.", 4);
|
||||
Thread.sleep(3000);
|
||||
} catch (InterruptedException e)
|
||||
}
|
||||
catch (InterruptedException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
@ -169,15 +171,13 @@ public class AutomationService extends Service implements OnInitListener
|
||||
}
|
||||
|
||||
//if still no POIs...
|
||||
if (//PointOfInterest.getPointOfInterestCollection() == null | PointOfInterest.getPointOfInterestCollection().size() == 0
|
||||
// &&
|
||||
Rule.getRuleCollection() == null | Rule.getRuleCollection().size() == 0
|
||||
)
|
||||
if (Rule.getRuleCollection() == null | Rule.getRuleCollection().size() == 0)
|
||||
{
|
||||
Miscellaneous.logEvent("w", "AutomationService", context.getResources().getString(R.string.serviceWontStart), 1);
|
||||
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStart), Toast.LENGTH_LONG).show();
|
||||
return false;
|
||||
} else
|
||||
}
|
||||
else
|
||||
{
|
||||
return true;
|
||||
}
|
||||
@ -318,6 +318,7 @@ public class AutomationService extends Service implements OnInitListener
|
||||
checkForTtsEngine();
|
||||
checkForPermissions();
|
||||
checkForRestrictedFeatures();
|
||||
checkForMissingBackgroundLocationPermission();
|
||||
|
||||
Actions.context = this;
|
||||
Actions.autoMationServerRef = this;
|
||||
@ -365,7 +366,10 @@ public class AutomationService extends Service implements OnInitListener
|
||||
|
||||
Intent intent = new Intent(AutomationService.this, ActivityPermissions.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.appRunningInLimitedMode), ActivityPermissions.notificationIdPermissions, pi);
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(1010, getResources().getString(R.string.featuresDisabled), ActivityPermissions.notificationIdPermissions, pi);
|
||||
else
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), ActivityPermissions.notificationIdPermissions, pi);
|
||||
}
|
||||
// else
|
||||
// Toast.makeText(Miscellaneous.getAnyContext(), "Have all required permissions.", Toast.LENGTH_LONG).show();
|
||||
@ -385,11 +389,45 @@ public class AutomationService extends Service implements OnInitListener
|
||||
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
// Miscellaneous.createDismissableNotification(getResources().getString(R.string.settingsReferringToRestrictedFeatures), ActivityPermissions.notificationIdPermissions, pi);
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.settingsReferringToRestrictedFeatures), notificationIdRestrictions, pi);
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(3300, getResources().getString(R.string.featuresDisabled), notificationIdRestrictions, pi);
|
||||
else
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), notificationIdRestrictions, pi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected void checkForMissingBackgroundLocationPermission()
|
||||
{
|
||||
if(Miscellaneous.googleToBlameForLocation(true))
|
||||
{
|
||||
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(2200, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
else
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
}
|
||||
|
||||
/*
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
{
|
||||
if (BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
|
||||
{
|
||||
if (Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest))
|
||||
{
|
||||
Intent intent = new Intent(AutomationService.this, ActivityMainTabLayout.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(AutomationService.this, 0, intent, 0);
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1)
|
||||
Miscellaneous.createDismissableNotificationWithDelay(2200, getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
else
|
||||
Miscellaneous.createDismissableNotification(getResources().getString(R.string.featuresDisabled), notificationIdLocationRestriction, pi);
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
public static void startAutomationService(Context context, boolean startAtBoot)
|
||||
{
|
||||
if(!(isMyServiceRunning(context)))
|
||||
|
@ -14,6 +14,7 @@ import android.content.pm.PackageInfo;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.AsyncTask;
|
||||
import android.os.Build;
|
||||
import android.os.Environment;
|
||||
import android.os.IBinder;
|
||||
@ -21,9 +22,6 @@ import android.provider.MediaStore;
|
||||
import android.provider.Settings.Secure;
|
||||
import android.util.Base64;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import com.jens.automation2.location.LocationProvider;
|
||||
import com.jens.automation2.receivers.PhoneStatusListener;
|
||||
@ -47,11 +45,14 @@ import org.xml.sax.SAXException;
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.io.OutputStream;
|
||||
import java.io.StringReader;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
@ -81,6 +82,8 @@ import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
|
||||
import androidx.core.app.NotificationCompat;
|
||||
|
||||
import static com.jens.automation2.AutomationService.NOTIFICATION_CHANNEL_ID;
|
||||
import static com.jens.automation2.AutomationService.channelName;
|
||||
|
||||
@ -340,8 +343,8 @@ public class Miscellaneous extends Service
|
||||
|
||||
for (String f : foldersToTestArray)
|
||||
{
|
||||
if (testFolder(f))
|
||||
{
|
||||
// if (testFolder(f))
|
||||
// {
|
||||
String pathToUse = f + "/" + Settings.folderName;
|
||||
|
||||
// Toast.makeText(getAnyContext(), "Using " + pathToUse + " to store settings and log.", Toast.LENGTH_LONG).show();
|
||||
@ -353,14 +356,24 @@ public class Miscellaneous extends Service
|
||||
{
|
||||
Miscellaneous.logEvent("i", "Path", "Found old path " + pathToUse + " for settings and logs. Migrating old files to new directory.", 2);
|
||||
|
||||
for (File moveFile : oldDirectory.listFiles())
|
||||
moveFile.renameTo(newDirectory);
|
||||
for (File fileToBeMoved : oldDirectory.listFiles())
|
||||
{
|
||||
File dstFile = new File(writeableFolderStringCache + "/" + fileToBeMoved.getName());
|
||||
|
||||
/*
|
||||
For some stupid reason Android's file.moveTo can't move files between
|
||||
mount points. That's why we have to copy it and delete the src if successful.
|
||||
*/
|
||||
|
||||
if(copyFileUsingStream(fileToBeMoved, dstFile))
|
||||
fileToBeMoved.delete();
|
||||
}
|
||||
|
||||
String message = String.format(Miscellaneous.getAnyContext().getResources().getString(R.string.filesHaveBeenMovedTo), newDirectory.getAbsolutePath());
|
||||
Miscellaneous.writeStringToFile(oldDirectory.getAbsolutePath() + "readme.txt", message);
|
||||
Miscellaneous.writeStringToFile(oldDirectory.getAbsolutePath() + "/readme.txt", message);
|
||||
break migration;
|
||||
}
|
||||
}
|
||||
// }
|
||||
}
|
||||
} catch (Exception e)
|
||||
{
|
||||
@ -754,10 +767,63 @@ public class Miscellaneous extends Service
|
||||
return allHostsValid;
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void createDismissableNotificationWithDelay(long delay, String textToDisplay, int notificationId, PendingIntent pendingIntent)
|
||||
{
|
||||
/*
|
||||
Now what's this about?
|
||||
From SDK 27 onwards you can only fire 1 notification per second:
|
||||
https://developer.android.com/about/versions/oreo/android-8.1?hl=bn#notify
|
||||
|
||||
There are some situations where the service is just being started - resulting in a notification. But we have
|
||||
additional need to inform the user about something and want to create another notification. That's why we have
|
||||
to delay it for a moment, but don't want to hold off the main threat.
|
||||
*/
|
||||
|
||||
class AsyncTaskCreateNotification extends AsyncTask<Void, Void, Void>
|
||||
{
|
||||
@Override
|
||||
protected Void doInBackground(Void... voids)
|
||||
{
|
||||
setDefaultBehaviour(this);
|
||||
|
||||
try
|
||||
{
|
||||
Thread.sleep(delay);
|
||||
}
|
||||
catch(Exception e)
|
||||
{}
|
||||
|
||||
createDismissableNotification(textToDisplay, notificationId, pendingIntent);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
AsyncTaskCreateNotification astCn = new AsyncTaskCreateNotification();
|
||||
astCn.execute(null, null);
|
||||
}
|
||||
|
||||
private static void setDefaultBehaviour(AsyncTask asyncTask)
|
||||
{
|
||||
// without this line debugger will - for some reason - skip all breakpoints in this class
|
||||
if(android.os.Debug.isDebuggerConnected())
|
||||
android.os.Debug.waitForDebugger();
|
||||
|
||||
// Thread.setDefaultUncaughtExceptionHandler(Miscellaneous.getUncaughtExceptionHandler(activityMainRef, true));
|
||||
}
|
||||
|
||||
@SuppressLint("NewApi")
|
||||
@SuppressWarnings("deprecation")
|
||||
public static void createDismissableNotification(String textToDisplay, int notificationId, PendingIntent pendingIntent)
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
createDismissableNotificationSdk26(textToDisplay, notificationId, pendingIntent);
|
||||
return;
|
||||
}
|
||||
|
||||
NotificationManager mNotificationManager = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
NotificationCompat.Builder dismissableNotificationBuilder = createDismissableNotificationBuilder(pendingIntent);
|
||||
@ -769,50 +835,78 @@ public class Miscellaneous extends Service
|
||||
|
||||
mNotificationManager.notify(notificationId, dismissableNotification);
|
||||
|
||||
/*NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_launcher) // notification icon
|
||||
.setContentTitle("Notification!") // title for notification
|
||||
.setContentText("Hello word") // message for notification
|
||||
.setAutoCancel(true); // clear notification after click
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(this,0,intent,Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
mBuilder.setContentIntent(pi);
|
||||
NotificationManager mNotificationManager =
|
||||
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNotificationManager.notify(0, dismissableNotification);*/
|
||||
/*NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this)
|
||||
.setSmallIcon(R.drawable.ic_launcher) // notification icon
|
||||
.setContentTitle("Notification!") // title for notification
|
||||
.setContentText("Hello word") // message for notification
|
||||
.setAutoCancel(true); // clear notification after click
|
||||
Intent intent = new Intent(this, MainActivity.class);
|
||||
PendingIntent pi = PendingIntent.getActivity(this,0,intent,Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
mBuilder.setContentIntent(pi);
|
||||
NotificationManager mNotificationManager =
|
||||
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
mNotificationManager.notify(0, dismissableNotification);*/
|
||||
}
|
||||
|
||||
/*protected static Notification.Builder createDismissableNotificationBuilder()
|
||||
public static void createDismissableNotificationSdk26(String textToDisplay, int notificationId, PendingIntent pendingIntent)
|
||||
{
|
||||
Notification.Builder builder = new Notification.Builder(AutomationService.getInstance());
|
||||
builder.setContentTitle("Automation");
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
builder.setCategory(Notification.CATEGORY_EVENT);
|
||||
NotificationManager mNotificationManager = (NotificationManager) AutomationService.getInstance().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
|
||||
NotificationCompat.Builder builder;
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "Functionality warnings", NotificationManager.IMPORTANCE_HIGH);
|
||||
// chan.setLightColor(Color.BLUE);
|
||||
chan.enableVibration(false);
|
||||
// chan.setSound(null, null);
|
||||
chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
|
||||
mNotificationManager.createNotificationChannel(chan);
|
||||
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance(), NOTIFICATION_CHANNEL_ID);
|
||||
}
|
||||
else
|
||||
builder = new NotificationCompat.Builder(AutomationService.getInstance());
|
||||
|
||||
// if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||
// builder.setCategory(Notification.CATEGORY_SERVICE);
|
||||
|
||||
builder.setWhen(System.currentTimeMillis());
|
||||
builder.setContentIntent(pendingIntent);
|
||||
|
||||
//static PendingIntent myPendingIntent = PendingIntent.getActivity(this, 0, myIntent, 0);
|
||||
builder.setContentTitle(AutomationService.getInstance().getResources().getString(R.string.app_name));
|
||||
builder.setOnlyAlertOnce(true);
|
||||
|
||||
//builder.setContentIntent(myPendingIntent);
|
||||
if(Settings.showIconWhenServiceIsRunning)
|
||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||
|
||||
// Notification defaultNotification = new Notification();
|
||||
*//* Notification defaultNotification = builder.build();
|
||||
builder.setContentText(textToDisplay);
|
||||
builder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
|
||||
|
||||
defaultNotification.icon = R.drawable.ic_launcher;
|
||||
defaultNotification.when = System.currentTimeMillis();
|
||||
NotificationManager notificationManager = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
notificationManager.notify(1, builder.build());
|
||||
|
||||
// defaultNotification.defaults |= Notification.DEFAULT_VIBRATE;
|
||||
// defaultNotification.defaults |= Notification.DEFAULT_LIGHTS;
|
||||
|
||||
defaultNotification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||
// defaultNotification.flags |= Notification.FLAG_SHOW_LIGHTS;
|
||||
defaultNotification.flags |= Notification.FLAG_ONLY_ALERT_ONCE;
|
||||
|
||||
// defaultNotification.ledARGB = Color.YELLOW;
|
||||
// defaultNotification.ledOnMS = 1500;
|
||||
// defaultNotification.ledOffMS = 1500;
|
||||
*//*
|
||||
return builder;
|
||||
}*/
|
||||
// Intent notifyIntent = new Intent(context, notification.class);
|
||||
// notifyIntent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
|
||||
//
|
||||
// pendingIntent.getIntentSender().g
|
||||
//
|
||||
// PendingIntent pendingIntent = PendingIntent.getActivities(context, 0,
|
||||
// new Intent[]{notifyIntent}, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
//
|
||||
// Notification notification = new Notification.Builder(Miscellaneous.getAnyContext())
|
||||
// .setSmallIcon(android.R.drawable.ic_dialog_info)
|
||||
// .setContentTitle("Automation")
|
||||
// .setContentText(textToDisplay)
|
||||
// .setAutoCancel(true)
|
||||
// .setContentIntent(pendingIntent)
|
||||
// .build();
|
||||
// notification.defaults |= Notification.DEFAULT_SOUND;
|
||||
// NotificationManager notificationManager =
|
||||
// (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||
// notificationManager.notify(1, notification);
|
||||
}
|
||||
|
||||
protected static NotificationCompat.Builder createDismissableNotificationBuilder(PendingIntent myPendingIntent)
|
||||
{
|
||||
@ -822,7 +916,7 @@ public class Miscellaneous extends Service
|
||||
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||
{
|
||||
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_LOW);
|
||||
NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH);
|
||||
// chan.setLightColor(Color.BLUE);
|
||||
// chan.enableVibration(false);
|
||||
// chan.setSound(null, null);
|
||||
@ -852,13 +946,21 @@ public class Miscellaneous extends Service
|
||||
return builder;
|
||||
}
|
||||
|
||||
public static String explode(ArrayList<String> arrayList)
|
||||
public static String explode(String glue, ArrayList<String> arrayList)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for(String s : arrayList)
|
||||
builder.append(s);
|
||||
if(arrayList != null)
|
||||
{
|
||||
StringBuilder builder = new StringBuilder();
|
||||
for (String s : arrayList)
|
||||
builder.append(s + glue);
|
||||
|
||||
return builder.toString();
|
||||
if (builder.length() > 0)
|
||||
builder.delete(builder.length() - glue.length(), builder.length());
|
||||
|
||||
return builder.toString();
|
||||
}
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
public static boolean isGooglePlayInstalled(Context context)
|
||||
@ -1056,4 +1158,53 @@ public class Miscellaneous extends Service
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean copyFileUsingStream(File source, File dest) throws IOException
|
||||
{
|
||||
boolean returnValue = false;
|
||||
|
||||
InputStream is = null;
|
||||
OutputStream os = null;
|
||||
try
|
||||
{
|
||||
is = new FileInputStream(source);
|
||||
os = new FileOutputStream(dest);
|
||||
byte[] buffer = new byte[1024];
|
||||
int length;
|
||||
while ((length = is.read(buffer)) > 0)
|
||||
{
|
||||
os.write(buffer, 0, length);
|
||||
}
|
||||
|
||||
returnValue = true;
|
||||
}
|
||||
finally
|
||||
{
|
||||
is.close();
|
||||
os.close();
|
||||
}
|
||||
|
||||
return returnValue;
|
||||
}
|
||||
|
||||
public static boolean googleToBlameForLocation(boolean checkExistingRules)
|
||||
{
|
||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||
{
|
||||
if (BuildConfig.FLAVOR.equalsIgnoreCase("googlePlayFlavor"))
|
||||
{
|
||||
if(checkExistingRules)
|
||||
{
|
||||
if (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.pointOfInterest))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -256,7 +256,18 @@ public class News
|
||||
@Override
|
||||
protected void onPostExecute(ArrayList arrayList)
|
||||
{
|
||||
ActivityMainScreen.getActivityMainScreenInstance().processNewsResult(arrayList);
|
||||
try
|
||||
{
|
||||
ActivityMainScreen.getActivityMainScreenInstance().processNewsResult(arrayList);
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "NewsDownload", "There was a problem displaying the already downloded news, probably ActivityMainScreen isn't currently shown: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "NewsDownload", "There was a problem displaying the already downloded news: " + Log.getStackTraceString(e), 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -145,7 +145,10 @@ public class ReceiverCoordinator
|
||||
|
||||
// startCellLocationChangedReceiver
|
||||
if(!ConnectivityReceiver.isAirplaneMode(AutomationService.getInstance()) && WifiBroadcastReceiver.mayCellLocationReceiverBeActivated() && (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.pointOfInterest) | Rule.isAnyRuleUsing(Trigger.Trigger_Enum.speed)))
|
||||
CellLocationChangedReceiver.startCellLocationChangedReceiver();
|
||||
{
|
||||
if(!Miscellaneous.googleToBlameForLocation(true))
|
||||
CellLocationChangedReceiver.startCellLocationChangedReceiver();
|
||||
}
|
||||
|
||||
// startBatteryReceiver
|
||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.charging) | Rule.isAnyRuleUsing(Trigger.Trigger_Enum.usb_host_connection) | Rule.isAnyRuleUsing(Trigger.Trigger_Enum.batteryLevel))
|
||||
|
@ -5,6 +5,7 @@ import android.content.SharedPreferences;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.util.Log;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@ -16,6 +17,8 @@ public class Settings implements SharedPreferences
|
||||
public static final int newsDisplayForXDays = 3;
|
||||
public static final String folderName = "Automation";
|
||||
|
||||
public static final String constNewsOptInDone ="newsOptInDone";
|
||||
|
||||
public static long minimumDistanceChangeForGpsUpdate;
|
||||
public static long minimumDistanceChangeForNetworkUpdate;
|
||||
public static long satisfactoryAccuracyGps;
|
||||
@ -62,6 +65,8 @@ public class Settings implements SharedPreferences
|
||||
public static boolean noticeAndroid10WifiShown;
|
||||
public static long lastNewsPolltime;
|
||||
|
||||
public static ArrayList<String> whatHasBeenDone;
|
||||
|
||||
/*
|
||||
Generic settings valid for all installations and not changable
|
||||
*/
|
||||
@ -250,6 +255,16 @@ public class Settings implements SharedPreferences
|
||||
noticeAndroid10WifiShown = prefs.getBoolean("noticeAndroid10WifiShown", false);
|
||||
|
||||
lastNewsPolltime = prefs.getLong("lastNewsPolltime", default_lastNewsPolltime);
|
||||
|
||||
String whbdString = prefs.getString("whatHasBeenDone", "");
|
||||
if(whbdString != null && whbdString.length() > 0)
|
||||
{
|
||||
whatHasBeenDone = new ArrayList<>();
|
||||
for(String s : whbdString.split(";"))
|
||||
{
|
||||
whatHasBeenDone.add(s);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
@ -261,6 +276,26 @@ public class Settings implements SharedPreferences
|
||||
initializeSettings(context, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void considerDone(String key)
|
||||
{
|
||||
if(whatHasBeenDone == null)
|
||||
whatHasBeenDone = new ArrayList<>();
|
||||
|
||||
if(!whatHasBeenDone.contains(key))
|
||||
whatHasBeenDone.add(key);
|
||||
}
|
||||
|
||||
public static boolean hasBeenDone(String key)
|
||||
{
|
||||
if(whatHasBeenDone != null)
|
||||
{
|
||||
if(whatHasBeenDone.contains(key))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**Makes sure a settings has a valid setting. If not it will assign a reasonable default setting to it.
|
||||
* If force settings will be initialized even if the user has set something.**/
|
||||
@ -410,6 +445,9 @@ public class Settings implements SharedPreferences
|
||||
|
||||
if(!prefs.contains("lastNewsPolltime") | force)
|
||||
editor.putLong("lastNewsPolltime", default_lastNewsPolltime);
|
||||
|
||||
if(!prefs.contains("whatHasBeenDone") | force)
|
||||
editor.putString("whatHasBeenDone", "");
|
||||
|
||||
editor.commit();
|
||||
|
||||
@ -480,6 +518,8 @@ public class Settings implements SharedPreferences
|
||||
|
||||
editor.putLong("lastNewsPolltime", lastNewsPolltime);
|
||||
|
||||
editor.putString("whatHasBeenDone", Miscellaneous.explode(";", whatHasBeenDone));
|
||||
|
||||
if(lastActivePoi == null)
|
||||
editor.putString("lastActivePoi", "null");
|
||||
else
|
||||
|
@ -114,7 +114,14 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
|
||||
myLocationManager = (LocationManager) AutomationService.getInstance().getSystemService(Context.LOCATION_SERVICE);
|
||||
currentLocation = getLocation("coarse");
|
||||
AutomationService.getInstance().getLocationProvider().setCurrentLocation(currentLocation, false);
|
||||
try
|
||||
{
|
||||
AutomationService.getInstance().getLocationProvider().setCurrentLocation(currentLocation, false);
|
||||
}
|
||||
catch(NullPointerException e)
|
||||
{
|
||||
Miscellaneous.logEvent("e", "LocationProvider", "Location provider is null: " + Log.getStackTraceString(e), 1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -123,7 +130,6 @@ public class CellLocationChangedReceiver extends PhoneStateListener
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Location getLocation(String accuracy)
|
||||
{
|
||||
Criteria crit = new Criteria();
|
||||
|
40
app/src/main/res/layout/activity_display_long_message.xml
Normal file
40
app/src/main/res/layout/activity_display_long_message.xml
Normal file
@ -0,0 +1,40 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_margin="@dimen/default_margin">
|
||||
|
||||
<ScrollView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMessageTitle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="30dp" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvLongMessage"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="20dp"
|
||||
android:layout_marginTop="@dimen/default_margin" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMessageLink"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textSize="20dp"
|
||||
android:layout_marginTop="@dimen/default_margin" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
</ScrollView>
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
@ -27,7 +27,7 @@
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMainScreenNote1"
|
||||
android:id="@+id/tvMainScreenNotePermissions"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
@ -40,7 +40,7 @@
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMainScreenNote2"
|
||||
android:id="@+id/tvMainScreenNoteFeaturesFromOtherFlavor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
@ -53,7 +53,20 @@
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMainScreenNote3"
|
||||
android:id="@+id/tvMainScreenNoteLocationImpossibleBlameGoogle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
android:layout_marginLeft="10dp"
|
||||
android:layout_marginRight="10dp"
|
||||
android:scrollHorizontally="false"
|
||||
android:textColor="@color/importantMessage"
|
||||
android:singleLine="false"
|
||||
android:visibility="gone"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvMainScreenNoteNews"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center"
|
||||
@ -355,6 +368,14 @@
|
||||
android:text="@string/defaultSettings" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvFileStoreLocation"
|
||||
android:layout_marginVertical="@dimen/default_margin"
|
||||
android:layout_gravity="center_horizontal"
|
||||
android:gravity="center_horizontal"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
|
@ -526,7 +526,7 @@
|
||||
<string name="continueText">Fortfahren</string>
|
||||
<string name="rule">Regel</string>
|
||||
<string name="storeSettings">Einstellungen lesen und speichern</string>
|
||||
<string name="appRunningInLimitedMode">Die Anwendung läuft in einem eingeschränkten Modus, weil nicht alle benötigen Rechte genehmigt wurden.</string>
|
||||
<string name="featuresDisabled">WARNING: Funktionen wurden deaktiviert, Automation läuft in einem eingeschränkten Modus. Klicken Sie hier für mehr Informationen.</string>
|
||||
<string name="ruleLegend">Grün = aktiviert, rot = deaktiviert, gelb = nicht genügend Rechte</string>
|
||||
<string name="systemSettingsNote1">Die Berechtigung Betriebssystemeinstellungen ändern zu können, wird benötigt (auch für einfache Dinge wie Bluetooth oder WLAN einschalten). Nach dem Klick auf "Fortfahren" öffnet sich ein Fenster, in dem Sie das für Automation aktivieren müssen. Drücken Sie dann auf Ihren "Zurück" Knopf.</string>
|
||||
<string name="systemSettingsNote2">Anschließend werden in einem zweiten Dialog weitere Berechtigungen angefragt.</string>
|
||||
@ -594,4 +594,8 @@
|
||||
<string name="deviceDoesNotHaveBluetooth">Dieses Gerät scheint kein Bluetooth zu haben. Sie können mit der Konfiguration fortfahren, aber es wird vermutlich keinen Effekt haben.</string>
|
||||
<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="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</string>
|
||||
</resources>
|
@ -523,7 +523,7 @@
|
||||
<string name="continueText">continue</string>
|
||||
<string name="rule">Rule</string>
|
||||
<string name="storeSettings">Read and store settings</string>
|
||||
<string name="appRunningInLimitedMode">The app is running in limited mode because of lacking permissions.</string>
|
||||
<string name="featuresDisabled">: Features are disabled, Automation is running in limited mode. Click here for more information.</string>
|
||||
<string name="ruleLegend">Green = enabled, red = disabled, yellow = not enough permissions</string>
|
||||
<string name="systemSettingsNote1">The permission to change some OS settings is required (even simple stuff like turn on bluetooth or wifi). After clicking "continue" a window will popup where you need to enable this for Automation. Then hit your "back" key.</string>
|
||||
<string name="systemSettingsNote2">Further permissions will be requested in a second dialog afterwards.</string>
|
||||
|
@ -82,7 +82,7 @@
|
||||
<string name="anyNumber">qualsiasi numero</string>
|
||||
<string name="anyWifi">qualsiasi wifi</string>
|
||||
<string name="appRequiresPermissiontoAccessExternalStorage">Automation richiede l’autorizzazione per archiviare e leggere le impostazioni e le regole.</string>
|
||||
<string name="appRunningInLimitedMode">L\'applicazione è in esecuzione in modalità limitata a causa di autorizzazioni mancanti.</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>
|
||||
|
@ -527,7 +527,7 @@
|
||||
<string name="continueText">continue</string>
|
||||
<string name="rule">Rule</string>
|
||||
<string name="storeSettings">Read and store settings</string>
|
||||
<string name="appRunningInLimitedMode">The app is running in limited mode because of lacking permissions.</string>
|
||||
<string name="featuresDisabled">WARNING: Features are disabled, Automation is running in limited mode. Click here for more information.</string>
|
||||
<string name="ruleLegend">Green = enabled, red = disabled, yellow = not enough permissions</string>
|
||||
<string name="systemSettingsNote1">The permission to change some OS settings is required (even simple stuff like turn on bluetooth or wifi). After clicking "continue" a window will popup where you need to enable this for Automation. Then hit your "back" key.</string>
|
||||
<string name="systemSettingsNote2">Further permissions will be requested in a second dialog afterwards.</string>
|
||||
@ -605,5 +605,10 @@
|
||||
<string name="publishedOn">published on</string>
|
||||
<string name="displayNewsOnMainScreen">Display application news on main screen</string>
|
||||
<string name="displayNewsOnMainScreenDescription">Announcements about this app only, we\'re probably talking about 1-2 per year, not more.</string>
|
||||
<string name="filesHaveBeenMovedTo">Automation now uses another path to store your files. The existing ones have been moved. You can find them here: %s.</string>
|
||||
<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="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 are 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 these 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</string>
|
||||
</resources>
|
2
fastlane/metadata/android/en-US/changelogs/99.txt
Normal file
2
fastlane/metadata/android/en-US/changelogs/99.txt
Normal file
@ -0,0 +1,2 @@
|
||||
Place to storage config files has been moved to regular location (program specific directory in Android/data).
|
||||
If you had previously used to app your existing files are moved to this new location. If that was successful the permission android.permission.WRITE_EXTERNAL_STORAGE is no longer required.
|
@ -35,4 +35,53 @@ Supported actions:
|
||||
* Speak text
|
||||
* Open music player
|
||||
* Change screen brightness
|
||||
* Send text message
|
||||
* Send text message
|
||||
|
||||
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 reported to me. But for that I'm dependend on your input.
|
||||
|
||||
A word about the many permissions....
|
||||
|
||||
It lies in the nature of this type of application that it requires a lot of permissions. However most of them are entirely optional and are not requested unless one of the rules you created needs it.
|
||||
|
||||
Let's go through them quickly:
|
||||
ACCESS_NETWORK_STATE, CHANGE_NETWORK_STATE: Check or change things like airplane mode, roaming.
|
||||
|
||||
ACCESS_WIFI_STATE, CHANGE_WIFI_STATE: Turn wifi on or off
|
||||
|
||||
INTERNET
|
||||
That's required for any of these 3 reasons:
|
||||
- You are using a locationing method that utilizes CellTowers (default setting)
|
||||
- You are using triggerUrl as action
|
||||
- You activate downloading news in settings
|
||||
|
||||
BLUETOOTH, BLUETOOTH_ADMIN: Check bluetooth connections or toggle BT on or off.
|
||||
|
||||
NFC: Use NFC tags if you created a rule that uses that.
|
||||
|
||||
Location (ACCESS_COARSE_LOCATION, ACCESS_FINE_LOCATION, ACCESS_BACKGROUND_LOCATION): This should be self-explanatory - are you using a rule with locations or speed as trigger?
|
||||
|
||||
PROCESS_OUTGOING_CALLS: You can use current calls as trigger. E.g. if wife calls....
|
||||
|
||||
SEND_SMS: You can have SMS sent as action. If you choose to do so you can enter the destination number manually or optionally pick one of your contacts which brings us to READ_CONTACTS
|
||||
|
||||
READ_EXTERNAL_STORAGE, WRITE_EXTERNAL_STORAGE: If you initially installed the app after March 2021 this is not required. In the past the app used to store its config file on the regular storage like "sdcard". The permission is still in there to ensure the app is also still working for legacy users. There the app will migrate the files to the new location.
|
||||
|
||||
GET_TASKS: For trigger "check if another app is running"
|
||||
|
||||
BATTERY_STATS: Check battery level as trigger
|
||||
|
||||
MODIFY_AUDIO_SETTINGS, ACCESS_NOTIFICATION_POLICY:
|
||||
From higher versions on this is required to be able to change, e.g. the ringtone or generally the sound settings.
|
||||
https://stackoverflow.com/questions/43123650/android-request-access-notification-policy-and-mute-phone/43127589#43127589
|
||||
ACCESS_NOTIFICATION_POLICY is also included to prepare for a new trigger - to use notifications of other applications as trigger. But this feature has not been implemented, yet.
|
||||
|
||||
RECORD_AUDIO: For trigger "check background noise". Btw - my use case for this is: My phone will turn on sounds in the morning. During the week that is quite early. But what if I have a day off? Then it will monitor the background noise as an additional condition. If there's noise it's fairly certain I'm actually awake. Unfortunately Google deactivated this feature with Android 8.
|
||||
|
||||
READ_PHONE_STATE: https://developer.android.com/reference/android/Manifest.permission#READ_PHONE_STATE
|
||||
|
||||
RECEIVE_BOOT_COMPLETED, FOREGROUND_SERVICE, WAKE_LOCK: Start the service automatically and keep it running
|
||||
|
||||
WRITE_SETTINGS: Change system settings
|
||||
|
||||
ACCESS_SUPERUSER: root is entirely optional. In the (far) past it used be possible to activate/deactivate USB tethering with regular API calls. But a long time ago this started to be possible using root only. So long story short: It's only necessary for some specific features.
|
Reference in New Issue
Block a user