forked from jens/Automation
Initial commit
This commit is contained in:
parent
a8950597d0
commit
8690dec2e2
@ -7,7 +7,7 @@ android {
|
|||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.jens.automation2"
|
applicationId "com.jens.automation2"
|
||||||
minSdkVersion 14
|
minSdkVersion 16
|
||||||
compileSdkVersion 29
|
compileSdkVersion 29
|
||||||
buildToolsVersion '29.0.2'
|
buildToolsVersion '29.0.2'
|
||||||
useLibrary 'org.apache.http.legacy'
|
useLibrary 'org.apache.http.legacy'
|
||||||
@ -64,16 +64,16 @@ android {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:16.0.1'
|
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
|
||||||
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:15.0.1'
|
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:17.1.0'
|
||||||
|
|
||||||
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:16.0.1'
|
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
|
||||||
apkFlavorImplementation 'com.google.android.gms:play-services-location:15.0.1'
|
apkFlavorImplementation 'com.google.android.gms:play-services-location:17.1.0'
|
||||||
|
|
||||||
implementation 'androidx.appcompat:appcompat:1.2.0'
|
implementation 'androidx.appcompat:appcompat:1.2.0'
|
||||||
|
|
||||||
implementation 'com.google.android.material:material:1.1.0'
|
implementation 'com.google.android.material:material:1.3.0'
|
||||||
testImplementation 'junit:junit:4.+'
|
testImplementation 'junit:junit:4.+'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0'
|
||||||
}
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.jens.automation2;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
|
import com.google.android.gms.common.GoogleApiAvailability;
|
||||||
|
|
||||||
|
public class MiscellaneousWithGoogleServices
|
||||||
|
{
|
||||||
|
public static boolean isPlayServiceAvailable()
|
||||||
|
{
|
||||||
|
GoogleApiAvailability aa = new GoogleApiAvailability();
|
||||||
|
if(aa.isGooglePlayServicesAvailable(Miscellaneous.getAnyContext()) == ConnectionResult.SUCCESS)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,391 @@
|
|||||||
|
package com.jens.automation2.receivers;
|
||||||
|
|
||||||
|
import android.app.IntentService;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
|
import com.google.android.gms.common.GooglePlayServicesUtil;
|
||||||
|
import com.google.android.gms.common.api.GoogleApiClient;
|
||||||
|
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
|
||||||
|
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.ActivityPermissions;
|
||||||
|
import com.jens.automation2.AutomationService;
|
||||||
|
import com.jens.automation2.Miscellaneous;
|
||||||
|
import com.jens.automation2.R;
|
||||||
|
import com.jens.automation2.Rule;
|
||||||
|
import com.jens.automation2.Settings;
|
||||||
|
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Date;
|
||||||
|
|
||||||
|
// See also: http://developer.android.com/reference/com/google/android/gms/location/ActivityRecognitionClient.html
|
||||||
|
// https://www.sitepoint.com/google-play-services-location-activity-recognition/
|
||||||
|
|
||||||
|
public class ActivityDetectionReceiver extends IntentService implements AutomationListenerInterface, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener
|
||||||
|
{
|
||||||
|
protected static ActivityRecognitionApi activityRecognitionClient = null;
|
||||||
|
protected static boolean connected = false;
|
||||||
|
protected static enum LastRequestEnum { start, stop, restart };
|
||||||
|
protected static LastRequestEnum lastRequest = null;
|
||||||
|
protected static GoogleApiClient googleApiClient = null;
|
||||||
|
protected static ActivityRecognitionResult activityDetectionLastResult = null;
|
||||||
|
protected static long lastUpdate = 0;
|
||||||
|
protected static Date currentTime;
|
||||||
|
protected static ActivityDetectionReceiver instance = null;
|
||||||
|
|
||||||
|
protected static ActivityDetectionReceiver getInstance()
|
||||||
|
{
|
||||||
|
if(instance == null)
|
||||||
|
instance = new ActivityDetectionReceiver();
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected static boolean activityDetectionReceiverRunning = false;
|
||||||
|
protected static ActivityDetectionReceiver activityDetectionReceiverInstance = null;
|
||||||
|
|
||||||
|
public static boolean isActivityDetectionReceiverRunning()
|
||||||
|
{
|
||||||
|
return activityDetectionReceiverRunning;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActivityRecognitionResult getActivityDetectionLastResult()
|
||||||
|
{
|
||||||
|
return activityDetectionLastResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static GoogleApiClient getApiClient()
|
||||||
|
{
|
||||||
|
if(googleApiClient == null)
|
||||||
|
{
|
||||||
|
googleApiClient = new GoogleApiClient.Builder(AutomationService.getInstance())
|
||||||
|
.addConnectionCallbacks(getInstance())
|
||||||
|
.addOnConnectionFailedListener(getInstance())
|
||||||
|
.addApi(ActivityRecognition.API)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
return googleApiClient;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void requestUpdates()
|
||||||
|
{
|
||||||
|
long frequency = Settings.activityDetectionFrequency * 1000;
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Requesting ActivityDetection updates with frequency " + String.valueOf(frequency) + " milliseconds.", 4);
|
||||||
|
|
||||||
|
|
||||||
|
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(getApiClient(), 1000, getInstance().getActivityDetectionPendingIntent());
|
||||||
|
}
|
||||||
|
private void reloadUpdates()
|
||||||
|
{
|
||||||
|
long frequency = Settings.activityDetectionFrequency * 1000;
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Re-requesting ActivityDetection updates with frequency " + String.valueOf(frequency) + " milliseconds.", 4);
|
||||||
|
|
||||||
|
activityRecognitionClient.removeActivityUpdates(getApiClient(), getInstance().getActivityDetectionPendingIntent());
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Thread.sleep(1000);
|
||||||
|
}
|
||||||
|
catch (InterruptedException e)
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Error reloading updates for ActivityDetectionReceiver: " + Log.getStackTraceString(e), 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
ActivityRecognition.ActivityRecognitionApi.requestActivityUpdates(getApiClient(), frequency, getInstance().getActivityDetectionPendingIntent());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void stopUpdates()
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Unsubscribing from ActivityDetection-updates.", 4);
|
||||||
|
|
||||||
|
ActivityRecognition.ActivityRecognitionApi.removeActivityUpdates(getApiClient(), getInstance().getActivityDetectionPendingIntent());
|
||||||
|
// activityRecognitionClient.removeActivityUpdates(getApiClient(), getInstance().getActivityDetectionPendingIntent());
|
||||||
|
// activityRecognitionClient.disconnect();
|
||||||
|
}
|
||||||
|
public static void startActivityDetectionReceiver()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Starting ActivityDetectionReceiver", 3);
|
||||||
|
|
||||||
|
if(activityDetectionReceiverInstance == null)
|
||||||
|
activityDetectionReceiverInstance = new ActivityDetectionReceiver();
|
||||||
|
|
||||||
|
if(!activityDetectionReceiverRunning && Rule.isAnyRuleUsing(Trigger_Enum.activityDetection))
|
||||||
|
{
|
||||||
|
if(isPlayServiceAvailable())
|
||||||
|
{
|
||||||
|
/*if(activityRecognitionClient == null)
|
||||||
|
activityRecognitionClient = new ActivityRecognitionClient(Miscellaneous.getAnyContext(), activityDetectionReceiverInstance, activityDetectionReceiverInstance);*/
|
||||||
|
|
||||||
|
lastRequest = LastRequestEnum.start;
|
||||||
|
|
||||||
|
if(!connected)
|
||||||
|
getApiClient().connect();
|
||||||
|
else
|
||||||
|
requestUpdates();
|
||||||
|
|
||||||
|
activityDetectionReceiverRunning = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("e", "ActivityDetectionReceiver", "Error starting ActivityDetectionReceiver: " + Log.getStackTraceString(ex), 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void restartActivityDetectionReceiver()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(!activityDetectionReceiverRunning && Rule.isAnyRuleUsing(Trigger_Enum.activityDetection))
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Restarting ActivityDetectionReceiver", 3);
|
||||||
|
|
||||||
|
if(activityDetectionReceiverInstance == null)
|
||||||
|
activityDetectionReceiverInstance = new ActivityDetectionReceiver();
|
||||||
|
|
||||||
|
if(isPlayServiceAvailable())
|
||||||
|
{
|
||||||
|
// if(activityRecognitionClient == null)
|
||||||
|
// activityRecognitionClient = new ActivityRecognitionClient(Miscellaneous.getAnyContext(), activityDetectionReceiverInstance, activityDetectionReceiverInstance);
|
||||||
|
|
||||||
|
lastRequest = LastRequestEnum.restart;
|
||||||
|
|
||||||
|
if(!connected)
|
||||||
|
getApiClient().connect();
|
||||||
|
else
|
||||||
|
requestUpdates();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("e", "ActivityDetectionReceiver", "Error starting ActivityDetectionReceiver: " + Log.getStackTraceString(ex), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopActivityDetectionReceiver()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(activityDetectionReceiverRunning)
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Stopping ActivityDetectionReceiver", 3);
|
||||||
|
|
||||||
|
if(isPlayServiceAvailable())
|
||||||
|
{
|
||||||
|
lastRequest = LastRequestEnum.stop;
|
||||||
|
|
||||||
|
if(!connected)
|
||||||
|
getApiClient().connect();
|
||||||
|
else
|
||||||
|
stopUpdates();
|
||||||
|
|
||||||
|
activityDetectionReceiverRunning = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(Exception ex)
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("e", "ActivityDetectionReceiver", "Error stopping ActivityDetectionReceiver: " + Log.getStackTraceString(ex), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnectionFailed(ConnectionResult arg0)
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Connection to Play Services failed.", 4);
|
||||||
|
if(connected && getApiClient().isConnected())
|
||||||
|
{
|
||||||
|
connected = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnected(Bundle arg0)
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Connected to Play Services.", 4);
|
||||||
|
|
||||||
|
connected = true;
|
||||||
|
|
||||||
|
if(lastRequest == null)
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("w", "ActivityDetectionReceiver", "Request type not specified. Start or stop listening to activity detection updates?", 4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(lastRequest.equals(LastRequestEnum.start))
|
||||||
|
requestUpdates();
|
||||||
|
else if(lastRequest.equals(LastRequestEnum.stop))
|
||||||
|
stopUpdates();
|
||||||
|
else //reload, e.g. to set a new update time
|
||||||
|
reloadUpdates();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onConnectionSuspended(int arg0)
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Connection to Play Services suspended.", 4);
|
||||||
|
// activityRecognitionClient.disconnect();
|
||||||
|
connected = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ActivityDetectionReceiver()
|
||||||
|
{
|
||||||
|
super("ActivityDetectionIntentService");
|
||||||
|
if(instance == null)
|
||||||
|
instance = this;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onHandleIntent(Intent intent)
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "onHandleIntent(): Received some status.", 5);
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if(isActivityDetectionReceiverRunning())
|
||||||
|
{
|
||||||
|
currentTime = new Date();
|
||||||
|
|
||||||
|
if(lastUpdate == 0 | currentTime.getTime() >= lastUpdate + Settings.activityDetectionFrequency * 1000 - 1000) // -1000 to include updates only marginaly below the threshold
|
||||||
|
{
|
||||||
|
lastUpdate = currentTime.getTime();
|
||||||
|
|
||||||
|
if(ActivityRecognitionResult.hasResult(intent))
|
||||||
|
{
|
||||||
|
activityDetectionLastResult = ActivityRecognitionResult.extractResult(intent);
|
||||||
|
|
||||||
|
for(DetectedActivity activity : activityDetectionLastResult.getProbableActivities())
|
||||||
|
{
|
||||||
|
int loglevel = 3;
|
||||||
|
if(activity.getConfidence() < Settings.activityDetectionRequiredProbability)
|
||||||
|
loglevel = 4;
|
||||||
|
|
||||||
|
Miscellaneous.logEvent("i", "ActivityDetectionReceiver", "Detected activity (probability " + String.valueOf(activity.getConfidence()) + "%): " + getDescription(activity.getType()), loglevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Returns the list of activities that where detected with the confidence value associated with each activity.
|
||||||
|
* The activities are sorted by most probable activity first.
|
||||||
|
* The sum of the confidences of all detected activities this method returns does not have to be <= 100
|
||||||
|
* since some activities are not mutually exclusive (for example, you can be walking while in a bus)
|
||||||
|
* and some activities are hierarchical (ON_FOOT is a generalization of WALKING and RUNNING).
|
||||||
|
*/
|
||||||
|
|
||||||
|
ArrayList<Rule> allRulesWithActivityDetection = Rule.findRuleCandidatesByActivityDetection();
|
||||||
|
for(int i=0; i<allRulesWithActivityDetection.size(); i++)
|
||||||
|
{
|
||||||
|
if(allRulesWithActivityDetection.get(i).applies(Miscellaneous.getAnyContext()))
|
||||||
|
allRulesWithActivityDetection.get(i).activate(AutomationService.getInstance(), false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Miscellaneous.logEvent("w", "ActivityDetectionReceiver", String.format(getResources().getString(R.string.ignoringActivityDetectionUpdateTooSoon), String.valueOf(Settings.activityDetectionFrequency)), 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Miscellaneous.logEvent("w", "ActivityDetectionReceiver", "I am not running. I shouldn't be getting updates. Ignoring it.", 5);
|
||||||
|
}
|
||||||
|
catch(Exception e)
|
||||||
|
{
|
||||||
|
// some error, don't care.
|
||||||
|
Miscellaneous.logEvent("e", "ActivityDetectionReceiver", "onHandleIntent(): Error while receiving status: " + Log.getStackTraceString(e), 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int[] getAllTypes()
|
||||||
|
{
|
||||||
|
return new int[] {
|
||||||
|
DetectedActivity.IN_VEHICLE,
|
||||||
|
DetectedActivity.ON_BICYCLE,
|
||||||
|
DetectedActivity.ON_FOOT,
|
||||||
|
DetectedActivity.STILL,
|
||||||
|
DetectedActivity.TILTING,
|
||||||
|
DetectedActivity.WALKING,
|
||||||
|
DetectedActivity.RUNNING,
|
||||||
|
DetectedActivity.UNKNOWN
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String getDescription(int type)
|
||||||
|
{
|
||||||
|
switch(type)
|
||||||
|
{
|
||||||
|
case(DetectedActivity.IN_VEHICLE):
|
||||||
|
return Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivityInVehicle);
|
||||||
|
case(DetectedActivity.ON_BICYCLE):
|
||||||
|
return Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivityOnBicycle);
|
||||||
|
case(DetectedActivity.ON_FOOT):
|
||||||
|
return Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivityOnFoot);
|
||||||
|
case(DetectedActivity.STILL):
|
||||||
|
return Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivityStill);
|
||||||
|
case(DetectedActivity.TILTING):
|
||||||
|
return Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivityTilting);
|
||||||
|
case(DetectedActivity.WALKING):
|
||||||
|
return Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivityWalking);
|
||||||
|
case(DetectedActivity.RUNNING):
|
||||||
|
return Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivityRunning);
|
||||||
|
case(DetectedActivity.UNKNOWN):
|
||||||
|
return Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivityUnknown);
|
||||||
|
default:
|
||||||
|
return Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivityInvalidStatus);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String[] getAllDescriptions()
|
||||||
|
{
|
||||||
|
ArrayList<String> types = new ArrayList<String>();
|
||||||
|
|
||||||
|
for(int type : getAllTypes())
|
||||||
|
types.add(getDescription(type));
|
||||||
|
|
||||||
|
return types.toArray(new String[types.size()]);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void startListener(AutomationService automationService)
|
||||||
|
{
|
||||||
|
ActivityDetectionReceiver.startActivityDetectionReceiver();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void stopListener(AutomationService automationService)
|
||||||
|
{
|
||||||
|
ActivityDetectionReceiver.stopActivityDetectionReceiver();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean haveAllPermission()
|
||||||
|
{
|
||||||
|
return ActivityPermissions.havePermission("com.google.android.gms.permission.ACTIVITY_RECOGNITION", Miscellaneous.getAnyContext());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isListenerRunning()
|
||||||
|
{
|
||||||
|
return ActivityDetectionReceiver.isActivityDetectionReceiverRunning();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Trigger_Enum[] getMonitoredTrigger()
|
||||||
|
{
|
||||||
|
return new Trigger_Enum[] { Trigger_Enum.activityDetection };
|
||||||
|
}
|
||||||
|
|
||||||
|
private PendingIntent getActivityDetectionPendingIntent()
|
||||||
|
{
|
||||||
|
Intent intent = new Intent(AutomationService.getInstance(), ActivityDetectionReceiver.class);
|
||||||
|
PendingIntent returnValue = PendingIntent.getService(AutomationService.getInstance(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
return returnValue;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,557 @@
|
|||||||
|
package com.jens.automation2;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.view.View.OnTouchListener;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
|
import com.jens.automation2.AutomationService.serviceCommands;
|
||||||
|
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||||
|
import com.jens.automation2.location.LocationProvider;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
public class ActivityMainScreen extends ActivityGeneric
|
||||||
|
{
|
||||||
|
private static boolean guiChangeInProgress = false;
|
||||||
|
|
||||||
|
private static ActivityMainScreen activityMainScreenInstance = null;
|
||||||
|
private ToggleButton toggleService, tbLockSound;
|
||||||
|
private Button bShowHelp, bPrivacy, bSettingsErase, bSettingsSetToDefault, bVolumeTest, bAddSoundLockTIme;
|
||||||
|
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNote, tvlockSoundDuration;
|
||||||
|
|
||||||
|
private ListView lvRuleHistory;
|
||||||
|
private ArrayAdapter<Rule> ruleHistoryListViewAdapter;
|
||||||
|
|
||||||
|
private static boolean uiUpdateRunning = false;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.main_overview_layout);
|
||||||
|
|
||||||
|
activityMainScreenInstance = this;
|
||||||
|
|
||||||
|
if(ActivityPermissions.needMorePermissions(ActivityMainScreen.this))
|
||||||
|
{
|
||||||
|
Intent permissionsIntent = new Intent(ActivityMainScreen.this, ActivityPermissions.class);
|
||||||
|
startActivityForResult(permissionsIntent, 7000);
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings.readFromPersistentStorage(this);
|
||||||
|
|
||||||
|
guiChangeInProgress = true;
|
||||||
|
|
||||||
|
tvActivePoi = (TextView) findViewById(R.id.tvActivePoi);
|
||||||
|
tvClosestPoi = (TextView) findViewById(R.id.tvClosestPoi);
|
||||||
|
lvRuleHistory = (ListView) findViewById(R.id.lvRuleHistory);
|
||||||
|
tvLastRule = (TextView) findViewById(R.id.tvTimeFrameHelpText);
|
||||||
|
tvMainScreenNote = (TextView) findViewById(R.id.tvMainScreenNote);
|
||||||
|
tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
|
||||||
|
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
|
||||||
|
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
|
||||||
|
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||||
|
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||||
|
{
|
||||||
|
if (!ActivityMainScreen.this.uiUpdateRunning)
|
||||||
|
{
|
||||||
|
if (toggleService.isChecked())
|
||||||
|
{
|
||||||
|
startAutomationService(getBaseContext(), false);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
stopAutomationService();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tvMainScreenNote.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
Intent intent = new Intent(ActivityMainScreen.this, ActivityPermissions.class);
|
||||||
|
startActivityForResult(intent, ActivityPermissions.requestCodeForPermissions);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tbLockSound.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||||
|
{
|
||||||
|
Settings.lockSoundChanges = isChecked;
|
||||||
|
|
||||||
|
if(!isChecked)
|
||||||
|
{
|
||||||
|
AutomationService.getInstance().nullLockSoundChangesEnd();
|
||||||
|
updateMainScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!guiChangeInProgress)
|
||||||
|
Settings.writeSettings(ActivityMainScreen.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button bSettings = (Button) findViewById(R.id.bSettings);
|
||||||
|
bSettings.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
Intent myIntent = new Intent(ActivityMainScreen.this, ActivitySettings.class);
|
||||||
|
startActivityForResult(myIntent, 6000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||||
|
bVolumeTest.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
Intent intent = new Intent(ActivityMainScreen.this, ActivityVolumeTest.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bShowHelp = (Button) findViewById(R.id.bShowHelp);
|
||||||
|
bShowHelp.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
Intent showHelpIntent = new Intent(ActivityMainScreen.this, ActivityHelp.class);
|
||||||
|
startActivity(showHelpIntent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bPrivacy = (Button) findViewById(R.id.bPrivacy);
|
||||||
|
bPrivacy.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityMainScreen.this);
|
||||||
|
builder.setMessage(getResources().getString(R.string.privacyConfirmationText));
|
||||||
|
builder.setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
openPrivacyPolicy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(getResources().getString(R.string.no), null);
|
||||||
|
builder.create().show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*bSettingsErase = (Button)findViewById(R.id.bSettingsErase);
|
||||||
|
bSettingsErase.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
getEraseSettingsDialog(ActivityMainScreen.this).show();
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
bSettingsSetToDefault = (Button) findViewById(R.id.bSettingsSetToDefault);
|
||||||
|
bSettingsSetToDefault.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
getDefaultSettingsDialog(ActivityMainScreen.this).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
lvRuleHistory.setOnTouchListener(new OnTouchListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event)
|
||||||
|
{
|
||||||
|
v.getParent().requestDisallowInterceptTouchEvent(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bAddSoundLockTIme = (Button)findViewById(R.id.bAddSoundLockTIme);
|
||||||
|
bAddSoundLockTIme.setText("+" + Settings.lockSoundChangesInterval + " min");
|
||||||
|
bAddSoundLockTIme.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View view)
|
||||||
|
{
|
||||||
|
if(AutomationService.isMyServiceRunning(ActivityMainScreen.this))
|
||||||
|
{
|
||||||
|
AutomationService.getInstance().lockSoundChangesEndAddTime();
|
||||||
|
ActivityMainScreen.updateMainScreen();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Toast.makeText(ActivityMainScreen.this, getResources().getString(R.string.serviceNotRunning), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ruleHistoryListViewAdapter = new ArrayAdapter<Rule>(this, R.layout.text_view_for_poi_listview_mediumtextsize, Rule.getRuleRunHistory());
|
||||||
|
|
||||||
|
if (PointOfInterest.getPointOfInterestCollection() == null | PointOfInterest.getPointOfInterestCollection().size() == 0)
|
||||||
|
PointOfInterest.loadPoisFromFile();
|
||||||
|
if (Rule.getRuleCollection() == null | Rule.getRuleCollection().size() == 0)
|
||||||
|
Rule.readFromFile();
|
||||||
|
|
||||||
|
ActivityMainScreen.updateMainScreen();
|
||||||
|
|
||||||
|
this.storeServiceReferenceInVariable();
|
||||||
|
|
||||||
|
guiChangeInProgress = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AlertDialog getEraseSettingsDialog(final Context context)
|
||||||
|
{
|
||||||
|
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||||
|
alertDialogBuilder.setTitle(context.getResources().getString(R.string.areYouSure));
|
||||||
|
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
if (Settings.eraseSettings(context))
|
||||||
|
Toast.makeText(context, context.getResources().getString(R.string.settingsErased), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||||
|
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||||
|
|
||||||
|
return alertDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AlertDialog getDefaultSettingsDialog(final Context context)
|
||||||
|
{
|
||||||
|
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||||
|
alertDialogBuilder.setTitle(context.getResources().getString(R.string.areYouSure));
|
||||||
|
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
if (Settings.initializeSettings(context, true))
|
||||||
|
Toast.makeText(context, context.getResources().getString(R.string.settingsSetToDefault), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||||
|
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||||
|
|
||||||
|
return alertDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActivityMainScreen getActivityMainScreenInstance()
|
||||||
|
{
|
||||||
|
return activityMainScreenInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateMainScreen()
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "MainScreen", "Request to update notification.", 5);
|
||||||
|
|
||||||
|
if (activityMainScreenInstance != null)
|
||||||
|
{
|
||||||
|
if(ActivityPermissions.needMorePermissions(activityMainScreenInstance))
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvMainScreenNote.setText(R.string.mainScreenPermissionNote);
|
||||||
|
activityMainScreenInstance.tvMainScreenNote.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvMainScreenNote.setText("");
|
||||||
|
activityMainScreenInstance.tvMainScreenNote.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AutomationService.isMyServiceRunning(activityMainScreenInstance))
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "MainScreen", "Service is running. Updating mainscreen with this info.", 5);
|
||||||
|
uiUpdateRunning = true;
|
||||||
|
activityMainScreenInstance.toggleService.setChecked(true);
|
||||||
|
uiUpdateRunning = false;
|
||||||
|
// if(activityMainScreenInstance.hasWindowFocus())
|
||||||
|
// {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PointOfInterest activePoi = PointOfInterest.getActivePoi();
|
||||||
|
if (activePoi == null)
|
||||||
|
{
|
||||||
|
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(LocationProvider.getInstance().getCurrentLocation());
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText("none");
|
||||||
|
activityMainScreenInstance.tvClosestPoi.setText(closestPoi.getName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText(activePoi.getName());
|
||||||
|
activityMainScreenInstance.tvClosestPoi.setText("n./a.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NullPointerException e)
|
||||||
|
{
|
||||||
|
if (PointOfInterest.getPointOfInterestCollection().size() > 0)
|
||||||
|
{
|
||||||
|
if(
|
||||||
|
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
|
||||||
|
&&
|
||||||
|
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, AutomationService.getInstance())
|
||||||
|
&&
|
||||||
|
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, AutomationService.getInstance())
|
||||||
|
)
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.stillGettingPosition));
|
||||||
|
else
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.locationEngineNotActive));
|
||||||
|
|
||||||
|
activityMainScreenInstance.tvClosestPoi.setText("n./a.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.noPoisDefinedShort));
|
||||||
|
activityMainScreenInstance.tvClosestPoi.setText("n./a.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvLastRule.setText(Rule.getLastActivatedRule().getName() + " " + activityMainScreenInstance.getResources().getString(R.string.at) + " " + Rule.getLastActivatedRuleActivationTime().toLocaleString());
|
||||||
|
activityMainScreenInstance.updateListView();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvLastRule.setText("n./a.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "MainScreen", "Service not running. Updating mainscreen with this info.", 5);
|
||||||
|
activityMainScreenInstance.toggleService.setChecked(false);
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.serviceNotRunning));
|
||||||
|
activityMainScreenInstance.tvClosestPoi.setText("");
|
||||||
|
activityMainScreenInstance.tvLastRule.setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// uiUpdateRunning = true;
|
||||||
|
if(AutomationService.isMyServiceRunning(ActivityMainScreen.getActivityMainScreenInstance()) && AutomationService.getInstance() != null)
|
||||||
|
{
|
||||||
|
AutomationService.getInstance().checkLockSoundChangesTimeElapsed();
|
||||||
|
|
||||||
|
Calendar end = AutomationService.getInstance().getLockSoundChangesEnd();
|
||||||
|
activityMainScreenInstance.tbLockSound.setChecked(end != null);
|
||||||
|
activityMainScreenInstance.tbLockSound.setEnabled(end != null);
|
||||||
|
|
||||||
|
if(end != null)
|
||||||
|
{
|
||||||
|
Calendar now = Calendar.getInstance();
|
||||||
|
long millis = end.getTimeInMillis() - now.getTimeInMillis();
|
||||||
|
long minutes = millis/1000/60;
|
||||||
|
if(minutes < 60)
|
||||||
|
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(minutes + " min..."));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double hours = (double)minutes / 60.0;
|
||||||
|
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(Math.round(hours * 100.0) / 100.0) + " h...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(""));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tbLockSound.setChecked(false);
|
||||||
|
activityMainScreenInstance.tbLockSound.setEnabled(false);
|
||||||
|
activityMainScreenInstance.tvlockSoundDuration.setText("");
|
||||||
|
}
|
||||||
|
Settings.writeSettings(activityMainScreenInstance);
|
||||||
|
// uiUpdateRunning = false;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// Miscellaneous.logEvent("i", "ActivityMainScreen", "Window doesn't have focus. We're not updating anything.", 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Miscellaneous.logEvent("i", "ActivityMainScreen", "Activity not running. No need to update.", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||||
|
{
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
|
// Miscellaneous.logEvent("i", "ListView", "Notifying ListViewAdapter", 4);
|
||||||
|
|
||||||
|
if (AutomationService.isMyServiceRunning(this))
|
||||||
|
bindToService();
|
||||||
|
|
||||||
|
switch (requestCode)
|
||||||
|
{
|
||||||
|
case ActivityPermissions.requestCodeForPermissions:
|
||||||
|
updateMainScreen();
|
||||||
|
break;
|
||||||
|
case 6000: //settings
|
||||||
|
Settings.readFromPersistentStorage(this);
|
||||||
|
|
||||||
|
if (boundToService && AutomationService.isMyServiceRunning(this))
|
||||||
|
myAutomationService.serviceInterface(serviceCommands.reloadSettings);
|
||||||
|
|
||||||
|
if(AutomationService.isMyServiceRunning(ActivityMainScreen.this))
|
||||||
|
Toast.makeText(this, getResources().getString(R.string.settingsWillTakeTime), Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AutomationService.isMyServiceRunning(this))
|
||||||
|
{
|
||||||
|
// Let service reload via binding interface.
|
||||||
|
if (boundToService)
|
||||||
|
{
|
||||||
|
myAutomationService.serviceInterface(serviceCommands.updateNotification); //in case names got changed.
|
||||||
|
unBindFromService();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Let service reload classically.
|
||||||
|
AutomationService service = AutomationService.getInstance();
|
||||||
|
if (service != null)
|
||||||
|
service.applySettingsAndRules();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startAutomationService(Context context, boolean startAtBoot)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Rule.getRuleCollection().size() > 0)
|
||||||
|
{
|
||||||
|
if (!AutomationService.isMyServiceRunning(context))
|
||||||
|
{
|
||||||
|
// if(myServiceIntent == null) //do we need that line?????
|
||||||
|
myServiceIntent = new Intent(context, AutomationService.class);
|
||||||
|
myServiceIntent.putExtra("startAtBoot", startAtBoot);
|
||||||
|
context.startService(myServiceIntent);
|
||||||
|
} else
|
||||||
|
Miscellaneous.logEvent("w", "Service", context.getResources().getString(R.string.logServiceAlreadyRunning), 3);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStart), Toast.LENGTH_LONG).show();
|
||||||
|
activityMainScreenInstance.toggleService.setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NullPointerException ne)
|
||||||
|
{
|
||||||
|
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStart), Toast.LENGTH_LONG).show();
|
||||||
|
activityMainScreenInstance.toggleService.setChecked(false);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Toast.makeText(context, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
activityMainScreenInstance.toggleService.setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopAutomationService()
|
||||||
|
{
|
||||||
|
if (myServiceIntent == null)
|
||||||
|
myServiceIntent = new Intent(this, AutomationService.class);
|
||||||
|
stopService(myServiceIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestart()
|
||||||
|
{
|
||||||
|
super.onRestart();
|
||||||
|
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||||
|
ActivityMainScreen.updateMainScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart()
|
||||||
|
{
|
||||||
|
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||||
|
ActivityMainScreen.updateMainScreen();
|
||||||
|
super.onStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume()
|
||||||
|
{
|
||||||
|
super.onResume();
|
||||||
|
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||||
|
ActivityMainScreen.updateMainScreen();
|
||||||
|
|
||||||
|
if(Build.VERSION.SDK_INT >= 28 && !Settings.noticeAndroid9MicrophoneShown && Rule.isAnyRuleUsing(Trigger_Enum.noiseLevel))
|
||||||
|
{
|
||||||
|
Settings.noticeAndroid9MicrophoneShown = true;
|
||||||
|
Settings.writeSettings(ActivityMainScreen.this);
|
||||||
|
Miscellaneous.messageBox(getResources().getString(R.string.app_name), getResources().getString(R.string.android9RecordAudioNotice) + " " + getResources().getString(R.string.messageNotShownAgain), ActivityMainScreen.this).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Build.VERSION.SDK_INT >= 29 && !Settings.noticeAndroid10WifiShown && Rule.isAnyRuleUsing(Action.Action_Enum.setWifi))
|
||||||
|
{
|
||||||
|
Settings.noticeAndroid10WifiShown = true;
|
||||||
|
Settings.writeSettings(ActivityMainScreen.this);
|
||||||
|
Miscellaneous.messageBox(getResources().getString(R.string.app_name), getResources().getString(R.string.android10WifiToggleNotice) + " " + getResources().getString(R.string.messageNotShownAgain), ActivityMainScreen.this).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy()
|
||||||
|
{
|
||||||
|
super.onDestroy();
|
||||||
|
activityMainScreenInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openPrivacyPolicy()
|
||||||
|
{
|
||||||
|
String privacyPolicyUrl = "http://server47.de/automation/privacy.html";
|
||||||
|
|
||||||
|
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl));
|
||||||
|
startActivity(browserIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateListView()
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ListView", "Attempting to update lvRuleHistory", 4);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (lvRuleHistory.getAdapter() == null)
|
||||||
|
lvRuleHistory.setAdapter(ruleHistoryListViewAdapter);
|
||||||
|
|
||||||
|
ruleHistoryListViewAdapter.notifyDataSetChanged();
|
||||||
|
}
|
||||||
|
catch (NullPointerException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showMessageBox(String title, String text)
|
||||||
|
{
|
||||||
|
Miscellaneous.messageBox(title, text, ActivityMainScreen.getActivityMainScreenInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1394
app/src/fdroidFlavor/java/com/jens/automation2/Rule.java
Normal file
1394
app/src/fdroidFlavor/java/com/jens/automation2/Rule.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,597 @@
|
|||||||
|
package com.jens.automation2;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.app.AlertDialog;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.DialogInterface;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.view.View;
|
||||||
|
import android.view.View.OnClickListener;
|
||||||
|
import android.view.View.OnTouchListener;
|
||||||
|
import android.widget.ArrayAdapter;
|
||||||
|
import android.widget.Button;
|
||||||
|
import android.widget.CompoundButton;
|
||||||
|
import android.widget.CompoundButton.OnCheckedChangeListener;
|
||||||
|
import android.widget.ListView;
|
||||||
|
import android.widget.TextView;
|
||||||
|
import android.widget.Toast;
|
||||||
|
import android.widget.ToggleButton;
|
||||||
|
|
||||||
|
import com.google.android.gms.appindexing.AppIndex;
|
||||||
|
import com.google.android.gms.appindexing.Thing;
|
||||||
|
import com.google.android.gms.common.api.GoogleApiClient;
|
||||||
|
import com.jens.automation2.AutomationService.serviceCommands;
|
||||||
|
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||||
|
import com.jens.automation2.location.LocationProvider;
|
||||||
|
|
||||||
|
import java.util.Calendar;
|
||||||
|
|
||||||
|
@SuppressLint("NewApi")
|
||||||
|
public class ActivityMainScreen extends ActivityGeneric
|
||||||
|
{
|
||||||
|
private static boolean guiChangeInProgress = false;
|
||||||
|
|
||||||
|
private static ActivityMainScreen activityMainScreenInstance = null;
|
||||||
|
private ToggleButton toggleService, tbLockSound;
|
||||||
|
private Button bShowHelp, bPrivacy, bSettingsErase, bSettingsSetToDefault, bVolumeTest, bAddSoundLockTIme;
|
||||||
|
private TextView tvActivePoi, tvClosestPoi, tvLastRule, tvMainScreenNote, tvlockSoundDuration;
|
||||||
|
|
||||||
|
private ListView lvRuleHistory;
|
||||||
|
private ArrayAdapter<Rule> ruleHistoryListViewAdapter;
|
||||||
|
|
||||||
|
private static boolean uiUpdateRunning = false;
|
||||||
|
/**
|
||||||
|
* ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||||
|
* See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||||
|
*/
|
||||||
|
private GoogleApiClient client;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate(Bundle savedInstanceState)
|
||||||
|
{
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
setContentView(R.layout.main_overview_layout);
|
||||||
|
|
||||||
|
activityMainScreenInstance = this;
|
||||||
|
|
||||||
|
if(ActivityPermissions.needMorePermissions(ActivityMainScreen.this))
|
||||||
|
{
|
||||||
|
Intent permissionsIntent = new Intent(ActivityMainScreen.this, ActivityPermissions.class);
|
||||||
|
startActivityForResult(permissionsIntent, 7000);
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings.readFromPersistentStorage(this);
|
||||||
|
|
||||||
|
guiChangeInProgress = true;
|
||||||
|
|
||||||
|
tvActivePoi = (TextView) findViewById(R.id.tvActivePoi);
|
||||||
|
tvClosestPoi = (TextView) findViewById(R.id.tvClosestPoi);
|
||||||
|
lvRuleHistory = (ListView) findViewById(R.id.lvRuleHistory);
|
||||||
|
tvLastRule = (TextView) findViewById(R.id.tvTimeFrameHelpText);
|
||||||
|
tvMainScreenNote = (TextView) findViewById(R.id.tvMainScreenNote);
|
||||||
|
tvlockSoundDuration = (TextView)findViewById(R.id.tvlockSoundDuration);
|
||||||
|
tbLockSound = (ToggleButton) findViewById(R.id.tbLockSound);
|
||||||
|
toggleService = (ToggleButton) findViewById(R.id.tbArmMastListener);
|
||||||
|
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||||
|
toggleService.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||||
|
{
|
||||||
|
if (!ActivityMainScreen.this.uiUpdateRunning)
|
||||||
|
{
|
||||||
|
if (toggleService.isChecked())
|
||||||
|
{
|
||||||
|
startAutomationService(getBaseContext(), false);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
stopAutomationService();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tvMainScreenNote.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
Intent intent = new Intent(ActivityMainScreen.this, ActivityPermissions.class);
|
||||||
|
startActivityForResult(intent, ActivityPermissions.requestCodeForPermissions);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
tbLockSound.setOnCheckedChangeListener(new OnCheckedChangeListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked)
|
||||||
|
{
|
||||||
|
Settings.lockSoundChanges = isChecked;
|
||||||
|
|
||||||
|
if(!isChecked)
|
||||||
|
{
|
||||||
|
AutomationService.getInstance().nullLockSoundChangesEnd();
|
||||||
|
updateMainScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!guiChangeInProgress)
|
||||||
|
Settings.writeSettings(ActivityMainScreen.this);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button bSettings = (Button) findViewById(R.id.bSettings);
|
||||||
|
bSettings.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
Intent myIntent = new Intent(ActivityMainScreen.this, ActivitySettings.class);
|
||||||
|
startActivityForResult(myIntent, 6000);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
Button bVolumeTest = (Button) findViewById(R.id.bVolumeTest);
|
||||||
|
bVolumeTest.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
Intent intent = new Intent(ActivityMainScreen.this, ActivityVolumeTest.class);
|
||||||
|
startActivity(intent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bShowHelp = (Button) findViewById(R.id.bShowHelp);
|
||||||
|
bShowHelp.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
Intent showHelpIntent = new Intent(ActivityMainScreen.this, ActivityHelp.class);
|
||||||
|
startActivity(showHelpIntent);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bPrivacy = (Button) findViewById(R.id.bPrivacy);
|
||||||
|
bPrivacy.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
AlertDialog.Builder builder = new AlertDialog.Builder(ActivityMainScreen.this);
|
||||||
|
builder.setMessage(getResources().getString(R.string.privacyConfirmationText));
|
||||||
|
builder.setPositiveButton(getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
openPrivacyPolicy();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
builder.setNegativeButton(getResources().getString(R.string.no), null);
|
||||||
|
builder.create().show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
/*bSettingsErase = (Button)findViewById(R.id.bSettingsErase);
|
||||||
|
bSettingsErase.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
getEraseSettingsDialog(ActivityMainScreen.this).show();
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
bSettingsSetToDefault = (Button) findViewById(R.id.bSettingsSetToDefault);
|
||||||
|
bSettingsSetToDefault.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View v)
|
||||||
|
{
|
||||||
|
getDefaultSettingsDialog(ActivityMainScreen.this).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
lvRuleHistory.setOnTouchListener(new OnTouchListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public boolean onTouch(View v, MotionEvent event)
|
||||||
|
{
|
||||||
|
v.getParent().requestDisallowInterceptTouchEvent(true);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
bAddSoundLockTIme = (Button)findViewById(R.id.bAddSoundLockTIme);
|
||||||
|
bAddSoundLockTIme.setText("+" + Settings.lockSoundChangesInterval + " min");
|
||||||
|
bAddSoundLockTIme.setOnClickListener(new OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(View view)
|
||||||
|
{
|
||||||
|
if(AutomationService.isMyServiceRunning(ActivityMainScreen.this))
|
||||||
|
{
|
||||||
|
AutomationService.getInstance().lockSoundChangesEndAddTime();
|
||||||
|
ActivityMainScreen.updateMainScreen();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Toast.makeText(ActivityMainScreen.this, getResources().getString(R.string.serviceNotRunning), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
ruleHistoryListViewAdapter = new ArrayAdapter<Rule>(this, R.layout.text_view_for_poi_listview_mediumtextsize, Rule.getRuleRunHistory());
|
||||||
|
|
||||||
|
if (PointOfInterest.getPointOfInterestCollection() == null | PointOfInterest.getPointOfInterestCollection().size() == 0)
|
||||||
|
PointOfInterest.loadPoisFromFile();
|
||||||
|
if (Rule.getRuleCollection() == null | Rule.getRuleCollection().size() == 0)
|
||||||
|
Rule.readFromFile();
|
||||||
|
|
||||||
|
ActivityMainScreen.updateMainScreen();
|
||||||
|
|
||||||
|
this.storeServiceReferenceInVariable();
|
||||||
|
|
||||||
|
guiChangeInProgress = false;
|
||||||
|
// ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||||
|
// See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||||
|
client = new GoogleApiClient.Builder(this).addApi(AppIndex.API).build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AlertDialog getEraseSettingsDialog(final Context context)
|
||||||
|
{
|
||||||
|
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||||
|
alertDialogBuilder.setTitle(context.getResources().getString(R.string.areYouSure));
|
||||||
|
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
if (Settings.eraseSettings(context))
|
||||||
|
Toast.makeText(context, context.getResources().getString(R.string.settingsErased), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||||
|
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||||
|
|
||||||
|
return alertDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static AlertDialog getDefaultSettingsDialog(final Context context)
|
||||||
|
{
|
||||||
|
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(context);
|
||||||
|
alertDialogBuilder.setTitle(context.getResources().getString(R.string.areYouSure));
|
||||||
|
alertDialogBuilder.setPositiveButton(context.getResources().getString(R.string.yes), new DialogInterface.OnClickListener()
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
if (Settings.initializeSettings(context, true))
|
||||||
|
Toast.makeText(context, context.getResources().getString(R.string.settingsSetToDefault), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
alertDialogBuilder.setNegativeButton(context.getResources().getString(R.string.no), null);
|
||||||
|
AlertDialog alertDialog = alertDialogBuilder.create();
|
||||||
|
|
||||||
|
return alertDialog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ActivityMainScreen getActivityMainScreenInstance()
|
||||||
|
{
|
||||||
|
return activityMainScreenInstance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateMainScreen()
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "MainScreen", "Request to update notification.", 5);
|
||||||
|
|
||||||
|
if (activityMainScreenInstance != null)
|
||||||
|
{
|
||||||
|
if(ActivityPermissions.needMorePermissions(activityMainScreenInstance))
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvMainScreenNote.setText(R.string.mainScreenPermissionNote);
|
||||||
|
activityMainScreenInstance.tvMainScreenNote.setVisibility(View.VISIBLE);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvMainScreenNote.setText("");
|
||||||
|
activityMainScreenInstance.tvMainScreenNote.setVisibility(View.GONE);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AutomationService.isMyServiceRunning(activityMainScreenInstance))
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "MainScreen", "Service is running. Updating mainscreen with this info.", 5);
|
||||||
|
uiUpdateRunning = true;
|
||||||
|
activityMainScreenInstance.toggleService.setChecked(true);
|
||||||
|
uiUpdateRunning = false;
|
||||||
|
// if(activityMainScreenInstance.hasWindowFocus())
|
||||||
|
// {
|
||||||
|
try
|
||||||
|
{
|
||||||
|
PointOfInterest activePoi = PointOfInterest.getActivePoi();
|
||||||
|
if (activePoi == null)
|
||||||
|
{
|
||||||
|
PointOfInterest closestPoi = PointOfInterest.getClosestPOI(LocationProvider.getInstance().getCurrentLocation());
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText("none");
|
||||||
|
activityMainScreenInstance.tvClosestPoi.setText(closestPoi.getName());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText(activePoi.getName());
|
||||||
|
activityMainScreenInstance.tvClosestPoi.setText("n./a.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NullPointerException e)
|
||||||
|
{
|
||||||
|
if (PointOfInterest.getPointOfInterestCollection().size() > 0)
|
||||||
|
{
|
||||||
|
if(
|
||||||
|
Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest)
|
||||||
|
&&
|
||||||
|
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationCoarse, AutomationService.getInstance())
|
||||||
|
&&
|
||||||
|
ActivityPermissions.havePermission(ActivityPermissions.permissionNameLocationFine, AutomationService.getInstance())
|
||||||
|
)
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.stillGettingPosition));
|
||||||
|
else
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.locationEngineNotActive));
|
||||||
|
|
||||||
|
activityMainScreenInstance.tvClosestPoi.setText("n./a.");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.noPoisDefinedShort));
|
||||||
|
activityMainScreenInstance.tvClosestPoi.setText("n./a.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvLastRule.setText(Rule.getLastActivatedRule().getName() + " " + activityMainScreenInstance.getResources().getString(R.string.at) + " " + Rule.getLastActivatedRuleActivationTime().toLocaleString());
|
||||||
|
activityMainScreenInstance.updateListView();
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tvLastRule.setText("n./a.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "MainScreen", "Service not running. Updating mainscreen with this info.", 5);
|
||||||
|
activityMainScreenInstance.toggleService.setChecked(false);
|
||||||
|
activityMainScreenInstance.tvActivePoi.setText(activityMainScreenInstance.getResources().getString(R.string.serviceNotRunning));
|
||||||
|
activityMainScreenInstance.tvClosestPoi.setText("");
|
||||||
|
activityMainScreenInstance.tvLastRule.setText("");
|
||||||
|
}
|
||||||
|
|
||||||
|
// uiUpdateRunning = true;
|
||||||
|
if(AutomationService.isMyServiceRunning(ActivityMainScreen.getActivityMainScreenInstance()) && AutomationService.getInstance() != null)
|
||||||
|
{
|
||||||
|
AutomationService.getInstance().checkLockSoundChangesTimeElapsed();
|
||||||
|
|
||||||
|
Calendar end = AutomationService.getInstance().getLockSoundChangesEnd();
|
||||||
|
activityMainScreenInstance.tbLockSound.setChecked(end != null);
|
||||||
|
activityMainScreenInstance.tbLockSound.setEnabled(end != null);
|
||||||
|
|
||||||
|
if(end != null)
|
||||||
|
{
|
||||||
|
Calendar now = Calendar.getInstance();
|
||||||
|
long millis = end.getTimeInMillis() - now.getTimeInMillis();
|
||||||
|
long minutes = millis/1000/60;
|
||||||
|
if(minutes < 60)
|
||||||
|
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(minutes + " min..."));
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double hours = (double)minutes / 60.0;
|
||||||
|
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(Math.round(hours * 100.0) / 100.0) + " h...");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
activityMainScreenInstance.tvlockSoundDuration.setText(String.valueOf(""));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
activityMainScreenInstance.tbLockSound.setChecked(false);
|
||||||
|
activityMainScreenInstance.tbLockSound.setEnabled(false);
|
||||||
|
activityMainScreenInstance.tvlockSoundDuration.setText("");
|
||||||
|
}
|
||||||
|
Settings.writeSettings(activityMainScreenInstance);
|
||||||
|
// uiUpdateRunning = false;
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// Miscellaneous.logEvent("i", "ActivityMainScreen", "Window doesn't have focus. We're not updating anything.", 5);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Miscellaneous.logEvent("i", "ActivityMainScreen", "Activity not running. No need to update.", 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onActivityResult(int requestCode, int resultCode, Intent data)
|
||||||
|
{
|
||||||
|
super.onActivityResult(requestCode, resultCode, data);
|
||||||
|
|
||||||
|
// Miscellaneous.logEvent("i", "ListView", "Notifying ListViewAdapter", 4);
|
||||||
|
|
||||||
|
if (AutomationService.isMyServiceRunning(this))
|
||||||
|
bindToService();
|
||||||
|
|
||||||
|
switch (requestCode)
|
||||||
|
{
|
||||||
|
case ActivityPermissions.requestCodeForPermissions:
|
||||||
|
updateMainScreen();
|
||||||
|
break;
|
||||||
|
case 6000: //settings
|
||||||
|
Settings.readFromPersistentStorage(this);
|
||||||
|
|
||||||
|
if (boundToService && AutomationService.isMyServiceRunning(this))
|
||||||
|
myAutomationService.serviceInterface(serviceCommands.reloadSettings);
|
||||||
|
|
||||||
|
if(AutomationService.isMyServiceRunning(ActivityMainScreen.this))
|
||||||
|
Toast.makeText(this, getResources().getString(R.string.settingsWillTakeTime), Toast.LENGTH_LONG).show();
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (AutomationService.isMyServiceRunning(this))
|
||||||
|
{
|
||||||
|
// Let service reload via binding interface.
|
||||||
|
if (boundToService)
|
||||||
|
{
|
||||||
|
myAutomationService.serviceInterface(serviceCommands.updateNotification); //in case names got changed.
|
||||||
|
unBindFromService();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Let service reload classically.
|
||||||
|
AutomationService service = AutomationService.getInstance();
|
||||||
|
if (service != null)
|
||||||
|
service.applySettingsAndRules();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startAutomationService(Context context, boolean startAtBoot)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (Rule.getRuleCollection().size() > 0)
|
||||||
|
{
|
||||||
|
if (!AutomationService.isMyServiceRunning(context))
|
||||||
|
{
|
||||||
|
// if(myServiceIntent == null) //do we need that line?????
|
||||||
|
myServiceIntent = new Intent(context, AutomationService.class);
|
||||||
|
myServiceIntent.putExtra("startAtBoot", startAtBoot);
|
||||||
|
context.startService(myServiceIntent);
|
||||||
|
} else
|
||||||
|
Miscellaneous.logEvent("w", "Service", context.getResources().getString(R.string.logServiceAlreadyRunning), 3);
|
||||||
|
} else
|
||||||
|
{
|
||||||
|
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStart), Toast.LENGTH_LONG).show();
|
||||||
|
activityMainScreenInstance.toggleService.setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (NullPointerException ne)
|
||||||
|
{
|
||||||
|
Toast.makeText(context, context.getResources().getString(R.string.serviceWontStart), Toast.LENGTH_LONG).show();
|
||||||
|
activityMainScreenInstance.toggleService.setChecked(false);
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Toast.makeText(context, "Error: " + e.getMessage(), Toast.LENGTH_LONG).show();
|
||||||
|
activityMainScreenInstance.toggleService.setChecked(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void stopAutomationService()
|
||||||
|
{
|
||||||
|
if (myServiceIntent == null)
|
||||||
|
myServiceIntent = new Intent(this, AutomationService.class);
|
||||||
|
stopService(myServiceIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onRestart()
|
||||||
|
{
|
||||||
|
super.onRestart();
|
||||||
|
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||||
|
ActivityMainScreen.updateMainScreen();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onStart()
|
||||||
|
{
|
||||||
|
super.onStart();
|
||||||
|
client.connect();
|
||||||
|
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||||
|
ActivityMainScreen.updateMainScreen();
|
||||||
|
AppIndex.AppIndexApi.start(client, getIndexApiAction());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onResume()
|
||||||
|
{
|
||||||
|
super.onResume();
|
||||||
|
toggleService.setChecked(AutomationService.isMyServiceRunning(this));
|
||||||
|
ActivityMainScreen.updateMainScreen();
|
||||||
|
|
||||||
|
if(Build.VERSION.SDK_INT >= 28 && !Settings.noticeAndroid9MicrophoneShown && Rule.isAnyRuleUsing(Trigger_Enum.noiseLevel))
|
||||||
|
{
|
||||||
|
Settings.noticeAndroid9MicrophoneShown = true;
|
||||||
|
Settings.writeSettings(ActivityMainScreen.this);
|
||||||
|
Miscellaneous.messageBox(getResources().getString(R.string.app_name), getResources().getString(R.string.android9RecordAudioNotice) + " " + getResources().getString(R.string.messageNotShownAgain), ActivityMainScreen.this).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(Build.VERSION.SDK_INT >= 29 && !Settings.noticeAndroid10WifiShown && Rule.isAnyRuleUsing(Action.Action_Enum.setWifi))
|
||||||
|
{
|
||||||
|
Settings.noticeAndroid10WifiShown = true;
|
||||||
|
Settings.writeSettings(ActivityMainScreen.this);
|
||||||
|
Miscellaneous.messageBox(getResources().getString(R.string.app_name), getResources().getString(R.string.android10WifiToggleNotice) + " " + getResources().getString(R.string.messageNotShownAgain), ActivityMainScreen.this).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onDestroy()
|
||||||
|
{
|
||||||
|
super.onDestroy();
|
||||||
|
activityMainScreenInstance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void openPrivacyPolicy()
|
||||||
|
{
|
||||||
|
String privacyPolicyUrl = "http://server47.de/automation/privacy.html";
|
||||||
|
|
||||||
|
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(privacyPolicyUrl));
|
||||||
|
startActivity(browserIntent);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateListView()
|
||||||
|
{
|
||||||
|
Miscellaneous.logEvent("i", "ListView", "Attempting to update lvRuleHistory", 4);
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if (lvRuleHistory.getAdapter() == null)
|
||||||
|
lvRuleHistory.setAdapter(ruleHistoryListViewAdapter);
|
||||||
|
|
||||||
|
ruleHistoryListViewAdapter.notifyDataSetChanged();
|
||||||
|
} catch (NullPointerException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||||
|
* See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||||
|
*/
|
||||||
|
public com.google.android.gms.appindexing.Action getIndexApiAction()
|
||||||
|
{
|
||||||
|
Thing object = new Thing.Builder()
|
||||||
|
.setName("ActivityMainScreen Page") // TODO: Define a title for the content shown.
|
||||||
|
// TODO: Make sure this auto-generated URL is correct.
|
||||||
|
.setUrl(Uri.parse("http://[ENTER-YOUR-URL-HERE]"))
|
||||||
|
.build();
|
||||||
|
return new com.google.android.gms.appindexing.Action.Builder(com.google.android.gms.appindexing.Action.TYPE_VIEW)
|
||||||
|
.setObject(object)
|
||||||
|
.setActionStatus(com.google.android.gms.appindexing.Action.STATUS_TYPE_COMPLETED)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onStop()
|
||||||
|
{
|
||||||
|
super.onStop();
|
||||||
|
|
||||||
|
// ATTENTION: This was auto-generated to implement the App Indexing API.
|
||||||
|
// See https://g.co/AppIndexing/AndroidStudio for more information.
|
||||||
|
AppIndex.AppIndexApi.end(client, getIndexApiAction());
|
||||||
|
client.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void showMessageBox(String title, String text)
|
||||||
|
{
|
||||||
|
Miscellaneous.messageBox(title, text, ActivityMainScreen.getActivityMainScreenInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package com.jens.automation2;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
|
import com.google.android.gms.common.GoogleApiAvailability;
|
||||||
|
|
||||||
|
public class MiscellaneousWithGoogleServices
|
||||||
|
{
|
||||||
|
public static boolean isPlayServiceAvailable()
|
||||||
|
{
|
||||||
|
GoogleApiAvailability aa = new GoogleApiAvailability();
|
||||||
|
if(aa.isGooglePlayServicesAvailable(Miscellaneous.getAnyContext()) == ConnectionResult.SUCCESS)
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
1425
app/src/googlePlayFlavor/java/com/jens/automation2/Rule.java
Normal file
1425
app/src/googlePlayFlavor/java/com/jens/automation2/Rule.java
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,54 @@
|
|||||||
|
package com.jens.automation2.location;
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.util.Log;
|
||||||
|
|
||||||
|
import com.google.android.gms.location.Geofence;
|
||||||
|
import com.google.android.gms.location.GeofencingEvent;
|
||||||
|
import com.jens.automation2.Miscellaneous;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static eu.chainfire.libsuperuser.Debug.TAG;
|
||||||
|
|
||||||
|
public class GeofenceBroadcastReceiver extends BroadcastReceiver
|
||||||
|
{
|
||||||
|
@Override
|
||||||
|
public void onReceive(Context context, Intent intent)
|
||||||
|
{
|
||||||
|
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
|
||||||
|
if (geofencingEvent.hasError())
|
||||||
|
{
|
||||||
|
// Miscellaneous.logEvent("i", "Geofence", geofenceTransitionDetails, 2);
|
||||||
|
// String errorMessage = GeofenceStatusCodes.getErrorString(geofencingEvent.getErrorCode());
|
||||||
|
Log.e(TAG, "Geofence error");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get the transition type.
|
||||||
|
int geofenceTransition = geofencingEvent.getGeofenceTransition();
|
||||||
|
|
||||||
|
// Test that the reported transition was of interest.
|
||||||
|
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER || geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT)
|
||||||
|
{
|
||||||
|
// Get the geofences that were triggered. A single event can trigger
|
||||||
|
// multiple geofences.
|
||||||
|
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
|
||||||
|
|
||||||
|
// Get the transition details as a String.
|
||||||
|
String geofenceTransitionDetails = "something happened";//getGeofenceTransitionDetails(this, geofenceTransition, triggeringGeofences);
|
||||||
|
|
||||||
|
// Send notification and log the transition details.
|
||||||
|
Miscellaneous.logEvent("i", "Geofence", geofenceTransitionDetails, 2);
|
||||||
|
Log.i(TAG, geofenceTransitionDetails);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Log the error.
|
||||||
|
// Log.e(TAG, getString(R.string.geofence_transition_invalid_type, geofenceTransition));
|
||||||
|
Log.e("Geofence", String.valueOf(geofenceTransition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,109 @@
|
|||||||
|
package com.jens.automation2.location;
|
||||||
|
|
||||||
|
import android.app.IntentService;
|
||||||
|
import android.app.PendingIntent;
|
||||||
|
import android.content.Intent;
|
||||||
|
|
||||||
|
import androidx.annotation.Nullable;
|
||||||
|
|
||||||
|
import com.google.android.gms.common.api.GoogleApiClient;
|
||||||
|
import com.google.android.gms.location.GeofencingClient;
|
||||||
|
import com.google.android.gms.location.GeofencingRequest;
|
||||||
|
import com.google.android.gms.location.LocationServices;
|
||||||
|
import com.jens.automation2.PointOfInterest;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class GeofenceIntentService extends IntentService
|
||||||
|
{
|
||||||
|
private GeofencingClient mGeofencingClient;
|
||||||
|
protected static GoogleApiClient googleApiClient = null;
|
||||||
|
PendingIntent geofencePendingIntent;
|
||||||
|
|
||||||
|
static GeofenceIntentService instance;
|
||||||
|
|
||||||
|
List<com.google.android.gms.location.Geofence> geoFenceList = new ArrayList<>();
|
||||||
|
|
||||||
|
public static GeofenceIntentService getInstance()
|
||||||
|
{
|
||||||
|
if (instance == null)
|
||||||
|
instance = new GeofenceIntentService("Automation");
|
||||||
|
|
||||||
|
return instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GeofenceIntentService(String name)
|
||||||
|
{
|
||||||
|
super(name);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onHandleIntent(@Nullable Intent intent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCreate()
|
||||||
|
{
|
||||||
|
mGeofencingClient = LocationServices.getGeofencingClient(this);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addFence(PointOfInterest poi)
|
||||||
|
{
|
||||||
|
com.google.android.gms.location.Geofence geofence = new com.google.android.gms.location.Geofence.Builder()
|
||||||
|
.setRequestId(poi.getName()) // Geofence ID
|
||||||
|
.setCircularRegion(poi.getLocation().getLatitude(), poi.getLocation().getLongitude(), (float) poi.getRadius()) // defining fence region
|
||||||
|
.setExpirationDuration(com.google.android.gms.location.Geofence.NEVER_EXPIRE) // expiring date
|
||||||
|
// Transition types that it should look for
|
||||||
|
.setTransitionTypes(com.google.android.gms.location.Geofence.GEOFENCE_TRANSITION_ENTER | com.google.android.gms.location.Geofence.GEOFENCE_TRANSITION_EXIT)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
geoFenceList.add(geofence);
|
||||||
|
|
||||||
|
GeofencingRequest request = new GeofencingRequest.Builder()
|
||||||
|
// Notification to trigger when the Geofence is created
|
||||||
|
.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
|
||||||
|
.addGeofence(geofence) // add a Geofence
|
||||||
|
.build();
|
||||||
|
|
||||||
|
mGeofencingClient.removeGeofences(getGeofencePendingIntent());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void startService()
|
||||||
|
{
|
||||||
|
for (PointOfInterest poi : PointOfInterest.getPointOfInterestCollection())
|
||||||
|
getInstance().addFence(poi);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void stopService()
|
||||||
|
{
|
||||||
|
for (PointOfInterest poi : PointOfInterest.getPointOfInterestCollection())
|
||||||
|
getInstance().addFence(poi);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets a PendingIntent to send with the request to add or remove Geofences. Location Services
|
||||||
|
* issues the Intent inside this PendingIntent whenever a geofence transition occurs for the
|
||||||
|
* current list of geofences.
|
||||||
|
*
|
||||||
|
* @return A PendingIntent for the IntentService that handles geofence transitions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private PendingIntent getGeofencePendingIntent()
|
||||||
|
{
|
||||||
|
// Reuse the PendingIntent if we already have it.
|
||||||
|
if (geofencePendingIntent != null)
|
||||||
|
{
|
||||||
|
return geofencePendingIntent;
|
||||||
|
}
|
||||||
|
Intent intent = new Intent(this, GeofenceBroadcastReceiver.class);
|
||||||
|
// We use FLAG_UPDATE_CURRENT so that we get the same pending intent back when
|
||||||
|
// calling addGeofences() and removeGeofences().
|
||||||
|
geofencePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||||
|
return geofencePendingIntent;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,6 @@ import android.util.Log;
|
|||||||
import com.google.android.gms.common.ConnectionResult;
|
import com.google.android.gms.common.ConnectionResult;
|
||||||
import com.google.android.gms.common.GooglePlayServicesUtil;
|
import com.google.android.gms.common.GooglePlayServicesUtil;
|
||||||
import com.google.android.gms.common.api.GoogleApiClient;
|
import com.google.android.gms.common.api.GoogleApiClient;
|
||||||
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
|
|
||||||
import com.google.android.gms.location.ActivityRecognition;
|
import com.google.android.gms.location.ActivityRecognition;
|
||||||
import com.google.android.gms.location.ActivityRecognitionApi;
|
import com.google.android.gms.location.ActivityRecognitionApi;
|
||||||
import com.google.android.gms.location.ActivityRecognitionResult;
|
import com.google.android.gms.location.ActivityRecognitionResult;
|
@ -34,11 +34,14 @@ import android.widget.ListView;
|
|||||||
import android.widget.TextView;
|
import android.widget.TextView;
|
||||||
import android.widget.Toast;
|
import android.widget.Toast;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
import com.jens.automation2.Action.Action_Enum;
|
import com.jens.automation2.Action.Action_Enum;
|
||||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||||
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
|
||||||
import com.jens.automation2.receivers.NfcReceiver;
|
import com.jens.automation2.receivers.NfcReceiver;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
|
|
||||||
@ -489,7 +492,8 @@ public class ActivityManageSpecificRule extends Activity
|
|||||||
.setTitle(getResources().getString(R.string.selectTypeOfTrigger))
|
.setTitle(getResources().getString(R.string.selectTypeOfTrigger))
|
||||||
.setAdapter(adapter, new DialogInterface.OnClickListener()
|
.setAdapter(adapter, new DialogInterface.OnClickListener()
|
||||||
{
|
{
|
||||||
public void onClick(DialogInterface dialog, int which)
|
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
{
|
{
|
||||||
triggerType = Trigger_Enum.values()[which];
|
triggerType = Trigger_Enum.values()[which];
|
||||||
|
|
||||||
@ -530,13 +534,25 @@ public class ActivityManageSpecificRule 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.activityDetection)
|
else if(triggerType == Trigger_Enum.activityDetection)
|
||||||
{
|
{
|
||||||
if(ActivityDetectionReceiver.isPlayServiceAvailable())
|
try
|
||||||
{
|
{
|
||||||
newTrigger.setTriggerType(Trigger_Enum.activityDetection);
|
Method m = Miscellaneous.getClassMethodReflective("ActivityDetectionReceiver", "isPlayServiceAvailable");
|
||||||
getTriggerActivityDetectionDialog().show();
|
if(m != null)
|
||||||
|
{
|
||||||
|
boolean available = (Boolean)m.invoke(null);
|
||||||
|
if(available)
|
||||||
|
{
|
||||||
|
newTrigger.setTriggerType(Trigger_Enum.activityDetection);
|
||||||
|
getTriggerActivityDetectionDialog().show();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
Toast.makeText(myContext, getResources().getString(R.string.triggerOnlyAvailableIfPlayServicesInstalled), Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException | InvocationTargetException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
Toast.makeText(myContext, getResources().getString(R.string.triggerOnlyAvailableIfPlayServicesInstalled), Toast.LENGTH_LONG).show();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if(triggerType == Trigger_Enum.nfcTag)
|
else if(triggerType == Trigger_Enum.nfcTag)
|
||||||
@ -898,25 +914,52 @@ public class ActivityManageSpecificRule extends Activity
|
|||||||
|
|
||||||
return alertDialog;
|
return alertDialog;
|
||||||
}
|
}
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||||
private AlertDialog getTriggerActivityDetectionDialog()
|
private AlertDialog getTriggerActivityDetectionDialog()
|
||||||
{
|
{
|
||||||
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
|
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
|
||||||
|
|
||||||
alertDialog.setTitle(Miscellaneous.getAnyContext().getResources().getString(R.string.selectTypeOfActivity));
|
alertDialog.setTitle(Miscellaneous.getAnyContext().getResources().getString(R.string.selectTypeOfActivity));
|
||||||
String[] choices = ActivityDetectionReceiver.getAllDescriptions();
|
|
||||||
alertDialog.setItems(choices, new DialogInterface.OnClickListener()
|
Method m = Miscellaneous.getClassMethodReflective("ActivityDetectionReceiver", "getAllDescriptions");
|
||||||
{
|
if(m != null)
|
||||||
@Override
|
{
|
||||||
public void onClick(DialogInterface dialog, int which)
|
String[] choices = new String[0];
|
||||||
|
try
|
||||||
{
|
{
|
||||||
newTrigger.setActivityDetectionType(ActivityDetectionReceiver.getAllTypes()[which]);
|
choices = (String[])m.invoke(null);
|
||||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
alertDialog.setItems(choices, new DialogInterface.OnClickListener()
|
||||||
refreshTriggerList();
|
{
|
||||||
|
@Override
|
||||||
|
public void onClick(DialogInterface dialog, int which)
|
||||||
|
{
|
||||||
|
Method m = Miscellaneous.getClassMethodReflective("ActivityDetectionReceiver", "getAllTypes");
|
||||||
|
if(m != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Integer[] choices = (Integer[])m.invoke(null);
|
||||||
|
|
||||||
|
newTrigger.setActivityDetectionType(choices[which]);
|
||||||
|
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||||
|
refreshTriggerList();
|
||||||
|
}
|
||||||
|
catch (IllegalAccessException | InvocationTargetException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
catch (IllegalAccessException | InvocationTargetException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return alertDialog.create();
|
return alertDialog.create();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class GenerateApplicationSelectionsDialogTask extends AsyncTask<ActivityManageSpecificRule, Void, String[]>
|
private static class GenerateApplicationSelectionsDialogTask extends AsyncTask<ActivityManageSpecificRule, Void, String[]>
|
||||||
{
|
{
|
||||||
|
@ -48,6 +48,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.lang.Thread.UncaughtExceptionHandler;
|
import java.lang.Thread.UncaughtExceptionHandler;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.math.RoundingMode;
|
import java.math.RoundingMode;
|
||||||
import java.net.HttpURLConnection;
|
import java.net.HttpURLConnection;
|
||||||
@ -72,12 +73,9 @@ import javax.net.ssl.X509TrustManager;
|
|||||||
import static com.jens.automation2.AutomationService.NOTIFICATION_CHANNEL_ID;
|
import static com.jens.automation2.AutomationService.NOTIFICATION_CHANNEL_ID;
|
||||||
import static com.jens.automation2.AutomationService.channelName;
|
import static com.jens.automation2.AutomationService.channelName;
|
||||||
|
|
||||||
//import android.R.string;
|
|
||||||
//import android.util.Log;
|
|
||||||
|
|
||||||
public class Miscellaneous extends Service
|
public class Miscellaneous extends Service
|
||||||
{
|
{
|
||||||
private static String writeableFolderStringCache = null;
|
protected static String writeableFolderStringCache = null;
|
||||||
public static final String lineSeparator = System.getProperty("line.separator");
|
public static final String lineSeparator = System.getProperty("line.separator");
|
||||||
|
|
||||||
public static String downloadURL(String url, String username, String password)
|
public static String downloadURL(String url, String username, String password)
|
||||||
@ -884,4 +882,26 @@ public class Miscellaneous extends Service
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static Method getClassMethodReflective(String className, String methodName)
|
||||||
|
{
|
||||||
|
Class atRecClass = null;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
atRecClass = Class.forName("ActivityDetectionReceiver");
|
||||||
|
for(Method m : atRecClass.getMethods())
|
||||||
|
{
|
||||||
|
if(m.getName().equalsIgnoreCase("isPlayServiceAvailable"))
|
||||||
|
{
|
||||||
|
return m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
@ -4,7 +4,6 @@ import android.util.Log;
|
|||||||
|
|
||||||
import com.jens.automation2.location.CellLocationChangedReceiver;
|
import com.jens.automation2.location.CellLocationChangedReceiver;
|
||||||
import com.jens.automation2.location.WifiBroadcastReceiver;
|
import com.jens.automation2.location.WifiBroadcastReceiver;
|
||||||
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
|
||||||
import com.jens.automation2.receivers.AlarmListener;
|
import com.jens.automation2.receivers.AlarmListener;
|
||||||
import com.jens.automation2.receivers.AutomationListenerInterface;
|
import com.jens.automation2.receivers.AutomationListenerInterface;
|
||||||
import com.jens.automation2.receivers.BatteryReceiver;
|
import com.jens.automation2.receivers.BatteryReceiver;
|
||||||
|
@ -2,10 +2,14 @@ package com.jens.automation2;
|
|||||||
|
|
||||||
import android.bluetooth.BluetoothDevice;
|
import android.bluetooth.BluetoothDevice;
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
|
import android.os.Build;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
|
||||||
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
|
||||||
import com.jens.automation2.receivers.BluetoothReceiver;
|
import com.jens.automation2.receivers.BluetoothReceiver;
|
||||||
|
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
|
import java.lang.reflect.Method;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
|
||||||
@ -215,22 +219,13 @@ public class Trigger
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@Override
|
@Override
|
||||||
public String toString()
|
public String toString()
|
||||||
{
|
{
|
||||||
StringBuilder returnString = new StringBuilder();
|
StringBuilder returnString = new StringBuilder();
|
||||||
|
|
||||||
/*
|
|
||||||
* public enum TriggerType_Enum { pointOfInterest, timeFrame, event };
|
|
||||||
public enum Event_Enum { charging_started, charging_stopped, usb_connected, usb_disconnected };
|
|
||||||
|
|
||||||
private TriggerType_Enum triggerType;
|
|
||||||
private PointOfInterest pointOfInterest;
|
|
||||||
private Event_Enum event;
|
|
||||||
private TimeFrame timeFrame;
|
|
||||||
*/
|
|
||||||
|
|
||||||
switch(this.getTriggerType())
|
switch(this.getTriggerType())
|
||||||
{
|
{
|
||||||
case charging:
|
case charging:
|
||||||
@ -358,8 +353,27 @@ public class Trigger
|
|||||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.closeTo) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.nfcTag) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.withLabel) + " " + this.getNfcTagId());
|
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.closeTo) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.nfcTag) + " " + Miscellaneous.getAnyContext().getResources().getString(R.string.withLabel) + " " + this.getNfcTagId());
|
||||||
break;
|
break;
|
||||||
case activityDetection:
|
case activityDetection:
|
||||||
// This type doesn't have an activate/deactivate equivalent, at least not yet.
|
if(ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), "com.google.android.gms.permission.ACTIVITY_RECOGNITION"))
|
||||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivity) + " " + ActivityDetectionReceiver.getDescription(getActivityDetectionType()));
|
{
|
||||||
|
// This type doesn't have an activate/deactivate equivalent, at least not yet.
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Class activityDetection = Class.forName("com.jens.automation2.receivers.ActivityDetectionReceiver");
|
||||||
|
for(Method method : activityDetection.getMethods())
|
||||||
|
{
|
||||||
|
if(method.getName().equalsIgnoreCase("getDescription"))
|
||||||
|
returnString.append(method.invoke(getActivityDetectionType()));
|
||||||
|
// returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivity) + " " + activityDetection.getDescription(getActivityDetectionType()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e)
|
||||||
|
{
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
else
|
||||||
|
returnString.append("Invalid trigger. This application version cannot handle ActivityDetection.");
|
||||||
break;
|
break;
|
||||||
case bluetoothConnection:
|
case bluetoothConnection:
|
||||||
String device = Miscellaneous.getAnyContext().getResources().getString(R.string.anyDevice);
|
String device = Miscellaneous.getAnyContext().getResources().getString(R.string.anyDevice);
|
||||||
|
@ -237,8 +237,8 @@ public class LocationProvider
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest))
|
// if(Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest))
|
||||||
GeofenceIntentService.startService();
|
// GeofenceIntentService.startService();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user