diff --git a/androidTest/java/com/example/hbox/ExampleInstrumentedTest.kt b/androidTest/java/com/example/hbox/ExampleInstrumentedTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..0b381bbd88ad29413af474fd3e262518c2110df9 --- /dev/null +++ b/androidTest/java/com/example/hbox/ExampleInstrumentedTest.kt @@ -0,0 +1,24 @@ +package com.example.hbox + +import androidx.test.InstrumentationRegistry +import androidx.test.runner.AndroidJUnit4 + +import org.junit.Test +import org.junit.runner.RunWith + +import org.junit.Assert.* + +/** + * Instrumented test, which will execute on an Android device. + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +@RunWith(AndroidJUnit4::class) +class ExampleInstrumentedTest { + @Test + fun useAppContext() { + // Context of the app under test. + val appContext = InstrumentationRegistry.getTargetContext() + assertEquals("com.example.hbox", appContext.packageName) + } +} diff --git a/main/AndroidManifest.xml b/main/AndroidManifest.xml new file mode 100644 index 0000000000000000000000000000000000000000..f0ac5f86d52a5644f258aadb3bb2e2b992a82ca6 --- /dev/null +++ b/main/AndroidManifest.xml @@ -0,0 +1,31 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="com.example.hbox"> + + <uses-permission android:name="android.permission.INTERNET"/> + <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> + + <application + android:usesCleartextTraffic="true" + android:allowBackup="true" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:roundIcon="@mipmap/ic_launcher_round" + android:supportsRtl="true" + android:theme="@style/AppTheme"> + <activity + android:name=".control.SettingsActivity" + android:label="@string/title_activity_settings"> + </activity> + adb<activity + android:name=".MainActivity" + android:label="@string/app_name"> + <intent-filter> + <action android:name="android.intent.action.MAIN"/> + + <category android:name="android.intent.category.LAUNCHER"/> + </intent-filter> + </activity> + </application> + +</manifest> \ No newline at end of file diff --git a/main/java/com/example/hbox/MainActivity.kt b/main/java/com/example/hbox/MainActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..a12c62da625d6a6d5cfb6fc51e2bb309b7afdcde --- /dev/null +++ b/main/java/com/example/hbox/MainActivity.kt @@ -0,0 +1,62 @@ +package com.example.hbox + +import android.os.Bundle +import com.google.android.material.bottomnavigation.BottomNavigationView +import androidx.fragment.app.Fragment +import androidx.appcompat.app.AppCompatActivity +import android.util.Log +import com.example.hbox.control.ControlFragment +import com.example.hbox.history.HistoryFragment +import com.example.hbox.home.HomeFragment +import com.example.hbox.settings.SettingsFragment +import kotlinx.android.synthetic.main.activity_main.* + +class MainActivity : AppCompatActivity() { + + private lateinit var homeFragment : HomeFragment + private lateinit var controlFragment : ControlFragment + private lateinit var historyFragment : HistoryFragment + private lateinit var settingsFragment : SettingsFragment + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setContentView(R.layout.activity_main) + Log.d("d", "onCreate von MainActivity") + navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) + + homeFragment = HomeFragment() + controlFragment = ControlFragment() + historyFragment = HistoryFragment() + settingsFragment = SettingsFragment() + + replaceFragment(HomeFragment()) + } + + private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> + when (item.itemId) { + R.id.navigation_home -> { + replaceFragment(homeFragment) + return@OnNavigationItemSelectedListener true + } + R.id.navigation_control-> { + replaceFragment(controlFragment) + return@OnNavigationItemSelectedListener true + } + R.id.navigation_history -> { + replaceFragment(historyFragment) + return@OnNavigationItemSelectedListener true + } + R.id.navigation_settings -> { + replaceFragment(settingsFragment) + return@OnNavigationItemSelectedListener true + } + } + false + } + + private fun replaceFragment(fragment: Fragment) { + val fragmentTransition = supportFragmentManager.beginTransaction() + fragmentTransition.replace(R.id.FragmentContainer, fragment) + fragmentTransition.commit() + } +} diff --git a/main/java/com/example/hbox/control/AutomaticFragment.kt b/main/java/com/example/hbox/control/AutomaticFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..c2db1e2d247ec98d2be394f2731ed540430740cb --- /dev/null +++ b/main/java/com/example/hbox/control/AutomaticFragment.kt @@ -0,0 +1,17 @@ +package com.example.hbox.control + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.example.hbox.R + +class AutomaticFragment : Fragment() { + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, state: Bundle?): View? { + return inflater.inflate(R.layout.fragment_control_automatic, container, false) + } + + +} diff --git a/main/java/com/example/hbox/control/ChildFragment.kt b/main/java/com/example/hbox/control/ChildFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..54d75017bc61724f020acb2b4130399f27c99995 --- /dev/null +++ b/main/java/com/example/hbox/control/ChildFragment.kt @@ -0,0 +1,43 @@ +package com.example.hbox.control + +import android.os.Bundle +import androidx.fragment.app.Fragment + +import android.view.LayoutInflater +import android.view.View +import android.view.View.OnClickListener +import android.view.ViewGroup +import android.widget.TextView +import android.widget.Toast +import com.example.hbox.R + +/** + * The child fragment is no different than any other fragment other than it is now being maintained by + * a child FragmentManager. + */ +class ChildFragment : Fragment(), OnClickListener { + + private var position: Int = 0 + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, state: Bundle?): View? { + position = arguments?.getInt(POSITION_KEY) ?: 0 + + val root = inflater.inflate(R.layout.fragment_control_manually, container, false) +/* + (root?.findViewById(R.id.textViewPosition) as TextView).apply { + text = String.format("%s", position) + setOnClickListener(this@ChildFragment) + } +*/ + return root + } + + override fun onClick(v: View) { + Toast.makeText(v.context, "Clicked Position: $position", Toast.LENGTH_LONG).show() + } + + companion object { + const val POSITION_KEY = "FragmentPositionKey" + fun newInstance(args: Bundle): ChildFragment = ChildFragment().apply { arguments = args } + } +} diff --git a/main/java/com/example/hbox/control/ControlFragment.kt b/main/java/com/example/hbox/control/ControlFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..857a7ad72bfc4eaa41e5f32878f99761890b37ab --- /dev/null +++ b/main/java/com/example/hbox/control/ControlFragment.kt @@ -0,0 +1,44 @@ +package com.example.hbox.control + +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentPagerAdapter +import androidx.viewpager.widget.ViewPager +import com.example.hbox.R +import com.google.android.material.tabs.TabLayout + +class ControlFragment : Fragment() { + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + val view = inflater.inflate(R.layout.fragment_control, container, false) + + val viewPager = view.findViewById<ViewPager>(R.id.viewPager) + viewPager.adapter = MyAdapter(childFragmentManager) + + val tabStrip = view.findViewById<TabLayout>(R.id.pagerTabStrip) + tabStrip.setupWithViewPager(viewPager) + + return view + } + + class MyAdapter internal constructor(fm: FragmentManager) : FragmentPagerAdapter(fm) { + + private var tabList: List<Fragment> = listOf(ManuallyFragment(), AutomaticFragment()) + + override fun getCount(): Int = tabList.size + + override fun getItem(position: Int): Fragment = tabList[position] + + + override fun getPageTitle(position: Int): CharSequence { + return when (position) { + 0 -> "Manuell" + else -> "Automatisch" + } + } + } +} diff --git a/main/java/com/example/hbox/control/ManuallyFragment.kt b/main/java/com/example/hbox/control/ManuallyFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..62b45bec52a7fee84960e4e7c7eece33fb5b591f --- /dev/null +++ b/main/java/com/example/hbox/control/ManuallyFragment.kt @@ -0,0 +1,65 @@ + +package com.example.hbox.control + +import android.os.AsyncTask +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import androidx.fragment.app.Fragment +import com.example.hbox.R +import com.example.hbox.model.Device +import com.example.hbox.model.DeviceList +import com.google.gson.Gson +import com.history.ChartListViewAdapter +import java.net.HttpURLConnection +import java.net.URL + +class ManuallyFragment : Fragment() { +/* + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, state: Bundle?): View? { + // fetch all available devices from server + val url = "http://87.156.139.113:3000/devices" + AsyncTaskHandleJson().execute(url) + // insert device switches in Layout + return inflater.inflate(R.layout.fragment_control_manually, container, false) + } + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + + //create onClick listeners + + } + + inner class AsyncTaskHandleJson : AsyncTask<String, String, String>() { + override fun doInBackground(vararg url: String?): String { + + var text: String + val connection = URL(url[0]).openConnection() as HttpURLConnection + try { + connection.connect() + text = connection.inputStream.use { it.reader().use { reader -> reader.readText() } } + } finally { + connection.disconnect() + } + return text + } + + override fun onPostExecute(result: String?) { + super.onPostExecute(result) + handleJson(result) + } + } + + private fun handleJson(jsonString: String?) { + + val deviceList = ArrayList<Device>() + val devices = Gson().fromJson(jsonString, DeviceList::class.java) + devices.devices?.forEach { deviceList.add(it) } + if (activity == null) return + val adapter = ChartListViewAdapter(activity!!.applicationContext, sensorList) + //historyListView.adapter = adapter + } +*/ +} diff --git a/main/java/com/example/hbox/control/SettingsActivity.kt b/main/java/com/example/hbox/control/SettingsActivity.kt new file mode 100644 index 0000000000000000000000000000000000000000..b97c535b03fcb2358825be42a6817d6c4c915b66 --- /dev/null +++ b/main/java/com/example/hbox/control/SettingsActivity.kt @@ -0,0 +1,244 @@ +package com.example.hbox.control + +import android.annotation.TargetApi +import android.content.Context +import android.content.Intent +import android.content.res.Configuration +import android.media.RingtoneManager +import android.net.Uri +import android.os.Build +import android.os.Bundle +import android.preference.ListPreference +import android.preference.Preference +import android.preference.PreferenceActivity +import android.preference.PreferenceFragment +import android.preference.PreferenceManager +import android.preference.RingtonePreference +import android.text.TextUtils +import android.view.MenuItem +import com.example.hbox.R + +/** + * A [PreferenceActivity] that presents a set of application settings. On + * handset devices, settings are presented as a single list. On tablets, + * settings are split by category, with category headers shown to the left of + * the list of settings. + * + * See [Android Design: Settings](http://developer.android.com/design/patterns/settings.html) + * for design guidelines and the [Settings API Guide](http://developer.android.com/guide/topics/ui/settings.html) + * for more information on developing a Settings UI. + */ +/* +class SettingsActivity : AppCompatPreferenceActivity() { + + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + setupActionBar() + } + + /** + * Set up the [android.app.ActionBar], if the API is available. + */ + private fun setupActionBar() { + supportActionBar?.setDisplayHomeAsUpEnabled(true) + } + + /** + * {@inheritDoc} + */ + override fun onIsMultiPane(): Boolean { + return isXLargeTablet(this) + } + + /** + * {@inheritDoc} + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + override fun onBuildHeaders(target: List<PreferenceActivity.Header>) { + loadHeadersFromResource(R.xml.pref_headers, target) + } + + /** + * This method stops fragment injection in malicious applications. + * Make sure to deny any unknown fragments here. + */ + override fun isValidFragment(fragmentName: String): Boolean { + return PreferenceFragment::class.java.name == fragmentName + || GeneralPreferenceFragment::class.java.name == fragmentName + || DataSyncPreferenceFragment::class.java.name == fragmentName + || NotificationPreferenceFragment::class.java.name == fragmentName + } + + /** + * This fragment shows general preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + class GeneralPreferenceFragment : PreferenceFragment() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + addPreferencesFromResource(R.xml.pref_general) + setHasOptionsMenu(true) + + // Bind the summaries of EditText/List/Dialog/Ringtone preferences + // to their values. When their values change, their summaries are + // updated to reflect the new value, per the Android Design + // guidelines. + bindPreferenceSummaryToValue(findPreference("example_text")) + bindPreferenceSummaryToValue(findPreference("example_list")) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + val id = item.itemId + if (id == android.R.id.home) { + startActivity(Intent(activity, SettingsActivity::class.java)) + return true + } + return super.onOptionsItemSelected(item) + } + } + + /** + * This fragment shows notification preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + class NotificationPreferenceFragment : PreferenceFragment() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + addPreferencesFromResource(R.xml.pref_notification) + setHasOptionsMenu(true) + + // Bind the summaries of EditText/List/Dialog/Ringtone preferences + // to their values. When their values change, their summaries are + // updated to reflect the new value, per the Android Design + // guidelines. + bindPreferenceSummaryToValue(findPreference("notifications_new_message_ringtone")) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + val id = item.itemId + if (id == android.R.id.home) { + startActivity(Intent(activity, SettingsActivity::class.java)) + return true + } + return super.onOptionsItemSelected(item) + } + } + + /** + * This fragment shows data and sync preferences only. It is used when the + * activity is showing a two-pane settings UI. + */ + @TargetApi(Build.VERSION_CODES.HONEYCOMB) + class DataSyncPreferenceFragment : PreferenceFragment() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + addPreferencesFromResource(R.xml.pref_data_sync) + setHasOptionsMenu(true) + + // Bind the summaries of EditText/List/Dialog/Ringtone preferences + // to their values. When their values change, their summaries are + // updated to reflect the new value, per the Android Design + // guidelines. + bindPreferenceSummaryToValue(findPreference("sync_frequency")) + } + + override fun onOptionsItemSelected(item: MenuItem): Boolean { + val id = item.itemId + if (id == android.R.id.home) { + startActivity(Intent(activity, SettingsActivity::class.java)) + return true + } + return super.onOptionsItemSelected(item) + } + } + + companion object { + + /** + * A preference value change listener that updates the preference's summary + * to reflect its new value. + */ + private val sBindPreferenceSummaryToValueListener = Preference.OnPreferenceChangeListener { preference, value -> + val stringValue = value.toString() + + if (preference is ListPreference) { + // For list preferences, look up the correct display value in + // the preference's 'entries' list. + val listPreference = preference + val index = listPreference.findIndexOfValue(stringValue) + + // Set the summary to reflect the new value. + preference.setSummary( + if (index >= 0) + listPreference.entries[index] + else + null + ) + + } else if (preference is RingtonePreference) { + // For ringtone preferences, look up the correct display value + // using RingtoneManager. + if (TextUtils.isEmpty(stringValue)) { + // Empty values correspond to 'silent' (no ringtone). + preference.setSummary(R.string.pref_ringtone_silent) + + } else { + val ringtone = RingtoneManager.getRingtone( + preference.getContext(), Uri.parse(stringValue) + ) + + if (ringtone == null) { + // Clear the summary if there was a lookup error. + preference.setSummary(null) + } else { + // Set the summary to reflect the new ringtone display + // name. + val name = ringtone.getTitle(preference.getContext()) + preference.setSummary(name) + } + } + + } else { + // For all other preferences, set the summary to the value's + // simple string representation. + preference.summary = stringValue + } + true + } + + /** + * Helper method to determine if the device has an extra-large screen. For + * example, 10" tablets are extra-large. + */ + private fun isXLargeTablet(context: Context): Boolean { + return context.resources.configuration.screenLayout and Configuration.SCREENLAYOUT_SIZE_MASK >= Configuration.SCREENLAYOUT_SIZE_XLARGE + } + + /** + * Binds a preference's summary to its value. More specifically, when the + * preference's value is changed, its summary (line of text below the + * preference title) is updated to reflect the value. The summary is also + * immediately updated upon calling this method. The exact display format is + * dependent on the type of preference. + + * @see .sBindPreferenceSummaryToValueListener + */ + private fun bindPreferenceSummaryToValue(preference: Preference) { + // Set the listener to watch for value changes. + preference.onPreferenceChangeListener = sBindPreferenceSummaryToValueListener + + // Trigger the listener immediately with the preference's + // current value. + sBindPreferenceSummaryToValueListener.onPreferenceChange( + preference, + PreferenceManager + .getDefaultSharedPreferences(preference.context) + .getString(preference.key, "") + ) + } + } + +} +*/ diff --git a/main/java/com/example/hbox/history/ChartListViewAdapter.kt b/main/java/com/example/hbox/history/ChartListViewAdapter.kt new file mode 100644 index 0000000000000000000000000000000000000000..67dc518046b44063b7c6ab358146f8a1d8c53c44 --- /dev/null +++ b/main/java/com/example/hbox/history/ChartListViewAdapter.kt @@ -0,0 +1,58 @@ +package com.history + +import android.annotation.SuppressLint +import android.content.Context +import android.graphics.Color +import android.util.Log +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.BaseAdapter +import com.example.hbox.history.axisStyler.TemperatureAxisStyler +import com.example.hbox.history.dataSetStyler.TemperaturDataSetStyler +import com.example.hbox.history.limitLinesFormatter.WeekdayLimitLinesCreator +import com.github.mikephil.charting.charts.LineChart +import com.github.mikephil.charting.data.Entry +import com.github.mikephil.charting.data.LineData +import com.github.mikephil.charting.data.LineDataSet + + +class ChartListViewAdapter(private val context: Context, private val sensorList: List<Sensor>) : BaseAdapter() { + + override fun getItem(position: Int): Sensor = sensorList[position] + override fun getItemId(position: Int): Long = position.toLong() + override fun getCount(): Int = sensorList.size + + @SuppressLint("ViewHolder") + override fun getView(position: Int, convertView: View?, parent: ViewGroup?): View { + val chartView = LayoutInflater.from(context).inflate(com.example.hbox.R.layout.row_layout, parent, false) + val view = chartView.findViewById<LineChart>(com.example.hbox.R.id.chart) + + // add entries + val entries: MutableList<Entry> = mutableListOf() + sensorList[position].data?.forEach { + entries.add(Entry(it.date.toFloat(), it.value)) + } + + // style dataset + val lineDataSet = LineDataSet(entries, sensorList[position].name) + TemperaturDataSetStyler.styleDataSet(lineDataSet) + + // style axis + TemperatureAxisStyler.styleXAxis(view.xAxis) + TemperatureAxisStyler.styleYAxisLeft(view.axisLeft) + TemperatureAxisStyler.styleYAxisRight(view.axisRight) + + // add weekdays + WeekdayLimitLinesCreator.create(view.xAxis, sensorList[position]) + + return view.apply { + data = LineData(lineDataSet) + isScaleYEnabled = false + description.isEnabled = false + setVisibleXRangeMinimum(86400000f) + setVisibleXRangeMaximum(86400000f*3) + moveViewToX(sensorList[position].data?.last()!!.date.toFloat().minus(86400000*3 )) + } + } +} \ No newline at end of file diff --git a/main/java/com/example/hbox/history/HistoryFragment.kt b/main/java/com/example/hbox/history/HistoryFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..34d48b26fe77513c840b68decc83bde0f6884c6f --- /dev/null +++ b/main/java/com/example/hbox/history/HistoryFragment.kt @@ -0,0 +1,66 @@ +package com.example.hbox.history + + +import android.os.AsyncTask +import android.os.Bundle +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import android.widget.ListView +import androidx.fragment.app.Fragment +import com.example.hbox.R +import com.google.gson.Gson +import com.history.ChartListViewAdapter +import com.history.History +import com.history.Sensor +import org.json.JSONObject +import java.net.HttpURLConnection +import java.net.URL + +class HistoryFragment : Fragment() { + + lateinit var historyListView: ListView + + override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_history, container, false) + } + + + override fun onViewCreated(view: View, savedInstanceState: Bundle?) { + super.onViewCreated(view, savedInstanceState) + historyListView = view.findViewById(R.id.history_listView) + val url = "http://87.148.35.81:3000/history" + AsyncTaskHandleJson().execute(url) + } + + inner class AsyncTaskHandleJson : AsyncTask<String, String, String>() { + override fun doInBackground(vararg url: String?): String { + + var text: String + val connection = URL(url[0]).openConnection() as HttpURLConnection + try { + connection.connect() + text = connection.inputStream.use { it.reader().use { reader -> reader.readText() } } + } finally { + connection.disconnect() + } + return text + } + + override fun onPostExecute(result: String?) { + super.onPostExecute(result) + handleJson(result) + } + } + + private fun handleJson(jsonString: String?) { + + val sensorList = ArrayList<Sensor>() + val history = Gson().fromJson(jsonString, History::class.java) + history.sensors?.forEach { sensorList.add(it) } + if (activity == null) return + val adapter = ChartListViewAdapter(activity!!.applicationContext, sensorList) + historyListView.adapter = adapter + } +} \ No newline at end of file diff --git a/main/java/com/example/hbox/history/axisFormatter/NullDigitsFormatter.kt b/main/java/com/example/hbox/history/axisFormatter/NullDigitsFormatter.kt new file mode 100644 index 0000000000000000000000000000000000000000..c55ca475c3c888b667e3d7df2c5b0737ea1b3ecb --- /dev/null +++ b/main/java/com/example/hbox/history/axisFormatter/NullDigitsFormatter.kt @@ -0,0 +1,15 @@ +package com.example.hbox.history.axisFormatter + +import com.github.mikephil.charting.components.AxisBase +import com.github.mikephil.charting.formatter.IAxisValueFormatter +import com.github.mikephil.charting.utils.ColorTemplate +import java.text.DecimalFormat + +class NullDigitsFormatter : IAxisValueFormatter { + override fun getFormattedValue(value: Float, axis: AxisBase?): String { + + val df = DecimalFormat("#") + //df.roundingMode = RoundingMode.CEILING + return df.format(value) + " °C" + } +} \ No newline at end of file diff --git a/main/java/com/example/hbox/history/axisFormatter/TimeFormatter.kt b/main/java/com/example/hbox/history/axisFormatter/TimeFormatter.kt new file mode 100644 index 0000000000000000000000000000000000000000..286c660f1b86dafea9cc2c5e84aa3d90b617d27d --- /dev/null +++ b/main/java/com/example/hbox/history/axisFormatter/TimeFormatter.kt @@ -0,0 +1,14 @@ +package com.example.hbox.history.axisFormatter + +import android.text.format.DateFormat +import com.github.mikephil.charting.components.AxisBase +import com.github.mikephil.charting.formatter.IAxisValueFormatter +import java.util.* + +class TimeFormatter : IAxisValueFormatter { + override fun getFormattedValue(value: Float, axis: AxisBase?): String { + val calendar = Calendar.getInstance(Locale.GERMAN) + calendar.timeInMillis = value.toLong() + return DateFormat.format("HH:mm", calendar).toString() + } +} diff --git a/main/java/com/example/hbox/history/axisStyler/TemperatureAxisStyler.kt b/main/java/com/example/hbox/history/axisStyler/TemperatureAxisStyler.kt new file mode 100644 index 0000000000000000000000000000000000000000..e0ad55d5517a099d429cf80705c620b4147ddcae --- /dev/null +++ b/main/java/com/example/hbox/history/axisStyler/TemperatureAxisStyler.kt @@ -0,0 +1,45 @@ +package com.example.hbox.history.axisStyler + +import android.graphics.Color +import com.example.hbox.history.axisFormatter.NullDigitsFormatter +import com.example.hbox.history.axisFormatter.TimeFormatter +import com.github.mikephil.charting.components.XAxis +import com.github.mikephil.charting.components.YAxis + +class TemperatureAxisStyler { + companion object { + fun styleXAxis(xAxis: XAxis) : XAxis { + xAxis.position = XAxis.XAxisPosition.BOTTOM + return xAxis.apply { + valueFormatter = TimeFormatter() + setDrawAxisLine(false) + setDrawGridLines(false) + setDrawLimitLinesBehindData(true) + textSize = 14f + } + } + + fun styleYAxisRight(yAxis: YAxis) : YAxis { + return yAxis.apply { + setDrawAxisLine(false) + setDrawLabels(false) + setDrawGridLines(false) + } + } + + fun styleYAxisLeft(yAxis: YAxis) : YAxis { + return yAxis.apply { + setDrawAxisLine(false) + textSize = 14f + valueFormatter = NullDigitsFormatter() + axisMinimum = 16f + axisMaximum = 32f + setDrawGridLines(true) + gridColor = Color.DKGRAY + setLabelCount(9,true) + + } + } + } + +} \ No newline at end of file diff --git a/main/java/com/example/hbox/history/dataSetStyler/TemperaturDataSetStyler.kt b/main/java/com/example/hbox/history/dataSetStyler/TemperaturDataSetStyler.kt new file mode 100644 index 0000000000000000000000000000000000000000..758918e997a22814e61d2230c9962b4dabed488b --- /dev/null +++ b/main/java/com/example/hbox/history/dataSetStyler/TemperaturDataSetStyler.kt @@ -0,0 +1,21 @@ +package com.example.hbox.history.dataSetStyler + +import android.graphics.Color +import com.github.mikephil.charting.data.LineDataSet + +class TemperaturDataSetStyler { + companion object { + fun styleDataSet (lineDataSet : LineDataSet) : LineDataSet { + return lineDataSet.apply{ + lineWidth = 0f + color = Color.argb(255,255,15,15) + fillColor = Color.argb(255,255,15,15) + fillAlpha = 100 + mode = LineDataSet.Mode.CUBIC_BEZIER + setDrawFilled(true) + setDrawCircles(false) + setDrawValues(false) + } + } + } +} \ No newline at end of file diff --git a/main/java/com/example/hbox/history/limitLinesFormatter/WeekdayLimitLinesCreator.kt b/main/java/com/example/hbox/history/limitLinesFormatter/WeekdayLimitLinesCreator.kt new file mode 100644 index 0000000000000000000000000000000000000000..3e21f08651ba8356f0d4cea308fe6d79aef51cc6 --- /dev/null +++ b/main/java/com/example/hbox/history/limitLinesFormatter/WeekdayLimitLinesCreator.kt @@ -0,0 +1,31 @@ +package com.example.hbox.history.limitLinesFormatter + +import android.graphics.Color +import com.github.mikephil.charting.components.LimitLine +import com.github.mikephil.charting.components.XAxis +import com.history.Sensor +import java.text.SimpleDateFormat +import java.util.* + +class WeekdayLimitLinesCreator { + companion object { + fun create(xAxis: XAxis, sensor : Sensor) { + val secondsPerDay = 86400000L + val firstTimestamp = sensor.data?.first()?.date!!.toLong() + val lastTimestamp = sensor.data?.last()?.date!!.toLong() + val firstDay = firstTimestamp - firstTimestamp?.rem(secondsPerDay) - 3600000 + + for (a in firstDay..lastTimestamp step secondsPerDay) { + val calendar = Calendar.getInstance(Locale.GERMAN) + calendar.timeInMillis = a + val weekday = SimpleDateFormat("EEE", Locale.GERMAN).format(calendar.time.time) + val dayLimitLine = LimitLine(a.toFloat(), weekday) + dayLimitLine.textSize = 22f + dayLimitLine.lineWidth = 2f + dayLimitLine.textColor = Color.LTGRAY + dayLimitLine.lineColor = Color.LTGRAY + xAxis.addLimitLine(dayLimitLine) + } + } + } +} \ No newline at end of file diff --git a/main/java/com/example/hbox/home/HomeFragment.kt b/main/java/com/example/hbox/home/HomeFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..20aea144dcd1c73548d9571f3b1007eb4f2970f9 --- /dev/null +++ b/main/java/com/example/hbox/home/HomeFragment.kt @@ -0,0 +1,32 @@ +package com.example.hbox.home + + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.hbox.R + + +// TODO: Rename parameter arguments, choose names that match +// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER +private const val ARG_PARAM1 = "param1" +private const val ARG_PARAM2 = "param2" + +/** + * A simple [Fragment] subclass. + * + */ +class HomeFragment : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_home, container, false) + } + + +} diff --git a/main/java/com/example/hbox/model/Device.kt b/main/java/com/example/hbox/model/Device.kt new file mode 100644 index 0000000000000000000000000000000000000000..1a642a06f1389474e6c904e086b4ba1ef3f71a93 --- /dev/null +++ b/main/java/com/example/hbox/model/Device.kt @@ -0,0 +1,12 @@ +package com.example.hbox.model + +import com.google.gson.annotations.SerializedName + +data class Device(@SerializedName("active") + val active: Boolean = false, + @SerializedName("name") + val name: String = "", + @SerializedName("id") + val id: Int = 0, + @SerializedName("pin") + val pin: Int = 0) \ No newline at end of file diff --git a/main/java/com/example/hbox/model/DeviceList.kt b/main/java/com/example/hbox/model/DeviceList.kt new file mode 100644 index 0000000000000000000000000000000000000000..9fd4f3aee5fb41511fe3011f06d0b3c810107217 --- /dev/null +++ b/main/java/com/example/hbox/model/DeviceList.kt @@ -0,0 +1,3 @@ +package com.example.hbox.model + +data class DeviceList(val devices: List<Device>?) \ No newline at end of file diff --git a/main/java/com/example/hbox/model/History.kt b/main/java/com/example/hbox/model/History.kt new file mode 100644 index 0000000000000000000000000000000000000000..53982cd4be250ff0c8bc628e6e6c9578eeebac41 --- /dev/null +++ b/main/java/com/example/hbox/model/History.kt @@ -0,0 +1,6 @@ +package com.history + +import com.google.gson.annotations.SerializedName + +data class History(@SerializedName("sensors") + val sensors: List<Sensor>?) \ No newline at end of file diff --git a/main/java/com/example/hbox/model/Reading.kt b/main/java/com/example/hbox/model/Reading.kt new file mode 100644 index 0000000000000000000000000000000000000000..4dad361381a30c5ff60c8eacbea50f1d74401856 --- /dev/null +++ b/main/java/com/example/hbox/model/Reading.kt @@ -0,0 +1,8 @@ +package com.history + +import com.google.gson.annotations.SerializedName + +data class Reading(@SerializedName("date") + val date: String = "", + @SerializedName("value") + val value: Float = -1f) \ No newline at end of file diff --git a/main/java/com/example/hbox/model/Sensor.kt b/main/java/com/example/hbox/model/Sensor.kt new file mode 100644 index 0000000000000000000000000000000000000000..c04a667f0559a3b3a029fcb86c84c43916b42f63 --- /dev/null +++ b/main/java/com/example/hbox/model/Sensor.kt @@ -0,0 +1,12 @@ +package com.history + +import com.google.gson.annotations.SerializedName + +data class Sensor(@SerializedName("id") + val id: String = "", + @SerializedName("name") + val name: String = "", + @SerializedName("type") + val type: String = "", + @SerializedName("data") + val data: List<Reading>?) \ No newline at end of file diff --git a/main/java/com/example/hbox/settings/SettingsFragment.kt b/main/java/com/example/hbox/settings/SettingsFragment.kt new file mode 100644 index 0000000000000000000000000000000000000000..9cd5c56d11aa4505e6a648c7e44b2b60e03f6536 --- /dev/null +++ b/main/java/com/example/hbox/settings/SettingsFragment.kt @@ -0,0 +1,32 @@ +package com.example.hbox.settings + + +import android.os.Bundle +import androidx.fragment.app.Fragment +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.example.hbox.R + + +// TODO: Rename parameter arguments, choose names that match +// the fragment initialization parameters, e.g. ARG_ITEM_NUMBER +private const val ARG_PARAM1 = "param1" +private const val ARG_PARAM2 = "param2" + +/** + * A simple [Fragment] subclass. + * + */ +class SettingsFragment : Fragment() { + + override fun onCreateView( + inflater: LayoutInflater, container: ViewGroup?, + savedInstanceState: Bundle? + ): View? { + // Inflate the layout for this fragment + return inflater.inflate(R.layout.fragment_settings, container, false) + } + + +} diff --git a/main/res/drawable-v24/ic_launcher_foreground.xml b/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 0000000000000000000000000000000000000000..6348baae395d261af8cd007f13d64674a5737553 --- /dev/null +++ b/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:aapt="http://schemas.android.com/aapt" + android:width="108dp" + android:height="108dp" + android:viewportHeight="108" + android:viewportWidth="108"> + <path + android:fillType="evenOdd" + android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z" + android:strokeColor="#00000000" + android:strokeWidth="1"> + <aapt:attr name="android:fillColor"> + <gradient + android:endX="78.5885" + android:endY="90.9159" + android:startX="48.7653" + android:startY="61.0927" + android:type="linear"> + <item + android:color="#44000000" + android:offset="0.0"/> + <item + android:color="#00000000" + android:offset="1.0"/> + </gradient> + </aapt:attr> + </path> + <path + android:fillColor="#FFFFFF" + android:fillType="nonZero" + android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z" + android:strokeColor="#00000000" + android:strokeWidth="1"/> +</vector> diff --git a/main/res/drawable/ic_home_black_24dp.xml b/main/res/drawable/ic_home_black_24dp.xml new file mode 100644 index 0000000000000000000000000000000000000000..70fb2910c0142b116ab903b289f77594898fbd7c --- /dev/null +++ b/main/res/drawable/ic_home_black_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M10,20v-6h4v6h5v-8h3L12,3 2,12h3v8z"/> +</vector> diff --git a/main/res/drawable/ic_info_black_24dp.xml b/main/res/drawable/ic_info_black_24dp.xml new file mode 100644 index 0000000000000000000000000000000000000000..8024b5b1d64c353bd26cfc0b714e6745ad9b4428 --- /dev/null +++ b/main/res/drawable/ic_info_black_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zm1,15h-2v-6h2v6zm0,-8h-2V7h2v2z"/> +</vector> diff --git a/main/res/drawable/ic_launcher_background.xml b/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 0000000000000000000000000000000000000000..a0ad202f9e3c49fda30c34a96774ef494f5e0862 --- /dev/null +++ b/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8"?> +<vector + xmlns:android="http://schemas.android.com/apk/res/android" + android:height="108dp" + android:width="108dp" + android:viewportHeight="108" + android:viewportWidth="108"> + <path android:fillColor="#008577" + android:pathData="M0,0h108v108h-108z"/> + <path android:fillColor="#00000000" android:pathData="M9,0L9,108" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M19,0L19,108" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M29,0L29,108" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M39,0L39,108" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M49,0L49,108" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M59,0L59,108" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M69,0L69,108" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M79,0L79,108" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M89,0L89,108" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M99,0L99,108" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M0,9L108,9" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M0,19L108,19" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M0,29L108,29" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M0,39L108,39" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M0,49L108,49" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M0,59L108,59" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M0,69L108,69" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M0,79L108,79" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M0,89L108,89" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M0,99L108,99" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M19,29L89,29" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M19,39L89,39" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M19,49L89,49" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M19,59L89,59" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M19,69L89,69" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M19,79L89,79" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M29,19L29,89" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M39,19L39,89" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M49,19L49,89" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M59,19L59,89" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M69,19L69,89" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> + <path android:fillColor="#00000000" android:pathData="M79,19L79,89" + android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/> +</vector> diff --git a/main/res/drawable/ic_notifications_black_24dp.xml b/main/res/drawable/ic_notifications_black_24dp.xml new file mode 100644 index 0000000000000000000000000000000000000000..14f20f98bfc151ddba374e177a7217877a8a8f6f --- /dev/null +++ b/main/res/drawable/ic_notifications_black_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M11.5,22c1.1,0 2,-0.9 2,-2h-4c0,1.1 0.9,2 2,2zm6.5,-6v-5.5c0,-3.07 -2.13,-5.64 -5,-6.32V3.5c0,-0.83 -0.67,-1.5 -1.5,-1.5S10,2.67 10,3.5v0.68c-2.87,0.68 -5,3.25 -5,6.32V16l-2,2v1h17v-1l-2,-2z"/> +</vector> diff --git a/main/res/drawable/ic_settings_black_24dp.xml b/main/res/drawable/ic_settings_black_24dp.xml new file mode 100644 index 0000000000000000000000000000000000000000..ace746c40eed65dfe0291e475271d25427219100 --- /dev/null +++ b/main/res/drawable/ic_settings_black_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/> +</vector> diff --git a/main/res/drawable/ic_settings_input_component_black_24dp.xml b/main/res/drawable/ic_settings_input_component_black_24dp.xml new file mode 100644 index 0000000000000000000000000000000000000000..389fe7e14218273f1bbe2372831143b6ec9babd0 --- /dev/null +++ b/main/res/drawable/ic_settings_input_component_black_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M5,2c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v4L1,6v6h6L7,6L5,6L5,2zM9,16c0,1.3 0.84,2.4 2,2.82L11,23h2v-4.18c1.16,-0.41 2,-1.51 2,-2.82v-2L9,14v2zM1,16c0,1.3 0.84,2.4 2,2.82L3,23h2v-4.18C6.16,18.4 7,17.3 7,16v-2L1,14v2zM21,6L21,2c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v4h-2v6h6L23,6h-2zM13,2c0,-0.55 -0.45,-1 -1,-1s-1,0.45 -1,1v4L9,6v6h6L15,6h-2L13,2zM17,16c0,1.3 0.84,2.4 2,2.82L19,23h2v-4.18c1.16,-0.41 2,-1.51 2,-2.82v-2h-6v2z"/> +</vector> diff --git a/main/res/drawable/ic_sync_black_24dp.xml b/main/res/drawable/ic_sync_black_24dp.xml new file mode 100644 index 0000000000000000000000000000000000000000..478aa984104d35cee727c173ec9317559be702c3 --- /dev/null +++ b/main/res/drawable/ic_sync_black_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M12 4V1L8 5l4 4V6c3.31 0 6 2.69 6 6 0 1.01,-.25 1.97,-.7 2.8l1.46 1.46C19.54 15.03 20 13.57 20 12c0,-4.42,-3.58,-8,-8,-8zm0 14c-3.31 0,-6,-2.69,-6,-6 0,-1.01.25,-1.97.7,-2.8L5.24 7.74C4.46 8.97 4 10.43 4 12c0 4.42 3.58 8 8 8v3l4,-4,-4,-4v3z"/> +</vector> \ No newline at end of file diff --git a/main/res/drawable/ic_trending_up_black_24dp.xml b/main/res/drawable/ic_trending_up_black_24dp.xml new file mode 100644 index 0000000000000000000000000000000000000000..4c9da94b922357957171b09168837f85f9b46687 --- /dev/null +++ b/main/res/drawable/ic_trending_up_black_24dp.xml @@ -0,0 +1,9 @@ +<vector xmlns:android="http://schemas.android.com/apk/res/android" + android:width="24dp" + android:height="24dp" + android:viewportWidth="24.0" + android:viewportHeight="24.0"> + <path + android:fillColor="#FF000000" + android:pathData="M16,6l2.29,2.29 -4.88,4.88 -4,-4L2,16.59 3.41,18l6,-6 4,4 6.3,-6.29L22,12V6z"/> +</vector> diff --git a/main/res/layout/activity_main.xml b/main/res/layout/activity_main.xml new file mode 100644 index 0000000000000000000000000000000000000000..b322708f4364965eca2c15aa5c9864b26da3ca75 --- /dev/null +++ b/main/res/layout/activity_main.xml @@ -0,0 +1,25 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout + xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/FragmentContainer" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".MainActivity"> + + + <com.google.android.material.bottomnavigation.BottomNavigationView + android:id="@+id/navigation" + android:layout_width="0dp" + android:layout_height="wrap_content" + android:layout_marginEnd="0dp" + android:layout_marginStart="0dp" + android:background="?android:attr/windowBackground" + app:layout_constraintBottom_toBottomOf="parent" + app:layout_constraintLeft_toLeftOf="parent" + app:layout_constraintRight_toRightOf="parent" + app:menu="@menu/navigation" +/> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/main/res/layout/fragment_control.xml b/main/res/layout/fragment_control.xml new file mode 100644 index 0000000000000000000000000000000000000000..f701465c6355066772c099767a68569f9d64d4a3 --- /dev/null +++ b/main/res/layout/fragment_control.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:app="http://schemas.android.com/apk/res-auto" + android:layout_width="match_parent" + android:layout_height="match_parent"> + +<com.google.android.material.tabs.TabLayout + android:id="@+id/pagerTabStrip" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:background="@color/colorAccent" + android:minHeight="?attr/actionBarSize" + android:theme="@style/ThemeOverlay.AppCompat.Dark.ActionBar" + app:tabIndicatorColor="@android:color/white" + app:tabIndicatorHeight="4dp" /> + +<androidx.viewpager.widget.ViewPager + android:id="@+id/viewPager" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:layout_below="@+id/pagerTabStrip" /> + +</RelativeLayout> \ No newline at end of file diff --git a/main/res/layout/fragment_control_automatic.xml b/main/res/layout/fragment_control_automatic.xml new file mode 100644 index 0000000000000000000000000000000000000000..912a5d046be2a515c79a5d91ae18714d7efe9e14 --- /dev/null +++ b/main/res/layout/fragment_control_automatic.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent"> + +</androidx.constraintlayout.widget.ConstraintLayout> \ No newline at end of file diff --git a/main/res/layout/fragment_control_manually.xml b/main/res/layout/fragment_control_manually.xml new file mode 100644 index 0000000000000000000000000000000000000000..6bd8ebe98a230afc1d0546e3f176d42da5eec75c --- /dev/null +++ b/main/res/layout/fragment_control_manually.xml @@ -0,0 +1,74 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:orientation="vertical" + android:divider="@android:drawable/divider_horizontal_dark" android:layout_margin="24dp" +> + + <ScrollView + android:layout_width="match_parent" + android:layout_height="match_parent"> + <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" + android:orientation="vertical"> + <Switch + android:text="Licht" + android:layout_width="match_parent" + android:layout_height="wrap_content" android:id="@+id/switch14" android:textSize="24sp" + android:textOff="is aus" android:textOn="is an" + android:padding="24dp"/> + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?android:attr/listDivider"/> + <Switch + android:text="Ventilator" + android:layout_width="match_parent" + android:layout_height="wrap_content" android:id="@+id/switch12" android:textSize="24sp" + android:textOff="is aus" android:textOn="is an" + android:padding="24dp"/> + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?android:attr/listDivider"/> + <Switch + android:text="Umluftventilator" + android:layout_width="match_parent" + android:layout_height="wrap_content" android:id="@+id/switch9" android:textSize="24sp" + android:textOff="is aus" android:textOn="is an" + android:padding="24dp"/> + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?android:attr/listDivider"/> + + <Switch + android:text="Luftentfeuchter" + android:layout_width="match_parent" + android:layout_height="wrap_content" android:id="@+id/switch11" android:textSize="24sp" + android:textOff="is aus" android:textOn="is an" + android:padding="24dp"/> + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?android:attr/listDivider" android:id="@+id/view"/> + <Switch + android:text="Luftbefeuchter" + android:layout_width="match_parent" + android:layout_height="wrap_content" android:id="@+id/switch1" android:textSize="24sp" + android:textOff="is aus" android:textOn="is an" + android:padding="24dp"/> + <View + android:layout_width="match_parent" + android:layout_height="1dp" + android:background="?android:attr/listDivider"/> + <Switch + android:text="Bewässerung" + android:layout_width="match_parent" + android:layout_height="wrap_content" android:id="@+id/switch13" android:textSize="24sp" + android:textOff="is aus" android:textOn="is an" + android:padding="24dp"/> + + </LinearLayout> + </ScrollView> +</LinearLayout> \ No newline at end of file diff --git a/main/res/layout/fragment_history.xml b/main/res/layout/fragment_history.xml new file mode 100644 index 0000000000000000000000000000000000000000..b90601d0f018a4b50879f3c94d61e03148ab1064 --- /dev/null +++ b/main/res/layout/fragment_history.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".history.HistoryFragment" + android:padding="8dp"> + + <ListView + android:id="@+id/history_listView" + android:layout_width="match_parent" + android:layout_height="match_parent"/> + +</FrameLayout> \ No newline at end of file diff --git a/main/res/layout/fragment_home.xml b/main/res/layout/fragment_home.xml new file mode 100644 index 0000000000000000000000000000000000000000..0b5213aecb31081a34ccfcc295e75600a6595f00 --- /dev/null +++ b/main/res/layout/fragment_home.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".home.HomeFragment"> + + <TextView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:text="HomeFragment"/> + +</FrameLayout> \ No newline at end of file diff --git a/main/res/layout/fragment_settings.xml b/main/res/layout/fragment_settings.xml new file mode 100644 index 0000000000000000000000000000000000000000..67943a903db0b8d939e61b08b4f3a07182b5ad77 --- /dev/null +++ b/main/res/layout/fragment_settings.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".settings.SettingsFragment"> + + <!-- TODO: Update blank fragment layout --> + <TextView + android:layout_width="match_parent" + android:layout_height="match_parent" + android:text="SettingsFragment"/> + +</FrameLayout> \ No newline at end of file diff --git a/main/res/layout/row_layout.xml b/main/res/layout/row_layout.xml new file mode 100644 index 0000000000000000000000000000000000000000..5bf01ee559b8db57c9104bd346bfd7a4a339899c --- /dev/null +++ b/main/res/layout/row_layout.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8"?> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:orientation="vertical" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:layout_marginBottom="50dp"> + <com.github.mikephil.charting.charts.LineChart + android:id="@+id/chart" + android:layout_width="match_parent" + android:layout_height="250dp"> + </com.github.mikephil.charting.charts.LineChart> + +</LinearLayout> \ No newline at end of file diff --git a/main/res/menu/navigation.xml b/main/res/menu/navigation.xml new file mode 100644 index 0000000000000000000000000000000000000000..7223195b2717290bbdd41a284c396368a7caccdd --- /dev/null +++ b/main/res/menu/navigation.xml @@ -0,0 +1,23 @@ +<?xml version="1.0" encoding="utf-8"?> +<menu xmlns:android="http://schemas.android.com/apk/res/android"> + + <item + android:id="@+id/navigation_home" + android:icon="@drawable/ic_home_black_24dp" + android:title="@string/title_home"/> + + <item + android:id="@+id/navigation_control" + android:icon="@drawable/ic_settings_input_component_black_24dp" + android:title="Control"/> + + <item + android:id="@+id/navigation_history" + android:icon="@drawable/ic_trending_up_black_24dp" + android:title="History"/> + <item + android:id="@+id/navigation_settings" + android:icon="@drawable/ic_settings_black_24dp" + android:title="Settings"/> + +</menu> diff --git a/main/res/mipmap-anydpi-v26/ic_launcher.xml b/main/res/mipmap-anydpi-v26/ic_launcher.xml new file mode 100644 index 0000000000000000000000000000000000000000..bbd3e021239ce758474da78cfc2ca3cf85ed0d91 --- /dev/null +++ b/main/res/mipmap-anydpi-v26/ic_launcher.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@drawable/ic_launcher_background"/> + <foreground android:drawable="@drawable/ic_launcher_foreground"/> +</adaptive-icon> \ No newline at end of file diff --git a/main/res/mipmap-anydpi-v26/ic_launcher_round.xml b/main/res/mipmap-anydpi-v26/ic_launcher_round.xml new file mode 100644 index 0000000000000000000000000000000000000000..bbd3e021239ce758474da78cfc2ca3cf85ed0d91 --- /dev/null +++ b/main/res/mipmap-anydpi-v26/ic_launcher_round.xml @@ -0,0 +1,5 @@ +<?xml version="1.0" encoding="utf-8"?> +<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> + <background android:drawable="@drawable/ic_launcher_background"/> + <foreground android:drawable="@drawable/ic_launcher_foreground"/> +</adaptive-icon> \ No newline at end of file diff --git a/main/res/mipmap-hdpi/ic_launcher.png b/main/res/mipmap-hdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..898f3ed59ac9f3248734a00e5902736c9367d455 Binary files /dev/null and b/main/res/mipmap-hdpi/ic_launcher.png differ diff --git a/main/res/mipmap-hdpi/ic_launcher_round.png b/main/res/mipmap-hdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..dffca3601eba7bf5f409bdd520820e2eb5122c75 Binary files /dev/null and b/main/res/mipmap-hdpi/ic_launcher_round.png differ diff --git a/main/res/mipmap-mdpi/ic_launcher.png b/main/res/mipmap-mdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..64ba76f75e9ce021aa3d95c213491f73bcacb597 Binary files /dev/null and b/main/res/mipmap-mdpi/ic_launcher.png differ diff --git a/main/res/mipmap-mdpi/ic_launcher_round.png b/main/res/mipmap-mdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..dae5e082342fcdeee5db8a6e0b27028e2d2808f5 Binary files /dev/null and b/main/res/mipmap-mdpi/ic_launcher_round.png differ diff --git a/main/res/mipmap-xhdpi/ic_launcher.png b/main/res/mipmap-xhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..e5ed46597ea8447d91ab1786a34e30f1c26b18bd Binary files /dev/null and b/main/res/mipmap-xhdpi/ic_launcher.png differ diff --git a/main/res/mipmap-xhdpi/ic_launcher_round.png b/main/res/mipmap-xhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..14ed0af35023e4f1901cf03487b6c524257b8483 Binary files /dev/null and b/main/res/mipmap-xhdpi/ic_launcher_round.png differ diff --git a/main/res/mipmap-xxhdpi/ic_launcher.png b/main/res/mipmap-xxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..b0907cac3bfd8fbfdc46e1108247f0a1055387ec Binary files /dev/null and b/main/res/mipmap-xxhdpi/ic_launcher.png differ diff --git a/main/res/mipmap-xxhdpi/ic_launcher_round.png b/main/res/mipmap-xxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..d8ae03154975f397f8ed1b84f2d4bf9783ecfa26 Binary files /dev/null and b/main/res/mipmap-xxhdpi/ic_launcher_round.png differ diff --git a/main/res/mipmap-xxxhdpi/ic_launcher.png b/main/res/mipmap-xxxhdpi/ic_launcher.png new file mode 100644 index 0000000000000000000000000000000000000000..2c18de9e66108411737e910f5c1972476f03ddbf Binary files /dev/null and b/main/res/mipmap-xxxhdpi/ic_launcher.png differ diff --git a/main/res/mipmap-xxxhdpi/ic_launcher_round.png b/main/res/mipmap-xxxhdpi/ic_launcher_round.png new file mode 100644 index 0000000000000000000000000000000000000000..beed3cdd2c32af5114a7dc70b9ef5b698eb8797e Binary files /dev/null and b/main/res/mipmap-xxxhdpi/ic_launcher_round.png differ diff --git a/main/res/values-w820dp/dimens.xml b/main/res/values-w820dp/dimens.xml new file mode 100644 index 0000000000000000000000000000000000000000..63fc816444614bd64f68a372d1f93211628ee51d --- /dev/null +++ b/main/res/values-w820dp/dimens.xml @@ -0,0 +1,6 @@ +<resources> + <!-- Example customization of dimensions originally defined in res/values/dimens.xml + (such as screen margins) for screens with more than 820dp of available width. This + would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). --> + <dimen name="activity_horizontal_margin">64dp</dimen> +</resources> diff --git a/main/res/values/colors.xml b/main/res/values/colors.xml new file mode 100644 index 0000000000000000000000000000000000000000..69b22338c6510250df3b43672635120dbce2fa49 --- /dev/null +++ b/main/res/values/colors.xml @@ -0,0 +1,6 @@ +<?xml version="1.0" encoding="utf-8"?> +<resources> + <color name="colorPrimary">#008577</color> + <color name="colorPrimaryDark">#00574B</color> + <color name="colorAccent">#D81B60</color> +</resources> diff --git a/main/res/values/dimens.xml b/main/res/values/dimens.xml new file mode 100644 index 0000000000000000000000000000000000000000..cef3abc49462768db38c80489d50543472c42b1b --- /dev/null +++ b/main/res/values/dimens.xml @@ -0,0 +1,7 @@ +<resources> + <!-- Default screen margins, per the Android Design guidelines. --> + <dimen name="activity_horizontal_margin">16dp</dimen> + <dimen name="activity_vertical_margin">16dp</dimen> + <dimen name="fab_margin">16dp</dimen> + <dimen name="appbar_padding_top">8dp</dimen> +</resources> diff --git a/main/res/values/strings.xml b/main/res/values/strings.xml new file mode 100644 index 0000000000000000000000000000000000000000..7d06bf5fd812253e40429c1df4b60f6ce771e899 --- /dev/null +++ b/main/res/values/strings.xml @@ -0,0 +1,91 @@ +<resources> + <string name="app_name">HBox</string> + <string name="title_home">Home</string> + <string name="title_dashboard">Dashboard</string> + <string name="title_notifications">Notifications</string> + + <!-- TODO: Remove or change this placeholder text --> + <string name="hello_blank_fragment">Hello blank fragment</string> + <string name="title_activity_control">ControlActivity</string> + <string name="action_settings">Settings</string> + <string name="section_format">Hello World from section: %1$d</string> + <string name="tab_text_1">Tab 1</string> + <string name="tab_text_2">Tab 2</string> + <string name="tab_text_3">Tab 3</string> + <string name="title_activity_test_tabbed">TestTabbedActivity</string> + <string name="title_activity_main2">Main2Activity</string> + <string name="title_activity_baba">baba</string> + <string name="title_activity_settings">Settings</string> + + <!-- Strings related to Settings --> + + <!-- Example General settings --> + <string name="pref_header_general">General</string> + + <string name="pref_title_social_recommendations">Enable social recommendations</string> + <string name="pref_description_social_recommendations">Recommendations for people to contact based on your message + history + </string> + + <string name="pref_title_display_name">Display name</string> + <string name="pref_default_display_name">John Smith</string> + + <string name="pref_title_add_friends_to_messages">Add friends to messages</string> + <string-array name="pref_example_list_titles"> + <item>Always</item> + <item>When possible</item> + <item>Never</item> + </string-array> + <string-array name="pref_example_list_values"> + <item>1</item> + <item>0</item> + <item>-1</item> + </string-array> + + <!-- Example settings for Data & Sync --> + <string name="pref_header_data_sync">Data & sync</string> + + <string name="pref_title_sync_frequency">Sync frequency</string> + <string-array name="pref_sync_frequency_titles"> + <item>15 minutes</item> + <item>30 minutes</item> + <item>1 hour</item> + <item>3 hours</item> + <item>6 hours</item> + <item>Never</item> + </string-array> + <string-array name="pref_sync_frequency_values"> + <item>15</item> + <item>30</item> + <item>60</item> + <item>180</item> + <item>360</item> + <item>-1</item> + </string-array> + + <string-array name="list_preference_entries"> + <item>Entry 1</item> + <item>Entry 2</item> + <item>Entry 3</item> + </string-array> + + <string-array name="list_preference_entry_values"> + <item>1</item> + <item>2</item> + <item>3</item> + </string-array> + + <string-array name="multi_select_list_preference_default_value"/> + + <string name="pref_title_system_sync_settings">System sync settings</string> + + <!-- Example settings for Notifications --> + <string name="pref_header_notifications">Notifications</string> + + <string name="pref_title_new_message_notifications">New message notifications</string> + + <string name="pref_title_ringtone">Ringtone</string> + <string name="pref_ringtone_silent">Silent</string> + + <string name="pref_title_vibrate">Vibrate</string> +</resources> diff --git a/main/res/values/styles.xml b/main/res/values/styles.xml new file mode 100644 index 0000000000000000000000000000000000000000..16dbab30f23fdd6b78a2bdff5c6bf2f9c76efe95 --- /dev/null +++ b/main/res/values/styles.xml @@ -0,0 +1,17 @@ +<resources> + + <!-- Base application theme. --> + <style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar"> + <!-- Customize your theme here. --> + <item name="colorPrimary">@color/colorPrimary</item> + <item name="colorPrimaryDark">@color/colorPrimaryDark</item> + <item name="colorAccent">@color/colorAccent</item> + </style> + <style name="AppTheme.NoActionBar"> + <item name="windowActionBar">false</item> + <item name="windowNoTitle">true</item> + </style> + <style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/> + <style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/> + +</resources> diff --git a/main/res/xml/pref_data_sync.xml b/main/res/xml/pref_data_sync.xml new file mode 100644 index 0000000000000000000000000000000000000000..9f0bf43fd55ee63f8ea1a5c9244733759d2f53c2 --- /dev/null +++ b/main/res/xml/pref_data_sync.xml @@ -0,0 +1,21 @@ +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + + <!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to + dismiss it. --> + <!-- NOTE: ListPreference's summary should be set to its value by the activity code. --> + <ListPreference + android:key="sync_frequency" + android:title="@string/pref_title_sync_frequency" + android:entries="@array/pref_sync_frequency_titles" + android:entryValues="@array/pref_sync_frequency_values" + android:defaultValue="180" + android:negativeButtonText="@null" + android:positiveButtonText="@null"/> + + <!-- This preference simply launches an intent when selected. Use this UI sparingly, per + design guidelines. --> + <Preference android:title="@string/pref_title_system_sync_settings"> + <intent android:action="android.settings.SYNC_SETTINGS"/> + </Preference> + +</PreferenceScreen> diff --git a/main/res/xml/pref_general.xml b/main/res/xml/pref_general.xml new file mode 100644 index 0000000000000000000000000000000000000000..45860e8dc6874290fe570aff0262d9fe2e080bfc --- /dev/null +++ b/main/res/xml/pref_general.xml @@ -0,0 +1,33 @@ +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + + <SwitchPreference + android:key="example_switch" + android:title="@string/pref_title_social_recommendations" + android:summary="@string/pref_description_social_recommendations" + android:defaultValue="true"/> + + <!-- NOTE: EditTextPreference accepts EditText attributes. --> + <!-- NOTE: EditTextPreference's summary should be set to its value by the activity code. --> + <EditTextPreference + android:key="example_text" + android:title="@string/pref_title_display_name" + android:defaultValue="@string/pref_default_display_name" + android:selectAllOnFocus="true" + android:inputType="textCapWords" + android:capitalize="words" + android:singleLine="true" + android:maxLines="1"/> + + <!-- NOTE: Hide buttons to simplify the UI. Users can touch outside the dialog to + dismiss it. --> + <!-- NOTE: ListPreference's summary should be set to its value by the activity code. --> + <ListPreference + android:key="example_list" + android:title="@string/pref_title_add_friends_to_messages" + android:defaultValue="-1" + android:entries="@array/pref_example_list_titles" + android:entryValues="@array/pref_example_list_values" + android:negativeButtonText="@null" + android:positiveButtonText="@null"/> + +</PreferenceScreen> diff --git a/main/res/xml/pref_headers.xml b/main/res/xml/pref_headers.xml new file mode 100644 index 0000000000000000000000000000000000000000..0268009e02b7df62c48987a7c79bc2128df5f56c --- /dev/null +++ b/main/res/xml/pref_headers.xml @@ -0,0 +1,20 @@ +<preference-headers xmlns:android="http://schemas.android.com/apk/res/android"> + + <!-- These settings headers are only used on tablets. --> + + <header + android:fragment="com.example.hbox.control.SettingsActivity$GeneralPreferenceFragment" + android:title="@string/pref_header_general" + android:icon="@drawable/ic_info_black_24dp"/> + + <header + android:fragment="com.example.hbox.control.SettingsActivity$NotificationPreferenceFragment" + android:title="@string/pref_header_notifications" + android:icon="@drawable/ic_notifications_black_24dp"/> + + <header + android:fragment="com.example.hbox.control.SettingsActivity$DataSyncPreferenceFragment" + android:title="@string/pref_header_data_sync" + android:icon="@drawable/ic_sync_black_24dp"/> + +</preference-headers> diff --git a/main/res/xml/pref_notification.xml b/main/res/xml/pref_notification.xml new file mode 100644 index 0000000000000000000000000000000000000000..523105865d7cbccbaf651c9eec496eaa676d2433 --- /dev/null +++ b/main/res/xml/pref_notification.xml @@ -0,0 +1,27 @@ +<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android"> + + <!-- A 'parent' preference, which enables/disables child preferences (below) + when checked/unchecked. --> + <SwitchPreference + android:key="notifications_new_message" + android:title="@string/pref_title_new_message_notifications" + android:defaultValue="true"/> + + <!-- Allows the user to choose a ringtone in the 'notification' category. --> + <!-- NOTE: This preference will be enabled only when the checkbox above is checked. --> + <!-- NOTE: RingtonePreference's summary should be set to its value by the activity code. --> + <RingtonePreference + android:dependency="notifications_new_message" + android:key="notifications_new_message_ringtone" + android:title="@string/pref_title_ringtone" + android:ringtoneType="notification" + android:defaultValue="content://settings/system/notification_sound"/> + + <!-- NOTE: This preference will be enabled only when the checkbox above is checked. --> + <SwitchPreference + android:dependency="notifications_new_message" + android:key="notifications_new_message_vibrate" + android:title="@string/pref_title_vibrate" + android:defaultValue="true"/> + +</PreferenceScreen> diff --git a/test/java/com/example/hbox/ExampleUnitTest.kt b/test/java/com/example/hbox/ExampleUnitTest.kt new file mode 100644 index 0000000000000000000000000000000000000000..7683ee07cf7ca2ad96eb916aa7b37d53535f698b --- /dev/null +++ b/test/java/com/example/hbox/ExampleUnitTest.kt @@ -0,0 +1,17 @@ +package com.example.hbox + +import org.junit.Test + +import org.junit.Assert.* + +/** + * Example local unit test, which will execute on the development machine (host). + * + * See [testing documentation](http://d.android.com/tools/testing). + */ +class ExampleUnitTest { + @Test + fun addition_isCorrect() { + assertEquals(4, 2 + 2) + } +}