From 3b3f70524e2194601b91313833630faa70add831 Mon Sep 17 00:00:00 2001 From: Pookii Date: Fri, 14 Jul 2023 15:28:55 +0100 Subject: [PATCH] add: urban computing course code --- Crawler/.gitignore | 2 + Crawler/how_to_run.txt | 1 + Crawler/request_noise_data.py | 51 ++++ UrbanApplication/.gitignore | 17 ++ UrbanApplication/HowToRun.md | 5 + UrbanApplication/app/.gitignore | 2 + UrbanApplication/app/build.gradle | 57 +++++ UrbanApplication/app/proguard-rules.pro | 21 ++ .../ExampleInstrumentedTest.java | 25 ++ .../app/src/main/AndroidManifest.xml | 33 +++ .../bingqi/urbanapplication/BaseActivity.java | 15 ++ .../com/bingqi/urbanapplication/CsvUtils.java | 52 ++++ .../bingqi/urbanapplication/DataUtils.java | 19 ++ .../com/bingqi/urbanapplication/GpsData.java | 21 ++ .../bingqi/urbanapplication/MainActivity.java | 237 ++++++++++++++++++ .../bingqi/urbanapplication/VolumeData.java | 18 ++ .../drawable-v24/ic_launcher_foreground.xml | 31 +++ .../res/drawable/ic_launcher_background.xml | 74 ++++++ .../app/src/main/res/layout/activity_main.xml | 38 +++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.webp | Bin 0 -> 1404 bytes .../res/mipmap-hdpi/ic_launcher_round.webp | Bin 0 -> 2898 bytes .../src/main/res/mipmap-mdpi/ic_launcher.webp | Bin 0 -> 982 bytes .../res/mipmap-mdpi/ic_launcher_round.webp | Bin 0 -> 1772 bytes .../main/res/mipmap-xhdpi/ic_launcher.webp | Bin 0 -> 1900 bytes .../res/mipmap-xhdpi/ic_launcher_round.webp | Bin 0 -> 3918 bytes .../main/res/mipmap-xxhdpi/ic_launcher.webp | Bin 0 -> 2884 bytes .../res/mipmap-xxhdpi/ic_launcher_round.webp | Bin 0 -> 5914 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.webp | Bin 0 -> 3844 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.webp | Bin 0 -> 7778 bytes .../app/src/main/res/values-night/themes.xml | 16 ++ .../app/src/main/res/values/colors.xml | 14 ++ .../app/src/main/res/values/strings.xml | 4 + .../app/src/main/res/values/themes.xml | 11 + .../app/src/main/res/xml/backup_rules.xml | 14 ++ .../main/res/xml/data_extraction_rules.xml | 20 ++ .../urbanapplication/ExampleUnitTest.java | 17 ++ UrbanApplication/build.gradle | 25 ++ UrbanApplication/gradle.properties | 21 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 59203 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + UrbanApplication/gradlew | 185 ++++++++++++++ UrbanApplication/gradlew.bat | 89 +++++++ UrbanApplication/settings.gradle | 16 ++ 45 files changed, 1167 insertions(+) create mode 100644 Crawler/.gitignore create mode 100644 Crawler/how_to_run.txt create mode 100644 Crawler/request_noise_data.py create mode 100644 UrbanApplication/.gitignore create mode 100644 UrbanApplication/HowToRun.md create mode 100644 UrbanApplication/app/.gitignore create mode 100644 UrbanApplication/app/build.gradle create mode 100644 UrbanApplication/app/proguard-rules.pro create mode 100644 UrbanApplication/app/src/androidTest/java/com/bingqi/urbanapplication/ExampleInstrumentedTest.java create mode 100644 UrbanApplication/app/src/main/AndroidManifest.xml create mode 100644 UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/BaseActivity.java create mode 100644 UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/CsvUtils.java create mode 100644 UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/DataUtils.java create mode 100644 UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/GpsData.java create mode 100644 UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/MainActivity.java create mode 100644 UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/VolumeData.java create mode 100644 UrbanApplication/app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 UrbanApplication/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 UrbanApplication/app/src/main/res/layout/activity_main.xml create mode 100644 UrbanApplication/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 UrbanApplication/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 UrbanApplication/app/src/main/res/mipmap-hdpi/ic_launcher.webp create mode 100644 UrbanApplication/app/src/main/res/mipmap-hdpi/ic_launcher_round.webp create mode 100644 UrbanApplication/app/src/main/res/mipmap-mdpi/ic_launcher.webp create mode 100644 UrbanApplication/app/src/main/res/mipmap-mdpi/ic_launcher_round.webp create mode 100644 UrbanApplication/app/src/main/res/mipmap-xhdpi/ic_launcher.webp create mode 100644 UrbanApplication/app/src/main/res/mipmap-xhdpi/ic_launcher_round.webp create mode 100644 UrbanApplication/app/src/main/res/mipmap-xxhdpi/ic_launcher.webp create mode 100644 UrbanApplication/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.webp create mode 100644 UrbanApplication/app/src/main/res/mipmap-xxxhdpi/ic_launcher.webp create mode 100644 UrbanApplication/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.webp create mode 100644 UrbanApplication/app/src/main/res/values-night/themes.xml create mode 100644 UrbanApplication/app/src/main/res/values/colors.xml create mode 100644 UrbanApplication/app/src/main/res/values/strings.xml create mode 100644 UrbanApplication/app/src/main/res/values/themes.xml create mode 100644 UrbanApplication/app/src/main/res/xml/backup_rules.xml create mode 100644 UrbanApplication/app/src/main/res/xml/data_extraction_rules.xml create mode 100644 UrbanApplication/app/src/test/java/com/bingqi/urbanapplication/ExampleUnitTest.java create mode 100644 UrbanApplication/build.gradle create mode 100644 UrbanApplication/gradle.properties create mode 100644 UrbanApplication/gradle/wrapper/gradle-wrapper.jar create mode 100644 UrbanApplication/gradle/wrapper/gradle-wrapper.properties create mode 100755 UrbanApplication/gradlew create mode 100644 UrbanApplication/gradlew.bat create mode 100644 UrbanApplication/settings.gradle diff --git a/Crawler/.gitignore b/Crawler/.gitignore new file mode 100644 index 0000000..36ed741 --- /dev/null +++ b/Crawler/.gitignore @@ -0,0 +1,2 @@ +*.json +.DS_Store \ No newline at end of file diff --git a/Crawler/how_to_run.txt b/Crawler/how_to_run.txt new file mode 100644 index 0000000..0bc794e --- /dev/null +++ b/Crawler/how_to_run.txt @@ -0,0 +1 @@ +use python3 request_noise_data.py to execute python server code \ No newline at end of file diff --git a/Crawler/request_noise_data.py b/Crawler/request_noise_data.py new file mode 100644 index 0000000..49a8c7e --- /dev/null +++ b/Crawler/request_noise_data.py @@ -0,0 +1,51 @@ +import requests +import pyrebase +from datetime import datetime +import time + +# Bingqi Xia +# 22300549 + +def initialize_firebase(config_file): + with open(config_file) as f: + config = f.readlines() + + firebase = pyrebase.initialize_app(config) + return firebase + +def request_noise_data(): + # current noise data for monitors + url = "https://dublincityairandnoise.ie/assets/php/get-monitors.php" + # url = "https://dublincityairandnoise.ie/readings?monitor=DCC-008&dateFrom=06+Nov+2022&dateTo=06+Nov+2022" + my_referer = "https://dublincityairandnoise.ie/readings?monitor=DCC-008&dateFrom=06+Nov+2022&dateTo=06+Nov+2022" + user_agent = "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/107.0.0.0 Safari/537.36" + accept = "application/json, text/javascript, */*; q=0.01" + + headers={'referer': my_referer, "accept": accept, "user_agent": user_agent} + + r = requests.get(url, headers) + noise_data = [] + if r.status_code == 200: + ret = r.json() + noise_data = [x for x in ret if x['monitor_type']['category']=='noise'] + return noise_data + +def push_noise_data(): + noise_data = request_noise_data() + firebase = initialize_firebase() + + db = firebase.database() + + for data in noise_data: + print(data) + results = db.child("noise_open_data") \ + .child(data['location']) \ + .child(data['latest_reading']['recorded_at']).set(data) + + +if __name__ == '__main__': + push_noise_data() + # while (datetime.now() <= datetime(2022, 11, 6, 17, 30)): + # print(datetime.now()) + # push_noise_data() + # time.sleep(300) \ No newline at end of file diff --git a/UrbanApplication/.gitignore b/UrbanApplication/.gitignore new file mode 100644 index 0000000..420b519 --- /dev/null +++ b/UrbanApplication/.gitignore @@ -0,0 +1,17 @@ +*.iml +.gradle +/local.properties +/.idea/caches +/.idea/libraries +/.idea/modules.xml +/.idea/workspace.xml +/.idea/navEditor.xml +/.idea/assetWizardSettings.xml +.DS_Store +/build +/captures +.externalNativeBuild +.cxx +local.properties +.idea/ +.DS_Store \ No newline at end of file diff --git a/UrbanApplication/HowToRun.md b/UrbanApplication/HowToRun.md new file mode 100644 index 0000000..6299f60 --- /dev/null +++ b/UrbanApplication/HowToRun.md @@ -0,0 +1,5 @@ +1. open the project with android studio or IntelliJ Idea +2. connect android phone(Turn on developer mode) with USB, open USB debug on the phone +3. build apk and it will install in your android phone +4. open app and allow all permissions, click start record then it start collect data +5. datas will be upload firebase. \ No newline at end of file diff --git a/UrbanApplication/app/.gitignore b/UrbanApplication/app/.gitignore new file mode 100644 index 0000000..65d12b9 --- /dev/null +++ b/UrbanApplication/app/.gitignore @@ -0,0 +1,2 @@ +/build +google-services.json \ No newline at end of file diff --git a/UrbanApplication/app/build.gradle b/UrbanApplication/app/build.gradle new file mode 100644 index 0000000..38c3bbd --- /dev/null +++ b/UrbanApplication/app/build.gradle @@ -0,0 +1,57 @@ +buildscript { + + repositories { + // Make sure that you have the following two repositories + google() // Google's Maven repository + mavenCentral() // Maven Central repository + } + + dependencies { + + // Add the dependency for the Google services Gradle plugin + classpath 'com.google.gms:google-services:4.3.14' + } +} + +plugins { + id 'com.android.application' + id 'com.google.gms.google-services' +} + +android { + compileSdk 28 + + defaultConfig { + applicationId "com.bingqi.urbanapplication" + minSdk 23 + targetSdk 28 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.3.0' + implementation 'com.google.android.material:material:1.4.0' + implementation 'androidx.constraintlayout:constraintlayout:2.1.4' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' + implementation 'pub.devrel:easypermissions:3.0.0' + + // Import the BoM for the Firebase platform + implementation platform('com.google.firebase:firebase-bom:31.0.2') + // Add the dependency for the Realtime Database library + implementation 'com.google.firebase:firebase-database' + implementation 'com.google.firebase:firebase-analytics' +} \ No newline at end of file diff --git a/UrbanApplication/app/proguard-rules.pro b/UrbanApplication/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/UrbanApplication/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile \ No newline at end of file diff --git a/UrbanApplication/app/src/androidTest/java/com/bingqi/urbanapplication/ExampleInstrumentedTest.java b/UrbanApplication/app/src/androidTest/java/com/bingqi/urbanapplication/ExampleInstrumentedTest.java new file mode 100644 index 0000000..ce0b0fa --- /dev/null +++ b/UrbanApplication/app/src/androidTest/java/com/bingqi/urbanapplication/ExampleInstrumentedTest.java @@ -0,0 +1,25 @@ +package com.bingqi.urbanapplication; + +import android.content.Context; +import androidx.test.platform.app.InstrumentationRegistry; +import androidx.test.ext.junit.runners.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext(); + assertEquals("com.bingqi.urbanapplication", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/UrbanApplication/app/src/main/AndroidManifest.xml b/UrbanApplication/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..d44f506 --- /dev/null +++ b/UrbanApplication/app/src/main/AndroidManifest.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/BaseActivity.java b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/BaseActivity.java new file mode 100644 index 0000000..45898c2 --- /dev/null +++ b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/BaseActivity.java @@ -0,0 +1,15 @@ +package com.bingqi.urbanapplication; + +import android.Manifest; +import android.app.Activity; +import android.os.Bundle; +import android.os.PersistableBundle; +import androidx.annotation.Nullable; +import androidx.appcompat.app.AppCompatActivity; +import pub.devrel.easypermissions.EasyPermissions; + +public class BaseActivity extends AppCompatActivity { + public void requestPermission(Activity context, String tip, int requestCode, String[] perms) { + EasyPermissions.requestPermissions(context, tip, requestCode, perms); + } +} diff --git a/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/CsvUtils.java b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/CsvUtils.java new file mode 100644 index 0000000..9cd3e67 --- /dev/null +++ b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/CsvUtils.java @@ -0,0 +1,52 @@ +package com.bingqi.urbanapplication; + +import android.os.Environment; +import android.util.Log; + +import java.io.*; +import java.util.ArrayList; + +public class CsvUtils { + private static final String TAG = "CsvUtils"; + + public static void saveToCsv(String fileName, ArrayList content) { + try { + String folderName = null; + if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){ + String path = Environment.getExternalStorageDirectory().getAbsolutePath(); + if (path != null) { + folderName = path +"/CSV/"; + } + } + + File fileDir = new File(folderName); + Log.e(TAG, "dataDir: " + folderName); + if(!fileDir.exists()) { + fileDir.mkdirs(); + } + + String savedPath = folderName + fileName; + Log.e(TAG, "DataPath: " + savedPath); + File file = new File(savedPath); + // if file doesnt exists, then create it + if (!file.exists()) { + file.createNewFile(); + } + + StringBuilder sb = new StringBuilder(); + for (int i = 0; i < content.size(); ++ i) { + sb.append(content.get(i)); + sb.append("\n"); + } + + FileWriter fw = new FileWriter(file.getAbsoluteFile(), true); + BufferedWriter bw = new BufferedWriter(fw); + bw.write(sb.toString()); + bw.close(); + fw.close(); + + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/DataUtils.java b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/DataUtils.java new file mode 100644 index 0000000..06ec136 --- /dev/null +++ b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/DataUtils.java @@ -0,0 +1,19 @@ +package com.bingqi.urbanapplication; + +import com.google.firebase.database.DatabaseReference; +import com.google.firebase.database.FirebaseDatabase; + +public class DataUtils { + + private static final String TAG = "DataUtils"; + private DatabaseReference mDatabase; + + public DataUtils(String path) { + mDatabase = FirebaseDatabase.getInstance().getReference(path); + } + + public void writeData(String pathString, Object obj) { + + mDatabase.child(pathString).setValue(obj); + } +} diff --git a/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/GpsData.java b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/GpsData.java new file mode 100644 index 0000000..ceba095 --- /dev/null +++ b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/GpsData.java @@ -0,0 +1,21 @@ +package com.bingqi.urbanapplication; + +import com.google.firebase.database.IgnoreExtraProperties; + +@IgnoreExtraProperties +public class GpsData { + public String currentTime; + public double latitude; + public double longitude; + + public GpsData() { + // Default constructor required for calls to DataSnapshot.getValue(User.class) + } + + public GpsData(String currentTime, double latitude, double longitude) { + this.currentTime = currentTime; + this.latitude = latitude; + this.longitude = longitude; + } + +} diff --git a/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/MainActivity.java b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/MainActivity.java new file mode 100644 index 0000000..3e92060 --- /dev/null +++ b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/MainActivity.java @@ -0,0 +1,237 @@ +package com.bingqi.urbanapplication; + +import android.Manifest; +import android.app.Activity; +import android.content.Intent; +import android.content.pm.PackageManager; +import android.location.Location; +import android.location.LocationListener; +import android.location.LocationManager; +import android.media.AudioFormat; +import android.media.AudioRecord; +import android.media.MediaRecorder; +import android.util.Log; +import android.view.View; +import android.widget.TextView; +import androidx.annotation.Nullable; +import android.os.Bundle; +import androidx.core.app.ActivityCompat; + +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.Locale; + +public class MainActivity extends BaseActivity { + + private static final String TAG = "MainActivity"; + private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 1; // 10 meters + private static final String VOLUME_DATA_PATH = "volume"; + private static final String GPS_DATA_PATH = "gps"; + + // The minimum time between updates in milliseconds +// private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute + + private static final long MIN_TIME_BW_UPDATES = 1000; //1s + private static final int MAX_DATA_LENGTH = 1200; + + public static SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault()); + + private static final int SAMPLE_RATE_IN_HZ = 8000; + + private String mInfo = ""; + private Location mLocation; + private double mVolume = 0; + private TextView tvLocationInfo; + private TextView tvVolumeInfo; + private LocationManager locationManager; + private String mCurrentTime; + private String mVolumeFileName; + private String mGpsFileName; + private ArrayList mVolumeData; + private ArrayList mGpsData; + + private static final int BUFFER_SIZE = AudioRecord.getMinBufferSize(SAMPLE_RATE_IN_HZ, + AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_PCM_16BIT); + + AudioRecord mAudioRecord; + boolean isGetVoiceRun; + final Object mLock = new Object(); + + @Override + protected void onCreate(@Nullable Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + + tvLocationInfo = (TextView) findViewById(R.id.info_location); + tvVolumeInfo = (TextView) findViewById(R.id.info_volume); + + String[] permissions = new String[]{ + Manifest.permission.RECORD_AUDIO, + Manifest.permission.READ_EXTERNAL_STORAGE, + Manifest.permission.WRITE_EXTERNAL_STORAGE, + Manifest.permission.ACCESS_FINE_LOCATION, + Manifest.permission.ACCESS_COARSE_LOCATION, + Manifest.permission.INTERNET + }; + + requestPermission(this, "Request Permission", 1, permissions); + +// prepareCsvFile(); + + findViewById(R.id.start_record).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + isGetVoiceRun = true; + getNoiseLevel(); + } + }); + + findViewById(R.id.stop_record).setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + isGetVoiceRun = false; + } + }); + +// get gps location + if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { + ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 101); + } + + locationManager = (LocationManager) getSystemService(LOCATION_SERVICE); + mLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER); + + updateLocation(); + // getting GPS status + boolean isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER); + + if (isGPSEnabled) { + Log.d("Gps", "Gps enabled"); +// request new location + locationManager.requestLocationUpdates( + LocationManager.GPS_PROVIDER, + MIN_TIME_BW_UPDATES, + MIN_DISTANCE_CHANGE_FOR_UPDATES, new LocationListener() { + @Override + public void onLocationChanged(Location location) { + mLocation = location; + updateLocation(); + } + + @Override + public void onStatusChanged(String provider, int status, Bundle extras) { + } + + @Override + public void onProviderEnabled(String provider) { + mLocation = locationManager.getLastKnownLocation(provider); + updateLocation(); + } + + @Override + public void onProviderDisabled(String provider) { + + } + }); + + } + } + + private void prepareCsvFile() { + + mCurrentTime = sdf.format(System.currentTimeMillis()); + mVolumeFileName = "volume_" + mCurrentTime + ".csv"; + mGpsFileName = "gps_" + mCurrentTime + ".csv"; + + ArrayList volumeColumns = new ArrayList<>(); + volumeColumns.add("Time,Sound Level (DB)"); + CsvUtils.saveToCsv(mVolumeFileName, volumeColumns); + + ArrayList gpsColumns = new ArrayList<>(); + gpsColumns.add("Time,Latitude,Longitude"); + CsvUtils.saveToCsv(mGpsFileName, gpsColumns); + } + + public void updateLocation() { + if (mLocation != null) { + String currentTime = sdf.format(System.currentTimeMillis()); + + double latitude = mLocation.getLatitude(); + double longitude = mLocation.getLongitude(); + + GpsData gpsData = new GpsData(currentTime, latitude, longitude); + DataUtils dataUtils = new DataUtils(GPS_DATA_PATH); + dataUtils.writeData(currentTime, gpsData); + + StringBuffer sb = new StringBuffer(); + sb.append("[Location]\n"); + sb.append("Latitude: "); + sb.append(mLocation.getLatitude()); + sb.append(", "); + sb.append("Longitude: "); + sb.append(mLocation.getLongitude()); + tvLocationInfo.setText(sb.toString()); + Log.d(TAG, "location: " + sb.toString()); + } + } + + public void updateVolume() { + StringBuffer sb = new StringBuffer(); + sb.append("[Volume] "); + sb.append(mVolume); + sb.append(" DB"); + tvVolumeInfo.setText(sb.toString()); + } + + public void getNoiseLevel() { + + mAudioRecord = new AudioRecord(MediaRecorder.AudioSource.MIC, SAMPLE_RATE_IN_HZ, + AudioFormat.CHANNEL_IN_DEFAULT, AudioFormat.ENCODING_PCM_16BIT, BUFFER_SIZE); + + new Thread(new Runnable() { + @Override + public void run() { + mAudioRecord.startRecording(); + short[] buffer = new short[BUFFER_SIZE]; + while (isGetVoiceRun) { + int r = mAudioRecord.read(buffer, 0, BUFFER_SIZE); + long v = 0; + for (short value : buffer) { + v += value * value; + } + double mean = v / (double) r; + mVolume = 10 * Math.log10(mean); + updateVolume(); + + String currentTime = sdf.format(System.currentTimeMillis()); + StringBuffer sb = new StringBuffer(); + sb.append(currentTime); + sb.append(","); + sb.append(mVolume); +// only save 1000 +// if (mVolumeData.size() < MAX_DATA_LENGTH) { +// mVolumeData.add(sb.toString()); +// } + + VolumeData volumeData = new VolumeData(currentTime, mVolume); + DataUtils dataUtils = new DataUtils(VOLUME_DATA_PATH); + dataUtils.writeData(currentTime, volumeData); + + Log.d(TAG, "volume record:\n" + sb.toString()); + + synchronized (mLock) { + try { + mLock.wait(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + mAudioRecord.stop(); + mAudioRecord.release(); + mAudioRecord = null; + } + }).start(); + } + +} \ No newline at end of file diff --git a/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/VolumeData.java b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/VolumeData.java new file mode 100644 index 0000000..a73f927 --- /dev/null +++ b/UrbanApplication/app/src/main/java/com/bingqi/urbanapplication/VolumeData.java @@ -0,0 +1,18 @@ +package com.bingqi.urbanapplication; + +import com.google.firebase.database.IgnoreExtraProperties; + +@IgnoreExtraProperties +public class VolumeData { + public String currentTime; + public double volume; + + public VolumeData() { + // Default constructor required for calls to DataSnapshot.getValue(User.class) + } + + public VolumeData(String currentTime, double volume) { + this.currentTime = currentTime; + this.volume = volume; + } +} diff --git a/UrbanApplication/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/UrbanApplication/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..1ee1493 --- /dev/null +++ b/UrbanApplication/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/UrbanApplication/app/src/main/res/drawable/ic_launcher_background.xml b/UrbanApplication/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..956b344 --- /dev/null +++ b/UrbanApplication/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/UrbanApplication/app/src/main/res/layout/activity_main.xml b/UrbanApplication/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..5cc823b --- /dev/null +++ b/UrbanApplication/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,38 @@ + + + +