finished streaming service lifecycle
This commit is contained in:
parent
b767c28e75
commit
1b542cea6c
|
@ -647,7 +647,15 @@
|
||||||
|
|
||||||
<receiver android:name=".receiver.ConnectivityStateReceiver">
|
<receiver android:name=".receiver.ConnectivityStateReceiver">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
|
<action
|
||||||
|
android:name="android.net.conn.CONNECTIVITY_CHANGE"
|
||||||
|
tools:ignore="BatteryLife"/>
|
||||||
|
</intent-filter>
|
||||||
|
</receiver>
|
||||||
|
<receiver android:name=".receiver.PowerStateReceiver">
|
||||||
|
<intent-filter>
|
||||||
|
<action android:name="android.intent.action.ACTION_POWER_CONNECTED"/>
|
||||||
|
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED"/>
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
<receiver
|
<receiver
|
||||||
|
|
|
@ -141,7 +141,7 @@ public class HotMobiLogger implements HotMobiConstants {
|
||||||
log(event, null);
|
log(event, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void log(final LogModel event, final PreProcessing preProcessing) {
|
public <T extends LogModel> void log(final T event, final PreProcessing<T> preProcessing) {
|
||||||
log(null, event, preProcessing);
|
log(null, event, preProcessing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,122 +0,0 @@
|
||||||
/*
|
|
||||||
* Twidere - Twitter client for Android
|
|
||||||
*
|
|
||||||
* Copyright (C) 2012-2015 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.util;
|
|
||||||
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.app.Application;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.os.Bundle;
|
|
||||||
|
|
||||||
import org.apache.commons.collections.primitives.ArrayIntList;
|
|
||||||
import org.apache.commons.collections.primitives.IntList;
|
|
||||||
import org.mariotaku.twidere.BuildConfig;
|
|
||||||
import org.mariotaku.twidere.activity.HomeActivity;
|
|
||||||
|
|
||||||
import edu.tsinghua.hotmobi.HotMobiLogger;
|
|
||||||
import edu.tsinghua.hotmobi.PreProcessing;
|
|
||||||
import edu.tsinghua.hotmobi.model.SessionEvent;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Created by mariotaku on 15/10/5.
|
|
||||||
*/
|
|
||||||
public class ActivityTracker implements Application.ActivityLifecycleCallbacks {
|
|
||||||
|
|
||||||
private final IntList mInternalStack = new ArrayIntList();
|
|
||||||
private SessionEvent mSessionEvent;
|
|
||||||
private boolean mHomeActivityStarted;
|
|
||||||
|
|
||||||
private boolean isSwitchingInSameTask(int hashCode) {
|
|
||||||
return mInternalStack.lastIndexOf(hashCode) < mInternalStack.size() - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int size() {
|
|
||||||
return mInternalStack.size();
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isEmpty() {
|
|
||||||
return mInternalStack.isEmpty();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityCreated(Activity activity, Bundle savedInstanceState) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityStarted(final Activity activity) {
|
|
||||||
mInternalStack.add(System.identityHashCode(activity));
|
|
||||||
if (activity instanceof HomeActivity) {
|
|
||||||
mHomeActivityStarted = true;
|
|
||||||
}
|
|
||||||
// BEGIN HotMobi
|
|
||||||
if (mSessionEvent == null && BuildConfig.HOTMOBI_LOG_ENABLED) {
|
|
||||||
mSessionEvent = SessionEvent.create(activity);
|
|
||||||
}
|
|
||||||
// END HotMobi
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityResumed(Activity activity) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityPaused(Activity activity) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityStopped(Activity activity) {
|
|
||||||
final int hashCode = System.identityHashCode(activity);
|
|
||||||
if (activity instanceof HomeActivity) {
|
|
||||||
mHomeActivityStarted = false;
|
|
||||||
}
|
|
||||||
// BEGIN HotMobi
|
|
||||||
final SessionEvent event = mSessionEvent;
|
|
||||||
if (event != null && !isSwitchingInSameTask(hashCode)) {
|
|
||||||
event.markEnd();
|
|
||||||
HotMobiLogger.getInstance(activity).log(event, new PreProcessing<SessionEvent>() {
|
|
||||||
@Override
|
|
||||||
public void process(SessionEvent event, Context appContext) {
|
|
||||||
event.dumpPreferences(appContext);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
mSessionEvent = null;
|
|
||||||
}
|
|
||||||
// END HotMobi
|
|
||||||
|
|
||||||
mInternalStack.removeElement(hashCode);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivitySaveInstanceState(Activity activity, Bundle outState) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onActivityDestroyed(Activity activity) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isHomeActivityStarted() {
|
|
||||||
return mHomeActivityStarted;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -66,8 +66,6 @@ import org.mariotaku.chameleon.ChameleonUtils
|
||||||
import org.mariotaku.kpreferences.get
|
import org.mariotaku.kpreferences.get
|
||||||
import org.mariotaku.kpreferences.set
|
import org.mariotaku.kpreferences.set
|
||||||
import org.mariotaku.ktextension.*
|
import org.mariotaku.ktextension.*
|
||||||
import org.mariotaku.sqliteqb.library.Columns
|
|
||||||
import org.mariotaku.sqliteqb.library.SQLFunctions
|
|
||||||
import org.mariotaku.twidere.Constants.*
|
import org.mariotaku.twidere.Constants.*
|
||||||
import org.mariotaku.twidere.R
|
import org.mariotaku.twidere.R
|
||||||
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarShowHideHelper
|
import org.mariotaku.twidere.activity.iface.IControlBarActivity.ControlBarShowHideHelper
|
||||||
|
@ -87,10 +85,9 @@ import org.mariotaku.twidere.model.SupportTabSpec
|
||||||
import org.mariotaku.twidere.model.Tab
|
import org.mariotaku.twidere.model.Tab
|
||||||
import org.mariotaku.twidere.model.UserKey
|
import org.mariotaku.twidere.model.UserKey
|
||||||
import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent
|
import org.mariotaku.twidere.model.event.UnreadCountUpdatedEvent
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore
|
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
|
import org.mariotaku.twidere.provider.TwidereDataStore.Activities
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
|
||||||
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
import org.mariotaku.twidere.provider.TwidereDataStore.Messages.Conversations
|
||||||
|
import org.mariotaku.twidere.provider.TwidereDataStore.Statuses
|
||||||
import org.mariotaku.twidere.service.StreamingService
|
import org.mariotaku.twidere.service.StreamingService
|
||||||
import org.mariotaku.twidere.util.*
|
import org.mariotaku.twidere.util.*
|
||||||
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
|
import org.mariotaku.twidere.util.KeyboardShortcutsHandler.KeyboardShortcutCallback
|
||||||
|
@ -270,7 +267,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
val initialTabPosition = handleIntent(intent, savedInstanceState == null)
|
val initialTabPosition = handleIntent(intent, savedInstanceState == null)
|
||||||
setTabPosition(initialTabPosition)
|
setTabPosition(initialTabPosition)
|
||||||
|
|
||||||
startService(Intent(this, StreamingService::class.java))
|
StreamingService.startOrStopService(this)
|
||||||
|
|
||||||
if (!showDrawerTutorial() && !kPreferences[defaultAutoRefreshAskedKey]) {
|
if (!showDrawerTutorial() && !kPreferences[defaultAutoRefreshAskedKey]) {
|
||||||
showAutoRefreshConfirm()
|
showAutoRefreshConfirm()
|
||||||
|
@ -312,7 +309,7 @@ class HomeActivity : BaseActivity(), OnClickListener, OnPageChangeListener, Supp
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
if (isFinishing) {
|
if (isFinishing) {
|
||||||
// Stop only when exiting explicitly
|
// Stop only when exiting explicitly
|
||||||
stopService(Intent(this, StreamingService::class.java))
|
StreamingService.startOrStopService(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete unused items in databases.
|
// Delete unused items in databases.
|
||||||
|
|
|
@ -45,10 +45,9 @@ import org.mariotaku.twidere.TwidereConstants.*
|
||||||
import org.mariotaku.twidere.activity.AssistLauncherActivity
|
import org.mariotaku.twidere.activity.AssistLauncherActivity
|
||||||
import org.mariotaku.twidere.activity.MainActivity
|
import org.mariotaku.twidere.activity.MainActivity
|
||||||
import org.mariotaku.twidere.activity.MainHondaJOJOActivity
|
import org.mariotaku.twidere.activity.MainHondaJOJOActivity
|
||||||
import org.mariotaku.twidere.constant.apiLastChangeKey
|
import org.mariotaku.twidere.constant.*
|
||||||
import org.mariotaku.twidere.constant.bugReportsKey
|
|
||||||
import org.mariotaku.twidere.constant.defaultFeatureLastUpdated
|
|
||||||
import org.mariotaku.twidere.model.DefaultFeatures
|
import org.mariotaku.twidere.model.DefaultFeatures
|
||||||
|
import org.mariotaku.twidere.service.StreamingService
|
||||||
import org.mariotaku.twidere.util.*
|
import org.mariotaku.twidere.util.*
|
||||||
import org.mariotaku.twidere.util.content.TwidereSQLiteOpenHelper
|
import org.mariotaku.twidere.util.content.TwidereSQLiteOpenHelper
|
||||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||||
|
@ -258,6 +257,14 @@ class TwidereApplication : Application(), Constants, OnSharedPreferenceChangeLis
|
||||||
KEY_NAME_FIRST, KEY_I_WANT_MY_STARS_BACK -> {
|
KEY_NAME_FIRST, KEY_I_WANT_MY_STARS_BACK -> {
|
||||||
contentNotificationManager.updatePreferences()
|
contentNotificationManager.updatePreferences()
|
||||||
}
|
}
|
||||||
|
streamingPowerSavingKey.key, streamingNonMeteredNetworkKey.key -> {
|
||||||
|
val streamingIntent = Intent(this, StreamingService::class.java)
|
||||||
|
if (activityTracker.isHomeActivityLaunched) {
|
||||||
|
startService(streamingIntent)
|
||||||
|
} else {
|
||||||
|
stopService(streamingIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@ package org.mariotaku.twidere.fragment
|
||||||
|
|
||||||
import org.mariotaku.twidere.R
|
import org.mariotaku.twidere.R
|
||||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_ENABLE_STREAMING
|
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_ENABLE_STREAMING
|
||||||
|
import org.mariotaku.twidere.service.StreamingService
|
||||||
|
|
||||||
class AccountStreamingSettingsFragment : BaseAccountPreferenceFragment() {
|
class AccountStreamingSettingsFragment : BaseAccountPreferenceFragment() {
|
||||||
|
|
||||||
|
@ -31,4 +32,8 @@ class AccountStreamingSettingsFragment : BaseAccountPreferenceFragment() {
|
||||||
|
|
||||||
override val switchPreferenceKey: String? = KEY_ENABLE_STREAMING
|
override val switchPreferenceKey: String? = KEY_ENABLE_STREAMING
|
||||||
|
|
||||||
|
override fun onSwitchPreferenceChanged(isChecked: Boolean) {
|
||||||
|
super.onSwitchPreferenceChanged(isChecked)
|
||||||
|
StreamingService.startOrStopService(context)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@
|
||||||
|
|
||||||
package org.mariotaku.twidere.fragment
|
package org.mariotaku.twidere.fragment
|
||||||
|
|
||||||
import android.content.SharedPreferences
|
|
||||||
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
|
import android.content.SharedPreferences.OnSharedPreferenceChangeListener
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.preference.PreferenceActivity.EXTRA_SHOW_FRAGMENT
|
import android.preference.PreferenceActivity.EXTRA_SHOW_FRAGMENT
|
||||||
|
@ -27,14 +26,30 @@ import android.text.TextUtils
|
||||||
import android.view.Menu
|
import android.view.Menu
|
||||||
import android.view.MenuInflater
|
import android.view.MenuInflater
|
||||||
import android.widget.CompoundButton
|
import android.widget.CompoundButton
|
||||||
import android.widget.CompoundButton.OnCheckedChangeListener
|
|
||||||
import org.mariotaku.twidere.R
|
import org.mariotaku.twidere.R
|
||||||
import org.mariotaku.twidere.TwidereConstants.ACCOUNT_PREFERENCES_NAME_PREFIX
|
import org.mariotaku.twidere.TwidereConstants.ACCOUNT_PREFERENCES_NAME_PREFIX
|
||||||
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT
|
import org.mariotaku.twidere.constant.IntentConstants.EXTRA_ACCOUNT
|
||||||
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NAME_FIRST
|
import org.mariotaku.twidere.constant.SharedPreferenceConstants.KEY_NAME_FIRST
|
||||||
import org.mariotaku.twidere.model.AccountDetails
|
import org.mariotaku.twidere.model.AccountDetails
|
||||||
|
|
||||||
abstract class BaseAccountPreferenceFragment : BasePreferenceFragment(), OnCheckedChangeListener, OnSharedPreferenceChangeListener {
|
abstract class BaseAccountPreferenceFragment : BasePreferenceFragment() {
|
||||||
|
|
||||||
|
protected val account: AccountDetails?
|
||||||
|
get() {
|
||||||
|
return arguments?.getParcelable(EXTRA_ACCOUNT)
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract val preferencesResource: Int
|
||||||
|
|
||||||
|
protected abstract val switchPreferenceDefault: Boolean
|
||||||
|
|
||||||
|
protected abstract val switchPreferenceKey: String?
|
||||||
|
|
||||||
|
private val preferenceChangeListener = OnSharedPreferenceChangeListener { _, key ->
|
||||||
|
if (key == switchPreferenceKey) {
|
||||||
|
updatePreferenceScreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
override fun onActivityCreated(savedInstanceState: Bundle?) {
|
||||||
super.onActivityCreated(savedInstanceState)
|
super.onActivityCreated(savedInstanceState)
|
||||||
|
@ -48,7 +63,7 @@ abstract class BaseAccountPreferenceFragment : BasePreferenceFragment(), OnCheck
|
||||||
pm.sharedPreferencesName = preferenceName
|
pm.sharedPreferencesName = preferenceName
|
||||||
addPreferencesFromResource(preferencesResource)
|
addPreferencesFromResource(preferencesResource)
|
||||||
val prefs = pm.sharedPreferences
|
val prefs = pm.sharedPreferences
|
||||||
prefs.registerOnSharedPreferenceChangeListener(this)
|
prefs.registerOnSharedPreferenceChangeListener(preferenceChangeListener)
|
||||||
val activity = activity
|
val activity = activity
|
||||||
val intent = activity.intent
|
val intent = activity.intent
|
||||||
if (intent.hasExtra(EXTRA_SHOW_FRAGMENT)) {
|
if (intent.hasExtra(EXTRA_SHOW_FRAGMENT)) {
|
||||||
|
@ -63,19 +78,10 @@ abstract class BaseAccountPreferenceFragment : BasePreferenceFragment(), OnCheck
|
||||||
override fun onDestroy() {
|
override fun onDestroy() {
|
||||||
val pm = preferenceManager
|
val pm = preferenceManager
|
||||||
val prefs = pm.sharedPreferences
|
val prefs = pm.sharedPreferences
|
||||||
prefs.unregisterOnSharedPreferenceChangeListener(this)
|
prefs.unregisterOnSharedPreferenceChangeListener(preferenceChangeListener)
|
||||||
super.onDestroy()
|
super.onDestroy()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCheckedChanged(buttonView: CompoundButton, isChecked: Boolean) {
|
|
||||||
val prefs = preferenceManager.sharedPreferences
|
|
||||||
val editor = prefs.edit()
|
|
||||||
if (prefs.getBoolean(switchPreferenceKey, switchPreferenceDefault) != isChecked) {
|
|
||||||
editor.putBoolean(switchPreferenceKey, isChecked)
|
|
||||||
editor.apply()
|
|
||||||
updatePreferenceScreen()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
|
||||||
val switchKey = switchPreferenceKey
|
val switchKey = switchPreferenceKey
|
||||||
|
@ -84,28 +90,24 @@ abstract class BaseAccountPreferenceFragment : BasePreferenceFragment(), OnCheck
|
||||||
val actionView = menu.findItem(R.id.toggle).actionView
|
val actionView = menu.findItem(R.id.toggle).actionView
|
||||||
val toggle = actionView.findViewById(android.R.id.toggle) as CompoundButton
|
val toggle = actionView.findViewById(android.R.id.toggle) as CompoundButton
|
||||||
val prefs = preferenceManager.sharedPreferences
|
val prefs = preferenceManager.sharedPreferences
|
||||||
toggle.setOnCheckedChangeListener(this)
|
toggle.setOnCheckedChangeListener { _, isChecked ->
|
||||||
|
val editor = prefs.edit()
|
||||||
|
if (prefs.getBoolean(switchPreferenceKey, switchPreferenceDefault) != isChecked) {
|
||||||
|
editor.putBoolean(switchPreferenceKey, isChecked)
|
||||||
|
editor.apply()
|
||||||
|
onSwitchPreferenceChanged(isChecked)
|
||||||
|
updatePreferenceScreen()
|
||||||
|
}
|
||||||
|
}
|
||||||
toggle.isChecked = prefs.getBoolean(switchKey, switchPreferenceDefault)
|
toggle.isChecked = prefs.getBoolean(switchKey, switchPreferenceDefault)
|
||||||
}
|
}
|
||||||
super.onCreateOptionsMenu(menu, inflater)
|
super.onCreateOptionsMenu(menu, inflater)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSharedPreferenceChanged(preferences: SharedPreferences, key: String) {
|
protected open fun onSwitchPreferenceChanged(isChecked: Boolean) {
|
||||||
if (key == switchPreferenceKey) {
|
|
||||||
updatePreferenceScreen()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected val account: AccountDetails?
|
|
||||||
get() {
|
|
||||||
return arguments?.getParcelable(EXTRA_ACCOUNT)
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract val preferencesResource: Int
|
|
||||||
|
|
||||||
protected abstract val switchPreferenceDefault: Boolean
|
|
||||||
|
|
||||||
protected abstract val switchPreferenceKey: String?
|
|
||||||
|
|
||||||
private fun updatePreferenceScreen() {
|
private fun updatePreferenceScreen() {
|
||||||
val screen = preferenceScreen
|
val screen = preferenceScreen
|
||||||
|
|
|
@ -30,6 +30,7 @@ import edu.tsinghua.hotmobi.model.NetworkEvent
|
||||||
import org.mariotaku.kpreferences.get
|
import org.mariotaku.kpreferences.get
|
||||||
import org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME
|
import org.mariotaku.twidere.TwidereConstants.SHARED_PREFERENCES_NAME
|
||||||
import org.mariotaku.twidere.constant.usageStatisticsKey
|
import org.mariotaku.twidere.constant.usageStatisticsKey
|
||||||
|
import org.mariotaku.twidere.service.StreamingService
|
||||||
import org.mariotaku.twidere.util.DebugLog
|
import org.mariotaku.twidere.util.DebugLog
|
||||||
import org.mariotaku.twidere.util.Utils
|
import org.mariotaku.twidere.util.Utils
|
||||||
import org.mariotaku.twidere.util.dagger.DependencyHolder
|
import org.mariotaku.twidere.util.dagger.DependencyHolder
|
||||||
|
@ -50,7 +51,8 @@ class ConnectivityStateReceiver : BroadcastReceiver() {
|
||||||
val appContext = context.applicationContext
|
val appContext = context.applicationContext
|
||||||
val cm = appContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
val cm = appContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
|
||||||
val isNetworkMetered = ConnectivityManagerCompat.isActiveNetworkMetered(cm)
|
val isNetworkMetered = ConnectivityManagerCompat.isActiveNetworkMetered(cm)
|
||||||
DependencyHolder.get(context).mediaPreloader.isNetworkMetered = isNetworkMetered
|
val holder = DependencyHolder.get(context)
|
||||||
|
holder.mediaPreloader.isNetworkMetered = isNetworkMetered
|
||||||
val isCharging = Utils.isCharging(appContext)
|
val isCharging = Utils.isCharging(appContext)
|
||||||
if (!isNetworkMetered && isCharging) {
|
if (!isNetworkMetered && isCharging) {
|
||||||
val currentTime = System.currentTimeMillis()
|
val currentTime = System.currentTimeMillis()
|
||||||
|
@ -59,7 +61,7 @@ class ConnectivityStateReceiver : BroadcastReceiver() {
|
||||||
appContext.startService(Intent(appContext, UploadLogsService::class.java))
|
appContext.startService(Intent(appContext, UploadLogsService::class.java))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
StreamingService.startOrStopService(context)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -0,0 +1,43 @@
|
||||||
|
/*
|
||||||
|
* 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.receiver
|
||||||
|
|
||||||
|
import android.content.BroadcastReceiver
|
||||||
|
import android.content.Context
|
||||||
|
import android.content.Intent
|
||||||
|
import org.mariotaku.twidere.service.StreamingService
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mariotaku on 2017/3/13.
|
||||||
|
*/
|
||||||
|
|
||||||
|
class PowerStateReceiver : BroadcastReceiver() {
|
||||||
|
override fun onReceive(context: Context, intent: Intent) {
|
||||||
|
when (intent.action) {
|
||||||
|
Intent.ACTION_POWER_CONNECTED -> {
|
||||||
|
StreamingService.startOrStopService(context)
|
||||||
|
}
|
||||||
|
Intent.ACTION_POWER_DISCONNECTED -> {
|
||||||
|
StreamingService.startOrStopService(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -45,6 +45,8 @@ abstract class BaseService : Service() {
|
||||||
lateinit var taskServiceRunner: TaskServiceRunner
|
lateinit var taskServiceRunner: TaskServiceRunner
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var connectivityManager: ConnectivityManager
|
lateinit var connectivityManager: ConnectivityManager
|
||||||
|
@Inject
|
||||||
|
lateinit var activityTracker: ActivityTracker
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
super.onCreate()
|
super.onCreate()
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.mariotaku.twidere.util.DataStoreUtils
|
||||||
import org.mariotaku.twidere.util.DebugLog
|
import org.mariotaku.twidere.util.DebugLog
|
||||||
import org.mariotaku.twidere.util.IntentUtils
|
import org.mariotaku.twidere.util.IntentUtils
|
||||||
import org.mariotaku.twidere.util.Utils
|
import org.mariotaku.twidere.util.Utils
|
||||||
|
import org.mariotaku.twidere.util.dagger.DependencyHolder
|
||||||
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
import org.mariotaku.twidere.util.dagger.GeneralComponentHelper
|
||||||
import org.mariotaku.twidere.util.streaming.TwitterTimelineStreamCallback
|
import org.mariotaku.twidere.util.streaming.TwitterTimelineStreamCallback
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
@ -56,7 +57,9 @@ class StreamingService : BaseService() {
|
||||||
private val submittedTasks = WeakHashMap<UserKey, StreamingRunnable<*>>()
|
private val submittedTasks = WeakHashMap<UserKey, StreamingRunnable<*>>()
|
||||||
|
|
||||||
private val accountChangeObserver = OnAccountsUpdateListener {
|
private val accountChangeObserver = OnAccountsUpdateListener {
|
||||||
setupStreaming()
|
if (!setupStreaming()) {
|
||||||
|
stopSelf()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onCreate() {
|
override fun onCreate() {
|
||||||
|
@ -84,27 +87,31 @@ class StreamingService : BaseService() {
|
||||||
if (setupStreaming()) {
|
if (setupStreaming()) {
|
||||||
return START_STICKY
|
return START_STICKY
|
||||||
}
|
}
|
||||||
|
stopSelf()
|
||||||
return START_NOT_STICKY
|
return START_NOT_STICKY
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onBind(intent: Intent) = throw UnsupportedOperationException()
|
override fun onBind(intent: Intent) = throw UnsupportedOperationException()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return True if there're enabled accounts, false if request not met and service should be stopped
|
||||||
|
*/
|
||||||
private fun setupStreaming(): Boolean {
|
private fun setupStreaming(): Boolean {
|
||||||
|
if (!activityTracker.isHomeActivityLaunched) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
val isNetworkMetered = ConnectivityManagerCompat.isActiveNetworkMetered(connectivityManager)
|
val isNetworkMetered = ConnectivityManagerCompat.isActiveNetworkMetered(connectivityManager)
|
||||||
if (preferences[streamingNonMeteredNetworkKey] && isNetworkMetered) {
|
if (preferences[streamingNonMeteredNetworkKey] && isNetworkMetered) {
|
||||||
stopSelf()
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
val isCharging = Utils.isCharging(this)
|
val isCharging = Utils.isCharging(this)
|
||||||
if (preferences[streamingPowerSavingKey] && !isCharging) {
|
if (preferences[streamingPowerSavingKey] && !isCharging) {
|
||||||
stopSelf()
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
if (updateStreamingInstances()) {
|
if (updateStreamingInstances()) {
|
||||||
showNotification()
|
showNotification()
|
||||||
return true
|
return true
|
||||||
} else {
|
} else {
|
||||||
stopSelf()
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -339,6 +346,15 @@ class StreamingService : BaseService() {
|
||||||
|
|
||||||
private val NOTIFICATION_SERVICE_STARTED = 1
|
private val NOTIFICATION_SERVICE_STARTED = 1
|
||||||
|
|
||||||
|
fun startOrStopService(context: Context) {
|
||||||
|
val streamingIntent = Intent(context, StreamingService::class.java)
|
||||||
|
val holder = DependencyHolder.get(context)
|
||||||
|
if (holder.activityTracker.isHomeActivityLaunched) {
|
||||||
|
context.startService(streamingIntent)
|
||||||
|
} else {
|
||||||
|
context.stopService(streamingIntent)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Twidere - Twitter client for Android
|
||||||
|
*
|
||||||
|
* Copyright (C) 2012-2015 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.util
|
||||||
|
|
||||||
|
|
||||||
|
import android.app.Activity
|
||||||
|
import android.app.Application
|
||||||
|
import android.os.Bundle
|
||||||
|
import edu.tsinghua.hotmobi.HotMobiLogger
|
||||||
|
import edu.tsinghua.hotmobi.model.SessionEvent
|
||||||
|
import org.apache.commons.collections.primitives.ArrayIntList
|
||||||
|
import org.mariotaku.twidere.BuildConfig
|
||||||
|
import org.mariotaku.twidere.activity.HomeActivity
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Created by mariotaku on 15/10/5.
|
||||||
|
*/
|
||||||
|
class ActivityTracker : Application.ActivityLifecycleCallbacks {
|
||||||
|
|
||||||
|
private val internalStack = ArrayIntList()
|
||||||
|
|
||||||
|
private var sessionEvent: SessionEvent? = null
|
||||||
|
|
||||||
|
var isHomeActivityStarted: Boolean = false
|
||||||
|
private set
|
||||||
|
var isHomeActivityLaunched: Boolean = false
|
||||||
|
private set
|
||||||
|
|
||||||
|
private fun isSwitchingInSameTask(hashCode: Int): Boolean {
|
||||||
|
return internalStack.lastIndexOf(hashCode) < internalStack.size() - 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun size(): Int {
|
||||||
|
return internalStack.size()
|
||||||
|
}
|
||||||
|
|
||||||
|
val isEmpty: Boolean
|
||||||
|
get() = internalStack.isEmpty
|
||||||
|
|
||||||
|
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
|
||||||
|
if (activity is HomeActivity) {
|
||||||
|
isHomeActivityLaunched = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityStarted(activity: Activity) {
|
||||||
|
internalStack.add(System.identityHashCode(activity))
|
||||||
|
if (activity is HomeActivity) {
|
||||||
|
isHomeActivityStarted = true
|
||||||
|
}
|
||||||
|
// BEGIN HotMobi
|
||||||
|
if (sessionEvent == null && BuildConfig.HOTMOBI_LOG_ENABLED) {
|
||||||
|
sessionEvent = SessionEvent.create(activity)
|
||||||
|
}
|
||||||
|
// END HotMobi
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityResumed(activity: Activity) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityPaused(activity: Activity) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityStopped(activity: Activity) {
|
||||||
|
val hashCode = System.identityHashCode(activity)
|
||||||
|
if (activity is HomeActivity) {
|
||||||
|
isHomeActivityStarted = false
|
||||||
|
}
|
||||||
|
// BEGIN HotMobi
|
||||||
|
val event = sessionEvent
|
||||||
|
if (event != null && !isSwitchingInSameTask(hashCode)) {
|
||||||
|
event.markEnd()
|
||||||
|
HotMobiLogger.getInstance(activity).log(event, SessionEvent::dumpPreferences)
|
||||||
|
sessionEvent = null
|
||||||
|
}
|
||||||
|
// END HotMobi
|
||||||
|
|
||||||
|
internalStack.removeElement(hashCode)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onActivityDestroyed(activity: Activity) {
|
||||||
|
if (activity is HomeActivity && activity.isFinishing()) {
|
||||||
|
isHomeActivityLaunched = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue