Skip to content

Commit

Permalink
Merge pull request #449 from mapzen/280-kill-notifications
Browse files Browse the repository at this point in the history
280 kill notifications
  • Loading branch information
ecgreb committed Mar 4, 2016
2 parents 23d93f5 + 02101a1 commit c63d175
Show file tree
Hide file tree
Showing 10 changed files with 110 additions and 18 deletions.
11 changes: 6 additions & 5 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,14 @@
android:name=".view.InitActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".util.NotificationBroadcastReceiver"/>
<service android:name=".service.NotificationService"/>
</application>

</manifest>
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ public open class MainPresenterImpl(val mapzenLocation: MapzenLocation, val bus:
}

@Subscribe public fun onRouteCancelEvent(event: RouteCancelEvent) {
onBackPressed()
mainViewController?.onBackPressed()
}

override fun updateLocation() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
@file:JvmName("NotificationService")
package com.mapzen.erasermap.service

import android.app.Service
import android.content.Intent
import android.os.Binder
import android.os.IBinder

/**
* Stub service to facilitate killing notification when app is killed from app tray
*/
class NotificationService : Service() {

internal var binder: IBinder = NotificationBinder(this)

override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
return Service.START_STICKY
}

override fun onBind(intent: Intent): IBinder? {
return binder
}

class NotificationBinder(val service: NotificationService) : Binder()
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,19 @@
package com.mapzen.erasermap.util

import com.mapzen.erasermap.R

import android.app.Activity
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
import android.content.SharedPreferences
import android.os.IBinder
import android.preference.PreferenceManager
import android.support.v4.app.NotificationCompat
import android.support.v4.app.TaskStackBuilder
import com.mapzen.erasermap.R
import com.mapzen.erasermap.service.NotificationService
import com.mapzen.erasermap.view.MainActivity

public class NotificationCreator(private val mainActivity: Activity) {
Expand All @@ -19,24 +24,46 @@ public class NotificationCreator(private val mainActivity: Activity) {
private var exitNavigationIntent: Intent? = null
private var pendingNotificationIntent: PendingIntent? = null
private var pendingExitNavigationIntent: PendingIntent? = null
private val mNotificationManager: NotificationManager
private val notificationManager: NotificationManager
private val serviceConnection: NotificationServiceConnection
private val preferences: SharedPreferences
private val serviceIntent: Intent

companion object {
val EXIT_NAVIGATION = "exit_navigation"
val NOTIFICATION_TAG_ROUTE = "route"
}

init {
mNotificationManager = mainActivity.getSystemService(
notificationManager = mainActivity.getSystemService(
Context.NOTIFICATION_SERVICE) as NotificationManager
serviceConnection = NotificationServiceConnection(mainActivity)
preferences = PreferenceManager.getDefaultSharedPreferences(mainActivity)
serviceIntent = Intent(mainActivity, NotificationService::class.java)
}

/**
* All notifications created through this class should be killed using the
* {@link NotificationCreator#killNotification()}, do not call
* {@link NotificationManager#cancelAll()} directly
*
* Before we create a notification, we bind to a stub service so that when app is killed
* {@link MainActivity#onDestroy} is reliably called. This triggers a
* call to {@link NotificationCreator#killNotification} which removes notification from manager
*/
fun createNewNotification(title: String, content: String) {
initBuilder(title, content)
initBigTextStyle(title, content)
builder?.setStyle(bigTextStyle)
initNotificationIntent()
initExitNavigationIntent()
initStackBuilder(notificationIntent)
builder?.addAction(R.drawable.ic_dismiss, "Exit Navigation", pendingExitNavigationIntent)
builder?.addAction(R.drawable.ic_dismiss, mainActivity.getString(R.string.exit_navigation),
pendingExitNavigationIntent)
builder?.setContentIntent(PendingIntent.getActivity(
mainActivity.applicationContext, 0, notificationIntent, 0))
mNotificationManager.notify("route", 0, builder!!.build())
mainActivity.bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE)
notificationManager.notify(NOTIFICATION_TAG_ROUTE, 0, builder!!.build())
}

private fun initExitNavigationIntent() {
Expand Down Expand Up @@ -77,11 +104,34 @@ public class NotificationCreator(private val mainActivity: Activity) {
}

public fun killNotification() {
val notificationManager = mainActivity.getSystemService(Activity.NOTIFICATION_SERVICE) as NotificationManager
notificationManager.cancelAll()
serviceConnection.service?.stopService(serviceIntent)
}

companion object {
val EXIT_NAVIGATION = "exit_navigation"
/**
* In charge of starting the stub service we bind to
*/
private class NotificationServiceConnection: ServiceConnection {

public val activity: Activity
public var service: NotificationService? = null

constructor(activity: Activity) {
this.activity = activity
}

override fun onServiceConnected(component: ComponentName?, inBinder: IBinder?) {
if (inBinder == null) {
return
}
val binder = inBinder as NotificationService.NotificationBinder
val intent: Intent = Intent(activity, NotificationService::class.java)
this.service = binder.service
binder.service?.startService(intent)
}

override fun onServiceDisconnected(component: ComponentName?) {
}

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@ public class MainActivity : AppCompatActivity(), MainViewController, RouteCallba
saveCurrentSearchTerm()
routeModeView.clearRoute()
findMe?.clear()
killNotifications()
}

private fun initMapController() {
Expand Down Expand Up @@ -946,9 +947,13 @@ public class MainActivity : AppCompatActivity(), MainViewController, RouteCallba
startNavigationButton.setOnClickListener({ presenter?.onClickStartNavigation() })
}

private fun killNotifications() {
routeModeView.notificationCreator?.killNotification()
}

override fun onBackPressed() {
if(findViewById(R.id.route_mode).visibility == View.VISIBLE) {
routeModeView.notificationCreator?.killNotification()
killNotifications()
}
presenter?.onBackPressed()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,5 @@ public interface MainViewController {
public fun drawTappedPoiPin()
public fun hideSettingsBtn()
public fun showSettingsBtn()
public fun onBackPressed()
}
1 change: 1 addition & 0 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
<string name="resume">Resume</string>
<string name="view_list">View List</string>
<string name="start_navigation">Start Navigation</string>
<string name="exit_navigation">Exit Navigation</string>
<string name="destination">Destination</string>
<string name="osm_attribution">Map data © OpenStreetMap</string>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import org.robolectric.shadows.ShadowApplication
import java.util.ArrayList

@RunWith(PrivateMapsTestRunner::class)
@Config(constants = BuildConfig::class, sdk=intArrayOf(21))
@Config(constants = BuildConfig::class, sdk = intArrayOf(21))
public class MainActivityTest {
val activity = Robolectric.setupActivity<MainActivity>(MainActivity::class.java)
val locationManager = activity.getSystemService(LOCATION_SERVICE) as LocationManager
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -471,8 +471,12 @@ public class MainPresenterTest {
}

@Test fun onRouteCancelEvent_shouldPopBackStack() {
vsm.viewState = ROUTING
mainController.popBackStack = false
presenter.onRouteCancelEvent(RouteCancelEvent())
assertThat(mainController.popBackStack).isTrue()

vsm.viewState = ROUTING
presenter.onBackPressed()
assertThat(vsm.viewState).isEqualTo(ROUTE_PREVIEW)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public class TestMainController : MainViewController {
public var isReverseGeocodeVisible: Boolean = false
public var isPlaceResultOverridden: Boolean = false
public var isSettingsVisible: Boolean = false
public var popBackStack: Boolean = false

override fun showSearchResults(features: List<Feature>) {
searchResults = features
Expand Down Expand Up @@ -184,4 +185,8 @@ public class TestMainController : MainViewController {
override fun showSettingsBtn() {
isSettingsVisible = true
}

override fun onBackPressed() {
popBackStack = true
}
}

0 comments on commit c63d175

Please sign in to comment.