Advertisement
tuomasvaltanen

Untitled

Feb 9th, 2023 (edited)
135
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 10.15 KB | None | 0 0
  1. // Edistynyt mobiiliohjelmointi, 9.2.2023
  2.  
  3. OpenWeatherMapin URL-pohja kyselyille:
  4.  
  5. // aseta oikeisiin kohtiin latitude, longitude ja oma API key OpenWeatherMapista
  6. https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}
  7.  
  8. Oletuksena OpenWeatherMap antaa lämpötilat Kelvineinä, muutetaan yksiköt lisäämällä units=metric perään:
  9.  
  10. https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}&units=metric
  11.  
  12. // data voisi olla esim tällaista:
  13.  
  14. {"coord":{"lon":25.7269,"lat":66.5032},"weather":[{"id":804,"main":"Clouds","description":"overcast clouds","icon":"04d"}],"base":"stations","main":{"temp":0.67,"feels_like":-5.35,"temp_min":0.67,"temp_max":0.67,"pressure":991,"humidity":93},"visibility":10000,"wind":{"speed":7.72,"deg":230},"clouds":{"all":100},"dt":1675944876,"sys":{"type":1,"id":1354,"country":"FI","sunrise":1675925418,"sunset":1675951944},"timezone":7200,"id":638936,"name":"Rovaniemi","cod":200}
  15.  
  16.  
  17. // tehdään navigationeditorilla CityWeatherFragment, joka ottaa argumenteiksi lat ja long, molemmat tyyppiä Float, ja oletusarvo 0.0
  18. // tehdään myös siirtymä MapsFragmentista -> CityWeatherFragment
  19.  
  20. // kun markeria klikataan, ajetaan tämä funktio:
  21. override fun onMarkerClick(p0: Marker): Boolean {
  22. Log.d("ADVTECH", "MARKKERI")
  23.  
  24. // markerin koordinaatit
  25. var coordinates : LatLng = p0.position
  26. Log.d("ADVTECH", coordinates.latitude.toString() + " - " + coordinates.longitude.toString())
  27.  
  28. // markerin mukana tullut lisätieto (tässä tapauksessa kaupungin nimi)
  29. var city = p0.tag.toString()
  30. Log.d("ADVTECH", city)
  31.  
  32. // siirrytään CityWeatherFragmentiin parametrien kanssa
  33. val action = MapsFragmentDirections.actionMapsFragmentToCityWeatherFragment(coordinates.latitude.toFloat(), coordinates.longitude.toFloat())
  34. findNavController().navigate(action)
  35.  
  36. return false
  37. }
  38.  
  39.  
  40. // CityWeatherFragmentin pohja:
  41.  
  42. class CityWeatherFragment : Fragment() {
  43. // change this to match your fragment name
  44. private var _binding: FragmentCityWeatherBinding? = null
  45.  
  46. // This property is only valid between onCreateView and
  47. // onDestroyView.
  48. private val binding get() = _binding!!
  49.  
  50. val args: CityWeatherFragmentArgs by navArgs()
  51.  
  52. override fun onCreateView(
  53. inflater: LayoutInflater,
  54. container: ViewGroup?,
  55. savedInstanceState: Bundle?
  56. ): View? {
  57. _binding = FragmentCityWeatherBinding.inflate(inflater, container, false)
  58. val root: View = binding.root
  59.  
  60. // the binding -object allows you to access views in the layout, textviews etc.
  61.  
  62. return root
  63. }
  64.  
  65. override fun onDestroyView() {
  66. super.onDestroyView()
  67. _binding = null
  68. }
  69. }
  70.  
  71. // rakennetaan tarvittava URL Volley:tä varten koodissa, esim:
  72.  
  73. override fun onCreateView(
  74. inflater: LayoutInflater,
  75. container: ViewGroup?,
  76. savedInstanceState: Bundle?
  77. ): View? {
  78. _binding = FragmentCityWeatherBinding.inflate(inflater, container, false)
  79. val root: View = binding.root
  80.  
  81. // the binding -object allows you to access views in the layout, textviews etc.
  82.  
  83. // haetaan API key local.properties -tiedostosta
  84. // tällä tavalla koodissa ei ole oikeita API-key -avaimia näkösällä
  85. val API_KEY : String = BuildConfig.OPENWEATHER_API_KEY
  86.  
  87. val JSON_URL = "https://api.openweathermap.org/data/2.5/weather?lat=${args.lat}&lon=${args.long}&appid=${API_KEY}&units=metric"
  88.  
  89. Log.d("ADVTECH", JSON_URL)
  90. Log.d("ADVTECH", args.lat.toString())
  91. Log.d("ADVTECH", args.long.toString())
  92.  
  93. return root
  94. }
  95.  
  96. // HUOM! Muista myös luoda tarvittavat data classit json2kt.com -palvelussa käyttämällä säätiedotuksen dataa!
  97. // vinkki: tee omille datatyypeille oma paketti Android-projektiin, esim datatypes, ja sinne jokaiselle datalle oma paketti.
  98.  
  99. // esim. datatypes.commen
  100. // - datatypes.todo
  101. // datatypes.cityweather
  102.  
  103. // jne. tällä tavalla projektin tiedostorakenne on selkeämpi
  104.  
  105. // Volley -rakenne, joka hyödyntää aiemmin tehtyä JSON_URL-muuttujaa sekä GSONia
  106. // sekä aiemmin tehtyä CityWeather-luokkaa (koostuu useasta tiedostosta)
  107.  
  108. override fun onCreateView(
  109. inflater: LayoutInflater,
  110. container: ViewGroup?,
  111. savedInstanceState: Bundle?
  112. ): View? {
  113. _binding = FragmentCityWeatherBinding.inflate(inflater, container, false)
  114. val root: View = binding.root
  115.  
  116. // the binding -object allows you to access views in the layout, textviews etc.
  117.  
  118. // haetaan API key local.properties -tiedostosta
  119. // tällä tavalla koodissa ei ole oikeita API-key -avaimia näkösällä
  120. val API_KEY : String = BuildConfig.OPENWEATHER_API_KEY
  121.  
  122. val JSON_URL = "https://api.openweathermap.org/data/2.5/weather?lat=${args.lat}&lon=${args.long}&appid=${API_KEY}&units=metric"
  123.  
  124. val gson = GsonBuilder().setPrettyPrinting().create()
  125.  
  126. // Request a string response from the provided URL.
  127. val stringRequest: StringRequest = object : StringRequest(
  128. Request.Method.GET, JSON_URL,
  129. Response.Listener { response ->
  130.  
  131. // print the response as a whole
  132. // we can use GSON to modify this response into something more usable
  133. Log.d("ADVTECH", response)
  134.  
  135. // muutetaan JSON -> CityWeatheriksi, koska vain yksi objekti JSONissa, käytetään tätä versiota
  136. var item : CityWeather = gson.fromJson(response, CityWeather::class.java)
  137.  
  138. Log.d("ADVTECH", item.main?.temp.toString() + " C")
  139.  
  140. // jos käyttöliittymässä olisi esim. TextView tällä id:llä, voimme asettaa
  141. // nyt helposti siihen dataa, esim. lämpötila
  142. // binding.textViewCurrentCityTemperature.text = item.main?.temp.toString() + " C"
  143.  
  144. },
  145. Response.ErrorListener {
  146. // typically this is a connection error
  147. Log.d("ADVTECH", it.toString())
  148. })
  149. {
  150. @Throws(AuthFailureError::class)
  151. override fun getHeaders(): Map<String, String> {
  152.  
  153. // basic headers for the data
  154. val headers = HashMap<String, String>()
  155. headers["Accept"] = "application/json"
  156. headers["Content-Type"] = "application/json; charset=utf-8"
  157. return headers
  158. }
  159. }
  160.  
  161. // Add the request to the RequestQueue. This has to be done in both getting and sending new data.
  162. // if using this in an activity, use "this" instead of "context"
  163. val requestQueue = Volley.newRequestQueue(context)
  164. requestQueue.add(stringRequest)
  165.  
  166. return root
  167. }
  168.  
  169. // ---------------------------------------
  170. // LISÄTEHTÄVÄ: OPENSTREETMAP ANDROIDISSA
  171. // ---------------------------------------
  172.  
  173. // ks. osoite: https://github.com/osmdroid/osmdroid
  174.  
  175. // module.gradleen import:
  176. implementation 'org.osmdroid:osmdroid-android:6.1.14'
  177.  
  178. // AndroidManifestiin permissionit:
  179.  
  180. <uses-permission android:name="android.permission.INTERNET" />
  181. <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
  182. <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
  183. <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
  184.  
  185. // open street map fragmentin ulkoasu:
  186. <?xml version="1.0" encoding="utf-8"?>
  187. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  188. android:orientation="vertical"
  189. android:layout_width="fill_parent"
  190. android:layout_height="fill_parent">
  191. <org.osmdroid.views.MapView android:id="@+id/map"
  192. android:layout_width="fill_parent"
  193. android:layout_height="fill_parent" />
  194. </LinearLayout>
  195.  
  196. // open street map fragment
  197.  
  198. import org.osmdroid.views.MapView
  199. import androidx.preference.PreferenceManager
  200. import org.osmdroid.config.Configuration.*
  201. import org.osmdroid.tileprovider.tilesource.TileSourceFactory
  202. import org.osmdroid.util.GeoPoint
  203. import org.osmdroid.views.overlay.Marker
  204.  
  205. /**
  206. * A simple [Fragment] subclass.
  207. * Use the [OpenStreetMapFragment.newInstance] factory method to
  208. * create an instance of this fragment.
  209. */
  210. class OpenStreetMapFragment : Fragment() {
  211. // change this to match your fragment name
  212. private var _binding: FragmentOpenStreetMapBinding? = null
  213.  
  214. // This property is only valid between onCreateView and
  215. // onDestroyView.
  216. private val binding get() = _binding!!
  217.  
  218. // viittaus ulkoasussa olevaan open street mapin MapViewiin
  219. private lateinit var map : MapView
  220.  
  221. override fun onCreateView(
  222. inflater: LayoutInflater,
  223. container: ViewGroup?,
  224. savedInstanceState: Bundle?
  225. ): View? {
  226. _binding = FragmentOpenStreetMapBinding.inflate(inflater, container, false)
  227. val root: View = binding.root
  228.  
  229. // HUOM! tämä vaatii module.gradleen importin:
  230. // implementation 'androidx.preference:preference:1.2.0'
  231. // ylhäällä pitää olla myös import näin (huomaa: androidx):
  232. // import androidx.preference.PreferenceManager
  233.  
  234. getInstance().load(context, PreferenceManager.getDefaultSharedPreferences(activity as Context))
  235. // the binding -object allows you to access views in the layout, textviews etc.
  236.  
  237. binding.map.setTileSource(TileSourceFactory.MAPNIK)
  238.  
  239. // zoomaaminen tiettyyn pisteeseen kartalla
  240. val mapController = binding.map.controller
  241. mapController.setZoom(18.0)
  242. val startPoint = GeoPoint(66.50319436087507, 25.726910828015637)
  243. mapController.setCenter(startPoint)
  244.  
  245. // markerin lisääminen
  246. var marker : Marker = Marker(binding.map)
  247. marker.position = startPoint
  248. marker.title = "Rovaniemi"
  249. marker.setAnchor(Marker.ANCHOR_CENTER, Marker.ANCHOR_CENTER)
  250. binding.map.overlays.add(marker)
  251. binding.map.invalidate()
  252.  
  253. return root
  254. }
  255.  
  256. override fun onDestroyView() {
  257. super.onDestroyView()
  258. _binding = null
  259. }
  260. }
  261.  
  262.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement