Minor fixes
This commit is contained in:
+1
-1
@@ -11,7 +11,7 @@ android {
|
|||||||
compileSdkVersion 36
|
compileSdkVersion 36
|
||||||
buildToolsVersion '36.0.0'
|
buildToolsVersion '36.0.0'
|
||||||
useLibrary 'org.apache.http.legacy'
|
useLibrary 'org.apache.http.legacy'
|
||||||
versionCode 149
|
versionCode 150
|
||||||
versionName "1.8.8"
|
versionName "1.8.8"
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
|
|||||||
+5
-1
@@ -403,7 +403,11 @@ public class ActivityDetectionReceiver extends IntentService implements Automati
|
|||||||
private PendingIntent getActivityDetectionPendingIntent()
|
private PendingIntent getActivityDetectionPendingIntent()
|
||||||
{
|
{
|
||||||
Intent intent = new Intent(AutomationService.getInstance(), ActivityDetectionReceiver.class);
|
Intent intent = new Intent(AutomationService.getInstance(), ActivityDetectionReceiver.class);
|
||||||
PendingIntent returnValue = PendingIntent.getService(AutomationService.getInstance(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
PendingIntent returnValue;
|
||||||
|
if(Miscellaneous.getTargetSDK(AutomationService.getInstance()) >= 31)
|
||||||
|
returnValue = PendingIntent.getService(AutomationService.getInstance(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT|PendingIntent.FLAG_IMMUTABLE);
|
||||||
|
else
|
||||||
|
returnValue = PendingIntent.getService(AutomationService.getInstance(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
return returnValue;
|
return returnValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -670,6 +670,8 @@ public class ActivityManageRule extends Activity
|
|||||||
items.add(new Item(typesLong[i].toString(), R.drawable.subsystemstate));
|
items.add(new Item(typesLong[i].toString(), R.drawable.subsystemstate));
|
||||||
else if(types[i].toString().equals(Trigger_Enum.checkVariable.toString()))
|
else if(types[i].toString().equals(Trigger_Enum.checkVariable.toString()))
|
||||||
items.add(new Item(typesLong[i].toString(), R.drawable.variable));
|
items.add(new Item(typesLong[i].toString(), R.drawable.variable));
|
||||||
|
else if(types[i].toString().equals(Trigger_Enum.proximity.toString()))
|
||||||
|
items.add(new Item(typesLong[i].toString(), R.drawable.proximity));
|
||||||
else if(types[i].toString().equals(Trigger_Enum.calendarEvent.toString()))
|
else if(types[i].toString().equals(Trigger_Enum.calendarEvent.toString()))
|
||||||
{
|
{
|
||||||
if(ActivityPermissions.isPermissionDeclaredInManifest(ActivityManageRule.this, Manifest.permission.READ_CALENDAR))
|
if(ActivityPermissions.isPermissionDeclaredInManifest(ActivityManageRule.this, Manifest.permission.READ_CALENDAR))
|
||||||
@@ -753,7 +755,17 @@ public class ActivityManageRule extends Activity
|
|||||||
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
|
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
|
||||||
else if(triggerType == Trigger_Enum.usb_host_connection)
|
else if(triggerType == Trigger_Enum.usb_host_connection)
|
||||||
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
|
booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)};
|
||||||
else if(triggerType == Trigger_Enum.speed || triggerType == Trigger_Enum.noiseLevel || triggerType == Trigger_Enum.batteryLevel)
|
else if(triggerType == Trigger_Enum.speed)
|
||||||
|
{
|
||||||
|
if(Miscellaneous.googleToBlameForLocation(false))
|
||||||
|
{
|
||||||
|
ActivityMainScreen.openGoogleBlamingWindow();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)};
|
||||||
|
}
|
||||||
|
else if(triggerType == Trigger_Enum.noiseLevel || triggerType == Trigger_Enum.batteryLevel)
|
||||||
booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)};
|
booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)};
|
||||||
else if(triggerType == Trigger_Enum.wifiConnection)
|
else if(triggerType == Trigger_Enum.wifiConnection)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -171,10 +171,10 @@ public class Miscellaneous extends Service
|
|||||||
URL urlObject = new URL(url);
|
URL urlObject = new URL(url);
|
||||||
HttpURLConnection connection;
|
HttpURLConnection connection;
|
||||||
|
|
||||||
if(url.toLowerCase().contains("https"))
|
if (url.toLowerCase().contains("https"))
|
||||||
{
|
{
|
||||||
connection = (HttpsURLConnection) urlObject.openConnection();
|
connection = (HttpsURLConnection) urlObject.openConnection();
|
||||||
if(Settings.httpAcceptAllCertificates)
|
if (Settings.httpAcceptAllCertificates)
|
||||||
{
|
{
|
||||||
SSLContext sslContext = SSLContext.getInstance("TLS"); // Use "TLS" (not "SSL" which is outdated)
|
SSLContext sslContext = SSLContext.getInstance("TLS"); // Use "TLS" (not "SSL" which is outdated)
|
||||||
sslContext.init(
|
sslContext.init(
|
||||||
@@ -182,8 +182,8 @@ public class Miscellaneous extends Service
|
|||||||
new TrustManager[]{new TrustAllCertificates()}, // Use our trust manager
|
new TrustManager[]{new TrustAllCertificates()}, // Use our trust manager
|
||||||
new SecureRandom() // Secure random number generator
|
new SecureRandom() // Secure random number generator
|
||||||
);
|
);
|
||||||
((HttpsURLConnection)connection).setSSLSocketFactory(sslContext.getSocketFactory());
|
((HttpsURLConnection) connection).setSSLSocketFactory(sslContext.getSocketFactory());
|
||||||
((HttpsURLConnection)connection).setHostnameVerifier((hostname, session) -> true); // Trust all hostnames
|
((HttpsURLConnection) connection).setHostnameVerifier((hostname, session) -> true); // Trust all hostnames
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -191,17 +191,17 @@ public class Miscellaneous extends Service
|
|||||||
connection = (HttpURLConnection) urlObject.openConnection();
|
connection = (HttpURLConnection) urlObject.openConnection();
|
||||||
|
|
||||||
// Add http simple authentication if specified
|
// Add http simple authentication if specified
|
||||||
if(username != null && password != null)
|
if (username != null && password != null)
|
||||||
{
|
{
|
||||||
String encodedCredentials = Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.DEFAULT);
|
String encodedCredentials = Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.DEFAULT);
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
connection.setDoOutput(true);
|
connection.setDoOutput(true);
|
||||||
connection.setRequestProperty ("Authorization", "Basic " + encodedCredentials);
|
connection.setRequestProperty("Authorization", "Basic " + encodedCredentials);
|
||||||
}
|
}
|
||||||
else if(method.equals(ActivityManageActionTriggerUrl.methodPost))
|
else if (method.equals(ActivityManageActionTriggerUrl.methodPost))
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
|
|
||||||
if(httpParams != null && httpParams.size() > 0)
|
if (httpParams != null && httpParams.size() > 0)
|
||||||
{
|
{
|
||||||
connection.setRequestMethod("POST");
|
connection.setRequestMethod("POST");
|
||||||
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
|
||||||
@@ -210,7 +210,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
List<NameValuePair> paramPairs = new ArrayList<NameValuePair>();
|
List<NameValuePair> paramPairs = new ArrayList<NameValuePair>();
|
||||||
|
|
||||||
for(String key : httpParams.keySet())
|
for (String key : httpParams.keySet())
|
||||||
paramPairs.add(new BasicNameValuePair(key, httpParams.get(key)));
|
paramPairs.add(new BasicNameValuePair(key, httpParams.get(key)));
|
||||||
|
|
||||||
OutputStream os = connection.getOutputStream();
|
OutputStream os = connection.getOutputStream();
|
||||||
@@ -220,13 +220,13 @@ public class Miscellaneous extends Service
|
|||||||
writer.close();
|
writer.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
InputStream content = (InputStream)connection.getInputStream();
|
InputStream content = (InputStream) connection.getInputStream();
|
||||||
BufferedReader in = new BufferedReader (new InputStreamReader (content));
|
BufferedReader in = new BufferedReader(new InputStreamReader(content));
|
||||||
String line;
|
String line;
|
||||||
while ((line = in.readLine()) != null)
|
while ((line = in.readLine()) != null)
|
||||||
responseBody.append(line + Miscellaneous.lineSeparator);
|
responseBody.append(line + Miscellaneous.lineSeparator);
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3);
|
Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3);
|
||||||
errorFound = true;
|
errorFound = true;
|
||||||
@@ -238,7 +238,7 @@ public class Miscellaneous extends Service
|
|||||||
// shut down the connection manager to ensure
|
// shut down the connection manager to ensure
|
||||||
// immediate deallocation of all system resources
|
// immediate deallocation of all system resources
|
||||||
httpclient.getConnectionManager().shutdown();
|
httpclient.getConnectionManager().shutdown();
|
||||||
if(errorFound)
|
if (errorFound)
|
||||||
return http_error_string;
|
return http_error_string;
|
||||||
else
|
else
|
||||||
return responseBody.toString();
|
return responseBody.toString();
|
||||||
@@ -307,7 +307,7 @@ public class Miscellaneous extends Service
|
|||||||
httpclient = Actions.getInsecureSslClient(httpclient);
|
httpclient = Actions.getInsecureSslClient(httpclient);
|
||||||
|
|
||||||
HttpRequestBase httpRequest;
|
HttpRequestBase httpRequest;
|
||||||
if(
|
if (
|
||||||
method.equals(ActivityManageActionTriggerUrl.methodPost)
|
method.equals(ActivityManageActionTriggerUrl.methodPost)
|
||||||
||
|
||
|
||||||
(username != null && password != null)
|
(username != null && password != null)
|
||||||
@@ -319,20 +319,20 @@ public class Miscellaneous extends Service
|
|||||||
httpRequest = new HttpGet(url);
|
httpRequest = new HttpGet(url);
|
||||||
|
|
||||||
// Add http simple authentication if specified
|
// Add http simple authentication if specified
|
||||||
if(username != null && password != null)
|
if (username != null && password != null)
|
||||||
{
|
{
|
||||||
String encodedCredentials = Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.DEFAULT);
|
String encodedCredentials = Base64.encodeToString(new String(username + ":" + password).getBytes(), Base64.DEFAULT);
|
||||||
httpRequest.addHeader("Authorization", "Basic " + encodedCredentials);
|
httpRequest.addHeader("Authorization", "Basic " + encodedCredentials);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(httpParams.size() > 0)
|
if (httpParams.size() > 0)
|
||||||
{
|
{
|
||||||
List<NameValuePair> paramPairs = new ArrayList<NameValuePair>();
|
List<NameValuePair> paramPairs = new ArrayList<NameValuePair>();
|
||||||
|
|
||||||
for(String key : httpParams.keySet())
|
for (String key : httpParams.keySet())
|
||||||
paramPairs.add(new BasicNameValuePair(key, httpParams.get(key)));
|
paramPairs.add(new BasicNameValuePair(key, httpParams.get(key)));
|
||||||
|
|
||||||
((HttpPost)httpRequest).setEntity(new UrlEncodedFormEntity(paramPairs, "UTF-8"));
|
((HttpPost) httpRequest).setEntity(new UrlEncodedFormEntity(paramPairs, "UTF-8"));
|
||||||
}
|
}
|
||||||
|
|
||||||
HttpResponse response = httpclient.execute(httpRequest);
|
HttpResponse response = httpclient.execute(httpRequest);
|
||||||
@@ -343,7 +343,7 @@ public class Miscellaneous extends Service
|
|||||||
return EntityUtils.toString(entity);
|
return EntityUtils.toString(entity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3);
|
Miscellaneous.logEvent("e", "HTTP error", Log.getStackTraceString(e), 3);
|
||||||
return http_error_string;
|
return http_error_string;
|
||||||
@@ -362,7 +362,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static int boolToInt(boolean input)
|
public static int boolToInt(boolean input)
|
||||||
{
|
{
|
||||||
if(input)
|
if (input)
|
||||||
return 1;
|
return 1;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
@@ -380,12 +380,12 @@ public class Miscellaneous extends Service
|
|||||||
{
|
{
|
||||||
header = getAnyContext().getResources().getString(R.string.app_name);
|
header = getAnyContext().getResources().getString(R.string.app_name);
|
||||||
}
|
}
|
||||||
catch(NullPointerException e)
|
catch (NullPointerException e)
|
||||||
{
|
{
|
||||||
header = "Automation";
|
header = "Automation";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Settings.logToConsole)
|
if (Settings.logToConsole)
|
||||||
{
|
{
|
||||||
if (type.equals("e"))
|
if (type.equals("e"))
|
||||||
Log.e(header, description);
|
Log.e(header, description);
|
||||||
@@ -397,7 +397,7 @@ public class Miscellaneous extends Service
|
|||||||
Log.i(header, description);
|
Log.i(header, description);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(Settings.writeLogFile && Settings.logLevel >= logLevel)
|
if (Settings.writeLogFile && Settings.logLevel >= logLevel)
|
||||||
{
|
{
|
||||||
writeToLogFile(type, header, description);
|
writeToLogFile(type, header, description);
|
||||||
|
|
||||||
@@ -409,13 +409,14 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected static boolean logCleanerRunning = false;
|
protected static boolean logCleanerRunning = false;
|
||||||
|
|
||||||
protected static void rotateLogFile(File logFile)
|
protected static void rotateLogFile(File logFile)
|
||||||
{
|
{
|
||||||
logCleanerRunning = true;
|
logCleanerRunning = true;
|
||||||
|
|
||||||
long maxSizeInBytes = (long)Settings.logFileMaxSize * 1024 * 1024;
|
long maxSizeInBytes = (long) Settings.logFileMaxSize * 1024 * 1024;
|
||||||
|
|
||||||
if(logFile.exists() && logFile.length() > (maxSizeInBytes))
|
if (logFile.exists() && logFile.length() > (maxSizeInBytes))
|
||||||
{
|
{
|
||||||
Miscellaneous.logEvent("i", "Logfile", "Cleaning up log file.", 3);
|
Miscellaneous.logEvent("i", "Logfile", "Cleaning up log file.", 3);
|
||||||
File archivedLogFile = new File(getWriteableFolder() + "/" + logFileName + "-old");
|
File archivedLogFile = new File(getWriteableFolder() + "/" + logFileName + "-old");
|
||||||
@@ -433,15 +434,15 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(folder.exists() || folder.mkdirs())
|
if (folder.exists() || folder.mkdirs())
|
||||||
{
|
{
|
||||||
XmlFileInterface.migrateFilesFromRootToFolder(folderPath, folder.getAbsolutePath());
|
XmlFileInterface.migrateFilesFromRootToFolder(folderPath, folder.getAbsolutePath());
|
||||||
|
|
||||||
File testFile = new File(folder + "/" + testFileName);
|
File testFile = new File(folder + "/" + testFileName);
|
||||||
if(!testFile.exists())
|
if (!testFile.exists())
|
||||||
testFile.createNewFile();
|
testFile.createNewFile();
|
||||||
|
|
||||||
if(testFile.canRead() && testFile.canWrite())
|
if (testFile.canRead() && testFile.canWrite())
|
||||||
{
|
{
|
||||||
testFile.delete();
|
testFile.delete();
|
||||||
writeableFolderStringCache = testFile.getParent();
|
writeableFolderStringCache = testFile.getParent();
|
||||||
@@ -461,7 +462,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static String getWriteableFolder()
|
public static String getWriteableFolder()
|
||||||
{
|
{
|
||||||
if(writeableFolderStringCache == null)
|
if (writeableFolderStringCache == null)
|
||||||
{
|
{
|
||||||
// Use the app-specific folder as new default.
|
// Use the app-specific folder as new default.
|
||||||
writeableFolderStringCache = Miscellaneous.getAnyContext().getFilesDir().getAbsolutePath();
|
writeableFolderStringCache = Miscellaneous.getAnyContext().getFilesDir().getAbsolutePath();
|
||||||
@@ -512,7 +513,7 @@ public class Miscellaneous extends Service
|
|||||||
mount points. That's why we have to copy it and delete the src if successful.
|
mount points. That's why we have to copy it and delete the src if successful.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if(copyFileUsingStream(fileToBeMoved, dstFile))
|
if (copyFileUsingStream(fileToBeMoved, dstFile))
|
||||||
fileToBeMoved.delete();
|
fileToBeMoved.delete();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -522,7 +523,8 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
} catch (Exception e)
|
}
|
||||||
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.w("getWritableFolder", folder + " not writable.");
|
Log.w("getWritableFolder", folder + " not writable.");
|
||||||
}
|
}
|
||||||
@@ -534,18 +536,19 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected final static String logFileName = "Automation_logfile.txt";
|
protected final static String logFileName = "Automation_logfile.txt";
|
||||||
|
|
||||||
protected static File getLogFile()
|
protected static File getLogFile()
|
||||||
{
|
{
|
||||||
File logFile = null;
|
File logFile = null;
|
||||||
logFile = new File(getWriteableFolder() + "/" + logFileName);
|
logFile = new File(getWriteableFolder() + "/" + logFileName);
|
||||||
if(!logFile.exists())
|
if (!logFile.exists())
|
||||||
{
|
{
|
||||||
Log.i("LogFile", "Creating new logfile: " + logFile.getAbsolutePath());
|
Log.i("LogFile", "Creating new logfile: " + logFile.getAbsolutePath());
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
logFile.createNewFile();
|
logFile.createNewFile();
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.e("LogFile", "Error writing logs to file: " + e.getMessage());
|
Log.e("LogFile", "Error writing logs to file: " + e.getMessage());
|
||||||
}
|
}
|
||||||
@@ -553,6 +556,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
return logFile;
|
return logFile;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void writeToLogFile(String type, String header, String description)
|
private static void writeToLogFile(String type, String header, String description)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
@@ -566,7 +570,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
// Log.i("LogFile", "Log entry written.");
|
// Log.i("LogFile", "Log entry written.");
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
Log.e("LogFile", "Error writing logs to file: " + e.getMessage());
|
Log.e("LogFile", "Error writing logs to file: " + e.getMessage());
|
||||||
}
|
}
|
||||||
@@ -591,17 +595,17 @@ public class Miscellaneous extends Service
|
|||||||
public static boolean compare(String direction, String needle, String haystack)
|
public static boolean compare(String direction, String needle, String haystack)
|
||||||
{
|
{
|
||||||
// If only one of needle or haystack is null
|
// If only one of needle or haystack is null
|
||||||
if(
|
if (
|
||||||
(needle == null && haystack != null)
|
(needle == null && haystack != null)
|
||||||
||
|
||
|
||||||
(needle != null && haystack == null)
|
(needle != null && haystack == null)
|
||||||
)
|
)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
switch(direction)
|
switch (direction)
|
||||||
{
|
{
|
||||||
case Trigger.directionEquals:
|
case Trigger.directionEquals:
|
||||||
if(Miscellaneous.isRegularExpression(needle))
|
if (Miscellaneous.isRegularExpression(needle))
|
||||||
return haystack.matches(needle);
|
return haystack.matches(needle);
|
||||||
else
|
else
|
||||||
return haystack.equalsIgnoreCase(needle);
|
return haystack.equalsIgnoreCase(needle);
|
||||||
@@ -624,33 +628,33 @@ public class Miscellaneous extends Service
|
|||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "To compare: " + time1.toString() + " / " + time2.toString());
|
// Miscellaneous.logEvent("i", "TimeCompare", "To compare: " + time1.toString() + " / " + time2.toString());
|
||||||
|
|
||||||
if(time1.getHours() == time2.getHours() && time1.getMinutes() == time2.getMinutes())
|
if (time1.getHours() == time2.getHours() && time1.getMinutes() == time2.getMinutes())
|
||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "Times are equal.");
|
// Miscellaneous.logEvent("i", "TimeCompare", "Times are equal.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(time1.getHours() > time2.getHours())
|
if (time1.getHours() > time2.getHours())
|
||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "Time1 is bigger/later by hours.");
|
// Miscellaneous.logEvent("i", "TimeCompare", "Time1 is bigger/later by hours.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(time1.getHours() < time2.getHours())
|
if (time1.getHours() < time2.getHours())
|
||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "Time2 is bigger/later by hours.");
|
// Miscellaneous.logEvent("i", "TimeCompare", "Time2 is bigger/later by hours.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(time1.getHours() == time2.getHours())
|
if (time1.getHours() == time2.getHours())
|
||||||
{
|
{
|
||||||
if(time1.getMinutes() < time2.getMinutes())
|
if (time1.getMinutes() < time2.getMinutes())
|
||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "Hours are equal. Time2 is bigger/later by minutes.");
|
// Miscellaneous.logEvent("i", "TimeCompare", "Hours are equal. Time2 is bigger/later by minutes.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(time1.getMinutes() > time2.getMinutes())
|
if (time1.getMinutes() > time2.getMinutes())
|
||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "Hours are equal. Time1 is bigger/later by minutes.");
|
// Miscellaneous.logEvent("i", "TimeCompare", "Hours are equal. Time1 is bigger/later by minutes.");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -664,33 +668,33 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static int compareTimes(Calendar calOne, Calendar calTwo)
|
public static int compareTimes(Calendar calOne, Calendar calTwo)
|
||||||
{
|
{
|
||||||
if(calOne.get(Calendar.HOUR_OF_DAY) == calTwo.get(Calendar.HOUR_OF_DAY) && calOne.get(Calendar.MINUTE) == calTwo.get((Calendar.MINUTE)))
|
if (calOne.get(Calendar.HOUR_OF_DAY) == calTwo.get(Calendar.HOUR_OF_DAY) && calOne.get(Calendar.MINUTE) == calTwo.get((Calendar.MINUTE)))
|
||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "Times are equal.");
|
// Miscellaneous.logEvent("i", "TimeCompare", "Times are equal.");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(calOne.get(Calendar.HOUR_OF_DAY) > calTwo.get(Calendar.HOUR_OF_DAY))
|
if (calOne.get(Calendar.HOUR_OF_DAY) > calTwo.get(Calendar.HOUR_OF_DAY))
|
||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "Time1 is bigger/later by hours.");
|
// Miscellaneous.logEvent("i", "TimeCompare", "Time1 is bigger/later by hours.");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(calOne.get(Calendar.HOUR_OF_DAY) < calTwo.get(Calendar.HOUR_OF_DAY))
|
if (calOne.get(Calendar.HOUR_OF_DAY) < calTwo.get(Calendar.HOUR_OF_DAY))
|
||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "Time2 is bigger/later by hours.");
|
// Miscellaneous.logEvent("i", "TimeCompare", "Time2 is bigger/later by hours.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(calOne.get(Calendar.HOUR_OF_DAY) == calTwo.get(Calendar.HOUR_OF_DAY))
|
if (calOne.get(Calendar.HOUR_OF_DAY) == calTwo.get(Calendar.HOUR_OF_DAY))
|
||||||
{
|
{
|
||||||
if(calOne.get(Calendar.MINUTE) < calTwo.get(Calendar.MINUTE))
|
if (calOne.get(Calendar.MINUTE) < calTwo.get(Calendar.MINUTE))
|
||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "Hours are equal. Time2 is bigger/later by minutes.");
|
// Miscellaneous.logEvent("i", "TimeCompare", "Hours are equal. Time2 is bigger/later by minutes.");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(calOne.get(Calendar.MINUTE) > calTwo.get(Calendar.MINUTE))
|
if (calOne.get(Calendar.MINUTE) > calTwo.get(Calendar.MINUTE))
|
||||||
{
|
{
|
||||||
// Miscellaneous.logEvent("i", "TimeCompare", "Hours are equal. Time1 is bigger/later by minutes.");
|
// Miscellaneous.logEvent("i", "TimeCompare", "Hours are equal. Time1 is bigger/later by minutes.");
|
||||||
return -1;
|
return -1;
|
||||||
@@ -712,18 +716,18 @@ public class Miscellaneous extends Service
|
|||||||
Context returnContext;
|
Context returnContext;
|
||||||
|
|
||||||
returnContext = AutomationService.getInstance();
|
returnContext = AutomationService.getInstance();
|
||||||
if(returnContext != null)
|
if (returnContext != null)
|
||||||
return returnContext;
|
return returnContext;
|
||||||
|
|
||||||
returnContext = ActivityMainScreen.getActivityMainScreenInstance();
|
returnContext = ActivityMainScreen.getActivityMainScreenInstance();
|
||||||
if(returnContext != null)
|
if (returnContext != null)
|
||||||
return returnContext;
|
return returnContext;
|
||||||
|
|
||||||
returnContext = ActivityPermissions.getInstance().getApplicationContext();
|
returnContext = ActivityPermissions.getInstance().getApplicationContext();
|
||||||
if(returnContext != null)
|
if (returnContext != null)
|
||||||
return returnContext;
|
return returnContext;
|
||||||
|
|
||||||
if(startupContext != null)
|
if (startupContext != null)
|
||||||
return startupContext;
|
return startupContext;
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
@@ -732,7 +736,7 @@ public class Miscellaneous extends Service
|
|||||||
public static boolean isDarkModeEnabled(Context context)
|
public static boolean isDarkModeEnabled(Context context)
|
||||||
{
|
{
|
||||||
int mode = context.getResources().getConfiguration().uiMode;
|
int mode = context.getResources().getConfiguration().uiMode;
|
||||||
switch(mode)
|
switch (mode)
|
||||||
{
|
{
|
||||||
case 33:
|
case 33:
|
||||||
case Configuration.UI_MODE_NIGHT_YES:
|
case Configuration.UI_MODE_NIGHT_YES:
|
||||||
@@ -750,12 +754,12 @@ public class Miscellaneous extends Service
|
|||||||
{
|
{
|
||||||
// Replace variable with actual content
|
// Replace variable with actual content
|
||||||
// Miscellaneous.logEvent("i", "Raw source", source);
|
// Miscellaneous.logEvent("i", "Raw source", source);
|
||||||
if(source.contains("[uniqueid]"))
|
if (source.contains("[uniqueid]"))
|
||||||
source = source.replace("[uniqueid]", Secure.getString(context.getContentResolver(), Secure.ANDROID_ID));
|
source = source.replace("[uniqueid]", Secure.getString(context.getContentResolver(), Secure.ANDROID_ID));
|
||||||
|
|
||||||
if(source.contains("[latitude]") | source.contains("[longitude]"))
|
if (source.contains("[latitude]") | source.contains("[longitude]"))
|
||||||
{
|
{
|
||||||
if(LocationProvider.getLastKnownLocation() != null)
|
if (LocationProvider.getLastKnownLocation() != null)
|
||||||
{
|
{
|
||||||
source = source.replace("[latitude]", String.valueOf(LocationProvider.getLastKnownLocation().getLatitude()));
|
source = source.replace("[latitude]", String.valueOf(LocationProvider.getLastKnownLocation().getLatitude()));
|
||||||
source = source.replace("[longitude]", String.valueOf(LocationProvider.getLastKnownLocation().getLongitude()));
|
source = source.replace("[longitude]", String.valueOf(LocationProvider.getLastKnownLocation().getLongitude()));
|
||||||
@@ -766,17 +770,17 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[phonenr]"))
|
if (source.contains("[phonenr]"))
|
||||||
{
|
{
|
||||||
String lastPhoneNr = PhoneStatusListener.getLastPhoneNumber();
|
String lastPhoneNr = PhoneStatusListener.getLastPhoneNumber();
|
||||||
|
|
||||||
if(lastPhoneNr != null && lastPhoneNr.length() > 0)
|
if (lastPhoneNr != null && lastPhoneNr.length() > 0)
|
||||||
source = source.replace("[phonenr]", PhoneStatusListener.getLastPhoneNumber());
|
source = source.replace("[phonenr]", PhoneStatusListener.getLastPhoneNumber());
|
||||||
else
|
else
|
||||||
Miscellaneous.logEvent("w", "TriggerURL", context.getResources().getString(R.string.triggerUrlReplacementPositionError), 3);
|
Miscellaneous.logEvent("w", "TriggerURL", context.getResources().getString(R.string.triggerUrlReplacementPositionError), 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[serialnr]"))
|
if (source.contains("[serialnr]"))
|
||||||
{
|
{
|
||||||
if (Build.VERSION.SDK_INT > 8)
|
if (Build.VERSION.SDK_INT > 8)
|
||||||
source = source.replace("[serialnr]", Secure.getString(context.getContentResolver(), Build.SERIAL));
|
source = source.replace("[serialnr]", Secure.getString(context.getContentResolver(), Build.SERIAL));
|
||||||
@@ -784,7 +788,7 @@ public class Miscellaneous extends Service
|
|||||||
source = source.replace("[serialnr]", "serialUnknown");
|
source = source.replace("[serialnr]", "serialUnknown");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(
|
if (
|
||||||
source.contains("[d]") ||
|
source.contains("[d]") ||
|
||||||
source.contains("[m]") ||
|
source.contains("[m]") ||
|
||||||
source.contains("[Y]") ||
|
source.contains("[Y]") ||
|
||||||
@@ -799,71 +803,71 @@ public class Miscellaneous extends Service
|
|||||||
{
|
{
|
||||||
Calendar cal = Calendar.getInstance();
|
Calendar cal = Calendar.getInstance();
|
||||||
|
|
||||||
if(source.contains("[d]"))
|
if (source.contains("[d]"))
|
||||||
{
|
{
|
||||||
String result = String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
|
String result = String.valueOf(cal.get(Calendar.DAY_OF_MONTH));
|
||||||
if(result.length() < 2)
|
if (result.length() < 2)
|
||||||
result = "0" + result;
|
result = "0" + result;
|
||||||
|
|
||||||
source = source.replace("[d]", result);
|
source = source.replace("[d]", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[m]"))
|
if (source.contains("[m]"))
|
||||||
{
|
{
|
||||||
String result = String.valueOf(cal.get(Calendar.MONTH) +1);
|
String result = String.valueOf(cal.get(Calendar.MONTH) + 1);
|
||||||
if(result.length() < 2)
|
if (result.length() < 2)
|
||||||
result = "0" + result;
|
result = "0" + result;
|
||||||
|
|
||||||
source = source.replace("[m]", result);
|
source = source.replace("[m]", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[Y]"))
|
if (source.contains("[Y]"))
|
||||||
{
|
{
|
||||||
source = source.replace("[Y]", String.valueOf(cal.get(Calendar.YEAR)));
|
source = source.replace("[Y]", String.valueOf(cal.get(Calendar.YEAR)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[h]"))
|
if (source.contains("[h]"))
|
||||||
{
|
{
|
||||||
String result = String.valueOf(cal.get(Calendar.HOUR));
|
String result = String.valueOf(cal.get(Calendar.HOUR));
|
||||||
if(result.length() < 2)
|
if (result.length() < 2)
|
||||||
result = "0" + result;
|
result = "0" + result;
|
||||||
|
|
||||||
source = source.replace("[h]", result);
|
source = source.replace("[h]", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[H]"))
|
if (source.contains("[H]"))
|
||||||
{
|
{
|
||||||
String result = String.valueOf(cal.get(Calendar.HOUR_OF_DAY));
|
String result = String.valueOf(cal.get(Calendar.HOUR_OF_DAY));
|
||||||
if(result.length() < 2)
|
if (result.length() < 2)
|
||||||
result = "0" + result;
|
result = "0" + result;
|
||||||
|
|
||||||
source = source.replace("[H]", result);
|
source = source.replace("[H]", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[i]"))
|
if (source.contains("[i]"))
|
||||||
{
|
{
|
||||||
String result = String.valueOf(cal.get(Calendar.MINUTE));
|
String result = String.valueOf(cal.get(Calendar.MINUTE));
|
||||||
if(result.length() < 2)
|
if (result.length() < 2)
|
||||||
result = "0" + result;
|
result = "0" + result;
|
||||||
|
|
||||||
source = source.replace("[i]", result);
|
source = source.replace("[i]", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[s]"))
|
if (source.contains("[s]"))
|
||||||
{
|
{
|
||||||
String result = String.valueOf(cal.get(Calendar.SECOND));
|
String result = String.valueOf(cal.get(Calendar.SECOND));
|
||||||
if(result.length() < 2)
|
if (result.length() < 2)
|
||||||
result = "0" + result;
|
result = "0" + result;
|
||||||
|
|
||||||
source = source.replace("[s]", result);
|
source = source.replace("[s]", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[ms]"))
|
if (source.contains("[ms]"))
|
||||||
{
|
{
|
||||||
source = source.replace("[ms]", String.valueOf(cal.get(Calendar.MILLISECOND)));
|
source = source.replace("[ms]", String.valueOf(cal.get(Calendar.MILLISECOND)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[w]"))
|
if (source.contains("[w]"))
|
||||||
{
|
{
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
|
SimpleDateFormat sdf = new SimpleDateFormat("EEEE");
|
||||||
Date d = new Date();
|
Date d = new Date();
|
||||||
@@ -872,7 +876,7 @@ public class Miscellaneous extends Service
|
|||||||
source = source.replace("[w]", dayOfTheWeek);
|
source = source.replace("[w]", dayOfTheWeek);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[F]"))
|
if (source.contains("[F]"))
|
||||||
{
|
{
|
||||||
SimpleDateFormat sdf = new SimpleDateFormat("MMMM");
|
SimpleDateFormat sdf = new SimpleDateFormat("MMMM");
|
||||||
Date d = new Date();
|
Date d = new Date();
|
||||||
@@ -882,9 +886,9 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[notificationTitle]"))
|
if (source.contains("[notificationTitle]"))
|
||||||
{
|
{
|
||||||
if(NotificationListener.getLastNotification() != null)
|
if (NotificationListener.getLastNotification() != null)
|
||||||
{
|
{
|
||||||
String notificationTitle = NotificationListener.getLastNotification().getTitle();
|
String notificationTitle = NotificationListener.getLastNotification().getTitle();
|
||||||
|
|
||||||
@@ -903,9 +907,9 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[notificationText]"))
|
if (source.contains("[notificationText]"))
|
||||||
{
|
{
|
||||||
if(NotificationListener.getLastNotification() != null)
|
if (NotificationListener.getLastNotification() != null)
|
||||||
{
|
{
|
||||||
String notificationText = NotificationListener.getLastNotification().getText();
|
String notificationText = NotificationListener.getLastNotification().getText();
|
||||||
|
|
||||||
@@ -925,7 +929,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[" + last_trigger_url_result_string + "]"))
|
if (source.contains("[" + last_trigger_url_result_string + "]"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -937,7 +941,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[last_run_executable_exit_code]"))
|
if (source.contains("[last_run_executable_exit_code]"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -949,7 +953,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[last_run_executable_output]"))
|
if (source.contains("[last_run_executable_output]"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -961,7 +965,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[last_calendar_title]"))
|
if (source.contains("[last_calendar_title]"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -973,7 +977,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[last_calendar_description]"))
|
if (source.contains("[last_calendar_description]"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -985,7 +989,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(source.contains("[last_calendar_location]"))
|
if (source.contains("[last_calendar_location]"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -997,7 +1001,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
while(source.contains("[variable-"))
|
while (source.contains("[variable-"))
|
||||||
{
|
{
|
||||||
int pos1 = source.indexOf("[variable-");
|
int pos1 = source.indexOf("[variable-");
|
||||||
int pos2 = source.indexOf("]", pos1);
|
int pos2 = source.indexOf("]", pos1);
|
||||||
@@ -1009,12 +1013,12 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
String replacement;
|
String replacement;
|
||||||
|
|
||||||
if(AutomationService.getInstance().variableMap.containsKey(variableName))
|
if (AutomationService.getInstance().variableMap.containsKey(variableName))
|
||||||
replacement = AutomationService.getInstance().variableMap.get(variableName);
|
replacement = AutomationService.getInstance().variableMap.get(variableName);
|
||||||
else
|
else
|
||||||
replacement = "unknownVariable";
|
replacement = "unknownVariable";
|
||||||
|
|
||||||
source = source.substring(0, pos1) + escapeStringForUrl(replacement) + source.substring(pos2 +1);
|
source = source.substring(0, pos1) + escapeStringForUrl(replacement) + source.substring(pos2 + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Miscellaneous.logEvent("i", "URL after replace", source);
|
// Miscellaneous.logEvent("i", "URL after replace", source);
|
||||||
@@ -1061,7 +1065,8 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
|
||||||
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
|
NetworkInfo[] netInfo = cm.getAllNetworkInfo();
|
||||||
for (NetworkInfo ni : netInfo) {
|
for (NetworkInfo ni : netInfo)
|
||||||
|
{
|
||||||
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
|
if (ni.getTypeName().equalsIgnoreCase("WIFI"))
|
||||||
if (ni.isConnected())
|
if (ni.isConnected())
|
||||||
haveConnectedWifi = true;
|
haveConnectedWifi = true;
|
||||||
@@ -1083,7 +1088,7 @@ public class Miscellaneous extends Service
|
|||||||
{
|
{
|
||||||
return Shell.SU.available();
|
return Shell.SU.available();
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
// get from build info
|
// get from build info
|
||||||
String buildTags = Build.TAGS;
|
String buildTags = Build.TAGS;
|
||||||
@@ -1168,7 +1173,7 @@ public class Miscellaneous extends Service
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(number.contains(String.valueOf(getDecimalSeparator())))
|
if (number.contains(String.valueOf(getDecimalSeparator())))
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
return true;
|
return true;
|
||||||
@@ -1294,8 +1299,9 @@ public class Miscellaneous extends Service
|
|||||||
{
|
{
|
||||||
Thread.sleep(delay);
|
Thread.sleep(delay);
|
||||||
}
|
}
|
||||||
catch(Exception e)
|
catch (Exception e)
|
||||||
{}
|
{
|
||||||
|
}
|
||||||
|
|
||||||
createDismissibleNotification(title, textToDisplay, notificationId, true, notificationChannelId, pendingIntent);
|
createDismissibleNotification(title, textToDisplay, notificationId, true, notificationChannelId, pendingIntent);
|
||||||
|
|
||||||
@@ -1310,7 +1316,7 @@ public class Miscellaneous extends Service
|
|||||||
private static void setDefaultBehaviour(AsyncTask asyncTask)
|
private static void setDefaultBehaviour(AsyncTask asyncTask)
|
||||||
{
|
{
|
||||||
// without this line debugger will - for some reason - skip all breakpoints in this class
|
// without this line debugger will - for some reason - skip all breakpoints in this class
|
||||||
if(android.os.Debug.isDebuggerConnected())
|
if (android.os.Debug.isDebuggerConnected())
|
||||||
android.os.Debug.waitForDebugger();
|
android.os.Debug.waitForDebugger();
|
||||||
|
|
||||||
// Thread.setDefaultUncaughtExceptionHandler(Miscellaneous.getUncaughtExceptionHandler(activityMainRef, true));
|
// Thread.setDefaultUncaughtExceptionHandler(Miscellaneous.getUncaughtExceptionHandler(activityMainRef, true));
|
||||||
@@ -1320,7 +1326,7 @@ public class Miscellaneous extends Service
|
|||||||
@SuppressWarnings("deprecation")
|
@SuppressWarnings("deprecation")
|
||||||
public static void createDismissibleNotification(String title, String textToDisplay, int notificationId, boolean vibrate, String notificationChannelId, PendingIntent pendingIntent)
|
public static void createDismissibleNotification(String title, String textToDisplay, int notificationId, boolean vibrate, String notificationChannelId, PendingIntent pendingIntent)
|
||||||
{
|
{
|
||||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
|
||||||
{
|
{
|
||||||
createDismissibleNotificationSdk26(title, textToDisplay, notificationId, vibrate, notificationChannelId, pendingIntent);
|
createDismissibleNotificationSdk26(title, textToDisplay, notificationId, vibrate, notificationChannelId, pendingIntent);
|
||||||
return;
|
return;
|
||||||
@@ -1330,7 +1336,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
NotificationCompat.Builder dismissibleNotificationBuilder = createDismissibleNotificationBuilder(vibrate, notificationChannelId, pendingIntent);
|
NotificationCompat.Builder dismissibleNotificationBuilder = createDismissibleNotificationBuilder(vibrate, notificationChannelId, pendingIntent);
|
||||||
|
|
||||||
if(title == null)
|
if (title == null)
|
||||||
dismissibleNotificationBuilder.setContentTitle(AutomationService.getInstance().getResources().getString(R.string.app_name));
|
dismissibleNotificationBuilder.setContentTitle(AutomationService.getInstance().getResources().getString(R.string.app_name));
|
||||||
else
|
else
|
||||||
dismissibleNotificationBuilder.setContentTitle(title);
|
dismissibleNotificationBuilder.setContentTitle(title);
|
||||||
@@ -1340,7 +1346,7 @@ public class Miscellaneous extends Service
|
|||||||
dismissibleNotificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
|
dismissibleNotificationBuilder.setStyle(new NotificationCompat.BigTextStyle().bigText(textToDisplay));
|
||||||
dismissibleNotificationBuilder.setAutoCancel(true);
|
dismissibleNotificationBuilder.setAutoCancel(true);
|
||||||
|
|
||||||
if(notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_RULES))
|
if (notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_RULES))
|
||||||
dismissibleNotificationBuilder.setSmallIcon(R.drawable.info);
|
dismissibleNotificationBuilder.setSmallIcon(R.drawable.info);
|
||||||
|
|
||||||
Notification dismissibleNotification = dismissibleNotificationBuilder.build();
|
Notification dismissibleNotification = dismissibleNotificationBuilder.build();
|
||||||
@@ -1351,25 +1357,26 @@ public class Miscellaneous extends Service
|
|||||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
static NotificationChannel findExistingChannel(List<NotificationChannel> channels, String channelId)
|
static NotificationChannel findExistingChannel(List<NotificationChannel> channels, String channelId)
|
||||||
{
|
{
|
||||||
for(NotificationChannel c : channels)
|
for (NotificationChannel c : channels)
|
||||||
{
|
{
|
||||||
if(c.getId().equals(channelId))
|
if (c.getId().equals(channelId))
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@RequiresApi(api = Build.VERSION_CODES.O)
|
@RequiresApi(api = Build.VERSION_CODES.O)
|
||||||
static NotificationChannel getNotificationChannel(String channelId)
|
static NotificationChannel getNotificationChannel(String channelId)
|
||||||
{
|
{
|
||||||
NotificationManager nm = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
NotificationManager nm = (NotificationManager) Miscellaneous.getAnyContext().getSystemService(Context.NOTIFICATION_SERVICE);
|
||||||
List<NotificationChannel> channels = nm.getNotificationChannels();
|
List<NotificationChannel> channels = nm.getNotificationChannels();
|
||||||
|
|
||||||
if(!Settings.hasBeenDone(Settings.constNotificationChannelCleanupApk118) && BuildConfig.VERSION_CODE < 120)
|
if (!Settings.hasBeenDone(Settings.constNotificationChannelCleanupApk118) && BuildConfig.VERSION_CODE < 120)
|
||||||
{
|
{
|
||||||
// Perform a one-time cleanup of notification channels as they have been redesigned.
|
// Perform a one-time cleanup of notification channels as they have been redesigned.
|
||||||
|
|
||||||
for(NotificationChannel c : channels)
|
for (NotificationChannel c : channels)
|
||||||
nm.deleteNotificationChannel(c.getId());
|
nm.deleteNotificationChannel(c.getId());
|
||||||
|
|
||||||
Settings.considerDone(Settings.constNotificationChannelCleanupApk118);
|
Settings.considerDone(Settings.constNotificationChannelCleanupApk118);
|
||||||
@@ -1378,7 +1385,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
NotificationChannel channel = findExistingChannel(channels, channelId);
|
NotificationChannel channel = findExistingChannel(channels, channelId);
|
||||||
|
|
||||||
if(channel == null)
|
if (channel == null)
|
||||||
{
|
{
|
||||||
switch (channelId)
|
switch (channelId)
|
||||||
{
|
{
|
||||||
@@ -1434,7 +1441,7 @@ public class Miscellaneous extends Service
|
|||||||
builder.setWhen(System.currentTimeMillis());
|
builder.setWhen(System.currentTimeMillis());
|
||||||
builder.setContentIntent(pendingIntent);
|
builder.setContentIntent(pendingIntent);
|
||||||
|
|
||||||
if(title == null)
|
if (title == null)
|
||||||
builder.setContentTitle(AutomationService.getInstance().getResources().getString(R.string.app_name));
|
builder.setContentTitle(AutomationService.getInstance().getResources().getString(R.string.app_name));
|
||||||
else
|
else
|
||||||
builder.setContentTitle(title);
|
builder.setContentTitle(title);
|
||||||
@@ -1442,14 +1449,14 @@ public class Miscellaneous extends Service
|
|||||||
builder.setOnlyAlertOnce(true);
|
builder.setOnlyAlertOnce(true);
|
||||||
|
|
||||||
//if(Settings.showIconWhenServiceIsRunning && notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
//if(Settings.showIconWhenServiceIsRunning && notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
||||||
if(notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
if (notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
||||||
{
|
{
|
||||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
if (BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||||
builder.setSmallIcon(R.drawable.crane);
|
builder.setSmallIcon(R.drawable.crane);
|
||||||
else
|
else
|
||||||
builder.setSmallIcon(R.drawable.ic_launcher);
|
builder.setSmallIcon(R.drawable.ic_launcher);
|
||||||
}
|
}
|
||||||
else if(!notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
else if (!notificationChannelId.equals(AutomationService.NOTIFICATION_CHANNEL_ID_SERVICE))
|
||||||
builder.setSmallIcon(R.drawable.info);
|
builder.setSmallIcon(R.drawable.info);
|
||||||
|
|
||||||
builder.setContentText(textToDisplay);
|
builder.setContentText(textToDisplay);
|
||||||
@@ -1499,7 +1506,7 @@ public class Miscellaneous extends Service
|
|||||||
else
|
else
|
||||||
builder = new NotificationCompat.Builder(AutomationService.getInstance());
|
builder = new NotificationCompat.Builder(AutomationService.getInstance());
|
||||||
|
|
||||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)
|
||||||
builder.setCategory(Notification.CATEGORY_SERVICE);
|
builder.setCategory(Notification.CATEGORY_SERVICE);
|
||||||
|
|
||||||
builder.setAutoCancel(true);
|
builder.setAutoCancel(true);
|
||||||
@@ -1520,7 +1527,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static String explode(String glue, ArrayList<String> arrayList)
|
public static String explode(String glue, ArrayList<String> arrayList)
|
||||||
{
|
{
|
||||||
if(arrayList != null)
|
if (arrayList != null)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for (String s : arrayList)
|
for (String s : arrayList)
|
||||||
@@ -1537,7 +1544,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static String explode(String glue, String[] inputArray)
|
public static String explode(String glue, String[] inputArray)
|
||||||
{
|
{
|
||||||
if(inputArray != null)
|
if (inputArray != null)
|
||||||
{
|
{
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for (String s : inputArray)
|
for (String s : inputArray)
|
||||||
@@ -1585,7 +1592,7 @@ public class Miscellaneous extends Service
|
|||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
String[] proj = { MediaStore.Images.Media.DATA, MediaStore.Audio.Media.DATA };
|
String[] proj = {MediaStore.Images.Media.DATA, MediaStore.Audio.Media.DATA};
|
||||||
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
|
cursor = context.getContentResolver().query(contentUri, proj, null, null, null);
|
||||||
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
|
||||||
cursor.moveToFirst();
|
cursor.moveToFirst();
|
||||||
@@ -1655,7 +1662,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
|
|
||||||
final String selection = "_id=?";
|
final String selection = "_id=?";
|
||||||
final String[] selectionArgs = new String[] { split[1] };
|
final String[] selectionArgs = new String[]{split[1]};
|
||||||
|
|
||||||
return getDataColumn(context, contentUri, selection, selectionArgs);
|
return getDataColumn(context, contentUri, selection, selectionArgs);
|
||||||
}
|
}
|
||||||
@@ -1678,7 +1685,7 @@ public class Miscellaneous extends Service
|
|||||||
{
|
{
|
||||||
Cursor cursor = null;
|
Cursor cursor = null;
|
||||||
final String column = "_data";
|
final String column = "_data";
|
||||||
final String[] projection = { column };
|
final String[] projection = {column};
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1719,9 +1726,9 @@ public class Miscellaneous extends Service
|
|||||||
try
|
try
|
||||||
{
|
{
|
||||||
foundClass = Class.forName(className);
|
foundClass = Class.forName(className);
|
||||||
for(Method m : foundClass.getDeclaredMethods())
|
for (Method m : foundClass.getDeclaredMethods())
|
||||||
{
|
{
|
||||||
if(m.getName().equalsIgnoreCase(methodName))
|
if (m.getName().equalsIgnoreCase(methodName))
|
||||||
{
|
{
|
||||||
return m;
|
return m;
|
||||||
}
|
}
|
||||||
@@ -1741,18 +1748,18 @@ public class Miscellaneous extends Service
|
|||||||
Object result = null;
|
Object result = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if(params == null)
|
if (params == null)
|
||||||
result = m.invoke((Object[]) null);
|
result = m.invoke((Object[]) null);
|
||||||
else
|
else
|
||||||
result = m.invoke(null, params);
|
result = m.invoke(null, params);
|
||||||
}
|
}
|
||||||
catch (IllegalAccessException e)
|
catch (IllegalAccessException e)
|
||||||
{
|
{
|
||||||
Miscellaneous.logEvent("w", "runMethodReflective", Log.getStackTraceString(e),5 );
|
Miscellaneous.logEvent("w", "runMethodReflective", Log.getStackTraceString(e), 5);
|
||||||
}
|
}
|
||||||
catch (InvocationTargetException e)
|
catch (InvocationTargetException e)
|
||||||
{
|
{
|
||||||
Miscellaneous.logEvent("w", "runMethodReflective", Log.getStackTraceString(e),5 );
|
Miscellaneous.logEvent("w", "runMethodReflective", Log.getStackTraceString(e), 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -1760,7 +1767,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static boolean restrictedFeaturesConfiguredFdroid()
|
public static boolean restrictedFeaturesConfiguredFdroid()
|
||||||
{
|
{
|
||||||
if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
|
if (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@@ -1777,9 +1784,9 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static boolean restrictedFeaturesConfiguredGoogle()
|
public static boolean restrictedFeaturesConfiguredGoogle()
|
||||||
{
|
{
|
||||||
if(Rule.isAnyRuleUsing(Action.Action_Enum.startPhoneCall) || Rule.isAnyRuleUsing(Action.Action_Enum.stopPhoneCall))
|
if (Rule.isAnyRuleUsing(Action.Action_Enum.startPhoneCall) || Rule.isAnyRuleUsing(Action.Action_Enum.stopPhoneCall))
|
||||||
{
|
{
|
||||||
if(BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
if (BuildConfig.FLAVOR.equals(AutomationService.flavor_name_googleplay))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2014,11 +2021,11 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static boolean googleToBlameForLocation(boolean checkExistingRules)
|
public static boolean googleToBlameForLocation(boolean checkExistingRules)
|
||||||
{
|
{
|
||||||
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q)
|
||||||
{
|
{
|
||||||
if (BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
|
if (BuildConfig.FLAVOR.equalsIgnoreCase(AutomationService.flavor_name_googleplay))
|
||||||
{
|
{
|
||||||
if(checkExistingRules)
|
if (checkExistingRules)
|
||||||
{
|
{
|
||||||
if (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.pointOfInterest))
|
if (Rule.isAnyRuleUsing(Trigger.Trigger_Enum.pointOfInterest))
|
||||||
{
|
{
|
||||||
@@ -2123,7 +2130,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
catch (Throwable t)
|
catch (Throwable t)
|
||||||
{
|
{
|
||||||
Toast.makeText(context, "Request failed try again: "+ t.toString(), Toast.LENGTH_LONG).show();
|
Toast.makeText(context, "Request failed try again: " + t.toString(), Toast.LENGTH_LONG).show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2139,7 +2146,7 @@ public class Miscellaneous extends Service
|
|||||||
"compareString".matches(regex); //will cause expection if no valid regex
|
"compareString".matches(regex); //will cause expection if no valid regex
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
catch(java.util.regex.PatternSyntaxException e)
|
catch (java.util.regex.PatternSyntaxException e)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -2149,9 +2156,9 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static boolean comparePhoneNumbers(String number1, String number2)
|
public static boolean comparePhoneNumbers(String number1, String number2)
|
||||||
{
|
{
|
||||||
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.S)
|
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.S)
|
||||||
{
|
{
|
||||||
TelephonyManager tm = (TelephonyManager)Miscellaneous.getAnyContext().getSystemService(Context.TELEPHONY_SERVICE);
|
TelephonyManager tm = (TelephonyManager) Miscellaneous.getAnyContext().getSystemService(Context.TELEPHONY_SERVICE);
|
||||||
return PhoneNumberUtils.areSamePhoneNumber(number1, number2, tm.getNetworkCountryIso());
|
return PhoneNumberUtils.areSamePhoneNumber(number1, number2, tm.getNetworkCountryIso());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2163,11 +2170,11 @@ public class Miscellaneous extends Service
|
|||||||
DateFormat sdf = null;
|
DateFormat sdf = null;
|
||||||
SimpleDateFormat fallBackFormatter = new SimpleDateFormat(Settings.dateFormat);
|
SimpleDateFormat fallBackFormatter = new SimpleDateFormat(Settings.dateFormat);
|
||||||
|
|
||||||
if(sdf == null && Settings.dateFormat != null)
|
if (sdf == null && Settings.dateFormat != null)
|
||||||
sdf = new SimpleDateFormat(Settings.dateFormat);
|
sdf = new SimpleDateFormat(Settings.dateFormat);
|
||||||
|
|
||||||
String formattedDate;
|
String formattedDate;
|
||||||
if(sdf != null)
|
if (sdf != null)
|
||||||
formattedDate = sdf.format(input);
|
formattedDate = sdf.format(input);
|
||||||
else
|
else
|
||||||
formattedDate = fallBackFormatter.format(input);
|
formattedDate = fallBackFormatter.format(input);
|
||||||
@@ -2177,9 +2184,9 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static int arraySearchIndexOf(String[] haystack, String needle, boolean caseSensitive, boolean matchFullLine)
|
public static int arraySearchIndexOf(String[] haystack, String needle, boolean caseSensitive, boolean matchFullLine)
|
||||||
{
|
{
|
||||||
if(matchFullLine)
|
if (matchFullLine)
|
||||||
{
|
{
|
||||||
if(caseSensitive)
|
if (caseSensitive)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < haystack.length; i++)
|
for (int i = 0; i < haystack.length; i++)
|
||||||
{
|
{
|
||||||
@@ -2198,7 +2205,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(caseSensitive)
|
if (caseSensitive)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < haystack.length; i++)
|
for (int i = 0; i < haystack.length; i++)
|
||||||
{
|
{
|
||||||
@@ -2221,9 +2228,9 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static boolean arraySearch(String[] haystack, String needle, boolean caseSensitive, boolean matchFullLine)
|
public static boolean arraySearch(String[] haystack, String needle, boolean caseSensitive, boolean matchFullLine)
|
||||||
{
|
{
|
||||||
if(matchFullLine)
|
if (matchFullLine)
|
||||||
{
|
{
|
||||||
if(caseSensitive)
|
if (caseSensitive)
|
||||||
{
|
{
|
||||||
for (String s : haystack)
|
for (String s : haystack)
|
||||||
{
|
{
|
||||||
@@ -2242,7 +2249,7 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(caseSensitive)
|
if (caseSensitive)
|
||||||
{
|
{
|
||||||
for (String s : haystack)
|
for (String s : haystack)
|
||||||
{
|
{
|
||||||
@@ -2270,6 +2277,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get ISO 3166-1 alpha-2 country code for this device (or null if not available)
|
* Get ISO 3166-1 alpha-2 country code for this device (or null if not available)
|
||||||
|
*
|
||||||
* @param context Context reference to get the TelephonyManager instance from
|
* @param context Context reference to get the TelephonyManager instance from
|
||||||
* @return country code or null
|
* @return country code or null
|
||||||
*/
|
*/
|
||||||
@@ -2297,7 +2305,8 @@ public class Miscellaneous extends Service
|
|||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{ }
|
{
|
||||||
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@@ -2340,7 +2349,7 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static void setUiTheme(Context context)
|
public static void setUiTheme(Context context)
|
||||||
{
|
{
|
||||||
switch(Settings.uiTheme)
|
switch (Settings.uiTheme)
|
||||||
{
|
{
|
||||||
case 0:
|
case 0:
|
||||||
context.setTheme(R.style.AppTheme);
|
context.setTheme(R.style.AppTheme);
|
||||||
@@ -2356,11 +2365,22 @@ public class Miscellaneous extends Service
|
|||||||
|
|
||||||
public static void setDisplayLanguage(Context context)
|
public static void setDisplayLanguage(Context context)
|
||||||
{
|
{
|
||||||
if(!Settings.displayLanguage.equals(Settings.default_displayLanguage))
|
String targetLanguage = null;
|
||||||
|
|
||||||
|
if (Settings.displayLanguage == null)
|
||||||
|
{
|
||||||
|
targetLanguage = Settings.default_displayLanguage;
|
||||||
|
}
|
||||||
|
else if (!Settings.displayLanguage.equals(Settings.default_displayLanguage))
|
||||||
|
{
|
||||||
|
targetLanguage = Settings.default_displayLanguage;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (targetLanguage != null)
|
||||||
{
|
{
|
||||||
Locale myLocale;
|
Locale myLocale;
|
||||||
|
|
||||||
if(Settings.displayLanguage.contains("_"))
|
if (Settings.displayLanguage.contains("_"))
|
||||||
{
|
{
|
||||||
String[] parts = Settings.displayLanguage.split("_");
|
String[] parts = Settings.displayLanguage.split("_");
|
||||||
myLocale = new Locale(parts[0], parts[1]);
|
myLocale = new Locale(parts[0], parts[1]);
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 2.9 KiB |
Reference in New Issue
Block a user