Newer
Older
OverlayMultiCounter / app / src / main / kotlin / jackall / overlaymulticounter / service / MainService.kt
MatsumotoKeiju on 10 Nov 2017 8 KB [add] Main view model, Update Counter UI
package jackall.overlaymulticounter.service

import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.databinding.DataBindingUtil
import android.graphics.PixelFormat
import android.graphics.Point
import android.os.Build
import android.os.IBinder
import android.support.v4.app.NotificationCompat
import android.view.*
import jackall.overlaymulticounter.Const
import jackall.overlaymulticounter.R
import jackall.overlaymulticounter.activity.MainActivity
import jackall.overlaymulticounter.common.PreferenceKeys
import jackall.overlaymulticounter.common.PreferenceNames
import jackall.overlaymulticounter.contract.MainServiceContract
import jackall.overlaymulticounter.databinding.OverlayCounterBinding
import jackall.overlaymulticounter.utils.MySharedPref
import jackall.overlaymulticounter.viewmodel.OverlayCounterViewModel
import jackall.overlaymulticounter.viewmodel.OverlayViewModel
import kotlinx.android.synthetic.main.overlay_move.view.*

/**
 * Created by matsumoto_k on 2017/11/08.
 */
class MainService : Service(), MainServiceContract {

    val mySharedPref by lazy { MySharedPref(this, PreferenceNames.CONFIG) }

    val overlayMoveView: ViewGroup by lazy { LayoutInflater.from(this).inflate(R.layout.overlay_move, null) as ViewGroup }
    val counterBinding by lazy {
        DataBindingUtil.inflate<OverlayCounterBinding>(LayoutInflater.from(this), R.layout.overlay_counter, null, false)
    }
    var overlayMoveViewParams: WindowManager.LayoutParams? = null
    var overlayCounterViewParams: WindowManager.LayoutParams? = null
    val overlayViewModel by lazy { OverlayViewModel(this as MainServiceContract) }
    val overlayCounterViewModel by lazy { OverlayCounterViewModel() }
    val windowManager: WindowManager by lazy { applicationContext.getSystemService(Context.WINDOW_SERVICE) as WindowManager }
    val displaySize: Point by lazy {
        val display = windowManager.defaultDisplay
        val size = Point()
        display.getSize(size)
        size
    }
    var isLongClick: Boolean = false


    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        val notificationBuilder = NotificationCompat.Builder(this, Const.serviceChannelId)
                .setSmallIcon(R.mipmap.ic_launcher) // TODO:白抜きのアイコンをセット
        notificationBuilder.setContentIntent(PendingIntent.getActivity(this, 0, Intent(this, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT))
        startForeground(Const.serviceNotificationId, notificationBuilder.build())

        setMoveViewConfig()
        setCounterViewConfig()
        showMoveView()

        return START_STICKY
    }

    override fun showMoveView() {
        overlayMoveViewParams?.x = mySharedPref.getValue(PreferenceKeys.VIEWX, Int::class.java, 0) as Int
        overlayMoveViewParams?.y = mySharedPref.getValue(PreferenceKeys.VIEWY, Int::class.java, 0) as Int

        if (counterBinding.root.isShown) {
            windowManager.removeView(counterBinding.root)
        }

        windowManager.addView(overlayMoveView, overlayMoveViewParams)
    }

    override fun showCounterView() {
        if (overlayMoveView.isShown) {
            windowManager.removeView(overlayMoveView)
        }

        windowManager.addView(counterBinding.root, overlayCounterViewParams)
    }

    fun setMoveViewConfig() {
        overlayMoveView.apply(setMoveViewClickListener())

        if (Build.VERSION.SDK_INT >= 26) {
            overlayMoveViewParams = WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
                            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                    PixelFormat.TRANSLUCENT)
        } else {
            overlayMoveViewParams = WindowManager.LayoutParams(
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.WRAP_CONTENT,
                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                    WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or
                            WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
                            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                    PixelFormat.TRANSLUCENT)
        }
    }

    fun setCounterViewConfig() {
        if (Build.VERSION.SDK_INT >= 26) {
            overlayCounterViewParams = WindowManager.LayoutParams(
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
                            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                    PixelFormat.TRANSLUCENT)
        } else {
            overlayCounterViewParams = WindowManager.LayoutParams(
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.MATCH_PARENT,
                    WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
                    WindowManager.LayoutParams.FLAG_LAYOUT_IN_SCREEN or
                            WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL or
                            WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
                    PixelFormat.TRANSLUCENT)
        }
        counterBinding.overlayViewModel = overlayViewModel
        counterBinding.counterViewModel = overlayCounterViewModel
        overlayCounterViewParams?.gravity = Gravity.TOP
    }

    private fun setMoveViewClickListener(): View.() -> Unit {
        return {
            setOnLongClickListener { view ->
                isLongClick = true
                view.move_button.alpha = Const.moveButtonActiveAlpha
                false
            }.apply {
                setOnTouchListener { view, motionEvent ->

                    val x = motionEvent.rawX.toInt()
                    val y = motionEvent.rawY.toInt()

                    when (motionEvent.action) {

                        MotionEvent.ACTION_MOVE -> {
                            if (isLongClick) {

                                val centerX = x - (displaySize.x / 2)
                                val centerY = y - (displaySize.y / 2)

                                overlayMoveViewParams?.x = centerX
                                overlayMoveViewParams?.y = centerY

                                windowManager.updateViewLayout(overlayMoveView, overlayMoveViewParams)
                            }
                        }

                        MotionEvent.ACTION_UP -> {
                            if (isLongClick) {
                                view.move_button.alpha = Const.moveButtonInactiveAlpha
                                mySharedPref.putValue(PreferenceKeys.VIEWX, Int::class.java, overlayMoveViewParams?.x ?: 0)
                                mySharedPref.putValue(PreferenceKeys.VIEWY, Int::class.java, overlayMoveViewParams?.y ?: 0)
                            } else {
                                showCounterView()
                            }
                            isLongClick = false
                        }
                    }
                    false
                }
            }
        }
    }

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

    override fun onDestroy() {
        super.onDestroy()
        if (overlayMoveView.isShown) {
            windowManager.removeView(overlayMoveView)
        }
        if (counterBinding.root.isShown) {
            windowManager.removeView(counterBinding.root)
        }
        overlayCounterViewModel.onDestory()
    }

    override fun finish() {
        stopSelf()
    }
}