Skip to content
Snippets Groups Projects
Commit 3628e2e1 authored by John Carlson's avatar John Carlson
Browse files

Fix the widgets from crashing for forever

parent b068f68e
No related branches found
No related tags found
No related merge requests found
Pipeline #
Loading
Loading
@@ -152,6 +152,11 @@
android:resource="@xml/widget_project_feed" />
</receiver>
 
<service
android:name=".widget.ProjectFeedWidgetService"
android:exported="false"
android:permission="android.permission.BIND_REMOTEVIEWS" />
</application>
 
</manifest>
\ No newline at end of file
Loading
Loading
@@ -40,7 +40,7 @@ class ProjectFeedWidgetConfigureActivity : BaseActivity() {
lateinit var adapterAccounts: AccountsAdapter
 
var account: Account? = null
var mAppWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID
var appWidgetId = AppWidgetManager.INVALID_APPWIDGET_ID
 
public override fun onCreate(icicle: Bundle?) {
super.onCreate(icicle)
Loading
Loading
@@ -52,11 +52,11 @@ class ProjectFeedWidgetConfigureActivity : BaseActivity() {
val intent = intent
val extras = intent.extras
if (extras != null) {
mAppWidgetId = extras.getInt(
appWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID, AppWidgetManager.INVALID_APPWIDGET_ID)
}
// If they gave us an intent without the widget id, just bail.
if (mAppWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
if (appWidgetId == AppWidgetManager.INVALID_APPWIDGET_ID) {
Timber.e("We did not get a widget id. Bail out")
finish()
}
Loading
Loading
@@ -103,12 +103,15 @@ class ProjectFeedWidgetConfigureActivity : BaseActivity() {
}
 
fun saveWidgetConfig(account: Account, project: Project) {
ProjectFeedWidgetPrefs.setAccount(this, mAppWidgetId, account)
ProjectFeedWidgetPrefs.setFeedUrl(this, mAppWidgetId, project.feedUrl!!.toString())
ProjectFeedWidgetPrefs.setAccount(this, appWidgetId, account)
ProjectFeedWidgetPrefs.setFeedUrl(this, appWidgetId, project.feedUrl!!.toString())
 
val resultValue = Intent()
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId)
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
setResult(Activity.RESULT_OK, resultValue)
finish()
//Manually have to trigger on update here, it seems
WidgetUtil.triggerWidgetUpdate(this, UserFeedWidgetProvider::class.java, appWidgetId)
}
}
Loading
Loading
@@ -51,23 +51,26 @@ class ProjectFeedWidgetProvider : AppWidgetProvider() {
 
val account = ProjectFeedWidgetPrefs.getAccount(context, widgetId)
val feedUrl = ProjectFeedWidgetPrefs.getFeedUrl(context, widgetId)
val intent = ProjectFeedWidgetService.newIntent(context, widgetId, account!!, feedUrl!!)
if (account != null && feedUrl!= null) {
val intent = ProjectFeedWidgetService.newIntent(context, widgetId, account, feedUrl)
 
intent.data = Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))
val rv = RemoteViews(context.packageName, R.layout.widget_layout_entry)
rv.setRemoteAdapter(R.id.list_view, intent)
 
rv.setEmptyView(R.id.list_view, R.id.empty_view)
intent.data = Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))
val rv = RemoteViews(context.packageName, R.layout.widget_layout_entry)
rv.setRemoteAdapter(R.id.list_view, intent)
 
val toastIntent = Intent(context, ProjectFeedWidgetProvider::class.java)
toastIntent.action = ProjectFeedWidgetProvider.ACTION_FOLLOW_LINK
toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)
intent.data = Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))
val toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
rv.setPendingIntentTemplate(R.id.list_view, toastPendingIntent)
rv.setEmptyView(R.id.list_view, R.id.empty_view)
 
appWidgetManager.updateAppWidget(widgetId, rv)
val toastIntent = Intent(context, ProjectFeedWidgetProvider::class.java)
toastIntent.action = ProjectFeedWidgetProvider.ACTION_FOLLOW_LINK
toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)
intent.data = Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))
val toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
rv.setPendingIntentTemplate(R.id.list_view, toastPendingIntent)
appWidgetManager.updateAppWidget(widgetId, rv)
}
}
super.onUpdate(context, appWidgetManager, appWidgetIds)
}
Loading
Loading
Loading
Loading
@@ -19,12 +19,10 @@ package com.commit451.gitlab.widget
import android.appwidget.AppWidgetManager
import android.content.Context
import android.content.Intent
import android.os.Parcelable
import android.widget.RemoteViewsService
import com.bluelinelabs.logansquare.LoganSquare
import com.commit451.gitlab.model.Account
import org.parceler.Parcels
import timber.log.Timber
 
/**
* Service that basically just defers everything to a Factory. Yay!
Loading
Loading
@@ -33,20 +31,28 @@ class ProjectFeedWidgetService : RemoteViewsService() {
 
companion object {
 
val EXTRA_ACCOUNT = "account"
val EXTRA_ACCOUNT_JSON = "account_json"
val EXTRA_FEED_URL = "feed_url"
 
/**
* Currently, when we pass this Intent along to certain launchers, they will not
* be able to un-marshall the Account class. So, we will just pass the account as json
* :(
*/
fun newIntent(context: Context, widgetId: Int, account: Account, feedUrl: String): Intent {
val accountJson = LoganSquare.serialize(account)
val intent = Intent(context, ProjectFeedWidgetService::class.java)
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)
intent.putExtra(EXTRA_ACCOUNT, Parcels.wrap(account))
intent.putExtra(EXTRA_ACCOUNT_JSON, accountJson)
intent.putExtra(EXTRA_FEED_URL, feedUrl)
return intent
}
}
 
override fun onGetViewFactory(intent: Intent): RemoteViewsService.RemoteViewsFactory {
val account = Parcels.unwrap<Account>(intent.getParcelableExtra<Parcelable>(EXTRA_ACCOUNT))
Timber.d("onGetViewFactory")
val accountJson = intent.getStringExtra(EXTRA_ACCOUNT_JSON)
val account = LoganSquare.parse(accountJson, Account::class.java)
val feedUrl = intent.getStringExtra(EXTRA_FEED_URL)
return FeedRemoteViewsFactory(applicationContext, intent, account, feedUrl)
}
Loading
Loading
Loading
Loading
@@ -77,15 +77,18 @@ class UserFeedWidgetConfigureActivity : BaseActivity() {
 
fun saveWidgetConfig(account: Account) {
UserFeedWidgetPrefs.setAccount(this@UserFeedWidgetConfigureActivity, appWidgetId, account)
// Push widget update to surface with newly set prefix
val appWidgetManager = AppWidgetManager.getInstance(this@UserFeedWidgetConfigureActivity)
// ExampleAppWidgetProvider.updateAppWidget(context, appWidgetManager,
// appWidgetId, titlePrefix);
// Make sure we pass back the original appWidgetId
val resultValue = Intent()
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
setResult(Activity.RESULT_OK, resultValue)
val data = Intent()
val extras = Bundle()
extras.putInt(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
data.putExtras(extras)
setResult(Activity.RESULT_OK, data)
appWidgetManager.updateAppWidgetOptions(appWidgetId, extras)
finish()
//Manually have to trigger on update here, it seems
WidgetUtil.triggerWidgetUpdate(this, UserFeedWidgetProvider::class.java, appWidgetId)
}
 
}
Loading
Loading
@@ -25,6 +25,7 @@ import android.net.Uri
import android.widget.RemoteViews
import com.commit451.gitlab.R
import com.commit451.gitlab.navigation.DeepLinker
import timber.log.Timber
 
class UserFeedWidgetProvider : AppWidgetProvider() {
 
Loading
Loading
@@ -34,10 +35,8 @@ class UserFeedWidgetProvider : AppWidgetProvider() {
}
 
override fun onReceive(context: Context, intent: Intent) {
val mgr = AppWidgetManager.getInstance(context)
Timber.d("onReceive")
if (intent.action == ACTION_FOLLOW_LINK) {
val appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID)
val uri = intent.getStringExtra(EXTRA_LINK)
val launchIntent = DeepLinker.generateDeeplinkIntentFromUri(context, Uri.parse(uri))
launchIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
Loading
Loading
@@ -48,15 +47,18 @@ class UserFeedWidgetProvider : AppWidgetProvider() {
 
override fun onUpdate(context: Context, appWidgetManager: AppWidgetManager, appWidgetIds: IntArray) {
for (widgetId in appWidgetIds) {
Timber.d("onUpdate with id: $widgetId")
 
// Here we setup the intent which points to the StackViewService which will
// provide the views for this collection.
val account = UserFeedWidgetPrefs.getAccount(context, widgetId)
if (account == null || account.user.feedUrl == null) {
//TODO alert the user to this misfortune?
Timber.e("Error getting account or feed url")
return
}
val feedUrl = account.user.feedUrl!!.toString()
Timber.d("Updating widget with url $feedUrl")
val intent = ProjectFeedWidgetService.newIntent(context, widgetId, account, feedUrl)
// When intents are compared, the extras are ignored, so we need to embed the extras
// into the data so that the extras will not be ignored.
Loading
Loading
@@ -70,13 +72,13 @@ class UserFeedWidgetProvider : AppWidgetProvider() {
// cannot setup their own pending intents, instead, the collection as a whole can
// setup a pending intent template, and the individual items can set a fillInIntent
// to create unique before on an item to item basis.
val toastIntent = Intent(context, UserFeedWidgetProvider::class.java)
toastIntent.action = UserFeedWidgetProvider.ACTION_FOLLOW_LINK
toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)
val actionIntent = Intent(context, UserFeedWidgetProvider::class.java)
actionIntent.action = UserFeedWidgetProvider.ACTION_FOLLOW_LINK
actionIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId)
intent.data = Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))
val toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent,
val actionPendingIntent = PendingIntent.getBroadcast(context, 0, actionIntent,
PendingIntent.FLAG_UPDATE_CURRENT)
rv.setPendingIntentTemplate(R.id.list_view, toastPendingIntent)
rv.setPendingIntentTemplate(R.id.list_view, actionPendingIntent)
 
appWidgetManager.updateAppWidget(widgetId, rv)
}
Loading
Loading
package com.commit451.gitlab.widget;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
/**
* Oh the woes of a weird widget
*/
public class WidgetUtil {
/**
* Update any widget
* @param context context
* @param clazz class of the widget provider
* @param widgetId the widget id
* @see <a href="http://stackoverflow.com/a/7738687/895797">http://stackoverflow.com/a/7738687/895797</a>
*/
public static void triggerWidgetUpdate(Context context, Class clazz, int widgetId) {
Intent intent = new Intent(context, clazz);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
// Use an array and EXTRA_APPWIDGET_IDS instead of AppWidgetManager.EXTRA_APPWIDGET_ID,
// since it seems the onUpdate() is only fired on that:
int[] ids = {widgetId};
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, ids);
context.sendBroadcast(intent);
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment