diff --git a/.github/workflows/android.yml b/.github/workflows/android.yml new file mode 100644 index 0000000..984a7ce --- /dev/null +++ b/.github/workflows/android.yml @@ -0,0 +1,26 @@ +name: Android CI + +on: + push: + branches: [ app_dev ] + pull_request: + branches: [ app_dev ] + +jobs: + build: + + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - name: set up JDK 11 + uses: actions/setup-java@v2 + with: + java-version: '11' + distribution: 'temurin' + cache: gradle + + - name: Grant execute permission for gradlew + run: chmod +x ./ClimateGoApp/gradlew + - name: Build with Gradle + run: cd ClimateGoApp && ./gradlew build diff --git a/.gitignore b/.gitignore index 5dcc104..fb2a675 100644 --- a/.gitignore +++ b/.gitignore @@ -444,3 +444,6 @@ obj/ # End of https://www.toptal.com/developers/gitignore/api/platformio,c,cmake,c++,intellij,android,androidstudio,clion+all,java + +### only on app_dev +firmware/ diff --git a/ClimateGoApp/.gitignore b/ClimateGoApp/.gitignore new file mode 100644 index 0000000..aa724b7 --- /dev/null +++ b/ClimateGoApp/.gitignore @@ -0,0 +1,15 @@ +*.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 diff --git a/ClimateGoApp/app/.gitignore b/ClimateGoApp/app/.gitignore new file mode 100644 index 0000000..42afabf --- /dev/null +++ b/ClimateGoApp/app/.gitignore @@ -0,0 +1 @@ +/build \ No newline at end of file diff --git a/ClimateGoApp/app/build.gradle b/ClimateGoApp/app/build.gradle new file mode 100644 index 0000000..45d8b9c --- /dev/null +++ b/ClimateGoApp/app/build.gradle @@ -0,0 +1,44 @@ +plugins { + id 'com.android.application' +} + +android { + compileSdk 32 + + defaultConfig { + applicationId "de.cdaut.climategoapp" + minSdk 23 + targetSdk 32 + versionCode 1 + versionName "1.0" + + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" + } + + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' + } + } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } + buildFeatures { + viewBinding true + } +} + +dependencies { + + implementation 'androidx.appcompat:appcompat:1.3.0' + implementation 'com.google.android.material:material:1.5.0' + implementation 'androidx.constraintlayout:constraintlayout:2.0.4' + implementation 'androidx.navigation:navigation-fragment:2.3.5' + implementation 'androidx.navigation:navigation-ui:2.3.5' + implementation 'com.google.android.material:material:1.6.0-alpha03' + testImplementation 'junit:junit:4.13.2' + androidTestImplementation 'androidx.test.ext:junit:1.1.3' + androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' +} \ No newline at end of file diff --git a/ClimateGoApp/app/proguard-rules.pro b/ClimateGoApp/app/proguard-rules.pro new file mode 100644 index 0000000..481bb43 --- /dev/null +++ b/ClimateGoApp/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/ClimateGoApp/app/src/androidTest/java/de/cdaut/climategoapp/ExampleInstrumentedTest.java b/ClimateGoApp/app/src/androidTest/java/de/cdaut/climategoapp/ExampleInstrumentedTest.java new file mode 100644 index 0000000..2fc3f8a --- /dev/null +++ b/ClimateGoApp/app/src/androidTest/java/de/cdaut/climategoapp/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package de.cdaut.climategoapp; + +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("de.cdaut.climategoapp", appContext.getPackageName()); + } +} \ No newline at end of file diff --git a/ClimateGoApp/app/src/debug/logo-playstore.png b/ClimateGoApp/app/src/debug/logo-playstore.png new file mode 100644 index 0000000..0bad5cf Binary files /dev/null and b/ClimateGoApp/app/src/debug/logo-playstore.png differ diff --git a/ClimateGoApp/app/src/debug/res/drawable/logo_foreground.xml b/ClimateGoApp/app/src/debug/res/drawable/logo_foreground.xml new file mode 100644 index 0000000..0761fda --- /dev/null +++ b/ClimateGoApp/app/src/debug/res/drawable/logo_foreground.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/ClimateGoApp/app/src/debug/res/mipmap-anydpi-v26/logo.xml b/ClimateGoApp/app/src/debug/res/mipmap-anydpi-v26/logo.xml new file mode 100644 index 0000000..afa7595 --- /dev/null +++ b/ClimateGoApp/app/src/debug/res/mipmap-anydpi-v26/logo.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ClimateGoApp/app/src/debug/res/mipmap-anydpi-v26/logo_round.xml b/ClimateGoApp/app/src/debug/res/mipmap-anydpi-v26/logo_round.xml new file mode 100644 index 0000000..afa7595 --- /dev/null +++ b/ClimateGoApp/app/src/debug/res/mipmap-anydpi-v26/logo_round.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/ClimateGoApp/app/src/debug/res/mipmap-hdpi/logo.png b/ClimateGoApp/app/src/debug/res/mipmap-hdpi/logo.png new file mode 100644 index 0000000..94f599f Binary files /dev/null and b/ClimateGoApp/app/src/debug/res/mipmap-hdpi/logo.png differ diff --git a/ClimateGoApp/app/src/debug/res/mipmap-hdpi/logo_round.png b/ClimateGoApp/app/src/debug/res/mipmap-hdpi/logo_round.png new file mode 100644 index 0000000..67b1537 Binary files /dev/null and b/ClimateGoApp/app/src/debug/res/mipmap-hdpi/logo_round.png differ diff --git a/ClimateGoApp/app/src/debug/res/mipmap-mdpi/logo.png b/ClimateGoApp/app/src/debug/res/mipmap-mdpi/logo.png new file mode 100644 index 0000000..86f888b Binary files /dev/null and b/ClimateGoApp/app/src/debug/res/mipmap-mdpi/logo.png differ diff --git a/ClimateGoApp/app/src/debug/res/mipmap-mdpi/logo_round.png b/ClimateGoApp/app/src/debug/res/mipmap-mdpi/logo_round.png new file mode 100644 index 0000000..f3747e6 Binary files /dev/null and b/ClimateGoApp/app/src/debug/res/mipmap-mdpi/logo_round.png differ diff --git a/ClimateGoApp/app/src/debug/res/mipmap-xhdpi/logo.png b/ClimateGoApp/app/src/debug/res/mipmap-xhdpi/logo.png new file mode 100644 index 0000000..1e361dc Binary files /dev/null and b/ClimateGoApp/app/src/debug/res/mipmap-xhdpi/logo.png differ diff --git a/ClimateGoApp/app/src/debug/res/mipmap-xhdpi/logo_round.png b/ClimateGoApp/app/src/debug/res/mipmap-xhdpi/logo_round.png new file mode 100644 index 0000000..1cbe2b9 Binary files /dev/null and b/ClimateGoApp/app/src/debug/res/mipmap-xhdpi/logo_round.png differ diff --git a/ClimateGoApp/app/src/debug/res/mipmap-xxhdpi/logo.png b/ClimateGoApp/app/src/debug/res/mipmap-xxhdpi/logo.png new file mode 100644 index 0000000..4dc422b Binary files /dev/null and b/ClimateGoApp/app/src/debug/res/mipmap-xxhdpi/logo.png differ diff --git a/ClimateGoApp/app/src/debug/res/mipmap-xxhdpi/logo_round.png b/ClimateGoApp/app/src/debug/res/mipmap-xxhdpi/logo_round.png new file mode 100644 index 0000000..e2cb13c Binary files /dev/null and b/ClimateGoApp/app/src/debug/res/mipmap-xxhdpi/logo_round.png differ diff --git a/ClimateGoApp/app/src/debug/res/mipmap-xxxhdpi/logo.png b/ClimateGoApp/app/src/debug/res/mipmap-xxxhdpi/logo.png new file mode 100644 index 0000000..4c7d03b Binary files /dev/null and b/ClimateGoApp/app/src/debug/res/mipmap-xxxhdpi/logo.png differ diff --git a/ClimateGoApp/app/src/debug/res/mipmap-xxxhdpi/logo_round.png b/ClimateGoApp/app/src/debug/res/mipmap-xxxhdpi/logo_round.png new file mode 100644 index 0000000..2a38f5a Binary files /dev/null and b/ClimateGoApp/app/src/debug/res/mipmap-xxxhdpi/logo_round.png differ diff --git a/ClimateGoApp/app/src/debug/res/values/logo_background.xml b/ClimateGoApp/app/src/debug/res/values/logo_background.xml new file mode 100644 index 0000000..eee1f15 --- /dev/null +++ b/ClimateGoApp/app/src/debug/res/values/logo_background.xml @@ -0,0 +1,4 @@ + + + #F3F3F3 + \ No newline at end of file diff --git a/ClimateGoApp/app/src/main/AndroidManifest.xml b/ClimateGoApp/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..7372be3 --- /dev/null +++ b/ClimateGoApp/app/src/main/AndroidManifest.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/DebugFragment.java b/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/DebugFragment.java new file mode 100644 index 0000000..021733d --- /dev/null +++ b/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/DebugFragment.java @@ -0,0 +1,63 @@ +package de.cdaut.climategoapp; + +import static android.app.Activity.RESULT_OK; + +import android.bluetooth.BluetoothAdapter; +import android.content.Intent; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Toast; + + +import androidx.activity.result.ActivityResultLauncher; +import androidx.activity.result.contract.ActivityResultContracts; +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import de.cdaut.climategoapp.databinding.FragmentDebugBinding; + +public class DebugFragment extends Fragment { + + private FragmentDebugBinding binding; + + //this is the Launcher that will make the request to + // enable Bluetooth and handle the result callback + private final ActivityResultLauncher mBtEnable = registerForActivityResult( + new ActivityResultContracts.StartActivityForResult(), + result -> { + if (result.getResultCode() != RESULT_OK) { + //make an error toast if the user denys enabling bluetooth + Toast.makeText( + getActivity().getApplicationContext(), + R.string.bt_required, + Toast.LENGTH_LONG + ).show(); + } + } + ); + + @Override + public View onCreateView( + @NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState + ) { + + binding = FragmentDebugBinding.inflate(inflater, container, false); + + this.binding.buttonTest.setOnClickListener(view -> { + //make request to enable bluetooth + mBtEnable.launch(new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)); + }); + + return binding.getRoot(); + + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } +} diff --git a/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/HomeFragment.java b/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/HomeFragment.java new file mode 100644 index 0000000..7f47487 --- /dev/null +++ b/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/HomeFragment.java @@ -0,0 +1,40 @@ +package de.cdaut.climategoapp; + +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; + +import androidx.annotation.NonNull; +import androidx.fragment.app.Fragment; + +import de.cdaut.climategoapp.databinding.FragmentHomeBinding; + +public class HomeFragment extends Fragment { + + private FragmentHomeBinding binding; + + @Override + public View onCreateView( + @NonNull LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState + ) { + + binding = FragmentHomeBinding.inflate(inflater, container, false); + + return binding.getRoot(); + + } + + @Override + public void onViewCreated(@NonNull View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + } + + @Override + public void onDestroyView() { + super.onDestroyView(); + binding = null; + } + +} \ No newline at end of file diff --git a/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/activities/HomeActivity.java b/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/activities/HomeActivity.java new file mode 100644 index 0000000..cc155ce --- /dev/null +++ b/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/activities/HomeActivity.java @@ -0,0 +1,136 @@ +package de.cdaut.climategoapp.activities; + +import android.os.Bundle; + + +import androidx.annotation.NonNull; +import androidx.appcompat.app.ActionBarDrawerToggle; +import androidx.appcompat.app.AppCompatActivity; + +import androidx.drawerlayout.widget.DrawerLayout; +import androidx.fragment.app.Fragment; +import androidx.navigation.NavController; +import androidx.navigation.Navigation; +import androidx.navigation.ui.AppBarConfiguration; +import androidx.navigation.ui.NavigationUI; + +import de.cdaut.climategoapp.DebugFragment; +import de.cdaut.climategoapp.HomeFragment; +import de.cdaut.climategoapp.R; +import de.cdaut.climategoapp.databinding.ActivityHomeBinding; + +import android.view.Menu; +import android.view.MenuItem; + +import com.google.android.material.navigation.NavigationView; + +public class HomeActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener { + + private AppBarConfiguration appBarConfiguration; + private ActivityHomeBinding binding; + public DrawerLayout drawerLayout; + public ActionBarDrawerToggle actionBarDrawerToggle; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + binding = ActivityHomeBinding.inflate(getLayoutInflater()); + setContentView(binding.getRoot()); + + setSupportActionBar(binding.toolbar); + + // drawer layout instance to toggle the menu icon to open + // drawer and back button to close drawer + drawerLayout = findViewById(R.id.home_drawer_layout); + actionBarDrawerToggle = new ActionBarDrawerToggle(this, + drawerLayout, + R.string.nav_open, + R.string.nav_close); + + // pass the Open and Close toggle for the drawer layout listener + // to toggle the button + drawerLayout.addDrawerListener(actionBarDrawerToggle); + actionBarDrawerToggle.syncState(); + + // to make the Navigation drawer icon always appear on the action bar + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + + //add the Home Fragment to the Fragment container + this.getSupportFragmentManager() + .beginTransaction() + .replace(R.id.home_act_fragment_container, new HomeFragment()) + .commit(); + + setNavigationViewListener(); + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + // Inflate the menu; this adds items to the action bar if it is present. + getMenuInflater().inflate(R.menu.menu_main, menu); + return true; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + if (actionBarDrawerToggle.onOptionsItemSelected(item)) { + return true; + } + + if (id == R.id.action_settings) { + return true; + } + + return super.onOptionsItemSelected(item); + } + + @Override + public boolean onSupportNavigateUp() { + NavController navController = Navigation.findNavController(this, + R.id.nav_host_fragment_content_nav + ); + return NavigationUI.navigateUp(navController, appBarConfiguration) + || super.onSupportNavigateUp(); + } + + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + + Fragment targetFragment; + + //determine which fragment to switch to + //TODO: switch this to some better switch value like a tag + switch (item.getItemId()) { + case R.id.nav_main: + targetFragment = new HomeFragment(); + break; + case R.id.nav_debug: + targetFragment = new DebugFragment(); + break; + default: + throw new IllegalAccessError("Illegal activity met in nav drawer"); + } + + //switch to the appropriate Fragment + this.getSupportFragmentManager() + .beginTransaction() + .replace(R.id.home_act_fragment_container, targetFragment) + .commit(); + + //close the nav drawer after switching fragments + this.drawerLayout.closeDrawers(); + return false; + } + + private void setNavigationViewListener() { + NavigationView navigationView = findViewById(R.id.nav_drawer); + navigationView.setNavigationItemSelectedListener(this); + } + +} \ No newline at end of file diff --git a/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/sensor/SensorDebugUtils.java b/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/sensor/SensorDebugUtils.java new file mode 100644 index 0000000..9f4cf3e --- /dev/null +++ b/ClimateGoApp/app/src/main/java/de/cdaut/climategoapp/sensor/SensorDebugUtils.java @@ -0,0 +1,18 @@ +package de.cdaut.climategoapp.sensor; + +import java.util.ArrayList; +import java.util.List; + +public final class SensorDebugUtils { + private SensorDebugUtils() { + throw new IllegalAccessError("Utility Class"); + } + + public static List readSensorData() { + ArrayList data = new ArrayList<>(); + data.add("Test"); + data.add("a"); + data.add("b"); + return data; + } +} diff --git a/ClimateGoApp/app/src/main/logo-playstore.png b/ClimateGoApp/app/src/main/logo-playstore.png new file mode 100644 index 0000000..1834bf4 Binary files /dev/null and b/ClimateGoApp/app/src/main/logo-playstore.png differ diff --git a/ClimateGoApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/ClimateGoApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000..2b068d1 --- /dev/null +++ b/ClimateGoApp/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,30 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/ClimateGoApp/app/src/main/res/drawable/ic_launcher_background.xml b/ClimateGoApp/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000..07d5da9 --- /dev/null +++ b/ClimateGoApp/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/ClimateGoApp/app/src/main/res/drawable/logo_foreground.xml b/ClimateGoApp/app/src/main/res/drawable/logo_foreground.xml new file mode 100644 index 0000000..0761fda --- /dev/null +++ b/ClimateGoApp/app/src/main/res/drawable/logo_foreground.xml @@ -0,0 +1,39 @@ + + + + + + + + + diff --git a/ClimateGoApp/app/src/main/res/layout/activity_home.xml b/ClimateGoApp/app/src/main/res/layout/activity_home.xml new file mode 100644 index 0000000..f0951c6 --- /dev/null +++ b/ClimateGoApp/app/src/main/res/layout/activity_home.xml @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ClimateGoApp/app/src/main/res/layout/content_nav.xml b/ClimateGoApp/app/src/main/res/layout/content_nav.xml new file mode 100644 index 0000000..482b09b --- /dev/null +++ b/ClimateGoApp/app/src/main/res/layout/content_nav.xml @@ -0,0 +1,19 @@ + + + + + \ No newline at end of file diff --git a/ClimateGoApp/app/src/main/res/layout/fragment_debug.xml b/ClimateGoApp/app/src/main/res/layout/fragment_debug.xml new file mode 100644 index 0000000..e66b45b --- /dev/null +++ b/ClimateGoApp/app/src/main/res/layout/fragment_debug.xml @@ -0,0 +1,28 @@ + + + +