diff --git a/app/build.gradle b/app/build.gradle index 797b6ae..a65e679 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -40,7 +40,7 @@ android { googlePlayFlavor { dimension "version" - applicationIdSuffix ".googlePlay" +// applicationIdSuffix ".googlePlay" versionNameSuffix "-googlePlay" targetSdkVersion 29 } @@ -48,7 +48,7 @@ android { fdroidFlavor { dimension "version" - applicationIdSuffix ".fdroid" +// applicationIdSuffix ".fdroid" versionNameSuffix "-fdroid" targetSdkVersion 28 } @@ -56,7 +56,7 @@ android { apkFlavor { dimension "version" - applicationIdSuffix ".apk" +// applicationIdSuffix ".apk" versionNameSuffix "-apk" targetSdkVersion 28 } diff --git a/app/src/apkFlavor/java/com/jens/automation2/MyGoogleServicesInterface.java b/app/src/apkFlavor/java/com/jens/automation2/MyGoogleServicesInterface.java deleted file mode 100644 index 3382ce6..0000000 --- a/app/src/apkFlavor/java/com/jens/automation2/MyGoogleServicesInterface.java +++ /dev/null @@ -1,16 +0,0 @@ -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; - } -} diff --git a/app/src/apkFlavor/java/com/jens/automation2/receivers/ActivityDetectionReceiver.java b/app/src/apkFlavor/java/com/jens/automation2/receivers/ActivityDetectionReceiver.java index 93a0347..90ca7e6 100644 --- a/app/src/apkFlavor/java/com/jens/automation2/receivers/ActivityDetectionReceiver.java +++ b/app/src/apkFlavor/java/com/jens/automation2/receivers/ActivityDetectionReceiver.java @@ -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; @@ -199,6 +198,15 @@ public class ActivityDetectionReceiver extends IntentService implements Automati { Miscellaneous.logEvent("e", "ActivityDetectionReceiver", "Error stopping ActivityDetectionReceiver: " + Log.getStackTraceString(ex), 3); } + } + + public static boolean isPlayServiceAvailable() + { + if(GooglePlayServicesUtil.isGooglePlayServicesAvailable(Miscellaneous.getAnyContext()) == ConnectionResult.SUCCESS) + return true; + else + return false; + } @Override diff --git a/app/src/googlePlayFlavor/java/com/jens/automation2/MyGoogleServicesInterface.java b/app/src/googlePlayFlavor/java/com/jens/automation2/MyGoogleServicesInterface.java deleted file mode 100644 index 1d983ec..0000000 --- a/app/src/googlePlayFlavor/java/com/jens/automation2/MyGoogleServicesInterface.java +++ /dev/null @@ -1,16 +0,0 @@ -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; - } -} \ No newline at end of file diff --git a/app/src/main/java/com/jens/automation2/ActivityManageSpecificRule.java b/app/src/main/java/com/jens/automation2/ActivityManageSpecificRule.java index dac191b..ec9e222 100644 --- a/app/src/main/java/com/jens/automation2/ActivityManageSpecificRule.java +++ b/app/src/main/java/com/jens/automation2/ActivityManageSpecificRule.java @@ -47,6 +47,8 @@ import java.util.Collections; public class ActivityManageSpecificRule extends Activity { + final static String activityDetectionClassPath = "com.jens.automation2.receivers.ActivityDetectionReceiver"; + public Context context; private Button cmdTriggerAdd, cmdActionAdd, cmdSaveRule; private ListView triggerListView, actionListView; @@ -536,7 +538,7 @@ public class ActivityManageSpecificRule extends Activity { try { - Method m = Miscellaneous.getClassMethodReflective("ActivityDetectionReceiver", "isPlayServiceAvailable"); + Method m = Miscellaneous.getClassMethodReflective(activityDetectionClassPath, "isPlayServiceAvailable"); if(m != null) { boolean available = (Boolean)m.invoke(null); @@ -548,6 +550,8 @@ public class ActivityManageSpecificRule extends Activity else Toast.makeText(myContext, getResources().getString(R.string.triggerOnlyAvailableIfPlayServicesInstalled), Toast.LENGTH_LONG).show(); } + else + Miscellaneous.messageBox(getResources().getString(R.string.error), getResources().getString(R.string.featureNotInFdroidVersion), ActivityManageSpecificRule.this).show(); } catch (IllegalAccessException | InvocationTargetException e) { @@ -921,7 +925,7 @@ public class ActivityManageSpecificRule extends Activity alertDialog.setTitle(Miscellaneous.getAnyContext().getResources().getString(R.string.selectTypeOfActivity)); - Method m = Miscellaneous.getClassMethodReflective("ActivityDetectionReceiver", "getAllDescriptions"); + Method m = Miscellaneous.getClassMethodReflective(activityDetectionClassPath, "getAllDescriptions"); if(m != null) { String[] choices = new String[0]; @@ -933,12 +937,12 @@ public class ActivityManageSpecificRule extends Activity @Override public void onClick(DialogInterface dialog, int which) { - Method m = Miscellaneous.getClassMethodReflective("ActivityDetectionReceiver", "getAllTypes"); + Method m = Miscellaneous.getClassMethodReflective(activityDetectionClassPath, "getAllTypes"); if(m != null) { try { - Integer[] choices = (Integer[])m.invoke(null); + int[] choices = (int[])m.invoke(null); newTrigger.setActivityDetectionType(choices[which]); ruleToEdit.getTriggerSet().add(newTrigger); diff --git a/app/src/main/java/com/jens/automation2/Miscellaneous.java b/app/src/main/java/com/jens/automation2/Miscellaneous.java index 29c60de..4e04094 100644 --- a/app/src/main/java/com/jens/automation2/Miscellaneous.java +++ b/app/src/main/java/com/jens/automation2/Miscellaneous.java @@ -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.InvocationTargetException; import java.lang.reflect.Method; import java.math.BigDecimal; import java.math.RoundingMode; @@ -885,13 +886,13 @@ public class Miscellaneous extends Service public static Method getClassMethodReflective(String className, String methodName) { - Class atRecClass = null; + Class foundClass = null; try { - atRecClass = Class.forName("ActivityDetectionReceiver"); - for(Method m : atRecClass.getMethods()) + foundClass = Class.forName(className); + for(Method m : foundClass.getDeclaredMethods()) { - if(m.getName().equalsIgnoreCase("isPlayServiceAvailable")) + if(m.getName().equalsIgnoreCase(methodName)) { return m; } @@ -904,4 +905,27 @@ public class Miscellaneous extends Service return null; } + + public static Object runMethodReflective(String className, String methodName, Object[] params) + { + Method m = getClassMethodReflective(className, methodName); + Object result = null; + try + { + if(params == null) + result = m.invoke((Object[]) null); + else + result = m.invoke(null, params); + } + catch (IllegalAccessException e) + { + e.printStackTrace(); + } + catch (InvocationTargetException e) + { + e.printStackTrace(); + } + + return result; + } } \ No newline at end of file diff --git a/app/src/main/java/com/jens/automation2/ReceiverCoordinator.java b/app/src/main/java/com/jens/automation2/ReceiverCoordinator.java index 46e5003..08d0d7e 100644 --- a/app/src/main/java/com/jens/automation2/ReceiverCoordinator.java +++ b/app/src/main/java/com/jens/automation2/ReceiverCoordinator.java @@ -1,5 +1,6 @@ package com.jens.automation2; +import android.os.Build; import android.util.Log; import com.jens.automation2.location.CellLocationChangedReceiver; @@ -15,6 +16,13 @@ import com.jens.automation2.receivers.PhoneStatusListener; import com.jens.automation2.receivers.ProcessListener; import com.jens.automation2.receivers.TimeZoneListener; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +import androidx.annotation.RequiresApi; + +import static com.jens.automation2.ActivityManageSpecificRule.activityDetectionClassPath; + /** * Created by jens on 08.03.2017. */ @@ -28,28 +36,58 @@ public class ReceiverCoordinator * - Accelerometer */ - public static final Class[] allImplementers = { - ActivityDetectionReceiver.class, - AlarmListener.class, - BatteryReceiver.class, - BluetoothReceiver.class, - ConnectivityReceiver.class, - HeadphoneJackListener.class, - //NfcReceiver.class, - NoiseListener.class, - PhoneStatusListener.class, - ProcessListener.class, - TimeZoneListener.class - }; + public static Class[] allImplementers; + + static void fillImplementers() + { + try + { + Class adClass = Class.forName("ActivityDetectionReceiver"); + allImplementers = new Class[] { + adClass, + AlarmListener.class, + BatteryReceiver.class, + BluetoothReceiver.class, + ConnectivityReceiver.class, + HeadphoneJackListener.class, + //NfcReceiver.class, + NoiseListener.class, + PhoneStatusListener.class, + ProcessListener.class, + TimeZoneListener.class + }; + } + catch (ClassNotFoundException e) + { + e.printStackTrace(); + + allImplementers = new Class[] { + AlarmListener.class, + BatteryReceiver.class, + BluetoothReceiver.class, + ConnectivityReceiver.class, + HeadphoneJackListener.class, + //NfcReceiver.class, + NoiseListener.class, + PhoneStatusListener.class, + ProcessListener.class, + TimeZoneListener.class + }; + } + } private static AutomationListenerInterface[] listeners = null; + @RequiresApi(api = Build.VERSION_CODES.KITKAT) public static void startAllReceivers() { /* * New procedure: * Save instances of Listeners in ArrayList and run them. */ + + fillImplementers(); + try { if(listeners == null) @@ -130,7 +168,10 @@ public class ReceiverCoordinator //startActivityDetectionReceiver if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection)) - ActivityDetectionReceiver.startActivityDetectionReceiver(); + { + Miscellaneous.runMethodReflective(activityDetectionClassPath, "startActivityDetectionReceiver", null); +// ActivityDetectionReceiver.startActivityDetectionReceiver(); + } //startBluetoothReceiver if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.bluetoothConnection)) @@ -153,7 +194,8 @@ public class ReceiverCoordinator AlarmListener.stopAlarmListener(AutomationService.getInstance()); NoiseListener.stopNoiseListener(); ProcessListener.stopProcessListener(AutomationService.getInstance()); - ActivityDetectionReceiver.stopActivityDetectionReceiver(); + Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "stopActivityDetectionReceiver", null); +// ActivityDetectionReceiver.stopActivityDetectionReceiver(); BluetoothReceiver.stopBluetoothReceiver(); HeadphoneJackListener.getInstance().stopListener(AutomationService.getInstance()); } @@ -213,25 +255,32 @@ public class ReceiverCoordinator if(Rule.isAnyRuleUsing(Trigger.Trigger_Enum.activityDetection)) { - if(ActivityDetectionReceiver.isActivityDetectionReceiverRunning()) + boolean isRunning = (Boolean)Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "isActivityDetectionReceiverRunning", null); + if(isRunning) { Miscellaneous.logEvent("i", "LocationProvider", "Restarting ActivityDetectionReceiver because used in a new/changed rule.", 4); - if(ActivityDetectionReceiver.haveAllPermission()) - ActivityDetectionReceiver.restartActivityDetectionReceiver(); + boolean haveAllPerms = (Boolean)Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "haveAllPermission", null); + if(haveAllPerms) + Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "restartActivityDetectionReceiver", null); +// ActivityDetectionReceiver.restartActivityDetectionReceiver(); } else { Miscellaneous.logEvent("i", "LocationProvider", "Starting ActivityDetectionReceiver because used in a new/changed rule.", 4); - if(ActivityDetectionReceiver.haveAllPermission()) - ActivityDetectionReceiver.startActivityDetectionReceiver(); + boolean haveAllPerms = (Boolean)Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "haveAllPermission", null); + if(haveAllPerms) + Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "startActivityDetectionReceiver", null); +// ActivityDetectionReceiver.startActivityDetectionReceiver(); } } else { - if(ActivityDetectionReceiver.isActivityDetectionReceiverRunning()) + boolean isRunning = (Boolean)Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "isActivityDetectionReceiverRunning", null); + if(isRunning) { Miscellaneous.logEvent("i", "LocationProvider", "Shutting down ActivityDetectionReceiver because not used in any rule.", 4); - ActivityDetectionReceiver.stopActivityDetectionReceiver(); + Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "stopActivityDetectionReceiver", null); +// ActivityDetectionReceiver.stopActivityDetectionReceiver(); } } diff --git a/app/src/main/java/com/jens/automation2/Trigger.java b/app/src/main/java/com/jens/automation2/Trigger.java index 243ddd7..205a9b8 100644 --- a/app/src/main/java/com/jens/automation2/Trigger.java +++ b/app/src/main/java/com/jens/automation2/Trigger.java @@ -356,20 +356,20 @@ public class Trigger 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(); - } +// try +// { + returnString.append(Miscellaneous.runMethodReflective(ActivityManageSpecificRule.activityDetectionClassPath, "getDescription", new Object[] { getActivityDetectionType() } )); +// for(Method method : activityDetection.getMethods()) +// { +// if(method.getName().equalsIgnoreCase("getDescription")) +// returnString.append(method.invoke()); +//// returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.detectedActivity) + " " + activityDetection.getDescription(getActivityDetectionType())); +// } +// } +// catch (ClassNotFoundException | IllegalAccessException | InvocationTargetException e) +// { +// e.printStackTrace(); +// } } else diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 45bda8b..0c16f3d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -597,4 +597,6 @@ Read location in background. This device does not seem to have bluetooth. You can still continue configuring this, but it will most likely not have an effect. Create or edit locations + Error + This feature is based on non-free software. Therefore is is not available in the F-Droid version. \ No newline at end of file