Mình đang làm một app dự báo thời tiết và đag xây dựng 1 cái widget cho nó mà mò bữa giờ chưa biết làm như nào để show dữ liệu lên cho nó.
Ở MainActivity thì mình dùng Room để lưu dữ liệu mình get từ api về.
private fun saveNewCityCollection(informationWeather: InformationWeather, state: Boolean = Constants.OTHER_LOCATION) {
val weatherRepository = WeatherRepository(applicationContext)
val cityCollection = CityCollection()
cityCollection.cityName = informationWeather.location.name
cityCollection.countryName = informationWeather.location.country
cityCollection.temp = informationWeather.current.temp
cityCollection.appTemp = informationWeather.current.appTemp
cityCollection.humidity = informationWeather.current.humidity
cityCollection.wind = informationWeather.current.windSpeed
cityCollection.cloud = informationWeather.current.cloud
cityCollection.description = informationWeather.current.condition.description
cityCollection.icon = informationWeather.current.condition.icon
cityCollection.date = informationWeather.current.date
cityCollection.day = informationWeather.current.isDay
if (location == cityCollection.cityName) {
cityCollection.state = true
}
if (state) {
cityCollection.state = true
val editor = getSharedPreferences(getString(R.string.shared_preference_name), Context.MODE_PRIVATE).edit()
editor.putString(Constants.NAME_LOCATION, cityCollection.cityName)
editor.apply()
}
weatherRepository.insert(cityCollection, this)
}
Dây là model CityColection, mình dùng Parcelable có thể dăng dữ liệu lên dễ dàng.
class CityCollection() : Parcelable {
@PrimaryKey
@NonNull
@ColumnInfo(name = "cityname")
lateinit var cityName: String
lateinit var countryName: String
var state = Constants.OTHER_LOCATION
var temp: Float = 0F
var appTemp: Float = 0F
var humidity: Int = 0
var wind: Float = 0F
var cloud: Int = 0
var day: Int = 0
lateinit var description: String
var icon: String = "na"
var date: String = "dd/mm/yy"
constructor(parcel: Parcel) : this() {
cityName = parcel.readString()
countryName = parcel.readString()
state = parcel.readByte() != 0.toByte()
temp = parcel.readFloat()
appTemp = parcel.readFloat()
humidity = parcel.readInt()
wind = parcel.readFloat()
cloud = parcel.readInt()
day = parcel.readInt()
description = parcel.readString()
icon = parcel.readString()
date = parcel.readString()
}
override fun writeToParcel(parcel: Parcel, flags: Int) {
parcel.writeString(cityName)
parcel.writeString(countryName)
parcel.writeByte(if (state) 1 else 0)
parcel.writeFloat(temp)
parcel.writeFloat(appTemp)
parcel.writeInt(humidity)
parcel.writeFloat(wind)
parcel.writeInt(cloud)
parcel.writeInt(day)
parcel.writeString(description)
parcel.writeString(icon)
parcel.writeString(date)
}
override fun describeContents(): Int {
return 0
}
companion object CREATOR : Parcelable.Creator<CityCollection> {
override fun createFromParcel(parcel: Parcel): CityCollection {
return CityCollection(parcel)
}
override fun newArray(size: Int): Array<CityCollection?> {
return arrayOfNulls(size)
}
}
}
Trong fragment của từng dự báo thành phố thì mình làm như này để nó get dữ liệu lên app của mình.
private fun initData() {
val bundle = arguments
if (bundle != null) {
val cityCollection: CityCollection = bundle.getParcelable(Constants.CITY_COLLECTION)
tvWind.text = cityCollection.wind.toInt().toString() + " km/h"
}
}
And my ViewPagerAdapter:
class ViewPagerAdapter(fm: FragmentManager, private var listCityCollection: MutableList<CityCollection>)
: FragmentStatePagerAdapter(fm) {
override fun getItem(position: Int): Fragment? {
return newFragment(listCityCollection[position])
}
override fun getItemPosition(`object`: Any): Int {
return PagerAdapter.POSITION_NONE
}
override fun getCount(): Int {
return listCityCollection.size
}
private fun newFragment(cityCollection: CityCollection): FragmentShowWeatherForecast {
val fragmentShowWeatherForecast = FragmentShowWeatherForecast()
val bundle = Bundle()
bundle.putParcelable(Constants.CITY_COLLECTION, cityCollection)
fragmentShowWeatherForecast.arguments = bundle
return fragmentShowWeatherForecast
}
}
Giờ mình cần làm như nào để get dữ liệu lên Widget. Đây là class widget của mình.
class WeatherWidget : AppWidgetProvider() {
override fun onEnabled(context: Context?) {
super.onEnabled(context)
val intent = Intent(context, WeatherWidget::class.java)
intent.action = Constants.UPDATE_WIDGET
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0)
val alarmManager = context?.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.setRepeating(AlarmManager.RTC, System.currentTimeMillis(), (Constants.UPDATE_INTERVAL * 1000).toLong(), pendingIntent)
}
@SuppressLint("SimpleDateFormat")
override fun onUpdate(context: Context?, appWidgetManager: AppWidgetManager?, appWidgetIds: IntArray?) {
if (appWidgetIds != null) {
for (i in appWidgetIds.indices) {
val views = RemoteViews(context?.packageName, R.layout.widget_weather)
val openApp = Intent(context, MainActivity::class.java)
val pIntent = PendingIntent.getActivity(context, 0, openApp, 0)
val simpleDateFormat = SimpleDateFormat("E MM/dd")
views.setOnClickPendingIntent(R.id.rlWidget, pIntent)
appWidgetManager?.updateAppWidget(appWidgetIds[i], views)
}
}
}
override fun onDeleted(context: Context?, appWidgetIds: IntArray?) {
super.onDeleted(context, appWidgetIds)
Toast.makeText(context, "onDeleted()", Toast.LENGTH_LONG).show()
}
override fun onDisabled(context: Context?) {
super.onDisabled(context)
val intent = Intent(context, WeatherWidget::class.java)
intent.action = Constants.UPDATE_WIDGET
val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0)
val alarmManager = context?.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmManager.cancel(pendingIntent)
}
}