Initial commit
This commit is contained in:
parent
a8950597d0
commit
8690dec2e2
@ -7,7 +7,7 @@ android {
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.jens.automation2"
|
||||
minSdkVersion 14
|
||||
minSdkVersion 16
|
||||
compileSdkVersion 29
|
||||
buildToolsVersion '29.0.2'
|
||||
useLibrary 'org.apache.http.legacy'
|
||||
@ -64,16 +64,16 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:16.0.1'
|
||||
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:15.0.1'
|
||||
googlePlayFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
|
||||
googlePlayFlavorImplementation 'com.google.android.gms:play-services-location:17.1.0'
|
||||
|
||||
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:16.0.1'
|
||||
apkFlavorImplementation 'com.google.android.gms:play-services-location:15.0.1'
|
||||
apkFlavorImplementation 'com.google.firebase:firebase-appindexing:19.2.0'
|
||||
apkFlavorImplementation 'com.google.android.gms:play-services-location:17.1.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.+'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
|
||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
|
||||
androidTestImplementation 'androidx.test.ext:junit:1.1.2'
|
||||
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.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;
|
@ -34,11 +34,14 @@ import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
||||
import androidx.annotation.RequiresApi;
|
||||
|
||||
import com.jens.automation2.Action.Action_Enum;
|
||||
import com.jens.automation2.Trigger.Trigger_Enum;
|
||||
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
||||
import com.jens.automation2.receivers.NfcReceiver;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
|
||||
@ -489,7 +492,8 @@ public class ActivityManageSpecificRule extends Activity
|
||||
.setTitle(getResources().getString(R.string.selectTypeOfTrigger))
|
||||
.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];
|
||||
|
||||
@ -530,13 +534,25 @@ public class ActivityManageSpecificRule extends Activity
|
||||
booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)};
|
||||
else if(triggerType == Trigger_Enum.activityDetection)
|
||||
{
|
||||
if(ActivityDetectionReceiver.isPlayServiceAvailable())
|
||||
try
|
||||
{
|
||||
newTrigger.setTriggerType(Trigger_Enum.activityDetection);
|
||||
getTriggerActivityDetectionDialog().show();
|
||||
Method m = Miscellaneous.getClassMethodReflective("ActivityDetectionReceiver", "isPlayServiceAvailable");
|
||||
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;
|
||||
}
|
||||
else if(triggerType == Trigger_Enum.nfcTag)
|
||||
@ -898,25 +914,52 @@ public class ActivityManageSpecificRule extends Activity
|
||||
|
||||
return alertDialog;
|
||||
}
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
private AlertDialog getTriggerActivityDetectionDialog()
|
||||
{
|
||||
AlertDialog.Builder alertDialog = new AlertDialog.Builder(this);
|
||||
|
||||
alertDialog.setTitle(Miscellaneous.getAnyContext().getResources().getString(R.string.selectTypeOfActivity));
|
||||
String[] choices = ActivityDetectionReceiver.getAllDescriptions();
|
||||
alertDialog.setItems(choices, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which)
|
||||
|
||||
Method m = Miscellaneous.getClassMethodReflective("ActivityDetectionReceiver", "getAllDescriptions");
|
||||
if(m != null)
|
||||
{
|
||||
String[] choices = new String[0];
|
||||
try
|
||||
{
|
||||
newTrigger.setActivityDetectionType(ActivityDetectionReceiver.getAllTypes()[which]);
|
||||
ruleToEdit.getTriggerSet().add(newTrigger);
|
||||
refreshTriggerList();
|
||||
choices = (String[])m.invoke(null);
|
||||
alertDialog.setItems(choices, new DialogInterface.OnClickListener()
|
||||
{
|
||||
@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();
|
||||
}
|
||||
}
|
||||
|
||||
private static class GenerateApplicationSelectionsDialogTask extends AsyncTask<ActivityManageSpecificRule, Void, String[]>
|
||||
{
|
||||
|
@ -48,6 +48,7 @@ import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.Thread.UncaughtExceptionHandler;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigDecimal;
|
||||
import java.math.RoundingMode;
|
||||
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.channelName;
|
||||
|
||||
//import android.R.string;
|
||||
//import android.util.Log;
|
||||
|
||||
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 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.WifiBroadcastReceiver;
|
||||
import com.jens.automation2.receivers.ActivityDetectionReceiver;
|
||||
import com.jens.automation2.receivers.AlarmListener;
|
||||
import com.jens.automation2.receivers.AutomationListenerInterface;
|
||||
import com.jens.automation2.receivers.BatteryReceiver;
|
||||
|
@ -2,10 +2,14 @@ package com.jens.automation2;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
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 java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.ArrayList;
|
||||
|
||||
|
||||
@ -215,22 +219,13 @@ public class Trigger
|
||||
}
|
||||
|
||||
|
||||
@RequiresApi(api = Build.VERSION_CODES.KITKAT)
|
||||
@SuppressWarnings("unused")
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
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())
|
||||
{
|
||||
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());
|
||||
break;
|
||||
case activityDetection:
|
||||
// This type doesn't have an activate/deactivate equivalent, at least not yet.
|
||||
returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivity) + " " + ActivityDetectionReceiver.getDescription(getActivityDetectionType()));
|
||||
if(ActivityPermissions.isPermissionDeclaratedInManifest(Miscellaneous.getAnyContext(), "com.google.android.gms.permission.ACTIVITY_RECOGNITION"))
|
||||
{
|
||||
// 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;
|
||||
case bluetoothConnection:
|
||||
String device = Miscellaneous.getAnyContext().getResources().getString(R.string.anyDevice);
|
||||
|
@ -237,8 +237,8 @@ public class LocationProvider
|
||||
}
|
||||
else
|
||||
{
|
||||
if(Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest))
|
||||
GeofenceIntentService.startService();
|
||||
// if(Rule.isAnyRuleUsing(Trigger_Enum.pointOfInterest))
|
||||
// GeofenceIntentService.startService();
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user