Weather is functional

This commit is contained in:
ottoptj 2024-08-01 06:12:35 +03:00
commit f23d71a477
13 changed files with 406 additions and 144 deletions

View file

@ -112,15 +112,15 @@ class AppMenuAdapter(
val app = apps[position]
if (app.second.second != 0) {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_work_app, null),null,null,null)
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_work_app, null),null, ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null)
}
else {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null,null,null)
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null,ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null)
}
when (preferences.getString("appMenuAlignment", "left")) {
"left" -> {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(holder.textView.compoundDrawables.filterNotNull().first(),null, null, null)
holder.textView.setCompoundDrawablesWithIntrinsicBounds(holder.textView.compoundDrawables.filterNotNull().first(),null, ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null), null)
holder.textView.gravity = Gravity.CENTER_VERTICAL or Gravity.START
}
"center" -> {
@ -129,7 +129,7 @@ class AppMenuAdapter(
}
"right" -> {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(null,null, holder.textView.compoundDrawables.filterNotNull().first(), null)
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null, holder.textView.compoundDrawables.filterNotNull().first(), null)
holder.textView.gravity = Gravity.CENTER_VERTICAL or Gravity.END
}
}

View file

@ -7,21 +7,21 @@ import android.content.IntentFilter
import android.os.BatteryManager
import android.widget.TextClock
class BatteryReceiver(private val dateText: TextClock) : BroadcastReceiver() {
class BatteryReceiver(private val activity: MainActivity) : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
intent?.let {
val level = it.getIntExtra(BatteryManager.EXTRA_LEVEL, -1)
val scale = it.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
val batteryPct = level * 100 / scale.toFloat()
dateText.format12Hour = "dd MMM yyyy | ${batteryPct.toInt()}%"
dateText.format24Hour = "dd MMM yyyy | ${batteryPct.toInt()}%"
activity.modifyDate("${batteryPct.toInt()}%", 2)
}
}
companion object {
fun register(context: Context, textView: TextClock): BatteryReceiver {
val receiver = BatteryReceiver(textView)
fun register(context: Context, activity: MainActivity): BatteryReceiver {
val receiver = BatteryReceiver(activity)
val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED)
context.registerReceiver(receiver, filter)
return receiver

View file

@ -35,7 +35,7 @@ class HiddenAppsAdapter(
inner class AppViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val listItem: FrameLayout = itemView.findViewById(R.id.list_item)
val textView: TextView = listItem.findViewById(R.id.app_name)
val actionMenuLayout: LinearLayout = listItem.findViewById(R.id.action_menu)
private val actionMenuLayout: LinearLayout = listItem.findViewById(R.id.action_menu)
private val editView: LinearLayout = listItem.findViewById(R.id.rename_view)
val editText: EditText = editView.findViewById(R.id.app_name_edit)
@ -103,14 +103,6 @@ class HiddenAppsAdapter(
val appInfo = app.first.activityInfo.applicationInfo
holder.textView.text = sharedPreferenceManager.getAppName(activity, app.first.applicationInfo.packageName,app.second.second, holder.itemView.context.packageManager.getApplicationLabel(appInfo))
holder.editText.setText(holder.textView.text)
if (appInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) {
holder.actionMenuLayout.findViewById<TextView>(R.id.uninstall).visibility = View.GONE
}
else {
holder.actionMenuLayout.findViewById<TextView>(R.id.uninstall).visibility = View.VISIBLE
}
holder.textView.visibility = View.VISIBLE
}

View file

@ -31,6 +31,7 @@ class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener {
private val appUtils = AppUtils()
private val sharedPreferenceManager = SharedPreferenceManager()
private var adapter: HiddenAppsAdapter? = null
private var stringUtils = StringUtils()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -89,7 +90,7 @@ class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener {
private fun filterItems(query: String?) {
val cleanQuery = query?.clean()
val cleanQuery = stringUtils.cleanString(query)
val newFilteredApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
val updatedApps = appUtils.getHiddenApps(requireActivity())
@ -104,9 +105,11 @@ class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener {
newFilteredApps.addAll(updatedApps)
} else {
updatedApps.forEach {
val cleanItemText = sharedPreferenceManager.getAppName(requireActivity(), it.first.applicationInfo.packageName, it.second.second, requireActivity().packageManager.getApplicationLabel(it.first.applicationInfo)).toString().clean()
if (cleanItemText.contains(cleanQuery, ignoreCase = true)) {
newFilteredApps.add(it)
val cleanItemText = stringUtils.cleanString(sharedPreferenceManager.getAppName(requireActivity(), it.first.applicationInfo.packageName, it.second.second, requireActivity().packageManager.getApplicationLabel(it.first.applicationInfo)).toString())
if (cleanItemText != null) {
if (cleanItemText.contains(cleanQuery, ignoreCase = true)) {
newFilteredApps.add(it)
}
}
}
}
@ -116,10 +119,6 @@ class HiddenAppsFragment : Fragment(), HiddenAppsAdapter.OnItemClickListener {
adapter?.updateApps(newFilteredApps)
}
private fun String.clean(): String {
return this.replace("[^a-zA-Z0-9]".toRegex(), "")
}
private fun showConfirmationDialog(appInfo: LauncherActivityInfo, appName: String, profile: Int) {
AlertDialog.Builder(requireContext()).apply {
setTitle("Confirmation")

View file

@ -0,0 +1,109 @@
package eu.ottop.yamlauncher
import android.app.AlertDialog
import android.os.Bundle
import android.text.Editable
import android.text.TextWatcher
import androidx.fragment.app.Fragment
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.EditText
import androidx.fragment.app.setFragmentResult
import androidx.preference.Preference
import androidx.recyclerview.widget.RecyclerView
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
class LocationFragment : Fragment(), LocationListAdapter.OnItemClickListener {
private var adapter: LocationListAdapter? = null
private val weatherSystem = WeatherSystem()
private val sharedPreferenceManager = SharedPreferenceManager()
override fun onCreateView(
inflater: LayoutInflater, container: ViewGroup?,
savedInstanceState: Bundle?
): View? {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_location, container, false)
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
val searchView = view.findViewById<EditText>(R.id.locationSearch)
adapter = LocationListAdapter(requireContext(), weatherSystem.getSearchedLocations(
searchView.text.toString()
), this)
val recyclerView = view.findViewById<RecyclerView>(R.id.locationrecycler)
val appMenuEdgeFactory = AppMenuEdgeFactory(requireActivity())
recyclerView.edgeEffectFactory = appMenuEdgeFactory
recyclerView.adapter = adapter
recyclerView.scrollToPosition(0)
recyclerView.addOnLayoutChangeListener { _, _, top, _, bottom, _, oldTop, _, oldBottom ->
if (bottom - top > oldBottom - oldTop) {
searchView.clearFocus()
}
}
searchView.addTextChangedListener(object :
TextWatcher {
override fun beforeTextChanged(s: CharSequence?, start: Int, count: Int, after: Int) {
}
override fun onTextChanged(s: CharSequence?, start: Int, before: Int, count: Int) {
println(searchView.text.toString())
CoroutineScope(Dispatchers.IO).launch {
val locations = weatherSystem.getSearchedLocations(
searchView.text.toString()
)
withContext(Dispatchers.Main) {
adapter?.updateApps(locations)
}
}
}
override fun afterTextChanged(s: Editable?) {
}
})
}
private fun showConfirmationDialog(appName: String?, latitude: String?, longitude: String?) {
AlertDialog.Builder(requireContext()).apply {
setTitle("Confirmation")
setMessage("Are you sure you want to select $appName?")
setPositiveButton("Yes") { _, _ ->
// Perform action on confirmation
performConfirmedAction(appName, latitude, longitude)
}
setNegativeButton("Cancel") { _, _ ->
}
}.create().show()
}
private fun performConfirmedAction(appName: String?, latitude: String?, longitude: String?) {
sharedPreferenceManager.setWeatherLocation(requireContext(), "latitude=${latitude}&longitude=${longitude}", appName)
requireActivity().supportFragmentManager.popBackStack()
}
override fun onItemClick(name: String?, latitude: String?, longitude: String?) {
showConfirmationDialog(name, latitude, longitude)
}
}

View file

@ -2,9 +2,7 @@ package eu.ottop.yamlauncher
import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ApplicationInfo
import android.content.pm.LauncherActivityInfo
import android.os.UserHandle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
@ -13,84 +11,37 @@ import android.widget.EditText
import android.widget.FrameLayout
import android.widget.LinearLayout
import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.res.ResourcesCompat
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.RecyclerView
class LocationListAdapter(
private val activity: Context,
var apps: MutableList<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>,
private val itemClickListener: OnItemClickListener,
private val shortcutListener: OnShortcutListener,
private val itemLongClickListener: OnItemLongClickListener
activity: Context,
var apps: MutableList<Map<String, String>>,
private val itemClickListener: OnItemClickListener
) :
RecyclerView.Adapter<LocationListAdapter.AppViewHolder>() {
var menuMode: String = "app"
var shortcutTextView: TextView? = null
private val sharedPreferenceManager = SharedPreferenceManager()
private var preferences = PreferenceManager.getDefaultSharedPreferences(activity)
private var preferences = PreferenceManager.getDefaultSharedPreferences(activity)
interface OnItemClickListener {
fun onItemClick(appInfo: LauncherActivityInfo, userHandle: UserHandle)
}
interface OnShortcutListener {
fun onShortcut(appInfo: LauncherActivityInfo, userHandle: UserHandle, textView: TextView, userProfile: Int, shortcutView: TextView)
}
interface OnItemLongClickListener {
fun onItemLongClick(
appInfo: LauncherActivityInfo,
userHandle: UserHandle,
userProfile: Int,
textView: TextView,
actionMenuLayout: LinearLayout,
editView: LinearLayout,
position: Int
)
fun onItemClick(name: String?, latitude: String?, longitude: String?)
}
inner class AppViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
private val listItem: FrameLayout = itemView.findViewById(R.id.list_item)
val textView: TextView = listItem.findViewById(R.id.app_name)
val actionMenuLayout: LinearLayout = listItem.findViewById(R.id.action_menu)
private val editView: LinearLayout = listItem.findViewById(R.id.rename_view)
val editText: EditText = editView.findViewById(R.id.app_name_edit)
private val listItem: ConstraintLayout = itemView.findViewById(R.id.location_place)
val textView: TextView = listItem.findViewById(R.id.location_name)
val regionText: TextView = listItem.findViewById(R.id.region_name)
init {
actionMenuLayout.visibility = View.INVISIBLE
editView.visibility = View.INVISIBLE
textView.setOnClickListener {
val position = bindingAdapterPosition
val app = apps[position].first
if (menuMode == "shortcut") {
shortcutListener.onShortcut(app, apps[position].second.first, textView, apps[position].second.second, shortcutTextView!!)
}
else if (menuMode == "app") {
itemClickListener.onItemClick(app, apps[position].second.first)
}
}
if (menuMode == "app") {
textView.setOnLongClickListener {
val position = bindingAdapterPosition
val app = apps[position].first
itemLongClickListener.onItemLongClick(
app,
apps[position].second.first,
apps[position].second.second,
textView,
actionMenuLayout,
editView,
position
)
return@setOnLongClickListener true
}
listItem.setOnClickListener {
val position = bindingAdapterPosition
val name = apps[position]["name"]
val latitude = apps[position]["latitude"]
val longitude = apps[position]["longitude"]
itemClickListener.onItemClick(name, latitude, longitude)
}
}
@ -98,63 +49,49 @@ class LocationListAdapter(
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): AppViewHolder {
val view = LayoutInflater.from(parent.context)
.inflate(R.layout.app_item_layout, parent, false)
.inflate(R.layout.location_item_layout, parent, false)
return AppViewHolder(view)
}
override fun onBindViewHolder(holder: AppViewHolder, position: Int) {
val app = apps[position]
if (app.second.second != 0) {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_work_app, null),null,null,null)
}
else {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(ResourcesCompat.getDrawable(activity.resources, R.drawable.ic_empty, null),null,null,null)
}
when (preferences.getString("appMenuAlignment", "left")) {
"left" -> {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(holder.textView.compoundDrawables.filterNotNull().first(),null, null, null)
holder.textView.gravity = Gravity.CENTER_VERTICAL or Gravity.START
holder.regionText.gravity = Gravity.CENTER_VERTICAL or Gravity.START
}
"center" -> {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(holder.textView.compoundDrawables.filterNotNull().first(),null,holder.textView.compoundDrawables.filterNotNull().first(), null)
holder.textView.gravity = Gravity.CENTER
holder.regionText.gravity = Gravity.CENTER
}
"right" -> {
holder.textView.setCompoundDrawablesWithIntrinsicBounds(null,null, holder.textView.compoundDrawables.filterNotNull().first(), null)
holder.textView.gravity = Gravity.CENTER_VERTICAL or Gravity.END
holder.regionText.gravity = Gravity.CENTER_VERTICAL or Gravity.END
}
}
when (preferences.getString("appMenuSize", "medium")) {
"small" -> {
holder.textView.textSize = 24F
holder.editText.textSize = 24F
holder.regionText.textSize = 14F
}
"medium" -> {
holder.textView.textSize = 26F
holder.editText.textSize = 26F
holder.regionText.textSize = 16F
}
"large" -> {
holder.textView.textSize = 28F
holder.editText.textSize = 28F
holder.regionText.textSize = 18F
}
}
val appInfo = app.first.activityInfo.applicationInfo
holder.textView.text = sharedPreferenceManager.getAppName(activity, app.first.applicationInfo.packageName,app.second.second, holder.itemView.context.packageManager.getApplicationLabel(appInfo))
holder.editText.setText(holder.textView.text)
if (appInfo.flags and ApplicationInfo.FLAG_SYSTEM != 0) {
holder.actionMenuLayout.findViewById<TextView>(R.id.uninstall).visibility = View.GONE
}
else {
holder.actionMenuLayout.findViewById<TextView>(R.id.uninstall).visibility = View.VISIBLE
}
holder.textView.text = app["name"]
holder.regionText.text = "${app["region"]}${app["country"]}"
holder.textView.visibility = View.VISIBLE
}
@ -164,8 +101,9 @@ class LocationListAdapter(
}
@SuppressLint("NotifyDataSetChanged")
fun updateApps(newApps: List<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>) {
apps = newApps.toMutableList()
fun updateApps(newApps: MutableList<Map<String, String>>) {
apps.clear()
apps = newApps
notifyDataSetChanged()
}
}

View file

@ -57,6 +57,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
private lateinit var searchView: EditText
private var adapter: AppMenuAdapter? = null
private var job: Job? = null
private var weatherJob: Job? = null
val cameraIntent = Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA_SECURE)
val phoneIntent = Intent(Intent.ACTION_DIAL)
private lateinit var batteryReceiver: BatteryReceiver
@ -79,6 +80,12 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
private lateinit var preferences: SharedPreferences
private val stringUtils = StringUtils()
private var dateElements = mutableListOf<String>()
private val weatherSystem = WeatherSystem()
@SuppressLint("ClickableViewAccessibility")
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -105,6 +112,8 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
dateText = findViewById(R.id.text_date)
dateElements = mutableListOf(dateText.format12Hour.toString(), dateText.format24Hour.toString(), "", "")
setClockAlignment(preferences.getString("clockAlignment", "left"), clock.id, clockMargin)
setupApps()
@ -121,7 +130,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
setSearchSize(preferences.getString("searchSize", "medium"))
batteryReceiver = BatteryReceiver.register(this, dateText)
batteryReceiver = BatteryReceiver.register(this, this@MainActivity)
binding.homeView.setOnTouchListener { _, event ->
gestureDetector.onTouchEvent(event)
@ -137,6 +146,25 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
}
fun modifyDate(value: String, index: Int) {
dateElements[index] = value
dateText.format12Hour = "${dateElements[0]}${stringUtils.addStartTextIfNotEmpty(dateElements[2], " | ")}${stringUtils.addStartTextIfNotEmpty(dateElements[3], " | ")}"
dateText.format24Hour = "${dateElements[1]}${stringUtils.addStartTextIfNotEmpty(dateElements[2], " | ")}${stringUtils.addStartTextIfNotEmpty(dateElements[3], " | ")}"
}
private fun startWeatherMonitor() {
weatherJob?.cancel()
weatherJob = CoroutineScope(Dispatchers.IO).launch {
while (true) {
val currentWeather = weatherSystem.getTemp(this@MainActivity)
withContext(Dispatchers.Main) {
modifyDate(stringUtils.addEndTextIfNotEmpty(currentWeather, "°C"), 3)
}
delay(300000)
}
}
}
override fun onSharedPreferenceChanged(preferences: SharedPreferences?, key: String?) {
when (key) {
@ -190,6 +218,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
override fun onStart() {
super.onStart()
startTask()
startWeatherMonitor()
// Keyboard is sometimes open when going back to the app, so close it.
closeKeyboard()
@ -392,7 +421,7 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
private suspend fun filterItems(query: String?) {
val cleanQuery = query?.clean()
val cleanQuery = stringUtils.cleanString(query)
val newFilteredApps = mutableListOf<Pair<LauncherActivityInfo, Pair<UserHandle, Int>>>()
val updatedApps = appUtils.getInstalledApps(this@MainActivity)
@ -408,9 +437,11 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
newFilteredApps.addAll(installedApps)
} else {
updatedApps.forEach {
val cleanItemText = sharedPreferenceManager.getAppName(this@MainActivity, it.first.applicationInfo.packageName, it.second.second, packageManager.getApplicationLabel(it.first.applicationInfo)).toString().clean()
if (cleanItemText.contains(cleanQuery, ignoreCase = true)) {
newFilteredApps.add(it)
val cleanItemText = stringUtils.cleanString(sharedPreferenceManager.getAppName(this@MainActivity, it.first.applicationInfo.packageName, it.second.second, packageManager.getApplicationLabel(it.first.applicationInfo)).toString())
if (cleanItemText != null) {
if (cleanItemText.contains(cleanQuery, ignoreCase = true)) {
newFilteredApps.add(it)
}
}
}
}
@ -425,10 +456,6 @@ class MainActivity : AppCompatActivity(), SharedPreferences.OnSharedPreferenceCh
}
}
private fun String.clean(): String {
return this.replace("[^a-zA-Z0-9]".toRegex(), "")
}
private fun startTask() {
job?.cancel()
job = CoroutineScope(Dispatchers.Default).launch {

View file

@ -1,38 +1,64 @@
package eu.ottop.yamlauncher
import android.os.Bundle
import androidx.fragment.app.setFragmentResultListener
import androidx.preference.Preference
import androidx.preference.PreferenceFragmentCompat
import androidx.preference.SwitchPreference
class SettingsFragment : PreferenceFragmentCompat() {
private var manualLocationPref: Preference? = null
private val sharedPreferenceManager = SharedPreferenceManager()
override fun onCreatePreferences(savedInstanceState: Bundle?, rootKey: String?) {
setPreferencesFromResource(R.xml.root_preferences, rootKey)
val weatherSystem = WeatherSystem()
val gpsLocationPref: SwitchPreference? = findPreference("gps_location")
val manualLocationPref: Preference? = findPreference("manual_location")
manualLocationPref = findPreference("manual_location")
manualLocationPref?.summary = sharedPreferenceManager.getWeatherRegion(requireContext())
if (gpsLocationPref != null && manualLocationPref != null) {
// Initial setup
manualLocationPref.isEnabled = !gpsLocationPref.isChecked
manualLocationPref?.isEnabled = !gpsLocationPref.isChecked
// Set up a listener to update the enabled state of manualLocationPref
gpsLocationPref.onPreferenceChangeListener =
Preference.OnPreferenceChangeListener { _, newValue ->
val isGpsEnabled = newValue as Boolean
manualLocationPref.isEnabled = !isGpsEnabled
if (isGpsEnabled) {
weatherSystem.setGpsLocation(requireActivity())
}
manualLocationPref?.isEnabled = !isGpsEnabled
true // Returning true means the change is persisted
}
manualLocationPref?.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
requireActivity().supportFragmentManager
.beginTransaction()
.replace(R.id.settings_layout, LocationFragment())
.addToBackStack(null)
.commit()
true
}
}
findPreference<Preference?>("hidden_apps")?.onPreferenceClickListener =
Preference.OnPreferenceClickListener {
activity?.supportFragmentManager
?.beginTransaction()
?.replace(R.id.settings_layout, HiddenAppsFragment())
?.addToBackStack(null)
?.commit()
requireActivity().supportFragmentManager
.beginTransaction()
.replace(R.id.settings_layout, HiddenAppsFragment())
.addToBackStack(null)
.commit()
true }
}
override fun onResume() {
super.onResume()
manualLocationPref?.summary = sharedPreferenceManager.getWeatherRegion(requireContext())
}
}

View file

@ -60,17 +60,25 @@ class SharedPreferenceManager {
editor.apply()
}
fun setWeatherLocation(cont: Context, location: String) {
fun setWeatherLocation(cont: Context, location: String, region: String?) {
val editor = cont.getSharedPreferences("weather_location", AppCompatActivity.MODE_PRIVATE).edit()
val key = "location"
val regionKey = "location_region"
editor.putString(key, location)
editor.putString(regionKey, region)
editor.apply()
}
fun getWeatherLocation(cont: Context) : String? {
val sharedPreferences = cont.getSharedPreferences("weather_location", AppCompatActivity.MODE_PRIVATE)
val key = "location"
return sharedPreferences.getString(key, null)
return sharedPreferences.getString(key, "")
}
fun getWeatherRegion(cont: Context) : String? {
val sharedPreferences = cont.getSharedPreferences("weather_location", AppCompatActivity.MODE_PRIVATE)
val key = "location_region"
return sharedPreferences.getString(key, "")
}
fun setClockAlignment(cont: Context, alignment: Int) {

View file

@ -0,0 +1,17 @@
package eu.ottop.yamlauncher
class StringUtils {
fun addEndTextIfNotEmpty(value: String, addition: String): String {
return if (value.isNotEmpty()) "$value$addition" else value
}
fun addStartTextIfNotEmpty(value: String, addition: String): String {
return if (value.isNotEmpty()) "$addition$value" else value
}
fun cleanString(string: String?) : String? {
return string?.replace("[^a-zA-Z0-9]".toRegex(), "")
}
}

View file

@ -10,9 +10,7 @@ import android.location.LocationManager
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.json.JSONObject
import java.net.HttpURLConnection
@ -21,8 +19,9 @@ import java.net.URL
class WeatherSystem {
private val sharedPreferenceManager = SharedPreferenceManager()
private val stringUtils = StringUtils()
fun getWeatherForCurrentLocation(activity: Activity) {
fun setGpsLocation(activity: Activity) {
val locationManager = activity.getSystemService(Context.LOCATION_SERVICE) as LocationManager
val locationListener = object : LocationListener {
@ -49,18 +48,50 @@ class WeatherSystem {
if (currentLocation != null) {
sharedPreferenceManager.setWeatherLocation(activity, "latitude=${currentLocation.latitude}&longitude=${currentLocation.longitude}")
sharedPreferenceManager.setWeatherLocation(activity, "latitude=${currentLocation.latitude}&longitude=${currentLocation.longitude}", sharedPreferenceManager.getWeatherRegion(activity))
}
else {
Toast.makeText(activity, "Unable to get location", Toast.LENGTH_SHORT).show()
}
}
fun getTemp(context: Context) {
CoroutineScope(Dispatchers.IO).launch {
// Run within Dispatchers.IO from the outside (doesn't refresh properly otherwise)
fun getSearchedLocations(searchTerm: String?) : MutableList<Map<String, String>> {
val foundLocations = mutableListOf<Map<String, String>>()
val url = URL("https://geocoding-api.open-meteo.com/v1/search?name=$searchTerm&count=50&language=en&format=json")
with(url.openConnection() as HttpURLConnection) {
requestMethod = "GET"
try {
inputStream.bufferedReader().use {
val response = it.readText()
println("yo")
val jsonObject = JSONObject(response)
val resultArray = jsonObject.getJSONArray("results")
for (i in 0 until resultArray.length()) {
val resultObject: JSONObject = resultArray.getJSONObject(i)
foundLocations.add(mapOf(
"name" to resultObject.getString("name"),
"latitude" to resultObject.getDouble("latitude").toString(),
"longitude" to resultObject.getDouble("longitude").toString(),
"country" to resultObject.optString("country", resultObject.optString("country_code","")),
"region" to stringUtils.addEndTextIfNotEmpty(resultObject.optString("admin2", resultObject.optString("admin1",resultObject.optString("admin3",""))), ", ")
))
}
}
}catch (e: Exception){
e.printStackTrace()
}
}
return foundLocations
}
suspend fun getTemp(context: Context) : String {
val location = sharedPreferenceManager.getWeatherLocation(context)
if (location != null) {
val url = URL("https://api.open-meteo.com/v1/forecast?$location&current=temperature_2m")
@ -73,9 +104,9 @@ class WeatherSystem {
val jsonObject = JSONObject(response)
val currentData = jsonObject.getJSONObject("current")
val currentWeather = currentData.getInt("temperature_2m")
println("Field1: $currentWeather")
return currentData.getInt("temperature_2m").toString()
}
}
}
@ -84,7 +115,8 @@ class WeatherSystem {
Toast.makeText(context, "No weather location set", Toast.LENGTH_SHORT).show()
}
}
}
return ""
}
}

View file

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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/manual_location_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="bottom"
android:orientation="vertical"
android:visibility="visible">
<Space
android:layout_width="match_parent"
android:layout_height="60dp" />
<TextView
android:id="@+id/location_menutitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clickable="false"
android:gravity="start"
android:paddingLeft="40dp"
android:paddingTop="20dp"
android:paddingRight="40dp"
android:paddingBottom="20dp"
android:text="Find your city"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#C1F3F3F3"
android:textSize="36sp" />
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/locationrecycler"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:clipToPadding="false"
android:fadingEdgeLength="20dp"
android:padding="0dp"
android:requiresFadingEdge="vertical"
android:scrollbars="none"
app:layoutManager="LinearLayoutManager">
</androidx.recyclerview.widget.RecyclerView>
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/locationSearch"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:layout_marginHorizontal="32dp"
android:layout_marginTop="5dp"
android:layout_marginBottom="10dp"
android:layout_weight="0.1"
android:background="@android:color/transparent"
android:cursorVisible="true"
android:drawableStart="@android:drawable/ic_menu_search"
android:drawablePadding="8dp"
android:editTextColor="#f3f3f3"
android:hint="@string/search"
android:singleLine="true"
android:textAlignment="viewStart"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textSize="25sp"
tools:ignore="RtlCompat" />
</LinearLayout>

View file

@ -0,0 +1,47 @@
<?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/location_place"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/location_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:clickable="false"
android:drawablePadding="3dp"
android:gravity="start"
android:paddingLeft="35dp"
android:paddingTop="20dp"
android:paddingRight="35dp"
android:paddingBottom="00dp"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#F3F3F3"
android:textSize="28sp"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/region_name"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:clickable="false"
android:drawablePadding="3dp"
android:gravity="start"
android:paddingLeft="35dp"
android:paddingTop="0dp"
android:paddingRight="35dp"
android:paddingBottom="20dp"
android:textAppearance="@android:style/TextAppearance.DeviceDefault"
android:textColor="#C3C3C3"
android:textSize="14sp"
android:visibility="visible"
app:layout_constraintEnd_toEndOf="@+id/location_name"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/location_name" />
</androidx.constraintlayout.widget.ConstraintLayout>