new triggers: service or device starts
This commit is contained in:
		| @@ -21,108 +21,109 @@ public class Action | ||||
| 	public static final String intentPairSeparator = "intPairSplit"; | ||||
| 	public static final String vibrateSeparator = ","; | ||||
|  | ||||
| 	public enum Action_Enum {	 | ||||
| 								setWifi, | ||||
| 								setBluetooth, | ||||
| 								setUsbTethering, | ||||
| 								setWifiTethering, | ||||
| 								setBluetoothTethering, | ||||
| 								setDisplayRotation, | ||||
| 								turnWifiOn,turnWifiOff, | ||||
| 								turnBluetoothOn,turnBluetoothOff, | ||||
| 								triggerUrl, | ||||
| 								changeSoundProfile, | ||||
| 								turnUsbTetheringOn,turnUsbTetheringOff, | ||||
| 								turnWifiTetheringOn,turnWifiTetheringOff, | ||||
| 								enableScreenRotation,disableScreenRotation, | ||||
| 								startOtherActivity, | ||||
| 								waitBeforeNextAction, | ||||
| 								turnScreenOnOrOff, | ||||
| 								setAirplaneMode, | ||||
| 								setDataConnection, | ||||
| 								speakText, | ||||
| 								playMusic, | ||||
| 								controlMediaPlayback, | ||||
| 								setScreenBrightness, | ||||
| 								playSound, | ||||
| 								vibrate, | ||||
| 								createNotification, | ||||
| 								closeNotification, | ||||
| 								sendTextMessage; | ||||
| 								 | ||||
| 								public String getFullName(Context context) | ||||
| 								{ | ||||
| 									switch(this) | ||||
| 									{ | ||||
| 										case setWifi: | ||||
| 											return context.getResources().getString(R.string.actionSetWifi); | ||||
| 										case setBluetooth: | ||||
| 											return context.getResources().getString(R.string.actionSetBluetooth); | ||||
| 										case setWifiTethering: | ||||
| 											return context.getResources().getString(R.string.actionSetWifiTethering); | ||||
| 										case setBluetoothTethering: | ||||
| 											return context.getResources().getString(R.string.actionSetBluetoothTethering); | ||||
| 										case setUsbTethering: | ||||
| 											return context.getResources().getString(R.string.actionSetUsbTethering); | ||||
| 										case setDisplayRotation: | ||||
| 											return context.getResources().getString(R.string.actionSetDisplayRotation); | ||||
| 										case turnWifiOn: | ||||
| 											return context.getResources().getString(R.string.actionTurnWifiOn); | ||||
| 										case turnWifiOff: | ||||
| 											return context.getResources().getString(R.string.actionTurnWifiOff); | ||||
| 										case turnBluetoothOn: | ||||
| 											return context.getResources().getString(R.string.actionTurnBluetoothOn); | ||||
| 										case turnBluetoothOff: | ||||
| 											return context.getResources().getString(R.string.actionTurnBluetoothOff); | ||||
| 										case triggerUrl: | ||||
| 											return context.getResources().getString(R.string.actionTriggerUrl); | ||||
| 										case changeSoundProfile: | ||||
| 											return context.getResources().getString(R.string.actionChangeSoundProfile); | ||||
| 										case turnUsbTetheringOn: | ||||
| 											return context.getResources().getString(R.string.actionTurnUsbTetheringOn); | ||||
| 										case turnUsbTetheringOff: | ||||
| 											return context.getResources().getString(R.string.actionTurnUsbTetheringOff); | ||||
| 										case turnWifiTetheringOn: | ||||
| 											return context.getResources().getString(R.string.actionTurnWifiTetheringOn); | ||||
| 										case turnWifiTetheringOff: | ||||
| 											return context.getResources().getString(R.string.actionTurnWifiTetheringOff); | ||||
| 										case enableScreenRotation: | ||||
| 											return context.getResources().getString(R.string.actionEnableScreenRotation); | ||||
| 										case disableScreenRotation: | ||||
| 											return context.getResources().getString(R.string.actionDisableScreenRotation); | ||||
| 										case startOtherActivity: | ||||
| 											return context.getResources().getString(R.string.startOtherActivity); | ||||
| 										case waitBeforeNextAction: | ||||
| 											return context.getResources().getString(R.string.waitBeforeNextAction); | ||||
| 										case turnScreenOnOrOff: | ||||
| 											return context.getResources().getString(R.string.turnScreenOnOrOff); | ||||
| 										case vibrate: | ||||
| 											return context.getResources().getString(R.string.vibrate); | ||||
| 										case setAirplaneMode: | ||||
| 											return context.getResources().getString(R.string.airplaneMode); | ||||
| 										case setDataConnection: | ||||
| 											return context.getResources().getString(R.string.actionDataConnection); | ||||
| 										case speakText: | ||||
| 											return context.getResources().getString(R.string.actionSpeakText); | ||||
| 										case playMusic: | ||||
| 											return context.getResources().getString(R.string.actionPlayMusic); | ||||
| 										case controlMediaPlayback: | ||||
| 											return context.getResources().getString(R.string.actionMediaControl); | ||||
| 										case playSound: | ||||
| 											return context.getResources().getString(R.string.playSound); | ||||
| 										case sendTextMessage: | ||||
| 											return context.getResources().getString(R.string.sendTextMessage); | ||||
| 										case setScreenBrightness: | ||||
| 											return context.getResources().getString(R.string.setScreenBrightness); | ||||
| 										case createNotification: | ||||
| 											return context.getResources().getString(R.string.createNotification); | ||||
| 										case closeNotification: | ||||
| 											return context.getResources().getString(R.string.closeNotifications); | ||||
| 										default: | ||||
| 											return "Unknown"; | ||||
| 									} | ||||
| 								} | ||||
| 							}; | ||||
| 	public enum Action_Enum | ||||
| 	{ | ||||
| 		setWifi, | ||||
| 		setBluetooth, | ||||
| 		setUsbTethering, | ||||
| 		setWifiTethering, | ||||
| 		setBluetoothTethering, | ||||
| 		setDisplayRotation, | ||||
| 		turnWifiOn,turnWifiOff, | ||||
| 		turnBluetoothOn,turnBluetoothOff, | ||||
| 		triggerUrl, | ||||
| 		changeSoundProfile, | ||||
| 		turnUsbTetheringOn,turnUsbTetheringOff, | ||||
| 		turnWifiTetheringOn,turnWifiTetheringOff, | ||||
| 		enableScreenRotation,disableScreenRotation, | ||||
| 		startOtherActivity, | ||||
| 		waitBeforeNextAction, | ||||
| 		turnScreenOnOrOff, | ||||
| 		setAirplaneMode, | ||||
| 		setDataConnection, | ||||
| 		speakText, | ||||
| 		playMusic, | ||||
| 		controlMediaPlayback, | ||||
| 		setScreenBrightness, | ||||
| 		playSound, | ||||
| 		vibrate, | ||||
| 		createNotification, | ||||
| 		closeNotification, | ||||
| 		sendTextMessage; | ||||
|  | ||||
| 		public String getFullName(Context context) | ||||
| 		{ | ||||
| 			switch(this) | ||||
| 			{ | ||||
| 				case setWifi: | ||||
| 					return context.getResources().getString(R.string.actionSetWifi); | ||||
| 				case setBluetooth: | ||||
| 					return context.getResources().getString(R.string.actionSetBluetooth); | ||||
| 				case setWifiTethering: | ||||
| 					return context.getResources().getString(R.string.actionSetWifiTethering); | ||||
| 				case setBluetoothTethering: | ||||
| 					return context.getResources().getString(R.string.actionSetBluetoothTethering); | ||||
| 				case setUsbTethering: | ||||
| 					return context.getResources().getString(R.string.actionSetUsbTethering); | ||||
| 				case setDisplayRotation: | ||||
| 					return context.getResources().getString(R.string.actionSetDisplayRotation); | ||||
| 				case turnWifiOn: | ||||
| 					return context.getResources().getString(R.string.actionTurnWifiOn); | ||||
| 				case turnWifiOff: | ||||
| 					return context.getResources().getString(R.string.actionTurnWifiOff); | ||||
| 				case turnBluetoothOn: | ||||
| 					return context.getResources().getString(R.string.actionTurnBluetoothOn); | ||||
| 				case turnBluetoothOff: | ||||
| 					return context.getResources().getString(R.string.actionTurnBluetoothOff); | ||||
| 				case triggerUrl: | ||||
| 					return context.getResources().getString(R.string.actionTriggerUrl); | ||||
| 				case changeSoundProfile: | ||||
| 					return context.getResources().getString(R.string.actionChangeSoundProfile); | ||||
| 				case turnUsbTetheringOn: | ||||
| 					return context.getResources().getString(R.string.actionTurnUsbTetheringOn); | ||||
| 				case turnUsbTetheringOff: | ||||
| 					return context.getResources().getString(R.string.actionTurnUsbTetheringOff); | ||||
| 				case turnWifiTetheringOn: | ||||
| 					return context.getResources().getString(R.string.actionTurnWifiTetheringOn); | ||||
| 				case turnWifiTetheringOff: | ||||
| 					return context.getResources().getString(R.string.actionTurnWifiTetheringOff); | ||||
| 				case enableScreenRotation: | ||||
| 					return context.getResources().getString(R.string.actionEnableScreenRotation); | ||||
| 				case disableScreenRotation: | ||||
| 					return context.getResources().getString(R.string.actionDisableScreenRotation); | ||||
| 				case startOtherActivity: | ||||
| 					return context.getResources().getString(R.string.startOtherActivity); | ||||
| 				case waitBeforeNextAction: | ||||
| 					return context.getResources().getString(R.string.waitBeforeNextAction); | ||||
| 				case turnScreenOnOrOff: | ||||
| 					return context.getResources().getString(R.string.turnScreenOnOrOff); | ||||
| 				case vibrate: | ||||
| 					return context.getResources().getString(R.string.vibrate); | ||||
| 				case setAirplaneMode: | ||||
| 					return context.getResources().getString(R.string.airplaneMode); | ||||
| 				case setDataConnection: | ||||
| 					return context.getResources().getString(R.string.actionDataConnection); | ||||
| 				case speakText: | ||||
| 					return context.getResources().getString(R.string.actionSpeakText); | ||||
| 				case playMusic: | ||||
| 					return context.getResources().getString(R.string.actionPlayMusic); | ||||
| 				case controlMediaPlayback: | ||||
| 					return context.getResources().getString(R.string.actionMediaControl); | ||||
| 				case playSound: | ||||
| 					return context.getResources().getString(R.string.playSound); | ||||
| 				case sendTextMessage: | ||||
| 					return context.getResources().getString(R.string.sendTextMessage); | ||||
| 				case setScreenBrightness: | ||||
| 					return context.getResources().getString(R.string.setScreenBrightness); | ||||
| 				case createNotification: | ||||
| 					return context.getResources().getString(R.string.createNotification); | ||||
| 				case closeNotification: | ||||
| 					return context.getResources().getString(R.string.closeNotifications); | ||||
| 				default: | ||||
| 					return "Unknown"; | ||||
| 			} | ||||
| 		} | ||||
| 	}; | ||||
| 	 | ||||
| 	private Action_Enum action; | ||||
| 	private boolean parameter1 = false; | ||||
|   | ||||
| @@ -529,6 +529,10 @@ public class ActivityManageRule extends Activity | ||||
| 				items.add(new Item(typesLong[i].toString(), R.drawable.sound)); | ||||
| 			else if(types[i].toString().equals(Trigger_Enum.screenState.toString())) | ||||
| 				items.add(new Item(typesLong[i].toString(), R.drawable.smartphone)); | ||||
| 			else if(types[i].toString().equals(Trigger_Enum.deviceStarts.toString())) | ||||
| 				items.add(new Item(typesLong[i].toString(), R.drawable.alarm)); | ||||
| 			else if(types[i].toString().equals(Trigger_Enum.serviceStarts.toString())) | ||||
| 				items.add(new Item(typesLong[i].toString(), R.drawable.alarm)); | ||||
| 			else | ||||
| 				items.add(new Item(typesLong[i].toString(), R.drawable.placeholder)); | ||||
| 		} | ||||
| @@ -593,7 +597,7 @@ public class ActivityManageRule extends Activity | ||||
| 						booleanChoices = new String[]{getResources().getString(R.string.started), getResources().getString(R.string.stopped)}; | ||||
| 					else if(triggerType == Trigger_Enum.usb_host_connection) | ||||
| 						booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)}; | ||||
| 					else if(triggerType == Trigger_Enum.speed | triggerType == Trigger_Enum.noiseLevel | triggerType == Trigger_Enum.batteryLevel) | ||||
| 					else if(triggerType == Trigger_Enum.speed || triggerType == Trigger_Enum.noiseLevel || triggerType == Trigger_Enum.batteryLevel) | ||||
| 						booleanChoices = new String[]{getResources().getString(R.string.exceeds), getResources().getString(R.string.dropsBelow)}; | ||||
| 					else if(triggerType == Trigger_Enum.wifiConnection) | ||||
| 					{ | ||||
| @@ -698,6 +702,20 @@ public class ActivityManageRule extends Activity | ||||
| 						getTriggerScreenStateDialog().show(); | ||||
| 						return; | ||||
| 					} | ||||
| 					else if(triggerType == Trigger_Enum.deviceStarts) | ||||
| 					{ | ||||
| 						newTrigger.setTriggerType(Trigger_Enum.deviceStarts); | ||||
| 						ruleToEdit.getTriggerSet().add(newTrigger); | ||||
| 						refreshTriggerList(); | ||||
| 						return; | ||||
| 					} | ||||
| 					else if(triggerType == Trigger_Enum.serviceStarts) | ||||
| 					{ | ||||
| 						newTrigger.setTriggerType(Trigger_Enum.serviceStarts); | ||||
| 						ruleToEdit.getTriggerSet().add(newTrigger); | ||||
| 						refreshTriggerList(); | ||||
| 						return; | ||||
| 					} | ||||
| 					else if(triggerType == Trigger_Enum.headsetPlugged) | ||||
| 						booleanChoices = new String[]{getResources().getString(R.string.connected), getResources().getString(R.string.disconnected)}; | ||||
|  | ||||
|   | ||||
| @@ -32,6 +32,7 @@ import com.jens.automation2.receivers.PackageReplacedReceiver; | ||||
| import com.jens.automation2.receivers.PhoneStatusListener; | ||||
|  | ||||
| import java.util.Calendar; | ||||
| import java.util.Set; | ||||
|  | ||||
| @SuppressLint("NewApi") | ||||
| public class AutomationService extends Service implements OnInitListener | ||||
| @@ -192,6 +193,9 @@ public class AutomationService extends Service implements OnInitListener | ||||
| 		{ | ||||
| 			Bundle b = intent.getExtras(); | ||||
| 			startAtBoot = b.getBoolean("startAtBoot", false); | ||||
|  | ||||
| 			if(startAtBoot) | ||||
| 				Settings.deviceStartDone = false; | ||||
| 		} | ||||
|  | ||||
| 		if (checkStartupRequirements(this, startAtBoot)) | ||||
| @@ -211,12 +215,9 @@ public class AutomationService extends Service implements OnInitListener | ||||
| 				ActivityMainScreen.updateMainScreen(); | ||||
|  | ||||
|             this.isRunning = true; | ||||
|  | ||||
| 			Miscellaneous.logEvent("i", "Service", this.getResources().getString(R.string.serviceStarted) + " VERSION_CODE: " + BuildConfig.VERSION_CODE + ", VERSION_NAME: " + BuildConfig.VERSION_NAME + ", flavor: " + BuildConfig.FLAVOR, 1); | ||||
| 			Toast.makeText(this, this.getResources().getString(R.string.serviceStarted), Toast.LENGTH_LONG).show(); | ||||
| 			// ********** Test area ********** | ||||
| //			Miscellaneous.logEvent("i", "setNetworkType", "bin hier.", 3); | ||||
| //			Actions.setData(true); | ||||
| 			// ********** Test area ********** | ||||
|  | ||||
| 			/* | ||||
| 				On normal phones the app is supposed to automatically restart in case of any problems. | ||||
| @@ -315,6 +316,8 @@ public class AutomationService extends Service implements OnInitListener | ||||
|  | ||||
| 	private void startUpRoutine() | ||||
| 	{ | ||||
| 		Settings.serviceStartDone = false; | ||||
|  | ||||
| 		checkForTtsEngine(); | ||||
| 		checkForPermissions(); | ||||
| 		checkForRestrictedFeatures(); | ||||
| @@ -333,6 +336,9 @@ public class AutomationService extends Service implements OnInitListener | ||||
| 			if(r.getsGreenLight(AutomationService.this)) | ||||
| 				r.activate(AutomationService.this, false); | ||||
| 		} | ||||
|  | ||||
| 		Settings.serviceStartDone = true; | ||||
| 		Settings.deviceStartDone = true; | ||||
| 	} | ||||
|  | ||||
| 	protected void startLocationProvider() | ||||
|   | ||||
| @@ -215,7 +215,7 @@ public class ReceiverCoordinator | ||||
|                 Class testClass = Class.forName(ActivityManageRule.activityDetectionClassPath); | ||||
|                 Miscellaneous.runMethodReflective("ActivityDetectionReceiver", "stopActivityDetectionReceiver", null); | ||||
|             } | ||||
|             catch(ClassNotFoundException e) | ||||
|             catch(Exception e) | ||||
|             { | ||||
|                 // Nothing to do, just not stopping this one. | ||||
|             } | ||||
|   | ||||
| @@ -12,7 +12,7 @@ import java.util.Set; | ||||
| public class Settings implements SharedPreferences | ||||
| { | ||||
| 	public static final int rulesThatHaveBeenRanHistorySize = 10; | ||||
| 	public final static int lockSoundChangesInterval = 15; | ||||
| 	public static final int lockSoundChangesInterval = 15; | ||||
| 	public static final int newsPollEveryXDays = 3; | ||||
| 	public static final int newsDisplayForXDays = 3; | ||||
| 	public static final int updateCheckFrequencyDays = 7; | ||||
| @@ -77,7 +77,13 @@ public class Settings implements SharedPreferences | ||||
| 	public static ArrayList<String> whatHasBeenDone; | ||||
|  | ||||
| 	/* | ||||
| 		Generic settings valid for all installations and not changable | ||||
| 		Not saved permanently. | ||||
| 	 */ | ||||
| 	public static boolean deviceStartDone = true;	// by default assume device has not just been started | ||||
| 	public static boolean serviceStartDone = false; | ||||
|  | ||||
| 	/* | ||||
| 		Generic settings valid for all installations and not changeable | ||||
| 	 */ | ||||
| 	public static final String dateFormat = "E dd.MM.yyyy HH:mm:ss:ssss"; | ||||
|  | ||||
| @@ -600,5 +606,4 @@ public class Settings implements SharedPreferences | ||||
| 		// TODO Auto-generated method stub | ||||
| 		return null; | ||||
| 	} | ||||
| 	 | ||||
| } | ||||
| @@ -3,7 +3,7 @@ package com.jens.automation2; | ||||
| import android.bluetooth.BluetoothDevice; | ||||
| import android.content.Context; | ||||
| import android.os.Build; | ||||
| import android.os.Bundle; | ||||
| import android.os.SystemClock; | ||||
| import android.service.notification.StatusBarNotification; | ||||
| import android.telephony.TelephonyManager; | ||||
| import android.util.Log; | ||||
| @@ -25,10 +25,6 @@ import com.jens.automation2.receivers.PhoneStatusListener; | ||||
| import com.jens.automation2.receivers.ProcessListener; | ||||
| import com.jens.automation2.receivers.ScreenStateReceiver; | ||||
|  | ||||
| import static com.jens.automation2.Trigger.triggerParameter2Split; | ||||
| import static com.jens.automation2.receivers.NotificationListener.EXTRA_TEXT; | ||||
| import static com.jens.automation2.receivers.NotificationListener.EXTRA_TITLE; | ||||
|  | ||||
| import org.apache.commons.lang3.StringUtils; | ||||
|  | ||||
| import java.sql.Time; | ||||
| @@ -38,8 +34,31 @@ import java.util.Date; | ||||
|  | ||||
| public class Trigger | ||||
| { | ||||
| 	public enum Trigger_Enum { | ||||
| 		pointOfInterest, timeFrame, charging, batteryLevel, usb_host_connection, speed, noiseLevel, wifiConnection, process_started_stopped, airplaneMode, roaming, nfcTag, activityDetection, bluetoothConnection, headsetPlugged, notification, deviceOrientation, profileActive, screenState, musicPlaying, phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy | ||||
| 	public enum Trigger_Enum | ||||
| 	{ | ||||
| 		pointOfInterest, | ||||
| 		timeFrame, | ||||
| 		charging, | ||||
| 		batteryLevel, | ||||
| 		usb_host_connection, | ||||
| 		speed, | ||||
| 		noiseLevel, | ||||
| 		wifiConnection, | ||||
| 		process_started_stopped, | ||||
| 		airplaneMode, | ||||
| 		roaming, | ||||
| 		nfcTag, | ||||
| 		activityDetection, | ||||
| 		bluetoothConnection, | ||||
| 		headsetPlugged, | ||||
| 		notification, | ||||
| 		deviceOrientation, | ||||
| 		profileActive, | ||||
| 		screenState, | ||||
| 		musicPlaying, | ||||
| 		deviceStarts, | ||||
| 		serviceStarts, | ||||
| 		phoneCall; //phoneCall always needs to be at the very end because of Google's shitty so called privacy | ||||
|  | ||||
| 		public String getFullName(Context context) | ||||
| 		{ | ||||
| @@ -87,6 +106,10 @@ public class Trigger | ||||
| 					return context.getResources().getString(R.string.musicPlaying); | ||||
| 				case screenState: | ||||
| 					return context.getResources().getString(R.string.screenState); | ||||
| 				case deviceStarts: | ||||
| 					return context.getResources().getString(R.string.deviceStarts); | ||||
| 				case serviceStarts: | ||||
| 					return context.getResources().getString(R.string.serviceStarts); | ||||
| 				default: | ||||
| 					return "Unknown"; | ||||
| 			} | ||||
| @@ -190,6 +213,14 @@ public class Trigger | ||||
| 					if(!checkScreenState()) | ||||
| 						result = false; | ||||
| 					break; | ||||
| 				case deviceStarts: | ||||
| 					if(!checkDeviceStarts()) | ||||
| 						result = false; | ||||
| 					break; | ||||
| 				case serviceStarts: | ||||
| 					if(!checkServiceStarts()) | ||||
| 						result = false; | ||||
| 					break; | ||||
| 				default: | ||||
| 					break; | ||||
| 			} | ||||
| @@ -343,6 +374,16 @@ public class Trigger | ||||
| 		return triggerParameter == MediaPlayerListener.isAudioPlaying(Miscellaneous.getAnyContext()); | ||||
| 	} | ||||
|  | ||||
| 	boolean checkDeviceStarts() | ||||
| 	{ | ||||
| 		return checkServiceStarts() && !Settings.deviceStartDone; | ||||
| 	} | ||||
|  | ||||
| 	boolean checkServiceStarts() | ||||
| 	{ | ||||
| 		return !Settings.serviceStartDone; | ||||
| 	} | ||||
|  | ||||
| 	boolean checkProfileActive() | ||||
| 	{ | ||||
| 		String demandedProfileName = getTriggerParameter2().split(Trigger.triggerParameter2Split)[0]; | ||||
| @@ -1546,9 +1587,13 @@ public class Trigger | ||||
| 					default: | ||||
| 						state = Miscellaneous.getAnyContext().getString(R.string.unknown); | ||||
| 				} | ||||
|  | ||||
| 				returnString.append(String.format(Miscellaneous.getAnyContext().getString(R.string.screenIs), state)); | ||||
|  | ||||
| 			case deviceStarts: | ||||
| 				// This type doesn't have an activate/deactivate equivalent | ||||
| 				returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.deviceHasJustStarted)); | ||||
| 				break; | ||||
| 			case serviceStarts: | ||||
| 				// This type doesn't have an activate/deactivate equivalent | ||||
| 				returnString.append(Miscellaneous.getAnyContext().getResources().getString(R.string.serviceHasJustStarted)); | ||||
| 				break; | ||||
| 			default: | ||||
| 				returnString.append("error"); | ||||
|   | ||||
| @@ -796,4 +796,8 @@ | ||||
|     <string name="musicCheckFrequencySummary">Milliseconds between checks</string> | ||||
|     <string name="locationNotWorkingOn12">Getting the location does not seem to be working on Android 12 devices currently. If it isn\'t working for you, I\'m sorry. I\'ll try to fix this as soon as I know the cause. So if the donut doesn\'t stop spinning, you know why.</string> | ||||
|     <string name="lastProfile">Last profile:</string> | ||||
|     <string name="deviceStarts">Device starts</string> | ||||
|     <string name="serviceStarts">Service starts</string> | ||||
|     <string name="deviceHasJustStarted">device has just started</string> | ||||
|     <string name="serviceHasJustStarted">service has just started</string> | ||||
| </resources> | ||||
		Reference in New Issue
	
	Block a user