diff --git a/.idea/.name b/.idea/.name new file mode 100644 index 0000000..ec9f2b3 --- /dev/null +++ b/.idea/.name @@ -0,0 +1 @@ +Schockwelle \ No newline at end of file diff --git a/app/arontestprojekt-default-rtdb-export.json b/app/arontestprojekt-default-rtdb-export.json new file mode 100644 index 0000000..355008a --- /dev/null +++ b/app/arontestprojekt-default-rtdb-export.json @@ -0,0 +1,36 @@ +{ + "overview" : { + "IDG1" : { + "amplitude" : 1001, + "breitengrad" : 49.5, + "ip" : "10.00.00.001", + "laengengrad" : 11.5, + "timestamp" : 1113456789, + "vibration" : true + }, + "IDG2" : { + "amplitude" : 200, + "breitengrad" : 40.70064147511923, + "ip" : "20.00.00.000", + "laengengrad" : -73.99376799797778, + "timestamp" : 1203456789, + "vibration" : false + }, + "IDG3" : { + "amplitude" : 30, + "breitengrad" : -33.93157129193122, + "ip" : "30.00.00.000", + "laengengrad" : 18.39666975233824, + "timestamp" : 1303456789, + "vibration" : false + }, + "IDG4" : { + "amplitude" : 4, + "breitengrad" : -33.40763257191139, + "ip" : "40.00.00.000", + "laengengrad" : -70.61870273653996, + "timestamp" : 1403456789, + "vibration" : false + } + } +} diff --git a/app/build.gradle b/app/build.gradle index 96e92cd..d2f02b8 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -1,5 +1,6 @@ plugins { id 'com.android.application' + id 'com.google.gms.google-services' } android { @@ -34,8 +35,10 @@ dependencies { implementation 'com.google.android.material:material:1.3.0' implementation 'androidx.constraintlayout:constraintlayout:2.0.4' implementation 'com.google.android.gms:play-services-maps:17.0.1' + implementation 'com.google.firebase:firebase-database:20.0.0' testImplementation 'junit:junit:4.+' androidTestImplementation 'androidx.test.ext:junit:1.1.2' androidTestImplementation 'androidx.test.espresso:espresso-core:3.3.0' implementation "com.google.android.gms:play-services-location:15.0.1" //Important to find the location from the device + implementation platform('com.google.firebase:firebase-bom:28.1.0') } \ No newline at end of file diff --git a/app/google-services.json b/app/google-services.json new file mode 100644 index 0000000..73a6b16 --- /dev/null +++ b/app/google-services.json @@ -0,0 +1,98 @@ +{ + "project_info": { + "project_number": "1097743535942", + "firebase_url": "https://arontestprojekt-default-rtdb.europe-west1.firebasedatabase.app", + "project_id": "arontestprojekt", + "storage_bucket": "arontestprojekt.appspot.com" + }, + "client": [ + { + "client_info": { + "mobilesdk_app_id": "1:1097743535942:android:527888c66e66b847d29f47", + "android_client_info": { + "package_name": "com.example.myapplication1fb" + } + }, + "oauth_client": [ + { + "client_id": "1097743535942-ajbqq8gjc565pj2c2j5qtlskoskevf6o.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCwR1_JUNHQznkwcDjx5mngPJuqktBKFeM" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1097743535942-ajbqq8gjc565pj2c2j5qtlskoskevf6o.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:1097743535942:android:fba2ee9540898b84d29f47", + "android_client_info": { + "package_name": "com.example.myapplicationf2" + } + }, + "oauth_client": [ + { + "client_id": "1097743535942-ajbqq8gjc565pj2c2j5qtlskoskevf6o.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCwR1_JUNHQznkwcDjx5mngPJuqktBKFeM" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1097743535942-ajbqq8gjc565pj2c2j5qtlskoskevf6o.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + }, + { + "client_info": { + "mobilesdk_app_id": "1:1097743535942:android:34888690bd5c9564d29f47", + "android_client_info": { + "package_name": "de.edotzlaff.schockwelle" + } + }, + "oauth_client": [ + { + "client_id": "1097743535942-ajbqq8gjc565pj2c2j5qtlskoskevf6o.apps.googleusercontent.com", + "client_type": 3 + } + ], + "api_key": [ + { + "current_key": "AIzaSyCwR1_JUNHQznkwcDjx5mngPJuqktBKFeM" + } + ], + "services": { + "appinvite_service": { + "other_platform_oauth_client": [ + { + "client_id": "1097743535942-ajbqq8gjc565pj2c2j5qtlskoskevf6o.apps.googleusercontent.com", + "client_type": 3 + } + ] + } + } + } + ], + "configuration_version": "1" +} \ No newline at end of file diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 869dd28..3013079 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -13,9 +13,9 @@ diff --git a/app/src/main/java/de/edotzlaff/schockwelle/Devices.java b/app/src/main/java/de/edotzlaff/schockwelle/Devices.java new file mode 100644 index 0000000..a3a844e --- /dev/null +++ b/app/src/main/java/de/edotzlaff/schockwelle/Devices.java @@ -0,0 +1,70 @@ +package de.edotzlaff.schockwelle; + +public class Devices { + private String ip; + private boolean vibration; + private long timestamp; + private double breitengrad; + private double laengengrad; + private int amplitude; + + public Devices() { + + } + + public Devices(String ip, boolean vibration, long timestamp, double breitengrad, double laengengrad, int amplitude) { + this.ip = ip; + this.vibration = vibration; + this.timestamp = timestamp; + this.breitengrad = breitengrad; + this.laengengrad = laengengrad; + this.amplitude = amplitude; + } + + public String getIp() { + return ip; + } + public void setIp(String ip) { + this.ip = ip; + } + + + public boolean isVibration() { + return vibration; + } + public void setVibration(boolean vibration) { + this.vibration = vibration; + } + + + public long getTimestamp() { + return timestamp; + } + public void setTimestamp(long timestamp) { + this.timestamp = timestamp; + } + + + public double getBreitengrad() { + return breitengrad; + } + public void setBreitengrad(double breitengrad) { + this.breitengrad = breitengrad; + } + + + public double getLaengengrad() { + return laengengrad; + } + public void setLaengengrad(double laengengrad) { + this.laengengrad = laengengrad; + } + + + public int getAmplitude() { + return amplitude; + } + public void setAmplitude(int amplitude) { + this.amplitude = amplitude; + } +} diff --git a/app/src/main/java/de/edotzlaff/schockwelle/EarthquakeMapsActivity.java b/app/src/main/java/de/edotzlaff/schockwelle/EarthquakeMapsActivity.java index dc96b88..0c3b16a 100644 --- a/app/src/main/java/de/edotzlaff/schockwelle/EarthquakeMapsActivity.java +++ b/app/src/main/java/de/edotzlaff/schockwelle/EarthquakeMapsActivity.java @@ -4,6 +4,7 @@ import android.Manifest; import android.content.pm.PackageManager; import android.location.Location; import android.os.Bundle; +import android.os.SystemClock; import android.util.Log; import android.widget.Toast; @@ -22,6 +23,11 @@ import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; public class EarthquakeMapsActivity extends FragmentActivity implements OnMapReadyCallback { @@ -34,11 +40,17 @@ public class EarthquakeMapsActivity extends FragmentActivity implements OnMapRea private GoogleMap mMap; private FusedLocationProviderClient mFusedLocationProviderClient; + private DatabaseReference mDatenbank; + + private double breitengrad; + private double laengengrad; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_earthquake_maps); + getDataBaseValues(); //TODO Edward: Nur als Anmerkung, diese Methode erfolgt damit deine Methode getDeviceLocation Koordinaten aus der DB bekommt getLocationPermission(); } @@ -99,7 +111,6 @@ public class EarthquakeMapsActivity extends FragmentActivity implements OnMapRea private void getDeviceLocation(){ mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this); - try { if (mLocationPermissionsGranted){ final Task location = mFusedLocationProviderClient.getLastLocation(); @@ -109,10 +120,10 @@ public class EarthquakeMapsActivity extends FragmentActivity implements OnMapRea @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()){ - - Location currentLocation = (Location) task.getResult(); //TODO Aron hier erhält die Anwendung die GPS Positionen + Location currentLocation = (Location) task.getResult(); + currentLocation.setLatitude(breitengrad); //TODO Edward: Hier werden beispielweise Koordinaten aus der Datenbank verwendet für Gerät IDG1 + currentLocation.setLongitude(laengengrad); moveCamera(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()),15f); - } else{ Toast.makeText(EarthquakeMapsActivity.this, "Current Location unavailable", Toast.LENGTH_SHORT).show(); @@ -130,6 +141,46 @@ public class EarthquakeMapsActivity extends FragmentActivity implements OnMapRea mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, zoom)); } + public void getDataBaseValues() + { + mDatenbank = FirebaseDatabase.getInstance().getReference(); + mDatenbank.addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(@NonNull DataSnapshot snapshot) { + processDataBaseValues(snapshot); //Daten Snapshot, Übergabe an processDataBaseValues + } + @Override + public void onCancelled(@NonNull DatabaseError error) { + getDataBaseFailure(error); + } + }); + } - //TODO Aron Daten an DB senden + public void processDataBaseValues (DataSnapshot data) + { + //####### Hier wird beispielweise mit IDG1 gearbeitet, sollte aber klüger ausgearbeitet werden #######: + String breitengradString = data.child("overview").child("IDG1").child("breitengrad").getValue().toString(); //TODO Aron/Team: Idee für passende ID je nach zugreifendem Gerät ==> Hardcoded oder flexibel? + String laengengradString = data.child("overview").child("IDG1").child("laengengrad").getValue().toString(); + breitengrad = Double.parseDouble(breitengradString); + laengengrad = Double.parseDouble(laengengradString); + } + + public void getDataBaseFailure (DatabaseError error) + { + System.out.println("Fehler"); + Log.w("Datenbankfehler", error.toException()); + } + + + //TODO Edward: Hier ist eine beispielhafte Methode mit der du Werte in der Datenbank setzen kannst + public void setDataBaseValues() + { + mDatenbank = FirebaseDatabase.getInstance().getReference(); + mDatenbank.child("overview").child("IDG1").child("ip").setValue("10.00.00.001"); + mDatenbank.child("overview").child("IDG1").child("vibration").setValue(true); + mDatenbank.child("overview").child("IDG1").child("timestamp").setValue(1113456789); + mDatenbank.child("overview").child("IDG1").child("breitengrad").setValue(49.5); + mDatenbank.child("overview").child("IDG1").child("laengengrad").setValue(11.5); + mDatenbank.child("overview").child("IDG1").child("amplitude").setValue(1001); + } } \ No newline at end of file diff --git a/app/src/main/java/de/edotzlaff/schockwelle/MainActivity.java b/app/src/main/java/de/edotzlaff/schockwelle/MainActivity.java index 6bd9b55..9b74200 100644 --- a/app/src/main/java/de/edotzlaff/schockwelle/MainActivity.java +++ b/app/src/main/java/de/edotzlaff/schockwelle/MainActivity.java @@ -1,5 +1,6 @@ package de.edotzlaff.schockwelle; +import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.fragment.app.FragmentActivity; @@ -14,12 +15,17 @@ import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; public class MainActivity extends FragmentActivity { private static final String TAG = "MainActivity"; private static final int ERROR_DIALOG_REQUEST = 9001; - + private DatabaseReference mDatenbank; @Override @@ -30,6 +36,8 @@ public class MainActivity extends FragmentActivity { if (isServiceOK()){ init(); } + + deviceInitDataBase(); //TODO Edward: Mit dieser Methode wird beim Starten der App die DB mit, vorerst festen, Werten für alle IDG 1-4 initialiert } private void init(){ @@ -51,11 +59,8 @@ public class MainActivity extends FragmentActivity { startActivity(intent); } }); - - } - public boolean isServiceOK(){ Log.d(TAG, "isServicesOK(): checking google services version"); @@ -75,4 +80,80 @@ public class MainActivity extends FragmentActivity { } return false; } + + public void deviceInitDataBase() + { + mDatenbank = FirebaseDatabase.getInstance().getReference(); + Devices d1 = new Devices("10.00.00.000", false, 1103456789, 49.45470362290784, 11.151032510281498, 1000); + Devices d2 = new Devices("20.00.00.000", false, 1203456789, 40.70064147511923, -73.993767997977787, 200); + Devices d3 = new Devices("30.00.00.000", false, 1303456789, -33.93157129193122, 18.39666975233824, 30); + Devices d4 = new Devices("40.00.00.000", false, 1403456789, -33.40763257191139, -70.61870273653996, 4); + mDatenbank.child("overview").child("IDG1").setValue(d1); + mDatenbank.child("overview").child("IDG2").setValue(d2); + mDatenbank.child("overview").child("IDG3").setValue(d3); + mDatenbank.child("overview").child("IDG4").setValue(d4); + getDataBaseValues(); + } + + public void getDataBaseValues() + { + mDatenbank.addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(@NonNull DataSnapshot snapshot) { + processDataBaseValues(snapshot); //Daten - Snapshot, Übergabe an Methode DataChangeProtocol + } + @Override + public void onCancelled(@NonNull DatabaseError error) { + getDataBaseFailure(error); + } + }); + } + + public void processDataBaseValues (DataSnapshot data) + { + for (int i = 1; i<=4; i++) //Für alle IDG 1-4 werden Werte ausgegeben + { + //####### Auslesen für String-Werte #######: + String ipAdresse = data.child("overview").child("IDG" + i).child("ip").getValue().toString(); + + //####### Auslesen für boolean-Werte #######: + String vibrationString = data.child("overview").child("IDG" + i).child("vibration").getValue().toString(); + boolean vibration; + if(vibrationString == "true"){ + vibration = true; + }else{ + vibration = false; + } + + //####### Auslesen für double-Werte #######: + String breitengradString = data.child("overview").child("IDG" + i).child("breitengrad").getValue().toString(); + String laengengradString = data.child("overview").child("IDG" + i).child("laengengrad").getValue().toString(); + double breitengrad = Double.parseDouble(breitengradString); + double laengengrad = Double.parseDouble(laengengradString); + + //####### Auslesen für long-Werte #######: + String timestampString = data.child("overview").child("IDG" + i).child("timestamp").getValue().toString(); + long timestamp = Long.parseLong(timestampString); + + //####### Auslesen für ing-Werte #######: + String amplitudeString = data.child("overview").child("IDG" + i).child("amplitude").getValue().toString(); + int amplitude = Integer.parseInt(amplitudeString); + + //####### Optional zur Kontrolle #######: + /* + System.out.println("IDG" + i + " - IP:" + data.child("overview").child("IDG" + i).child("ip").getValue().toString()); + System.out.println("IDG" + i + " - Vibration:" + data.child("overview").child("IDG" + i).child("vibration").getValue().toString()); + System.out.println("IDG" + i + " - Zeitstempel:" + data.child("overview").child("IDG" + i).child("timestamp").getValue().toString()); + System.out.println("IDG" + i + " - Breitengrad:" + data.child("overview").child("IDG" + i).child("breitengrad").getValue().toString()); + System.out.println("IDG" + i + " - Laengengrad:" + data.child("overview").child("IDG" + i).child("laengengrad").getValue().toString()); + System.out.println("IDG" + i + " - Amplitude:" + data.child("overview").child("IDG" + i).child("amplitude").getValue().toString()); + */ + } + } + + public void getDataBaseFailure (DatabaseError error) + { + System.out.println("Fehler"); + Log.w("Datenbankfehler", error.toException()); + } } \ No newline at end of file diff --git a/app/src/main/java/de/edotzlaff/schockwelle/SensorMapsActivity.java b/app/src/main/java/de/edotzlaff/schockwelle/SensorMapsActivity.java index 769ffae..6134ff1 100644 --- a/app/src/main/java/de/edotzlaff/schockwelle/SensorMapsActivity.java +++ b/app/src/main/java/de/edotzlaff/schockwelle/SensorMapsActivity.java @@ -1,9 +1,12 @@ package de.edotzlaff.schockwelle; +import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; import android.location.Location; import android.os.Bundle; +import android.os.SystemClock; +import android.util.Log; import android.widget.TextView; import com.google.android.gms.maps.CameraUpdateFactory; @@ -12,12 +15,18 @@ import com.google.android.gms.maps.OnMapReadyCallback; import com.google.android.gms.maps.SupportMapFragment; import com.google.android.gms.maps.model.LatLng; import com.google.android.gms.maps.model.MarkerOptions; +import com.google.firebase.database.DataSnapshot; +import com.google.firebase.database.DatabaseError; +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; +import com.google.firebase.database.ValueEventListener; import org.w3c.dom.Text; public class SensorMapsActivity extends FragmentActivity implements OnMapReadyCallback { private GoogleMap mMap; + private DatabaseReference mDatenbank; @Override protected void onCreate(Bundle savedInstanceState) { @@ -27,7 +36,6 @@ public class SensorMapsActivity extends FragmentActivity implements OnMapReadyCa TextView tv= (TextView) findViewById(R.id.txtSensor); initMap(); - } void initMap(){ @@ -45,12 +53,72 @@ public class SensorMapsActivity extends FragmentActivity implements OnMapReadyCa LatLng sydney = new LatLng(-34, 151); mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney")); mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney)); - - - } - //TODO Aron Daten von DB abfragen + //TODO Edward: Mit Methode getDataBaseValues werden die Werte in der DB abgefragt. In Methode processDataBaseValues werden diese beispielhaft ausgelesen. Kann nach Bedarf angepasst werden. + public void getDataBaseValues() + { + mDatenbank = FirebaseDatabase.getInstance().getReference(); + mDatenbank.addValueEventListener(new ValueEventListener() { + @Override + public void onDataChange(@NonNull DataSnapshot snapshot) { + processDataBaseValues(snapshot); //Daten - Snapshot, Übergabe an Methode DataChangeProtocol + } + @Override + public void onCancelled(@NonNull DatabaseError error) { + getDataBaseFailure(error); + } + }); + } + + public void processDataBaseValues (DataSnapshot data) + { + for (int i = 1; i<=4; i++) //Für alle IDG 1-4 werden Werte ausgegeben + { + //####### Auslesen für String-Werte #######: + String ipAdresse = data.child("overview").child("IDG" + i).child("ip").getValue().toString(); + + //####### Auslesen für boolean-Werte #######: + String vibrationString = data.child("overview").child("IDG" + i).child("vibration").getValue().toString(); + boolean vibration; + if(vibrationString == "true"){ + vibration = true; + }else{ + vibration = false; + } + + //####### Auslesen für double-Werte #######: + String breitengradString = data.child("overview").child("IDG" + i).child("breitengrad").getValue().toString(); + String laengengradString = data.child("overview").child("IDG" + i).child("laengengrad").getValue().toString(); + double breitengrad = Double.parseDouble(breitengradString); + double laengengrad = Double.parseDouble(laengengradString); + + //####### Auslesen für long-Werte #######: + String timestampString = data.child("overview").child("IDG" + i).child("timestamp").getValue().toString(); + long timestamp = Long.parseLong(timestampString); + + //####### Auslesen für ing-Werte #######: + String amplitudeString = data.child("overview").child("IDG" + i).child("amplitude").getValue().toString(); + int amplitude = Integer.parseInt(amplitudeString); + + //####### Optional zur Kontrolle #######: + /* + System.out.println("IDG" + i + " - IP:" + data.child("overview").child("IDG" + i).child("ip").getValue().toString()); + System.out.println("IDG" + i + " - Vibration:" + data.child("overview").child("IDG" + i).child("vibration").getValue().toString()); + System.out.println("IDG" + i + " - Zeitstempel:" + data.child("overview").child("IDG" + i).child("timestamp").getValue().toString()); + System.out.println("IDG" + i + " - Breitengrad:" + data.child("overview").child("IDG" + i).child("breitengrad").getValue().toString()); + System.out.println("IDG" + i + " - Laengengrad:" + data.child("overview").child("IDG" + i).child("laengengrad").getValue().toString()); + System.out.println("IDG" + i + " - Amplitude:" + data.child("overview").child("IDG" + i).child("amplitude").getValue().toString()); + */ + } + } + + public void getDataBaseFailure (DatabaseError error) + { + System.out.println("Fehler"); + Log.w("Datenbankfehler", error.toException()); + } + //TODO Edward Distanz zwischen zwei Punkten berechnen //TODO Edward Dauer für Timer berechnen bis Smartphone vibriert /* @@ -63,6 +131,4 @@ public class SensorMapsActivity extends FragmentActivity implements OnMapReadyCa return distanceInMeters; } */ - - } \ 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 index 94270dc..bae6234 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -11,7 +11,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnEarthquake" - android:text="Generate Earthquake" + android:text="@string/generate_earthquake" android:layout_centerVertical="true" android:layout_centerHorizontal="true" /> @@ -19,7 +19,7 @@ android:layout_width="wrap_content" android:layout_height="wrap_content" android:id="@+id/btnSensor" - android:text="Be a Sensor" + android:text="@string/be_a_sensor" android:layout_centerHorizontal="true" android:layout_below="@id/btnEarthquake"/> diff --git a/app/src/main/res/mipmap-xxhdpi/schockicon.png b/app/src/main/res/mipmap-xxhdpi/schockicon.png new file mode 100644 index 0000000..5880335 Binary files /dev/null and b/app/src/main/res/mipmap-xxhdpi/schockicon.png differ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 688748b..22aa00c 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -2,4 +2,6 @@ Schockwelle Map Map + Be a Sensor + Generate Earthquake \ No newline at end of file diff --git a/build.gradle b/build.gradle index ec19a1f..8f2442f 100644 --- a/build.gradle +++ b/build.gradle @@ -6,6 +6,7 @@ buildscript { } dependencies { classpath "com.android.tools.build:gradle:4.1.3" + classpath 'com.google.gms:google-services:4.3.8' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files