fixed user stream position key - now notifications can work properly

This commit is contained in:
Mariotaku Lee 2017-03-12 22:28:57 +08:00
parent 112e8fdb7d
commit 62a52c78ed
No known key found for this signature in database
GPG Key ID: 15C10F89D7C33535
8 changed files with 115 additions and 28 deletions

View File

@ -69,6 +69,8 @@ val floatingDetailedContentsKey = KBooleanKey("floating_detailed_contents", true
val localTrendsWoeIdKey = KIntKey(KEY_LOCAL_TRENDS_WOEID, 1)
val phishingLinksWaringKey = KBooleanKey(KEY_PHISHING_LINK_WARNING, true)
val multiColumnWidthKey = KStringKey("multi_column_tab_width", "normal")
val streamingNonMeteredNetworkKey = KBooleanKey("streaming_non_metered_network", true)
val streamingPowerSavingKey = KBooleanKey("streaming_power_saving", true)
object themeBackgroundAlphaKey : KSimpleKey<Int>(KEY_THEME_BACKGROUND_ALPHA, 0xFF) {
override fun read(preferences: SharedPreferences): Int {

View File

@ -16,7 +16,7 @@ import org.mariotaku.twidere.activity.SignInActivity
/**
* Created by mariotaku on 2016/12/2.
*/
class AccountAuthenticatorService : Service() {
class AccountAuthenticatorService : BaseService() {
private lateinit var authenticator: TwidereAccountAuthenticator

View File

@ -10,7 +10,7 @@ import android.os.IBinder
/**
* Created by mariotaku on 2016/12/3.
*/
class AccountSyncService : Service() {
class AccountSyncService : BaseService() {
override fun onCreate() {
/*

View File

@ -0,0 +1,53 @@
/*
* Twidere - Twitter client for Android
*
* Copyright (C) 2012-2017 Mariotaku Lee <mariotaku.lee@gmail.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package org.mariotaku.twidere.service
import android.app.Service
import android.net.ConnectivityManager
import com.twitter.Extractor
import com.twitter.Validator
import org.mariotaku.twidere.util.*
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import javax.inject.Inject
abstract class BaseService : Service() {
@Inject
lateinit var preferences: SharedPreferencesWrapper
@Inject
lateinit var twitterWrapper: AsyncTwitterWrapper
@Inject
lateinit var notificationManager: NotificationManagerWrapper
@Inject
lateinit var validator: Validator
@Inject
lateinit var extractor: Extractor
@Inject
lateinit var userColorNameManager: UserColorNameManager
@Inject
lateinit var taskServiceRunner: TaskServiceRunner
@Inject
lateinit var connectivityManager: ConnectivityManager
override fun onCreate() {
super.onCreate()
GeneralComponentHelper.build(this).inject(this)
}
}

View File

@ -19,26 +19,18 @@
package org.mariotaku.twidere.service
import android.app.Service
import android.content.Intent
import android.os.Build
import android.os.IBinder
import org.mariotaku.kpreferences.KPreferences
import org.mariotaku.kpreferences.get
import org.mariotaku.twidere.annotation.AutoRefreshType
import org.mariotaku.twidere.constant.autoRefreshCompatibilityModeKey
import org.mariotaku.twidere.util.TaskServiceRunner
import org.mariotaku.twidere.util.TaskServiceRunner.Companion.ACTION_REFRESH_DIRECT_MESSAGES
import org.mariotaku.twidere.util.TaskServiceRunner.Companion.ACTION_REFRESH_HOME_TIMELINE
import org.mariotaku.twidere.util.TaskServiceRunner.Companion.ACTION_REFRESH_NOTIFICATIONS
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import javax.inject.Inject
class LegacyTaskService : Service() {
@Inject
internal lateinit var taskServiceRunner: TaskServiceRunner
@Inject
internal lateinit var kPreferences: KPreferences
class LegacyTaskService : BaseService() {
override fun onBind(intent: Intent): IBinder? = null
@ -49,7 +41,7 @@ class LegacyTaskService : Service() {
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP &&
!kPreferences[autoRefreshCompatibilityModeKey]) return START_NOT_STICKY
!preferences[autoRefreshCompatibilityModeKey]) return START_NOT_STICKY
val action = intent?.action ?: return START_NOT_STICKY
taskServiceRunner.runTask(action) {
stopSelfResult(startId)

View File

@ -3,14 +3,15 @@ package org.mariotaku.twidere.service
import android.accounts.AccountManager
import android.accounts.OnAccountsUpdateListener
import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.os.Handler
import android.os.Looper
import android.support.v4.app.NotificationCompat
import android.support.v4.net.ConnectivityManagerCompat
import org.apache.commons.lang3.concurrent.BasicThreadFactory
import org.mariotaku.abstask.library.TaskStarter
import org.mariotaku.kpreferences.get
import org.mariotaku.ktextension.addOnAccountsUpdatedListenerSafe
import org.mariotaku.ktextension.removeOnAccountsUpdatedListenerSafe
import org.mariotaku.library.objectcursor.ObjectCursor
@ -21,8 +22,11 @@ import org.mariotaku.microblog.library.twitter.model.Activity
import org.mariotaku.microblog.library.twitter.model.DirectMessage
import org.mariotaku.microblog.library.twitter.model.Status
import org.mariotaku.twidere.R
import org.mariotaku.twidere.TwidereConstants.LOGTAG
import org.mariotaku.twidere.activity.SettingsActivity
import org.mariotaku.twidere.annotation.AccountType
import org.mariotaku.twidere.constant.streamingNonMeteredNetworkKey
import org.mariotaku.twidere.constant.streamingPowerSavingKey
import org.mariotaku.twidere.extension.model.isOfficial
import org.mariotaku.twidere.extension.model.isStreamingSupported
import org.mariotaku.twidere.extension.model.newMicroBlogInstance
@ -35,7 +39,8 @@ import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
import org.mariotaku.twidere.task.twitter.GetActivitiesAboutMeTask
import org.mariotaku.twidere.task.twitter.message.GetMessagesTask
import org.mariotaku.twidere.util.DataStoreUtils
import org.mariotaku.twidere.util.NotificationManagerWrapper
import org.mariotaku.twidere.util.DebugLog
import org.mariotaku.twidere.util.Utils
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
import org.mariotaku.twidere.util.streaming.TwitterTimelineStreamCallback
import java.util.*
@ -43,12 +48,9 @@ import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
import java.util.concurrent.Future
import java.util.concurrent.TimeUnit
import javax.inject.Inject
class StreamingService : Service() {
class StreamingService : BaseService() {
@Inject
internal lateinit var notificationManager: NotificationManagerWrapper
internal lateinit var threadPoolExecutor: ExecutorService
internal lateinit var handler: Handler
@ -84,6 +86,16 @@ class StreamingService : Service() {
override fun onBind(intent: Intent) = throw UnsupportedOperationException()
private fun setupStreaming(): Boolean {
val isNetworkMetered = ConnectivityManagerCompat.isActiveNetworkMetered(connectivityManager)
if (preferences[streamingNonMeteredNetworkKey] && isNetworkMetered) {
stopSelf()
return false
}
val isCharging = Utils.isCharging(this)
if (preferences[streamingPowerSavingKey] && !isCharging) {
stopSelf()
return false
}
if (updateStreamingInstances()) {
showNotification()
return true
@ -162,7 +174,7 @@ class StreamingService : Service() {
try {
instance.beginStreaming()
} catch (e: MicroBlogException) {
DebugLog.w(LOGTAG, tr = e)
}
Thread.sleep(TimeUnit.MINUTES.toMillis(1))
}
@ -191,6 +203,9 @@ class StreamingService : Service() {
}
val callback = object : TwitterTimelineStreamCallback(account.key.id) {
private var lastStatusTimestamps = LongArray(2)
private var homeInsertGap = false
private var interactionsInsertGap = false
override fun onConnected(): Boolean {
@ -200,9 +215,23 @@ class StreamingService : Service() {
}
override fun onHomeTimeline(status: Status): Boolean {
val parcelableStatus = ParcelableStatusUtils.fromStatus(status, account.key,
homeInsertGap, profileImageSize)
val currentTimeMillis = System.currentTimeMillis()
if (lastStatusTimestamps[0] >= parcelableStatus.timestamp) {
val extraValue = (currentTimeMillis - lastStatusTimestamps[1]).coerceAtMost(499)
parcelableStatus.position_key = parcelableStatus.timestamp + extraValue
} else {
parcelableStatus.position_key = parcelableStatus.timestamp
}
parcelableStatus.inserted_date = currentTimeMillis
lastStatusTimestamps[0] = parcelableStatus.position_key
lastStatusTimestamps[1] = parcelableStatus.inserted_date
val values = ObjectCursor.valuesCreatorFrom(ParcelableStatus::class.java)
.create(ParcelableStatusUtils.fromStatus(status, account.key, homeInsertGap,
profileImageSize))
.create(parcelableStatus)
context.contentResolver.insert(Statuses.CONTENT_URI, values)
homeInsertGap = false
return true
@ -217,9 +246,11 @@ class StreamingService : Service() {
handler.postDelayed(interactionsTimeoutRunnable, TimeUnit.SECONDS.toMillis(30))
}
} else {
val parcelableActivity = ParcelableActivityUtils.fromActivity(activity,
account.key, interactionsInsertGap, profileImageSize)
parcelableActivity.position_key = parcelableActivity.timestamp
val values = ObjectCursor.valuesCreatorFrom(ParcelableActivity::class.java)
.create(ParcelableActivityUtils.fromActivity(activity, account.key,
interactionsInsertGap, profileImageSize))
.create(parcelableActivity)
context.contentResolver.insert(Activities.AboutMe.CONTENT_URI, values)
interactionsInsertGap = false
}
@ -236,6 +267,11 @@ class StreamingService : Service() {
return true
}
override fun onException(ex: Throwable): Boolean {
DebugLog.w(LOGTAG, tr = ex)
return true
}
private fun getInteractions() {
val task = GetActivitiesAboutMeTask(context)
task.params = object : SimpleRefreshTaskParam() {

View File

@ -297,6 +297,11 @@ class ApplicationModule(private val application: Application) {
return application.getSystemService(Context.LOCATION_SERVICE) as LocationManager
}
@Provides
fun connectivityManager(): ConnectivityManager {
return application.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
}
@Provides
fun okHttpClient(preferences: SharedPreferencesWrapper, dns: Dns, connectionPool: ConnectionPool,
cache: Cache): OkHttpClient {

View File

@ -38,10 +38,7 @@ import org.mariotaku.twidere.preference.PremiumEntryPreferenceCategory
import org.mariotaku.twidere.preference.sync.SyncItemPreference
import org.mariotaku.twidere.provider.CacheProvider
import org.mariotaku.twidere.provider.TwidereDataProvider
import org.mariotaku.twidere.service.BaseIntentService
import org.mariotaku.twidere.service.JobTaskService
import org.mariotaku.twidere.service.LegacyTaskService
import org.mariotaku.twidere.service.StreamingService
import org.mariotaku.twidere.service.*
import org.mariotaku.twidere.task.BaseAbstractTask
import org.mariotaku.twidere.task.ManagedAsyncTask
import org.mariotaku.twidere.text.util.EmojiEditableFactory
@ -144,4 +141,6 @@ interface GeneralComponent {
fun inject(fragment: ExoPlayerPageFragment)
fun inject(service: StreamingService)
fun inject(service: BaseService)
}