widgetupdatehelper's People
widgetupdatehelper's Issues
A RemoteServiceException
Hi Alex,
I got this kind of crash error when I'm using your project.
Fatal Exception: android.app.RemoteServiceException
Context.startForegroundService() did not then call Service.startForeground(): ServiceRecord{heyalex.widgethelper.WidgetUpdateService}
android.app.ActivityThread$H.handleMessage (ActivityThread.java:2067)
Do you have any suggestion?
Thanks
Works in debug mode, but not in release
Hi,
I'm struggling to make this work. It works in debug mode but not in production. I used the single example. I'm not sure what I'm doing wrong. I converted the code to kotlin as most of the code is written in it.
Here's the code:
SmallWidgetUpdater.kt
class SmallWidgetUpdater : WidgetUpdater() {
override fun update(context: Context, dataBundle: Bundle?, vararg ids: Int) {
//This callback will be running on background thread
val appWidgetManager = AppWidgetManager.getInstance(context)
var weatherData: WeatherMapper? = null
try {
//DB or Internet requests
// Thread.sleep(10000)
getWeather(context, getCity(context), getUnit(context))
weatherData = WeatherMapper.fromJson(getWeatherData(context))
} catch (e: InterruptedException) {
e.printStackTrace()
}
val pendingIntent: PendingIntent = Intent(context, MainActivity::class.java)
.let { intent ->
PendingIntent.getActivity(context, 0, intent, 0)
}
//make RemoteViews depends on dataBundle and update by widget ID
val remoteViews = RemoteViews(context.packageName, R.layout.current_weather).apply {}
remoteViews.setOnClickPendingIntent(R.id.city, pendingIntent)
if (weatherData?.weather != null){
remoteViews.setTextViewText(R.id.condition, weatherData.weather!![0].description)
remoteViews.setImageViewResource(R.id.icon, context.resources.getIdentifier("ic_" + weatherData.weather!![0].icon, "drawable", context.packageName))
remoteViews.setTextViewText(R.id.city, weatherData.name)
remoteViews.setTextViewText(R.id.temperature, weatherData.main?.temp.toString().substringBefore(".") + getUnitString(context))
}
for (widgetId in ids) {
appWidgetManager.updateAppWidget(widgetId, remoteViews)
}
}
@RequiresApi(Build.VERSION_CODES.O)
override fun makeNotification(context: Context): Notification {
val notifChannelID = "widget_updater"
val channelName = "widget updating"
val chan = NotificationChannel(notifChannelID, channelName, NotificationManager.IMPORTANCE_NONE)
val manager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
manager.createNotificationChannel(chan)
val notificationBuilder = Notification.Builder(context, notifChannelID)
return notificationBuilder.build()
}
companion object {
private fun getCity(context: Context): String {
val prefs: Prefs?
prefs = Prefs(context)
return prefs.city!!
}
private fun getWeatherData(context: Context): String {
val prefs: Prefs?
prefs = Prefs(context)
return prefs.currentWeather!!
}
private fun getLat(context: Context): Double {
val prefs: Prefs?
prefs = Prefs(context)
return prefs.lat
}
private fun getLon(context: Context): Double {
val prefs: Prefs?
prefs = Prefs(context)
return prefs.lon
}
private fun getUnitString(context: Context): String {
val prefs: Prefs?
prefs = Prefs(context)
val unit = prefs.unit
val unitString: String
unitString = when (unit) {
0.toLong() -> {
"°C"
}
1.toLong() -> {
"°F"
}
else -> {
"K"
}
}
return unitString
}
private fun getUnit(context: Context): String {
val prefs: Prefs?
prefs = Prefs(context)
val unit = prefs.unit
val unitString: String
unitString = when (unit) {
0.toLong() -> {
"/metric"
}
1.toLong() -> {
"/imperial"
}
else -> {
""
}
}
return unitString
}
private fun getWeather(context: Context, city: String, unitString: String) {
val url: URL = if (getCity(context) != "") {
URL("...")
} else {
URL("...")
}
val client = OkHttpClient()
val request = Request.Builder()
.url(url)
.get()
.build()
client.newCall(request).enqueue(object : Callback {
override fun onFailure(call: Call, e: IOException) {
e.printStackTrace()
}
override fun onResponse(call: Call, response: Response) {
response.use {
if (!response.isSuccessful) throw IOException("Unexpected code $response")
val responseBody = response.body
val content = responseBody!!.string()
val prefs: Prefs?
prefs = Prefs(context)
println("content")
println(content)
prefs.currentWeather = content
}
}
})
}
}
}
SmallWidgetProvider.kt
@RemoteViewsUpdater(SmallWidgetUpdater::class)
class SmallWidgetProvider : AppWidgetProvider() {
override fun onReceive(context: Context?, intent: Intent?) {
println("updateWidgets onReceive")
super.onReceive(context, intent)
val appWidgetManager = AppWidgetManager.getInstance(context)
val widgetIds = appWidgetManager.getAppWidgetIds(
context?.let { ComponentName(it, SmallWidgetProvider::class.java) })
// update widgets
for (widgetId in widgetIds) {
WidgetUpdateService.updateWidgets(context, this, null, widgetId)
}
}
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
println("updateWidgets onUpdate")
// trigger you WidgetUpdater by this call
for (widgetId in appWidgetIds) {
WidgetUpdateService.updateWidgets(context, this, null, widgetId)
}
}
override fun onEnabled(context: Context) {
println("updateWidgets onEnabled")
val appWidgetManager = AppWidgetManager.getInstance(context)
val widgetIds = appWidgetManager.getAppWidgetIds(
ComponentName(context, SmallWidgetProvider::class.java))
// update widgets
for (widgetId in widgetIds) {
WidgetUpdateService.updateWidgets(context, this, null, widgetId)
}
}
override fun onDisabled(context: Context) {
println("updateWidgets onDisabled")
}
}
and added this to manifest:
<receiver android:name=".SmallWidgetProvider">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/current_weather_info" />
</receiver>
I'm storing the data in sharedPrefs and then using it. Tried using it directly also in updater but same effect.
Any idea why is this happening?
and the appwidget-provider xml is this:
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/current_weather"
android:initialLayout="@layout/current_weather"
android:minHeight="110dp"
android:minResizeHeight="40dp"
android:minWidth="110dp"
android:minResizeWidth="40dp"
android:previewImage="@drawable/current_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="1800000"
android:widgetCategory="home_screen" />
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.