diff --git a/.idea/gradle.xml b/.idea/gradle.xml index 8d2df47..d390b65 100644 --- a/.idea/gradle.xml +++ b/.idea/gradle.xml @@ -3,9 +3,10 @@ - + diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 6564d52..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..635e32e --- /dev/null +++ b/README.md @@ -0,0 +1,5 @@ +# Smart Security + +For documentations read projectReport.pdf. + +To see screenshots of the application see appScreenshots.png \ No newline at end of file diff --git a/app/build.gradle b/app/build.gradle index efff41f..5b2e233 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -6,7 +6,7 @@ android { defaultConfig { applicationId "com.proseminar.smartsecurity" - minSdkVersion 15 + minSdkVersion 18 targetSdkVersion 23 versionCode 1 versionName "1.0" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index b33fb97..a746924 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -11,6 +11,8 @@ --> + + @@ -28,8 +30,8 @@ - - + diff --git a/app/src/main/aidl/com/proseminar/smartsecurity/SensorDataCollectorApi.aidl b/app/src/main/aidl/com/proseminar/smartsecurity/SensorDataCollectorApi.aidl index 6cc861b..11172ef 100644 --- a/app/src/main/aidl/com/proseminar/smartsecurity/SensorDataCollectorApi.aidl +++ b/app/src/main/aidl/com/proseminar/smartsecurity/SensorDataCollectorApi.aidl @@ -4,6 +4,7 @@ package com.proseminar.smartsecurity; // Declare any non-default types here with import statements import com.proseminar.smartsecurity.SensorDataUpdateResult; import com.proseminar.smartsecurity.SensorDataCollectorListener; +import android.bluetooth.BluetoothDevice; interface SensorDataCollectorApi { @@ -14,4 +15,8 @@ interface SensorDataCollectorApi { void addListener(SensorDataCollectorListener listener); void removeListener(SensorDataCollectorListener listener); + + void addBluetoothConnection(String s); + + void removeBluetoothConnection(String s); } \ No newline at end of file diff --git a/app/src/main/java/com/proseminar/smartsecurity/AlarmOnActivity.java b/app/src/main/java/com/proseminar/smartsecurity/AlarmOnActivity.java index eefc436..3cc16f3 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/AlarmOnActivity.java +++ b/app/src/main/java/com/proseminar/smartsecurity/AlarmOnActivity.java @@ -5,11 +5,11 @@ import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; +import android.content.res.Resources; import android.os.Bundle; import android.os.CountDownTimer; import android.os.IBinder; import android.os.RemoteException; -import android.preference.PreferenceManager; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; @@ -38,6 +38,8 @@ public class AlarmOnActivity extends AppCompatActivity { // Count down timers private CountDownTimer turnOnTimer; + Resources res; + private SensorDataCollectorApi api; private SensorDataCollectorListener.Stub collectorListener = new SensorDataCollectorListener.Stub() { @@ -76,7 +78,6 @@ protected void onCreate(Bundle savedInstanceState) { currentStatus = mPrefs.getBoolean(KEY, OFF); updater = mPrefs.edit(); - Log.e(TAG, "+++++++++++++++ ON CREATE"); // Set different layouts depending on the status of the alarm. if (currentStatus) { setContentView(R.layout.activity_alarm_on); @@ -86,13 +87,15 @@ protected void onCreate(Bundle savedInstanceState) { } initButton(); + res = getResources(); + final int countDownMiliSeconds = res.getInteger(R.integer.ui_alarm_on_countdown); + if (!currentStatus) { // Timer counting down the time until the alarm gets turned on (30 000) - turnOnTimer = new CountDownTimer(2000, 1000) { + turnOnTimer = new CountDownTimer(countDownMiliSeconds, 1000) { public void onTick(long millisUntilFinished) { tvSeconds.setText(Integer.toString((int) (millisUntilFinished / 1000))); - Log.e("STOP", "click"); } // The timer is over the alarm turns on. @@ -116,11 +119,23 @@ protected void onResume() { turnOnTimer.start(); } - Intent intent = new Intent(SensorDataCollectorService.class.getName()); + Intent intent; + int currentapiVersion = android.os.Build.VERSION.SDK_INT; + if (currentapiVersion >= android.os.Build.VERSION_CODES.LOLLIPOP){ + // Do something for lollipop and above versions + + intent = new Intent(SensorDataCollectorService.class.getCanonicalName()); + // This is the key line that fixed everything for me + intent.setPackage("com.proseminar.smartsecurity"); + } else{ + // do something for phones running an SDK before lollipop + + intent = new Intent(SensorDataCollectorService.class.getName()); + } // start the service explicitly. // otherwise it will only run while the IPC connection is up. this.startService(intent); - bindService(intent, serviceConnection, 0); + this.bindService(intent, serviceConnection, Context.BIND_AUTO_CREATE); } @Override @@ -135,7 +150,6 @@ protected void onPause() { @Override protected void onDestroy() { super.onDestroy(); - Log.e(TAG, "+++++++++++++++DSTRY"); if (!(turnOnTimer == null)) { turnOnTimer.cancel(); } diff --git a/app/src/main/java/com/proseminar/smartsecurity/BluetoothLeConnector.java b/app/src/main/java/com/proseminar/smartsecurity/BluetoothLeConnector.java new file mode 100644 index 0000000..dcf90d5 --- /dev/null +++ b/app/src/main/java/com/proseminar/smartsecurity/BluetoothLeConnector.java @@ -0,0 +1,373 @@ +package com.proseminar.smartsecurity; + +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothGatt; +import android.bluetooth.BluetoothGattCallback; +import android.bluetooth.BluetoothGattCharacteristic; +import android.bluetooth.BluetoothGattDescriptor; +import android.bluetooth.BluetoothGattService; +import android.bluetooth.BluetoothProfile; +import android.content.Context; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; +import java.util.Arrays; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Observable; +import java.util.UUID; + +/** + * Created by christian on 28.01.16. + */ + + + +public class BluetoothLeConnector extends Observable { + + + private HashMap gatts = new HashMap<>(); + private Context context; + private BluetoothAdapter adapter; + private List services = new LinkedList<>(); + private LinkedList messageQueue = new LinkedList<>(); + + + private final UUID UUID_HUM_SERV = UUID.fromString("f000aa20-0451-4000-b000-000000000000"); + private final UUID UUID_HUM_CONF = UUID.fromString("f000aa22-0451-4000-b000-000000000000");// 0: disable, 1: enable + private final UUID UUID_HUM_DATA = UUID.fromString("f000aa21-0451-4000-b000-000000000000"); + private final UUID UUID_HUM_PERI = UUID.fromString("f000aa23-0451-4000-b000-000000000000"); // Period in tens of milliseconds + private final UUID UUID_ACC_SERV = UUID.fromString("f000aa10-0451-4000-b000-000000000000"); + private final UUID UUID_ACC_DATA = UUID.fromString("f000aa11-0451-4000-b000-000000000000"); + private final UUID UUID_ACC_CONF = UUID.fromString("f000aa12-0451-4000-b000-000000000000"); // 0: disable, 1: enable + private final UUID UUID_ACC_PERI = UUID.fromString("f000aa13-0451-4000-b000-000000000000"); // Period in tens of ms + + + private final UUID UUID_SENSI_HUM_SERV = UUID.fromString("00001234-B38D-4985-0720E-0F993A68EE41"); + private final UUID UUID_SENSI_HUM_DATA = UUID.fromString("00001235-B38D-4985-0720E-0F993A68EE41"); + private final UUID UUID_SENSI_TEMP_SERV = UUID.fromString("00002234-B38D-4985-0720E-0F993A68EE41"); + private final UUID UUID_SENSI_TEMP_DATA = UUID.fromString("00002235-B38D-4985-0720E-0F993A68EE41"); + + private HashMap humidity = new HashMap<>(); + private HashMap temperature = new HashMap<>(); + private HashMap acc = new HashMap<>(); + + public class Message { + private int id; + private String address; + Message (int i, String s) { + id = i; + address = s; + } + public int getId() { return id; } + public String getAddress() { return address; } + } + + public class Acceleration { + private int aX; + private int aY; + private int aZ; + Acceleration (int x, int y, int z) { + aX = x; + aY = y; + aZ = z; + } + public int getX() { return aX; } + public int getY() { return aY; } + public int getZ() { return aZ; } + } + + + private final BluetoothGattCallback btleGattCallback = new BluetoothGattCallback() { + + @Override + public void onCharacteristicChanged(BluetoothGatt gatt, final BluetoothGattCharacteristic characteristic) { + // this will get called anytime you perform a read or write characteristic operation + if (characteristic.getUuid().equals(UUID_HUM_DATA)) { + calculateHumidity(characteristic, gatt); + } + else if (characteristic.getUuid().equals(UUID_ACC_DATA)) { + calculateAcceleration(characteristic, gatt); + } + else if (characteristic.getUuid().equals(UUID_SENSI_HUM_DATA)) { + calculateHumSensi(characteristic, gatt); + } + else if (characteristic.getUuid().equals(UUID_SENSI_TEMP_DATA)) { + calculateTempSensi(characteristic, gatt); + } + if (messageQueue.size() > 0) { + Message m = messageQueue.getFirst(); + messageQueue.removeFirst(); + callFunctionByMessage(m); + System.out.println("Activate Function on Change: " + m.getId()); + } + } + + @Override + public void onCharacteristicWrite(BluetoothGatt gatt, + BluetoothGattCharacteristic characteristic, int status) { + + if (messageQueue.size() > 0) { + Message m = messageQueue.getFirst(); + messageQueue.removeFirst(); + callFunctionByMessage(m); + System.out.println("Activate Function on Write: " + m.getId()); + } + } + + @Override + public void onConnectionStateChange(final BluetoothGatt gatt, final int status, final int newState) { + // this will get called when a device connects or disconnects + if (newState == BluetoothProfile.STATE_CONNECTED) { + System.out.println("Fick ja!"); + messageQueue = new LinkedList<>(); + gatt.discoverServices(); + } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { + System.out.println("Disconnected!"); + disconnect(gatt.getDevice().getAddress()); + } else { + System.out.println("No Conenction:" + status); + connectTo(gatt.getDevice()); + } + } + + @Override + public void onServicesDiscovered(final BluetoothGatt gatt, final int status) { + // this will get called after the client initiates a BluetoothGatt.discoverServices() call + System.out.println("Services Discovered!"); + services = gatt.getServices(); + System.out.println("Anzahl Services: " + services.size()); + for (int i = 0; i < services.size(); i++) { + BluetoothGattService s = services.get(i); + if (s.getUuid().equals(UUID_HUM_SERV)) { + Message m10 = new Message(10, gatt.getDevice().getAddress()); + Message m20 = new Message(20, gatt.getDevice().getAddress()); + messageQueue.add(m10); + messageQueue.add(m20); + } + else if (s.getUuid().equals(UUID_ACC_SERV)) { + Message m11 = new Message(11, gatt.getDevice().getAddress()); + Message m21 = new Message(21, gatt.getDevice().getAddress()); + messageQueue.add(m11); + messageQueue.add(m21); + } + else if (s.getUuid().equals(UUID_SENSI_HUM_SERV)) { + Message m30 = new Message(30, gatt.getDevice().getAddress()); + messageQueue.add(m30); + } + else if (s.getUuid().equals(UUID_SENSI_TEMP_SERV)) { + Message m31 = new Message(31, gatt.getDevice().getAddress()); + messageQueue.add(m31); + } + } + /** + * This is a self-contained function for turning on the magnetometer + * sensor. It must be called AFTER the onServicesDiscovered callback + * is received. + */ + if (messageQueue.size() > 0) { + Message m = messageQueue.getFirst(); + messageQueue.removeFirst(); + callFunctionByMessage(m); + System.out.println("Activate Function on Services: " + m.getId()); + } + } + }; + + + BluetoothLeConnector(Context context, BluetoothAdapter btAdapter) { + this.context = context; + this.adapter = btAdapter; + //startScan(); + } + + public void disconnect(String address) { + if (gatts.containsKey(address)) { + BluetoothGatt bg = gatts.get(address); + if (bg != null) { + bg.disconnect(); + bg.close(); + humidity.put(address, 0.00); + temperature.put(address, 0.00); + setChanged(); + notifyObservers(getSensorData(bg)); + } else { + System.out.println("Null gatts!"); + } + gatts.remove(address); + } else { + System.out.println("No such Key! " + address); + } + } + + public void disconnect() { + for (BluetoothGatt bg : gatts.values()) { + if (bg != null) { + bg.disconnect(); + bg.close(); + } + } + } + + + public void connectTo(BluetoothDevice device) { + if (device != null) { + BluetoothGatt bg = device.connectGatt(context, false, btleGattCallback); + gatts.put(device.getAddress(), bg); + temperature.put(device.getAddress(), 0.0); + humidity.put(device.getAddress(), 0.0); + } else { + System.out.println("null device!"); + } + } + + public void connectToString(String str) { + BluetoothDevice device = adapter.getRemoteDevice(str); + connectTo(device); + } + + private void callFunctionByMessage(Message m) { + int id = m.getId(); + BluetoothGatt gatt = gatts.get(m.getAddress()); + System.out.println("Call Function: " + id); + switch (id) { + case 10: + turnOnService(gatt, UUID_HUM_SERV, UUID_HUM_CONF); + break; + case 11: + turnOnService(gatt, UUID_ACC_SERV, UUID_ACC_CONF); + break; + case 20: + enableNotifications(gatt, UUID_HUM_SERV, UUID_HUM_DATA); + break; + case 21: + enableNotifications(gatt, UUID_ACC_SERV, UUID_ACC_DATA); + break; + case 30: + enableNotifications(gatt, UUID_SENSI_HUM_SERV, UUID_SENSI_HUM_DATA); + break; + case 31: + enableNotifications(gatt, UUID_SENSI_TEMP_SERV, UUID_SENSI_TEMP_DATA); + break; + default: + break; + } + } + + private void turnOnService(BluetoothGatt gatt, UUID serviceUUID, UUID configUUID) { + + + BluetoothGattService humService = gatt.getService(serviceUUID); + BluetoothGattCharacteristic config = humService.getCharacteristic(configUUID); + config.setValue(new byte[]{1}); // 01 for Humidity; 01 for +-2g deviation//NB: the config value is different for the Gyroscope + gatt.writeCharacteristic(config); + } + + private void enableNotifications(BluetoothGatt gatt, UUID serviceUuid, UUID dataUuid) { + UUID CCC = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); + + BluetoothGattService service = gatt.getService(serviceUuid); + BluetoothGattCharacteristic dataCharacteristic = service.getCharacteristic(dataUuid); + gatt.setCharacteristicNotification(dataCharacteristic, true); //Enabled locally + + BluetoothGattDescriptor config = dataCharacteristic.getDescriptor(CCC); + config.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); + gatt.writeDescriptor(config); //Enabled remotely + } + + private void calculateHumidity(BluetoothGattCharacteristic characteristic, BluetoothGatt gatt) { + String address = gatt.getDevice().getAddress(); + /*calculate humididty*/ + Integer lowerTempByte = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 0); + Integer upperTempByte = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 1); + Integer lowerHumByte = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 2); + Integer upperHumByte = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_UINT8, 3); // Note: interpret MSB as unsigned. + // Humidity + int hum = (upperHumByte << 8) + lowerHumByte; + hum=hum-(hum%4); + double humi = (-6f) + 125f * (hum / 65535f); + humidity.put(address, humi); + // Temperature + int temp = (upperTempByte << 8) + lowerTempByte; + double t = -46.85f + (175.72f/65536f) * (float)temp; + temperature.put(address, t); + System.out.println("Humidity: " + humidity); + System.out.println("Temperature: " + temperature); + SensorData sd = getSensorData(gatt); + setChanged(); + notifyObservers(sd); + } + + private void calculateAcceleration(BluetoothGattCharacteristic characteristic, BluetoothGatt gatt) { + /* + * The accelerometer has the range [-2g, 2g] with unit (1/64)g. + * + * To convert from unit (1/64)g to unit g we divide by 64. + * + * (g = 9.81 m/s^2) + * + * The z value is multiplied with -1 to coincide + * with how we have arbitrarily defined the positive y direction. + * (illustrated by the apps accelerometer image) + * + * -32 = -2g + * -16 = -1g + * 0 = 0g + * 16 = 1g + * 32 = 2g + * */ + + int accX = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT8, 0); + int accY = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT8, 1); + int accZ = characteristic.getIntValue(BluetoothGattCharacteristic.FORMAT_SINT8, 2) * -1; + System.out.println("Acc X: " + accX + " Y: " + accY + " Z: " + accZ); + Acceleration a = new Acceleration(accX, accY, accZ); + acc.put(gatt.getDevice().getAddress(), a); + setChanged(); + notifyObservers(getSensorData(gatt)); + } + + private void calculateHumSensi(BluetoothGattCharacteristic chara, BluetoothGatt gatt) { + byte[] data = chara.getValue(); + double fl = (double) ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getFloat(); + String address = gatt.getDevice().getAddress(); + humidity.put(address, fl); + SensorData sd = getSensorData(gatt); + setChanged(); + notifyObservers(sd); + } + + private void calculateTempSensi(BluetoothGattCharacteristic chara, BluetoothGatt gatt) { + byte[] data = chara.getValue(); + double fl = (double) ByteBuffer.wrap(data).order(ByteOrder.LITTLE_ENDIAN).getFloat(); + String address = gatt.getDevice().getAddress(); + temperature.put(address, fl); + SensorData sd = getSensorData(gatt); + setChanged(); + notifyObservers(sd); + } + + public SensorData getSensorData(BluetoothGatt gatt) { + BluetoothDevice dev = gatt.getDevice(); + String address = dev.getAddress(); + double temp = temperature.get(address); + double hum = humidity.get(address); + int accX = 0; + int accY = 0; + int accZ = 0; + Acceleration a = acc.get(address); + if (a != null) { + accX = a.getX(); + accY = a.getY(); + accZ = a.getZ(); + } + String name = dev.getName(); + // System.out.println("Temp: " + temp + " Humi: " + hum + " Name: " + name + " Adresse: " + address + "AccX: " + accX + " AccY: " + accY + " AccX: " + accZ); + SensorData sens = new SensorData(name, address, temp, hum, accX, accY, accZ); + return sens; + } + + +} diff --git a/app/src/main/java/com/proseminar/smartsecurity/DbHandler.java b/app/src/main/java/com/proseminar/smartsecurity/ContactDbHandler.java similarity index 95% rename from app/src/main/java/com/proseminar/smartsecurity/DbHandler.java rename to app/src/main/java/com/proseminar/smartsecurity/ContactDbHandler.java index 5a16473..f0a5e0f 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/DbHandler.java +++ b/app/src/main/java/com/proseminar/smartsecurity/ContactDbHandler.java @@ -6,7 +6,7 @@ import android.content.Context; import android.content.ContentValues; -public class DbHandler extends SQLiteOpenHelper{ +public class ContactDbHandler extends SQLiteOpenHelper{ //use if you have only one table private static final int DATABASE_VERSION = 1; @@ -15,7 +15,7 @@ public class DbHandler extends SQLiteOpenHelper{ public static final String COLUMN_PHONE = "phone"; public static final String COLUMN_NAME = "name"; - public DbHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { + public ContactDbHandler(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) { super(context, name, factory, version); } diff --git a/app/src/main/java/com/proseminar/smartsecurity/InfoActivity.java b/app/src/main/java/com/proseminar/smartsecurity/InfoActivity.java index 2a26618..b2ad5b9 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/InfoActivity.java +++ b/app/src/main/java/com/proseminar/smartsecurity/InfoActivity.java @@ -1,14 +1,20 @@ package com.proseminar.smartsecurity; +import android.Manifest; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; import android.content.SharedPreferences; +import android.content.pm.PackageManager; +import android.content.res.Resources; import android.os.Bundle; import android.os.IBinder; import android.os.RemoteException; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; @@ -21,6 +27,8 @@ import java.util.ArrayList; import java.util.List; +import java.util.Timer; +import java.util.TimerTask; import static android.support.v4.app.ActivityCompat.startActivityForResult; @@ -35,6 +43,8 @@ public class InfoActivity extends AppCompatActivity { static final String KEY = "alarm_status"; private static final String TAG = InfoActivity.class.getSimpleName(); + Resources res; + // Recalls the last state - ON or OFF private SharedPreferences mPrefs; private boolean currentStatus; @@ -42,15 +52,14 @@ public class InfoActivity extends AppCompatActivity { boolean connected; BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter(); - private final static int REQUEST_ENABLE_BT=1; // UI Elements GridView gridView; - List sDataList; - Context context = this; + Thread t; + private ServiceConnection serviceConnection = new ServiceConnection() { @Override public void onServiceConnected(ComponentName name, IBinder service) { @@ -85,15 +94,36 @@ public void handleSensorDataUpdated() throws RemoteException { } }; + private Timer timer; + private TimerTask updateInfo = new TimerTask() { + @Override + public void run() { + updateGridView(); + } + }; + + private BluetoothLeConnector mBLEConnector; + private BluetoothAdapter btAdapter; + private static final int REQUEST_ENABLE_BT = 1; + private int MY_PERMISSIONS_REQUEST_ACCESS_LOCATION = 2; + private SyncManager manager = SyncManager.getInstance(); + @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - - mPrefs = getSharedPreferences("latest_alarm_status", Context.MODE_PRIVATE); currentStatus = mPrefs.getBoolean(KEY, OFF); + System.out.println("Created!"); + + int permissionCheck = ContextCompat.checkSelfPermission(this, + Manifest.permission.SEND_SMS); + System.out.print(permissionCheck); + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.SEND_SMS}, + 10); + Log.e(TAG, Boolean.toString(currentStatus)); if (currentStatus) { Intent i = new Intent(this, AlarmOnActivity.class); @@ -104,16 +134,6 @@ public void onCreate(Bundle savedInstanceState) { @Override protected void onDestroy() { super.onDestroy(); - - try { - api.removeListener(collectorListener); - unbindService(serviceConnection); - } catch (Throwable t) { - // catch any issues, typical for destroy routines - // even if we failed to destroy something, we need to continue destroying - Log.w(TAG, "Failed to unbind from the service", t); - } - Log.i(TAG, "Activity destroyed"); } @@ -126,16 +146,66 @@ protected void onResume() { startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT); } initializeInfoUI(); + + res = getResources(); + final int updateSeconds = res.getInteger(R.integer.ui_update_info_page); + + t = new Thread() { + @Override + public void run() { + try { + while (!isInterrupted()) { + Thread.sleep(updateSeconds); + runOnUiThread(new Runnable() { + @Override + public void run() { + updateGridView(); + } + }); + } + } catch (InterruptedException e) { + } + } + }; + t.start(); + } + + @Override + protected void onPause() { + super.onPause(); + t.interrupt(); + try { + api.removeListener(collectorListener); + unbindService(serviceConnection); + } catch (Throwable t) { + // catch any issues, typical for destroy routines + // even if we failed to destroy something, we need to continue destroying + Log.w(TAG, "Failed to unbind from the service", t); + } } private void initializeInfoUI() { setContentView(R.layout.activity_info_activity); //Intent intent = new Intent(SensorDataCollectorService.class.getName()); - Intent intent = new Intent(SensorDataCollectorService.class.getName()); + Intent intent; + int currentapiVersion = android.os.Build.VERSION.SDK_INT; + if (currentapiVersion >= android.os.Build.VERSION_CODES.LOLLIPOP){ + // Do something for lollipop and above versions + + //intent = new Intent(this, SensorDataCollectorService.class); + + intent = new Intent(SensorDataCollectorService.class.getCanonicalName()); + // This is the key line that fixed everything for me + intent.setPackage("com.proseminar.smartsecurity"); + } else{ + // do something for phones running an SDK before lollipop + + intent = new Intent(SensorDataCollectorService.class.getName()); + } this.startService(intent); - bindService(intent, serviceConnection, 0); + this.bindService(intent, serviceConnection, BIND_AUTO_CREATE); Log.i(TAG, "Activity created"); @@ -165,17 +235,22 @@ private void updateGridView() { SensorDataAdapter adapter = new SensorDataAdapter(context, arrayOfUsers); // Attach the adapter to a ListView gridView.setAdapter(adapter); - try { - SensorDataUpdateResult sdur = api.getLatestUpdateResult(); - sDataList = sdur.getSensorData(); - // Fill with Dummy items - if (!(sDataList == null)) { - for (SensorData sd : sDataList) { - adapter.add(sd); + if (api != null) { + try { + List sDataList; + SensorDataUpdateResult sdur = api.getLatestUpdateResult(); + sDataList = sdur.getSensorData(); + // Fill with Dummy items + if (sDataList != null) { + for (SensorData sd : sDataList) { + Log.e(TAG, sd.getName() + " " + sd.getTemp() + " " + sd.getMacAddress()); + adapter.add(sd); + } } + } catch (RemoteException e) { + e.printStackTrace(); } - } catch (RemoteException e) { - e.printStackTrace(); } } + } diff --git a/app/src/main/java/com/proseminar/smartsecurity/MainActivity.java b/app/src/main/java/com/proseminar/smartsecurity/MainActivity.java deleted file mode 100644 index 647169b..0000000 --- a/app/src/main/java/com/proseminar/smartsecurity/MainActivity.java +++ /dev/null @@ -1,148 +0,0 @@ -package com.proseminar.smartsecurity; - - -import android.content.ComponentName; -import android.content.Context; -import android.content.Intent; -import android.content.ServiceConnection; -import android.os.Bundle; -import android.os.Handler; -import android.os.IBinder; -import android.os.RemoteException; -import android.support.v7.app.AppCompatActivity; -import android.text.Html; -import android.util.Log; -import android.view.View; -import android.widget.TextView; -import android.widget.Toast; -import android.widget.ToggleButton; - -// A mess. Would be reimplemened. -public class MainActivity extends AppCompatActivity { - - private static final String TAG = MainActivity.class.getSimpleName(); - - boolean mBound; - - private ServiceConnection serviceConnection = new ServiceConnection() { - @Override - public void onServiceConnected(ComponentName name, IBinder service) { - Log.i(TAG, "Service connection established"); - - // that's how we get the client side of the IPC connection - api = SensorDataCollectorApi.Stub.asInterface(service); - try { - api.addListener(collectorListener); - } catch (RemoteException e) { - Log.e(TAG, "Failed to add listener", e); - } - // updateTweetView(); - } - - @Override - public void onServiceDisconnected(ComponentName name) { - Log.i(TAG, "Service connection closed"); - } - }; - - private SensorDataCollectorApi api; - - //private Handler handler; - - private SensorDataCollectorListener.Stub collectorListener = new SensorDataCollectorListener.Stub() { - @Override - public void handleSensorDataUpdated() throws RemoteException { - // updateTweetView(); - } - }; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_main); - - // handler = new Handler(); // handler will be bound to the current thread (UI) - - // Don't delete. Will be used later for the overview activity, when the alarm is off. - // tweetView = (TextView) findViewById(R.id.tweet_view); - - //Intent intent = new Intent(SensorDataCollectorService.class.getName()); - Intent intent = new Intent(this, SensorDataCollectorService.class); - - // start the service explicitly. - // otherwise it will only run while the IPC connection is up. - //startService(intent); - this.startService(intent); - - bindService(intent, serviceConnection, 0); - - mBound = true; - - Log.i(TAG, "Activity created"); - } - - @Override - protected void onDestroy() { - super.onDestroy(); - - - - Log.i(TAG, "Activity destroyed"); - } - - public void onToggle(View view) throws RemoteException { - Intent intent = new Intent(SensorDataCollectorService.class.getName()); - if (!mBound) { - Log.w(TAG, "++ START & BIND ++"); - startService(intent); - bindService(intent, serviceConnection, 0); - mBound = true; - } else { - Log.w(TAG, "++ UNBIND & STOP ++"); - unbindService(serviceConnection); - mBound = false; - } - } - - - - public void onScanClick(View view) { - Intent i = new Intent(this, SettingsActivity.class); - startActivity(i); - } - - - - // Don't delete. Will be used later for the overview activity, when the alarm is off. - /** - private void updateTweetView() { - // doing this in a Handler allows to call this method safely from any thread - // see Handler docs for more info - handler.post(new Runnable() { - @Override - public void run() { - try { - SensorDataUpdateResult result = api.getLatestUpdateResult(); - - if (result.getSensorData().isEmpty()) { - tweetView.setText("Sorry, no tweets yet"); - } else { - StringBuilder builder = new StringBuilder(); - for (SensorData sensorData : result.getSensorData()) { - builder.append(String.format("
%s: %f %f %f
", - sensorData.getSensorId(), - sensorData.getTemp(), - sensorData.getHumidity(), - sensorData.getAccelometer())); - } - - tweetView.setText(Html.fromHtml(builder.toString())); - } - } catch (Throwable t) { - Log.e(TAG, "Error while updating the UI with tweets", t); - } - } - }); - } - */ -} diff --git a/app/src/main/java/com/proseminar/smartsecurity/Sensor.java b/app/src/main/java/com/proseminar/smartsecurity/Sensor.java index 36b3561..00294d8 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/Sensor.java +++ b/app/src/main/java/com/proseminar/smartsecurity/Sensor.java @@ -1,41 +1,60 @@ package com.proseminar.smartsecurity; -import java.lang.reflect.Array; -import java.security.InvalidParameterException; +import android.util.Log; + import java.util.ArrayList; +import java.util.Observable; +import java.util.Observer; /** * Created by Joachim on 26.01.2016. */ public class Sensor { - private static int numberOfPastValues = 10; + private static int numberOfPastValues = 60; private static int numberOfPredictedValues = 5; private static int weightNewerValues = 3; private static double halfConfCap = 0.2; private static ArrayList sensorNames = new ArrayList(); - private String sensorId; + private String macAddress; private String name; private double[] temperature; + + + private double[] accelerometer; private int valIndex; private int dataCounter; + + private double[] newtemps; + private double x; + private double y; + private double z; + private double xold; + private double yold; + private double zold; + private static double newCap = 0.12; + + public Sensor(String name, String macAddress) { + for (String str : sensorNames) { + if (str.equals(macAddress)) { + throw new IllegalArgumentException("The device with MAC-Address: " + + macAddress + ", is already paired."); + } + } - public Sensor(String name, String sensorId) { - for (String str : sensorNames) - if (str.equals(sensorId)) - throw new IllegalArgumentException("The name " + sensorId + " has already been taken."); - - this.sensorId = sensorId; + this.macAddress = macAddress; this.name = name; temperature = new double[numberOfPastValues]; valIndex = 0; dataCounter = 0; + + newtemps = new double[6]; } public boolean idFits(SensorData sd) { - return sensorId.equals(sd.getSensorId()); + return macAddress.equals(sd.getMacAddress()); } public void resetData() { @@ -48,27 +67,68 @@ public void resetData() { // adds the newest value to the array and returns true if there's enough data collected to start identifying possible threats public boolean updateSensorData(SensorData sd) { double newTemp = sd.getTemp(); - - temperature[valIndex] = newTemp; - valIndex++; - if (valIndex == numberOfPastValues) - valIndex = 0; - - if (dataCounter == numberOfPastValues) { - return true; - } else { + + newtemps[5] = newtemps[4]; + newtemps[4] = newtemps[3]; + newtemps[3] = newtemps[2]; + newtemps[2] = newtemps[1]; + newtemps[1] = newtemps[0]; + newtemps[0] = newTemp; + + if (dataCounter < 30) dataCounter++; + + xold = x; + yold = y; + zold = z; + x = sd.getAccX(); + y = sd.getAccY(); + z = sd.getAccZ(); + + if (dataCounter < 30) return false; - } + else + return true; + + //temperature[valIndex] = newTemp; + //valIndex++; + //if (valIndex == numberOfPastValues) + // valIndex = 0; + + //if (dataCounter == numberOfPastValues) { + // return true; + //} else { + // dataCounter++; + // return false; + //} } // returns how confident the sensor is that the newest values indicate a threat public double calcRobberyConfidence() { - if (dataCounter < numberOfPastValues) + if (dataCounter < 30) return 0.0d; + + double sum = 0.0d; + + for (int i = 5; i > 0; i--) + { + if (newtemps[i] > newtemps[i - 1]) + sum += Math.pow(Math.abs(newtemps[i] - newtemps[i - 1]), (4 / 3)); + } + + double dx = Math.abs(x - xold); + double dy = Math.abs(y - yold); + double dz = Math.abs(z - zold); + + if (dx >= 3.0d || dy >= 3.0d || dz >= 3.0d) + return 1.0d; + + + return Math.min(sum / (newCap * 2), 1); + // -------------- Regression - + /* double sum_w = 0; double sum_wxy = 0; double sum_wx = 0; @@ -121,13 +181,23 @@ public double calcRobberyConfidence() { // ----------------- Confidence double confidence = Math.min(sum / (halfConfCap * 2), 1); - - return confidence; + */ + + //return confidence; } - public String getSensorId() { return sensorId; } + public String getSensorId() { return macAddress; } public String getName() { return name; } public void setName(String name) { this.name = name; } + + public double[] getTemperature() { + return temperature; + } + + public double[] getAccelerometer() { + return accelerometer; + } + } \ No newline at end of file diff --git a/app/src/main/java/com/proseminar/smartsecurity/SensorCollection.java b/app/src/main/java/com/proseminar/smartsecurity/SensorCollection.java index 9f16868..87804dd 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/SensorCollection.java +++ b/app/src/main/java/com/proseminar/smartsecurity/SensorCollection.java @@ -17,13 +17,15 @@ public class SensorCollection { Context c; private Contact[] contact; private final String DATABASE_NAME = "contacts.db"; - private DbHandler myHandle; + private ContactDbHandler myHandle; private SensorDbHandler mySensorHandle1; private boolean notified; + private static final String TAG = SensorCollection.class.getSimpleName(); public SensorCollection(Context c) { + this.c = c; - myHandle = new DbHandler(c, DATABASE_NAME, null, 1); + myHandle = new ContactDbHandler(c, DATABASE_NAME, null, 1); mySensorHandle1 = new SensorDbHandler (c, "sensors.db", null, 1); notified = false; Sensor[] sa = mySensorHandle1.databaseToString(); @@ -45,10 +47,11 @@ public void update(SensorDataUpdateResult newVals, boolean alarmIsOn) { if (sensor.idFits(sd)) { if (sensor.updateSensorData(sd)) { double conf = sensor.calcRobberyConfidence(); - if (alarmIsOn && conf >= 0.5) { + Log.e(TAG, "---------------------------" + Double.toString(conf) + " || " + Double.toString(sd.getAccX()) + " || " + Double.toString(sd.getAccY()) + " || " + Double.toString(sd.getAccZ()) + "-------------------------------"); + if (alarmIsOn && conf >= 0.8) { if (!notified) { - Log.e("COLECTION", "++++++++++++++++++++++++++++SMS SENT+++++++++++++++++++++++++"); - // notifySMS(); + Log.e(TAG, "++++++++++++++++++++++++ SMS SENT ++++++++++++++++++++++++"); + notifySMS(sensor.getName(), conf); notified = true; } } @@ -59,22 +62,31 @@ public void update(SensorDataUpdateResult newVals, boolean alarmIsOn) { } } - private void notifySMS() { + private void notifySMS(String room, double conf) { contact = myHandle.databaseToString(); if (!(contact == null)) { for (Contact cont: contact) { - Sms.sendSMS(cont.getNumber(), "SmartSecurity detected a possible threat "); + Sms.sendSMS(cont.getNumber(), "SmartSecurity detected a possible threat in the " + room + " with a confidence of " + Long.toString(Math.round(conf * 100.0d)) + "%."); } } } public static void addSensor(Sensor sensor) { - sensors.add(sensor); + if (sensors != null) { + sensors.add(sensor); + } } - public void removeSensor(String sensorId) { - // + public static void removeSensor (String sensorId) { + if (sensors != null) { + for (Sensor s:sensors) { + if (s.getSensorId().equals(sensorId)) { + sensors.remove(s); + break; + } + } + } } public void reset() { diff --git a/app/src/main/java/com/proseminar/smartsecurity/SensorData.java b/app/src/main/java/com/proseminar/smartsecurity/SensorData.java index 32c82d5..3cafd6d 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/SensorData.java +++ b/app/src/main/java/com/proseminar/smartsecurity/SensorData.java @@ -20,26 +20,35 @@ public SensorData[] newArray(int size) { return new SensorData[size]; } }; - - private String sensorId; + + private String name; + private String macAddress; private double temp; private double humidity; - private double accelometer; - private String name; + private double accX; + private double accY; + private double accZ; + - public SensorData(String name, String sensorId, double temp, double humidity, double accelometer) { + + public SensorData(String name, String macAddress, double temp, double humidity, double accX, double accY, double accZ) { this.name = name; - this.sensorId = sensorId; + this.macAddress = macAddress; this.temp = temp; this.humidity = humidity; - this.accelometer = accelometer; + this.accX = accX; + this.accY = accY; + this.accZ = accZ; } private SensorData(Parcel source) { - sensorId = source.readString(); + name = source.readString(); + macAddress = source.readString(); temp = source.readDouble(); humidity = source.readDouble(); - accelometer = source.readDouble(); + accX = source.readDouble(); + accY = source.readDouble(); + accZ = source.readDouble(); } public String getName() { @@ -47,15 +56,15 @@ public String getName() { } public void setSensorId(String sensorId) { - this.sensorId = sensorId; + this.macAddress = sensorId; } public void setName(String name) { this.name = name; } - public String getSensorId() { - return sensorId; + public String getMacAddress() { + return macAddress; } public double getTemp() { @@ -66,9 +75,11 @@ public double getHumidity() { return humidity; } - public double getAccelometer() { - return accelometer; - } + public double getAccX() { return accX; } + + public double getAccY() { return accY; } + + public double getAccZ() { return accZ; } @Override public int describeContents() { @@ -77,9 +88,13 @@ public int describeContents() { @Override public void writeToParcel(Parcel dest, int flags) { - dest.writeString(sensorId); + dest.writeString(name); + dest.writeString(macAddress); dest.writeDouble(temp); dest.writeDouble(humidity); - dest.writeDouble(accelometer); + dest.writeDouble(accX); + dest.writeDouble(accY); + dest.writeDouble(accZ); + } } diff --git a/app/src/main/java/com/proseminar/smartsecurity/SensorDataAdapter.java b/app/src/main/java/com/proseminar/smartsecurity/SensorDataAdapter.java index 49e219c..8dad797 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/SensorDataAdapter.java +++ b/app/src/main/java/com/proseminar/smartsecurity/SensorDataAdapter.java @@ -21,6 +21,7 @@ public SensorDataAdapter(Context context, ArrayList users) { public View getView(int position, View convertView, ViewGroup parent) { // Get the data item for this position SensorData sensorData = getItem(position); + // Check if an existing view is being reused, otherwise inflate the view if (convertView == null) { convertView = LayoutInflater.from(getContext()).inflate(R.layout.grid_item_info, parent, false); @@ -28,10 +29,13 @@ public View getView(int position, View convertView, ViewGroup parent) { // Lookup view for data population TextView tvRoom = (TextView) convertView.findViewById(R.id.tvRoom); TextView tvTemp = (TextView) convertView.findViewById(R.id.tvTemp); - // TODO: add sensor name to SensorData. + TextView tvHumid = (TextView) convertView.findViewById(R.id.tvHumid); + // Populate the data into the template view using the data object - tvRoom.setText(sensorData.getSensorId()); - tvTemp.setText(Double.toString(sensorData.getTemp()) + " °C"); + tvRoom.setText(sensorData.getName()); + tvTemp.setText(String.format("%.1f", sensorData.getTemp()) + "°C"); + tvHumid.setText(String.format("%.1f", sensorData.getHumidity()) + "%"); + // Return the completed view to render on screen return convertView; } diff --git a/app/src/main/java/com/proseminar/smartsecurity/SensorDataCollectorService.java b/app/src/main/java/com/proseminar/smartsecurity/SensorDataCollectorService.java index de7c4ec..2a87994 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/SensorDataCollectorService.java +++ b/app/src/main/java/com/proseminar/smartsecurity/SensorDataCollectorService.java @@ -5,17 +5,24 @@ import java.util.Timer; import java.util.TimerTask; +import android.Manifest; import android.app.Service; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothClass; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; +import android.content.pm.PackageManager; import android.os.IBinder; import android.os.RemoteException; import android.os.SystemClock; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.util.Log; +import android.widget.Toast; -import static android.support.v4.app.ActivityCompat.startActivityForResult; /** * A Service class, that runs in the background and implements the connection between the @@ -23,6 +30,13 @@ */ public class SensorDataCollectorService extends Service { + // Bluetooth Connector + private BluetoothLeConnector mBLEConnector; + private BluetoothAdapter btAdapter; + private static final int REQUEST_ENABLE_BT = 1; + private int MY_PERMISSIONS_REQUEST_ACCESS_LOCATION = 2; + private SyncManager manager = SyncManager.getInstance(); + // Constants private static final String TAG = SensorDataCollectorService.class.getSimpleName(); static final boolean ON = true; @@ -33,25 +47,20 @@ public class SensorDataCollectorService extends Service { private SharedPreferences mPrefs; private boolean currentStatus; - private SensorCollection logic; + SensorDataUpdater updater; Context context = this; private Timer timer; - - int counter; private TimerTask updateTask = new TimerTask() { @Override public void run() { try { - SensorDataUpdater updater = new SensorDataUpdater(); SensorDataUpdateResult newUpdateResult = updater.update(context); - Log.d(TAG, "++++++++++++++Retrieved Data from " + newUpdateResult.getSensorData().size() + " sensor(s)"); + Log.d(TAG, "+++Retrieved Data from " + newUpdateResult.getSensorData().size() + " sensor(s)+++"); logic.update(newUpdateResult, currentStatus); - counter++; - Log.e(TAG, Integer.toString(counter)); synchronized (latestUpdateResultLock) { latestUpdateResult = newUpdateResult; @@ -111,7 +120,7 @@ public void addListener(SensorDataCollectorListener listener) throws RemoteException { synchronized (listeners) { - Log.e(TAG, "+++++++++++++++++++++ ADDED LISTENER"); + Log.e(TAG, "+++++++++++++++++++++ ADDED LISTENER +++++++++++++++++++++"); listeners.add(listener); } } @@ -121,10 +130,22 @@ public void removeListener(SensorDataCollectorListener listener) throws RemoteException { synchronized (listeners) { - Log.e(TAG, "+++++++++++++++++++++ REMOVED LISTENER+++++++++++++++++++++"); + Log.e(TAG, "+++++++++++++++++++++ REMOVED LISTENER +++++++++++++++++++++"); listeners.remove(listener); } } + + @Override + public void addBluetoothConnection (String s) throws RemoteException { + mBLEConnector.connectToString(s); + } + + @Override + public void removeBluetoothConnection (String macAdress) throws RemoteException { + // Remove sensor with macAdress + System.out.println("-----------remove BLE: " + macAdress); + mBLEConnector.disconnect(macAdress); + } }; @@ -153,8 +174,21 @@ public IBinder onBind(Intent intent) { public void onCreate() { super.onCreate(); Log.i(TAG, "Service created"); - counter = 0; logic = new SensorCollection(context); + updater = new SensorDataUpdater(); + + initializeBT(); + mBLEConnector = new BluetoothLeConnector(this, btAdapter); + manager.setBluetoothLeConnector(mBLEConnector); + + SensorDbHandler mySensorHandler = new SensorDbHandler(this, "some", null, 1); + Sensor sList[] = mySensorHandler.databaseToString(); + + if (sList != null) { + for (Sensor s: sList) { + mBLEConnector.connectToString(s.getSensorId()); + } + } timer = new Timer ("SensorDataCollectorTimer"); timer.schedule(updateTask, 5000L, 1000L); @@ -187,4 +221,40 @@ private void goInInfoMode() { Log.i(TAG, "++++++++++++++ info mode on"); } + + + + + + + + + + + + + + + + + + + + + + + + + + private void initializeBT() { + // Initializes Bluetooth adapter. + final BluetoothManager bluetoothManager = + (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + btAdapter = bluetoothManager.getAdapter(); + if (btAdapter == null) { + Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show(); + return; + } + } + } diff --git a/app/src/main/java/com/proseminar/smartsecurity/SensorDataUpdater.java b/app/src/main/java/com/proseminar/smartsecurity/SensorDataUpdater.java index 718bfd0..6833cb5 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/SensorDataUpdater.java +++ b/app/src/main/java/com/proseminar/smartsecurity/SensorDataUpdater.java @@ -3,17 +3,25 @@ import android.content.Context; import android.util.Log; -import java.util.ArrayList; -import java.util.Random; +import java.util.HashMap; +import java.util.Observable; +import java.util.Observer; -public final class SensorDataUpdater { +public final class SensorDataUpdater implements Observer { private static final String TAG = SensorDataUpdater.class.getSimpleName(); - SensorDbHandler mySensorHandler; + private SensorDbHandler mySensorHandler; + private SensorData sensorData; + private HashMap sensorDataHashMap = new HashMap<>(); + + public SensorDataUpdater () { + SyncManager manager = SyncManager.getInstance(); + manager.setObserver(this); + sensorData = new SensorData("Name","adress",0,0,0,0,0); + } /** - * For Christian * Gathers data from all sensors and returns a SensorDataUpdateResult object. * Idea: Run the connection to every sensor in separate thread, gather the data here * and pack it in a SensorDataUpdateResult object, which would be than returned in @@ -22,45 +30,32 @@ public final class SensorDataUpdater { */ public SensorDataUpdateResult update(Context x) { + SensorDataUpdateResult result; + mySensorHandler = new SensorDbHandler(x, "some", null, 1); - SensorDataUpdateResult result = new SensorDataUpdateResult(); - SensorData sd; - Sensor[] sList; - ArrayList sdList = new ArrayList(); - mySensorHandler = new SensorDbHandler(x, "doesn't matter", null ,1); - - sList = mySensorHandler.databaseToString(); + result = new SensorDataUpdateResult(); + Sensor sList[] = mySensorHandler.databaseToString(); - // Convert to Sensor Data if (sList != null) { - for (Sensor s: sList) { - sd = new SensorData(s.getName(), s.getSensorId(), genTemp(), 0 ,0); - result.addSensorData(sd); + + // Set the right name. + for (Sensor s: mySensorHandler.databaseToString()) { + SensorData sd = sensorDataHashMap.get(s.getSensorId()); + if (sd != null) { + if (s.getSensorId().equals(sd.getMacAddress())) { + sd.setName(s.getName()); + result.addSensorData(sd); + Log.e(TAG, "Updated with " + sd.getTemp() + " " + sd.getMacAddress() + " " + sd.getName()); + } + } } } - - - // Example for Data from one sensor - - String id = "asdf"; - String name = "ivan"; - double temp = 24.1; - double hum = 29.4; - double acc = 1.2; - SensorData exampleSD = new SensorData(name, id, temp, hum, acc); - - // End of example - return result; } - private int genTemp() { - int min = -15; - int max = 20; - int value = max - min; - - Random r = new Random(); - int i1 = r.nextInt(value) + min; - return i1; + @Override + public void update(Observable observable, Object data) { + SensorData sd = (SensorData) data; + sensorDataHashMap.put(sd.getMacAddress(), sd); } } diff --git a/app/src/main/java/com/proseminar/smartsecurity/SensorDbHandler.java b/app/src/main/java/com/proseminar/smartsecurity/SensorDbHandler.java index a847b3d..770df3c 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/SensorDbHandler.java +++ b/app/src/main/java/com/proseminar/smartsecurity/SensorDbHandler.java @@ -6,7 +6,9 @@ import android.database.sqlite.SQLiteDatabase; import android.database.sqlite.SQLiteOpenHelper; - +/** + * Sensor database handler class. + */ public class SensorDbHandler extends SQLiteOpenHelper { //use if you have only one table @@ -66,9 +68,7 @@ public void updateRow(Sensor sensor, Sensor newSensor) { //get String values public Sensor[] databaseToString() { SQLiteDatabase db = getWritableDatabase(); - //Cursor cursor = db.rawQuery("SELECT COUNT(*) FROM contacts;", null); Sensor[] sensor = new Sensor[db.rawQuery("SELECT " + COLUMN_NAME + " FROM " + TABLE_SENSORS + ";", null).getCount()]; - //SQLiteDatabase db = getWritableDatabase(); String query = "SELECT * FROM " + TABLE_SENSORS + " WHERE 1"; Cursor c = db.rawQuery(query, null); diff --git a/app/src/main/java/com/proseminar/smartsecurity/SensorListActivity.java b/app/src/main/java/com/proseminar/smartsecurity/SensorListActivity.java index 8d5e0af..68e363c 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/SensorListActivity.java +++ b/app/src/main/java/com/proseminar/smartsecurity/SensorListActivity.java @@ -1,64 +1,216 @@ package com.proseminar.smartsecurity; +import android.Manifest; import android.app.AlertDialog; +import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothDevice; +import android.bluetooth.BluetoothManager; +import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.ServiceConnection; +import android.content.pm.PackageManager; import android.os.Bundle; +import android.os.Handler; +import android.os.IBinder; +import android.os.RemoteException; +import android.support.v4.app.ActivityCompat; +import android.support.v4.content.ContextCompat; import android.support.v7.app.AppCompatActivity; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.EditText; import android.widget.ListView; +import android.widget.TextView; import android.widget.Toast; import java.util.ArrayList; +import java.util.HashMap; /** * Created by Daniel on 27/01/2016. */ public class SensorListActivity extends AppCompatActivity { + private static final String TAG = SensorListActivity.class.getSimpleName(); + SensorDbHandler mySensorHandle; final Context context = this; + private Handler mHandler = new Handler(); + private BluetoothLeConnector mBLEConnector; + private BluetoothAdapter btAdapter; + private static final int REQUEST_ENABLE_BT = 1; + private int MY_PERMISSIONS_REQUEST_ACCESS_LOCATION = 2; + //private LinkedList deviceList = new LinkedList<>(); + //LIST OF ARRAY STRINGS WHICH WILL SERVE AS LIST ITEMS + ArrayList listItems = new ArrayList(); + + //DEFINING A STRING ADAPTER WHICH WILL HANDLE THE DATA OF THE LISTVIEW + ArrayAdapter adapter; + private HashMap deviceList = new HashMap(); + private SyncManager manager = SyncManager.getInstance(); + + private SensorDataCollectorApi api; + + private SensorDataCollectorListener.Stub collectorListener = new SensorDataCollectorListener.Stub() { + @Override + public void handleSensorDataUpdated() throws RemoteException { + } + }; + + private ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + Log.i(TAG, "Service connection established"); + + // that's how we get the client side of the IPC connection + api = SensorDataCollectorApi.Stub.asInterface(service); + try { + api.addListener(collectorListener); + } catch (RemoteException e) { + Log.e(TAG, "Failed to add listener", e); + } + // updateTweetView(); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + Log.i(TAG, "Service connection closed"); + } + }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_list_sensors_in_range); mySensorHandle = new SensorDbHandler(this, "doesn't matter", null ,1); + System.out.println("Sensoren"); + + checkPermissions(); + initializeBT(); - final ListView listView = (ListView) findViewById(R.id.list_sensors); - String[] values = new String[] { "Android", "iPhone", "WindowsMobile", - "Blackberry", "WebOS", "Ubuntu", "Windows7", "Max OS X", - "Linux", "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", - "OS/2", "Ubuntu", "Windows7", "Max OS X", "Linux", "OS/2", - "Android", "iPhone", "WindowsMobile" }; - - final ArrayList list = new ArrayList(); - for (int i = 0; i < values.length; ++i) { - list.add(values[i]); - } - ArrayAdapter adapter = new ArrayAdapter(this, - R.layout.list_item_add_sensor, R.id.sensorName, values); + final ListView listView = (ListView) findViewById(R.id.list_sensors); + adapter = new ArrayAdapter(this, + android.R.layout.simple_list_item_1, + listItems); listView.setAdapter(adapter); + listView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView parent, View view, int position, long id) { - int itemPosition = position; - String sensor_name = (String) listView.getItemAtPosition(position); - setSensorName(sensor_name); + String selectedFromList = (String) (listView.getItemAtPosition(position)); + BluetoothDevice device = deviceList.get(selectedFromList); + String sensor_mac = device.getAddress(); + setSensorName(sensor_mac); + stopScan(); + // mBLEConnector.connectTo(device); } }); + + //--- + System.out.println("Created!"); + + // mBLEConnector = manager.getConnector(); + //manager.setBluetoothLeConnector(mBLEConnector); + startScan(10000); + CharSequence text = "Scanning"; + int duration = Toast.LENGTH_SHORT; + + for (int i=0; i < 5; i++) { + Toast toast = Toast.makeText(context, text, duration); + toast.show(); + } + + TextView tv = (TextView) findViewById(R.id.refresh_button_sensors); + tv.setOnClickListener(new View.OnClickListener() { + + @Override + public void onClick(View v) { + finish(); + startActivity(getIntent()); + } + }); + } + + private void checkPermissions() { + // Use this check to determine whether BLE is supported on the device. Then + // you can selectively disable BLE-related features. + if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { + Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show(); + finish(); + } + if (ContextCompat.checkSelfPermission(context, + Manifest.permission.ACCESS_COARSE_LOCATION) + != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, + new String[]{Manifest.permission.ACCESS_COARSE_LOCATION}, + MY_PERMISSIONS_REQUEST_ACCESS_LOCATION); + + } + if (btAdapter != null && !btAdapter.isEnabled()) { + Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); + startActivityForResult(enableIntent, REQUEST_ENABLE_BT); + } + } + private void initializeBT() { + // Initializes Bluetooth adapter. + final BluetoothManager bluetoothManager = + (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); + btAdapter = bluetoothManager.getAdapter(); + if (btAdapter == null) { + Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show(); + finish(); + return; + } + } + + + private BluetoothAdapter.LeScanCallback leScanCallback = new BluetoothAdapter.LeScanCallback() { + + @Override + public void onLeScan(final BluetoothDevice device, final int rssi, final byte[] scanRecord) { + // your implementation here + newDeviceFound(device); + } + }; + + public void startScan(int period) { + btAdapter.startLeScan(leScanCallback); + mHandler.postDelayed(new Runnable() { + @Override + public void run() { + btAdapter.stopLeScan(leScanCallback); + } + }, period); + } + + public void stopScan() { + btAdapter.stopLeScan(leScanCallback); + } + + private void newDeviceFound(BluetoothDevice device) { + if (device != null) { + if (!deviceList.containsValue(device)) { + String name = device.getName(); + String address = device.getAddress(); + String s = name + " : " + address; + deviceList.put(s, device); + listItems.add(s); + adapter.notifyDataSetChanged(); + } + } } + private void setSensorName(final String macAdress) { // get prompts.xml view LayoutInflater layoutInflater = LayoutInflater.from(SensorListActivity.this); @@ -77,6 +229,11 @@ public void onClick(DialogInterface dialog, int id) { } else { Sensor sensor = new Sensor(name.getText().toString(), macAdress); mySensorHandle.addSensors(sensor); + try { + api.addBluetoothConnection(macAdress); + } catch (RemoteException e) { + e.printStackTrace(); + } Intent i = new Intent(SensorListActivity.this, SettingsActivity.class); SensorCollection.addSensor(sensor); finish(); @@ -122,4 +279,38 @@ public void onClick(DialogInterface dialog, int id) { // show it alertDialog.show(); } -} + + @Override + protected void onResume() { + super.onResume(); + Intent intent; + int currentapiVersion = android.os.Build.VERSION.SDK_INT; + if (currentapiVersion >= android.os.Build.VERSION_CODES.LOLLIPOP){ + // Do something for lollipop and above versions + + intent = new Intent(SensorDataCollectorService.class.getCanonicalName()); + // This is the key line that fixed everything for me + intent.setPackage("com.proseminar.smartsecurity"); + } else{ + // do something for phones running an SDK before lollipop + + intent = new Intent(SensorDataCollectorService.class.getName()); + } + // start the service explicitly. + // otherwise it will only run while the IPC connection is up. + this.startService(intent); + this.bindService(intent, serviceConnection, BIND_AUTO_CREATE); + } + + + @Override + protected void onPause() { + super.onPause(); + try { + api.removeListener(collectorListener); + } catch (RemoteException e) { + e.printStackTrace(); + } + unbindService(serviceConnection); + } +} \ No newline at end of file diff --git a/app/src/main/java/com/proseminar/smartsecurity/SensorRUMEN.java b/app/src/main/java/com/proseminar/smartsecurity/SensorRUMEN.java deleted file mode 100644 index 5e0b2f7..0000000 --- a/app/src/main/java/com/proseminar/smartsecurity/SensorRUMEN.java +++ /dev/null @@ -1,36 +0,0 @@ -package com.proseminar.smartsecurity; - -import android.content.Intent; -import android.support.v7.app.AppCompatActivity; -import android.os.Bundle; -import android.view.View; -import android.widget.Button; -import android.widget.EditText; - -public class SensorRUMEN extends AppCompatActivity { - - - Button mButton; - EditText macText; - EditText nameText; - SensorDbHandler mySensorHandle; - - @Override - protected void onCreate(Bundle savedInstanceState) { - super.onCreate(savedInstanceState); - setContentView(R.layout.activity_sensor_list); - mButton = (Button)findViewById(R.id.click_me_baby); - nameText = (EditText) findViewById(R.id.enter_me_name_sensor); - macText = (EditText) findViewById(R.id.enter_me_mac_adress); - mySensorHandle = new SensorDbHandler(this, "doesn't matter", null ,1); - - mButton.setOnClickListener(new View.OnClickListener() { - public void onClick(View view) { - SensorData sensor = new SensorData(nameText.getText().toString(), macText.getText().toString(), 0,0,0); - //mySensorHandle.addSensors(sensor); - Intent i = new Intent(SensorRUMEN.this, SettingsActivity.class); - startActivity(i); - } - }); - } -} diff --git a/app/src/main/java/com/proseminar/smartsecurity/SettingsActivity.java b/app/src/main/java/com/proseminar/smartsecurity/SettingsActivity.java index 002dc9d..6de80c3 100644 --- a/app/src/main/java/com/proseminar/smartsecurity/SettingsActivity.java +++ b/app/src/main/java/com/proseminar/smartsecurity/SettingsActivity.java @@ -1,11 +1,16 @@ package com.proseminar.smartsecurity; import android.app.AlertDialog; +import android.content.ComponentName; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; +import android.content.ServiceConnection; +import android.os.IBinder; +import android.os.RemoteException; import android.support.v7.app.AppCompatActivity; import android.os.Bundle; +import android.util.Log; import android.view.LayoutInflater; import android.view.View; import android.widget.EditText; @@ -20,9 +25,11 @@ */ public class SettingsActivity extends AppCompatActivity { + private static final String TAG = SettingsActivity.class.getSimpleName(); ArrayList arrayOfUsers; ImageButton addPeople; + //make dynamic array if i give a fuck ImageButton[] updaterButton = new ImageButton[100]; TextView[] myAwesomeNameView = new TextView[100]; @@ -37,7 +44,7 @@ public class SettingsActivity extends AppCompatActivity { public static final String COLUMN_PHONE = "phone"; public static final String COLUMN_NAME = "name"; - DbHandler myHandle; + ContactDbHandler contactsHandle; //Sensor variables: ImageButton addSensors; @@ -46,6 +53,34 @@ public class SettingsActivity extends AppCompatActivity { ImageButton[] destoyerButtonSensors = new ImageButton[100]; SensorDbHandler mySensorHandler; + private SensorDataCollectorApi api; + + private SensorDataCollectorListener.Stub collectorListener = new SensorDataCollectorListener.Stub() { + @Override + public void handleSensorDataUpdated() throws RemoteException { + } + }; + + private ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + Log.i(TAG, "Service connection established"); + + // that's how we get the client side of the IPC connection + api = SensorDataCollectorApi.Stub.asInterface(service); + try { + api.addListener(collectorListener); + } catch (RemoteException e) { + Log.e(TAG, "Failed to add listener", e); + } + // updateTweetView(); + } + + @Override + public void onServiceDisconnected(ComponentName name) { + Log.i(TAG, "Service connection closed"); + } + }; @Override protected void onCreate(Bundle savedInstanceState) { @@ -53,7 +88,7 @@ protected void onCreate(Bundle savedInstanceState) { setContentView(R.layout.activity_settings); addPeople = (ImageButton) findViewById(R.id.button_button_add_new_contact); - myHandle = new DbHandler(this, DATABASE_NAME, null, 1); + contactsHandle = new ContactDbHandler(this, DATABASE_NAME, null, 1); addPeople.setOnClickListener(new View.OnClickListener() { public void onClick(View v) { @@ -77,7 +112,7 @@ public void onClick(DialogInterface dialog, int id) { Contact contact = new Contact(input1.getEditableText().toString(), input2.getEditableText().toString()); //contact.setName(input1.getEditableText().toString()); //contact.setNumber(input2.getEditableText().toString()); - myHandle.addContact(contact); + contactsHandle.addContact(contact); Intent intent = getIntent(); finish(); startActivity(intent); @@ -101,7 +136,7 @@ public void onClick(DialogInterface dialog, int id) { LinearLayout contactslist = (LinearLayout) findViewById(R.id.list_contacts); ArrayList contactsReadFromFile = new ArrayList<>(); - Contact[] contacts = myHandle.databaseToString(); + Contact[] contacts = contactsHandle.databaseToString(); if (contacts != null) { for (int i = 0; i < contacts.length; i++) { @@ -145,16 +180,50 @@ public void onClick(View v) { } myAwesomeNameViewSensors[i].setId(i+500); updaterButtonSensors[i] = (ImageButton) findViewById(R.id.button_edit_sensors); - updaterButtonSensors[i].setId(i+600); + updaterButtonSensors[i].setId(i + 600); updaterButtonSensors[i].setOnClickListener(sensorUpdater); destoyerButtonSensors[i] = (ImageButton) findViewById(R.id.button_delete_sensors); - destoyerButtonSensors[i].setId(i+700); + destoyerButtonSensors[i].setId(i + 700); destoyerButtonSensors[i].setOnClickListener(sensorDestroyer); } } } - View.OnClickListener clickListener = new View.OnClickListener() { + @Override + protected void onResume() { + super.onResume(); + Intent intent; + int currentapiVersion = android.os.Build.VERSION.SDK_INT; + if (currentapiVersion >= android.os.Build.VERSION_CODES.LOLLIPOP){ + // Do something for lollipop and above versions + + intent = new Intent(SensorDataCollectorService.class.getCanonicalName()); + // This is the key line that fixed everything for me + intent.setPackage("com.proseminar.smartsecurity"); + } else{ + // do something for phones running an SDK before lollipop + + intent = new Intent(SensorDataCollectorService.class.getName()); + } + // start the service explicitly. + // otherwise it will only run while the IPC connection is up. + this.startService(intent); + this.bindService(intent, serviceConnection, BIND_AUTO_CREATE); + } + + @Override + protected void onPause() { + super.onPause(); + try { + api.removeListener(collectorListener); + } catch (RemoteException e) { + e.printStackTrace(); + } + unbindService(serviceConnection); + } + + // Edit contact info button and pop-up. + public View.OnClickListener clickListener = new View.OnClickListener() { public void onClick(View v) { int number = 0; for (int i = 0; i<100; i++){ @@ -184,9 +253,7 @@ public void onClick(DialogInterface dialog, int id) { } else { Contact contactHolderOld = new Contact(myAwesomeNameView[number1].getText().toString(), myAwesomePhoneView[number1].getText().toString()); Contact contactHolderNew = new Contact(name.getEditableText().toString(), phone.getEditableText().toString()); - //contact.setName(input1.getEditableText().toString()); - //contact.setNumber(input2.getEditableText().toString()); - myHandle.updateRow(contactHolderOld, contactHolderNew); + contactsHandle.updateRow(contactHolderOld, contactHolderNew); Intent intent = getIntent(); finish(); startActivity(intent); @@ -205,7 +272,7 @@ public void onClick(DialogInterface dialog, int id) { } }; - //method to delete entry + // Delete contact from contacts - button and pop-up. View.OnClickListener clickDestroyer = new View.OnClickListener() { public void onClick(View v) { int position =0; @@ -227,7 +294,7 @@ public void onClick(View v) { .setPositiveButton("Yes",new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int id) { Contact contactHolder = new Contact((String)myAwesomeNameView[i].getText(), (String)myAwesomePhoneView[i].getText()); - myHandle.deleteContact(contactHolder); + contactsHandle.deleteContact(contactHolder); Intent intent = getIntent(); finish(); startActivity(intent); @@ -247,6 +314,7 @@ public void onClick(DialogInterface dialog,int id) { } }; + // Check for empty fields. public void emptyFields(){ AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( context); @@ -273,6 +341,7 @@ public void onClick(DialogInterface dialog, int id) { alertDialog.show(); } + // Edit sensor name button and pop-up. View.OnClickListener sensorUpdater = new View.OnClickListener() { public void onClick(View v) { int number = 0; @@ -320,7 +389,7 @@ public void onClick(DialogInterface dialog, int id) { } }; - //method to delete entry + // Remove sensor button and pop-up. View.OnClickListener sensorDestroyer = new View.OnClickListener() { public void onClick(View v) { int position =0; @@ -334,7 +403,7 @@ public void onClick(View v) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( context); // set title - alertDialogBuilder.setTitle("Delete Contact"); + alertDialogBuilder.setTitle("Remove sensor"); // set dialog message alertDialogBuilder .setMessage("Click yes to delete!") @@ -342,8 +411,20 @@ public void onClick(View v) { .setPositiveButton("Yes",new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog,int id) { Sensor sensorHolder = new Sensor(myAwesomeNameViewSensors[i].getText().toString(), null); + for (Sensor s: mySensorHandler.databaseToString()) { + if(s.getName().equals(myAwesomeNameViewSensors[i].getText().toString())) { + sensorHolder = s; + break; + } + } mySensorHandler.deleteSensor(sensorHolder); Intent intent = getIntent(); + try { + api.removeBluetoothConnection(sensorHolder.getSensorId()); + } catch (RemoteException e) { + e.printStackTrace(); + } + SensorCollection.removeSensor(sensorHolder.getSensorId()); finish(); startActivity(intent); } @@ -372,6 +453,4 @@ public void infoOnClick(View v) { Intent i = new Intent(this, InfoActivity.class); startActivity(i); } - - } diff --git a/app/src/main/java/com/proseminar/smartsecurity/SyncManager.java b/app/src/main/java/com/proseminar/smartsecurity/SyncManager.java new file mode 100644 index 0000000..91f3d19 --- /dev/null +++ b/app/src/main/java/com/proseminar/smartsecurity/SyncManager.java @@ -0,0 +1,51 @@ +package com.proseminar.smartsecurity; + +import java.util.LinkedList; +import java.util.Observable; +import java.util.Observer; + +/** + * Created by christian on 31.01.16. + */ +public class SyncManager { + + private static SyncManager instance = new SyncManager(); + private static Observable observed; + private static volatile BluetoothLeConnector bluetoothLeConnector; + private static volatile LinkedList observer = new LinkedList(); + + public static SyncManager getInstance() { + return instance; + } + private SyncManager() { + + } + + public void registerObservable(Observable o) { + observed = o; + } + + public static BluetoothLeConnector getConnector() { + return bluetoothLeConnector; + } + + public static void setBluetoothLeConnector(BluetoothLeConnector connector) { + bluetoothLeConnector = connector; + if (observer.size() > 0) { + for (int i = 0; i < observer.size(); i++) { + bluetoothLeConnector.addObserver(observer.get(i)); + System.out.println("added Observer later!"); + } + observer = new LinkedList(); + } + } + + public static void setObserver(Observer obs) { + if (bluetoothLeConnector == null) { + observer.add(obs); + } else { + bluetoothLeConnector.addObserver(obs); + System.out.println("added Observer!"); + } + } +} \ No newline at end of file diff --git a/app/src/main/res/drawable/gear65.png b/app/src/main/res/drawable/gear65.png deleted file mode 100644 index 0ba24f9..0000000 Binary files a/app/src/main/res/drawable/gear65.png and /dev/null differ diff --git a/app/src/main/res/drawable/humid.png b/app/src/main/res/drawable/humid.png new file mode 100644 index 0000000..05f645e Binary files /dev/null and b/app/src/main/res/drawable/humid.png differ diff --git a/app/src/main/res/drawable/info.png b/app/src/main/res/drawable/info.png deleted file mode 100644 index 8cc4686..0000000 Binary files a/app/src/main/res/drawable/info.png and /dev/null differ diff --git a/app/src/main/res/drawable/label36.png b/app/src/main/res/drawable/label36.png deleted file mode 100644 index 294f81f..0000000 Binary files a/app/src/main/res/drawable/label36.png and /dev/null differ diff --git a/app/src/main/res/drawable/levels1.png b/app/src/main/res/drawable/levels1.png deleted file mode 100644 index e6adb73..0000000 Binary files a/app/src/main/res/drawable/levels1.png and /dev/null differ diff --git a/app/src/main/res/drawable/news2.png b/app/src/main/res/drawable/news2.png deleted file mode 100644 index b7b35af..0000000 Binary files a/app/src/main/res/drawable/news2.png and /dev/null differ diff --git a/app/src/main/res/drawable/open95.png b/app/src/main/res/drawable/open95.png deleted file mode 100644 index 5eaf4d7..0000000 Binary files a/app/src/main/res/drawable/open95.png and /dev/null differ diff --git a/app/src/main/res/drawable/pencil17.png b/app/src/main/res/drawable/pencil17.png deleted file mode 100644 index f0d9f1e..0000000 Binary files a/app/src/main/res/drawable/pencil17.png and /dev/null differ diff --git a/app/src/main/res/drawable/plus25.png b/app/src/main/res/drawable/plus25.png deleted file mode 100644 index 4a88240..0000000 Binary files a/app/src/main/res/drawable/plus25.png and /dev/null differ diff --git a/app/src/main/res/drawable/power.png b/app/src/main/res/drawable/power.png deleted file mode 100644 index 194252c..0000000 Binary files a/app/src/main/res/drawable/power.png and /dev/null differ diff --git a/app/src/main/res/drawable/power1.png b/app/src/main/res/drawable/power1.png deleted file mode 100644 index a70bc4a..0000000 Binary files a/app/src/main/res/drawable/power1.png and /dev/null differ diff --git a/app/src/main/res/drawable/remove11.png b/app/src/main/res/drawable/remove11.png deleted file mode 100644 index 00b894f..0000000 Binary files a/app/src/main/res/drawable/remove11.png and /dev/null differ diff --git a/app/src/main/res/drawable/settings.png b/app/src/main/res/drawable/settings.png deleted file mode 100644 index 2b978a7..0000000 Binary files a/app/src/main/res/drawable/settings.png and /dev/null differ diff --git a/app/src/main/res/drawable/temp.png b/app/src/main/res/drawable/temp.png new file mode 100644 index 0000000..1d98f87 Binary files /dev/null and b/app/src/main/res/drawable/temp.png differ diff --git a/app/src/main/res/drawable/tools6.png b/app/src/main/res/drawable/tools6.png deleted file mode 100644 index 63a680c..0000000 Binary files a/app/src/main/res/drawable/tools6.png and /dev/null differ diff --git a/app/src/main/res/drawable/turnoff1.png b/app/src/main/res/drawable/turnoff1.png deleted file mode 100644 index 4c6d08d..0000000 Binary files a/app/src/main/res/drawable/turnoff1.png and /dev/null differ diff --git a/app/src/main/res/layout/activity_alarm_on.xml b/app/src/main/res/layout/activity_alarm_on.xml index d860e52..fc16500 100644 --- a/app/src/main/res/layout/activity_alarm_on.xml +++ b/app/src/main/res/layout/activity_alarm_on.xml @@ -25,7 +25,6 @@ android:text="@string/alarm_on_text_top" android:textSize="50sp" android:textColor="#efefef" - android:textStyle="bold" android:fontFamily="sans-serif-thin"/> @@ -36,9 +35,9 @@ android:layout_gravity="center" android:textAlignment="center" android:text="@string/alarm_on_text_middle" + android:textStyle="bold" android:textSize="150sp" android:textColor="#00ccd6" - android:textStyle="bold" android:fontFamily="sans-serif-thin"/> @@ -81,7 +79,6 @@ android:text="@string/turnOffButton" android:background="#00ccd6" android:textSize="50sp" - android:textStyle="bold" android:textColor="#333333" android:fontFamily="sans-serif-light" /> diff --git a/app/src/main/res/layout/activity_alarm_warning.xml b/app/src/main/res/layout/activity_alarm_warning.xml index 1aa5670..6329f10 100644 --- a/app/src/main/res/layout/activity_alarm_warning.xml +++ b/app/src/main/res/layout/activity_alarm_warning.xml @@ -25,7 +25,6 @@ android:text="@string/alarm_warning_text_top" android:textSize="35sp" android:textColor="#efefef" - android:textStyle="bold" android:fontFamily="sans-serif-thin"/> + android:textStyle="bold" + android:fontFamily="sans-serif-thin"/> @@ -72,7 +71,6 @@ android:text="@string/cancelButton" android:background="#00ccd6" android:textSize="50sp" - android:textStyle="bold" android:textColor="#333333" android:fontFamily="sans-serif-light" /> diff --git a/app/src/main/res/layout/activity_info_activity.xml b/app/src/main/res/layout/activity_info_activity.xml index 0b167da..01bcb70 100644 --- a/app/src/main/res/layout/activity_info_activity.xml +++ b/app/src/main/res/layout/activity_info_activity.xml @@ -5,9 +5,15 @@ android:layout_height="match_parent" android:background="#efefef"> + + - + android:layout_height="match_parent"> - + android:layout_height="wrap_content"> + + + + + + + + + + + android:layout_width="0dp" + android:layout_height="0dp" + android:layout_weight="1"/> - + android:layout_height="wrap_content" + android:layout_alignParentBottom="true"> + + + + + + + - - \ No newline at end of file + \ No newline at end of file diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml deleted file mode 100644 index d9e993a..0000000 --- a/app/src/main/res/layout/activity_main.xml +++ /dev/null @@ -1,59 +0,0 @@ - - - - - - - - - - -