Some sort of location logic for weather and some error management.

This commit is contained in:
ottoptj 2024-07-03 04:21:01 +03:00
commit f518328e6b
3 changed files with 96 additions and 32 deletions

View file

@ -5,6 +5,7 @@
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" /> <uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES" />
<uses-permission android:name="android.permission.EXPAND_STATUS_BAR" /> <uses-permission android:name="android.permission.EXPAND_STATUS_BAR" />
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<queries> <queries>
<intent> <intent>

View file

@ -5,6 +5,7 @@ import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.pm.LauncherActivityInfo import android.content.pm.LauncherActivityInfo
import android.content.pm.LauncherApps import android.content.pm.LauncherApps
import android.content.pm.PackageManager
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import android.os.Handler import android.os.Handler
@ -24,6 +25,8 @@ import android.widget.Toast
import androidx.activity.OnBackPressedCallback import androidx.activity.OnBackPressedCallback
import androidx.annotation.RequiresApi import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import androidx.core.content.res.ResourcesCompat import androidx.core.content.res.ResourcesCompat
import androidx.recyclerview.widget.RecyclerView import androidx.recyclerview.widget.RecyclerView
import eu.ottop.yamlauncher.databinding.ActivityMainBinding import eu.ottop.yamlauncher.databinding.ActivityMainBinding
@ -150,7 +153,7 @@ class MainActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, Ap
val statusBarManager: Class<*> = Class.forName("android.app.StatusBarManager") val statusBarManager: Class<*> = Class.forName("android.app.StatusBarManager")
val expandMethod: Method = statusBarManager.getMethod("expandNotificationsPanel") val expandMethod: Method = statusBarManager.getMethod("expandNotificationsPanel")
expandMethod.invoke(statusBarService) expandMethod.invoke(statusBarService)
weatherSystem.getWeather() weatherSystem.getWeatherForCurrentLocation(this@MainActivity)
} }
// Detect swipe left // Detect swipe left
@ -377,11 +380,21 @@ class MainActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, Ap
animations.backgroundOut(this@MainActivity) animations.backgroundOut(this@MainActivity)
val handler = Handler(Looper.getMainLooper()) val handler = Handler(Looper.getMainLooper())
handler.postDelayed({ handler.postDelayed({
binding.menutitle.visibility = View.VISIBLE try {
searchView.setText("") binding.menutitle.visibility = View.VISIBLE
searchView.setText("")
}
catch (_: UninitializedPropertyAccessException) {
}
}, 100) }, 100)
handler.postDelayed({ handler.postDelayed({
recyclerView.scrollToPosition(0) try {
recyclerView.scrollToPosition(0)
}
catch (_: UninitializedPropertyAccessException) {
}
CoroutineScope(Dispatchers.Default).launch { CoroutineScope(Dispatchers.Default).launch {
refreshAppMenu() refreshAppMenu()
} }
@ -485,7 +498,20 @@ class MainActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, Ap
val oldSet = oldList.map { Pair(it.first.applicationInfo.packageName, it.second.second) }.toSet() val oldSet = oldList.map { Pair(it.first.applicationInfo.packageName, it.second.second) }.toSet()
val newSet = newList.map { Pair(it.first.applicationInfo.packageName, it.second.second) }.toSet() val newSet = newList.map { Pair(it.first.applicationInfo.packageName, it.second.second) }.toSet()
//Detect updates // Detect removals
oldList.forEachIndexed { index, oldItem ->
if (!newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) {
removalChanges.add(Change(ChangeType.REMOVE, index))
}
}
// Detect insertions
newList.forEachIndexed { index, newItem ->
if (!oldSet.contains(Pair(newItem.first.applicationInfo.packageName, newItem.second.second))) {
changes.add(Change(ChangeType.INSERT, index))
}
}
oldList.forEachIndexed { index, oldItem -> oldList.forEachIndexed { index, oldItem ->
if (newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) { if (newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) {
val newIndex = newList.indexOfFirst { it.first.applicationInfo.packageName == oldItem.first.applicationInfo.packageName && it.second.second == oldItem.second.second } val newIndex = newList.indexOfFirst { it.first.applicationInfo.packageName == oldItem.first.applicationInfo.packageName && it.second.second == oldItem.second.second }
@ -502,20 +528,6 @@ class MainActivity : AppCompatActivity(), AppMenuAdapter.OnItemClickListener, Ap
} }
} }
// Detect removals
oldList.forEachIndexed { index, oldItem ->
if (!newSet.contains(Pair(oldItem.first.applicationInfo.packageName, oldItem.second.second))) {
removalChanges.add(Change(ChangeType.REMOVE, index))
}
}
// Detect insertions
newList.forEachIndexed { index, newItem ->
if (!oldSet.contains(Pair(newItem.first.applicationInfo.packageName, newItem.second.second))) {
changes.add(Change(ChangeType.INSERT, index))
}
}
changes.addAll(removalChanges.reversed()) changes.addAll(removalChanges.reversed())
return changes return changes

View file

@ -1,31 +1,82 @@
package eu.ottop.yamlauncher package eu.ottop.yamlauncher
import android.Manifest
import android.app.Activity
import android.content.Context
import android.content.pm.PackageManager
import android.location.Criteria
import android.location.Location
import android.location.LocationListener
import android.location.LocationManager
import android.os.Bundle
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import org.json.JSONObject import org.json.JSONObject
import java.net.HttpURLConnection import java.net.HttpURLConnection
import java.net.URL import java.net.URL
import java.util.function.Consumer
class WeatherSystem { class WeatherSystem {
fun getWeather() { fun getWeather() {
CoroutineScope(Dispatchers.IO).launch { getTempForLocation("latitude=60.16&longitude=24.93")
val url = URL("https://api.open-meteo.com/v1/forecast?latitude=60.16&longitude=24.93&current=temperature_2m") }
with(url.openConnection() as HttpURLConnection) {
requestMethod = "GET"
inputStream.bufferedReader().use { fun getWeatherForCurrentLocation(activity: Activity) {
val response = it.readText() val locationManager = activity.getSystemService(Context.LOCATION_SERVICE) as LocationManager
// Parse the JSON response val locationListener = object : LocationListener {
val jsonObject = JSONObject(response) override fun onLocationChanged(location: Location) {
println(location)
// Access specific fields or nested objects locationManager.removeUpdates(this)
val currentData = jsonObject.getJSONObject("current")
val currentWeather = currentData.getInt("temperature_2m")
println("Field1: $currentWeather")
} }
}}
override fun onStatusChanged(provider: String?, status: Int, extras: Bundle?) {}
override fun onProviderEnabled(provider: String) {}
override fun onProviderDisabled(provider: String) {}
}
// Check for location permissions
if (ContextCompat.checkSelfPermission(activity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// Permissions are not granted
return
}
// Request location updates from both providers
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0f, locationListener)
// Try to get the last known location from both providers as a fallback
val currentLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER)
if (currentLocation != null) {
getTempForLocation("latitude=${currentLocation.latitude}&longitude=${currentLocation.longitude}")
}
}
private fun getTempForLocation(location: String) {
CoroutineScope(Dispatchers.IO).launch {
val url = URL("https://api.open-meteo.com/v1/forecast?$location&current=temperature_2m")
with(url.openConnection() as HttpURLConnection) {
requestMethod = "GET"
inputStream.bufferedReader().use {
val response = it.readText()
val jsonObject = JSONObject(response)
val currentData = jsonObject.getJSONObject("current")
val currentWeather = currentData.getInt("temperature_2m")
println("Field1: $currentWeather")
}
}}
} }
} }