Coder Social home page Coder Social logo

overlay-service's People

Contributors

saeed-younus avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

overlay-service's Issues

How to launch new Activity from FrameLayout

I try to study overlay library for kotlin applications https://github.com/KoderLabs/overlay-service. Right now I have a problem related with opening a new activity from a button which is located inside a FrameLayout class.
So, the task is push on button on Main Activity -> open new overlay small window and roll up Main Activity -> push on button inside a small window -> open new Activity.
In this code nothing happens after the clicking on button.
The project include main 3 classes:

  1. MainActivity

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    btn_simple_pip.setOnClickListener {
        checkDrawOverlayPermission(IMPLEMENTED_PIP_OVERLAY_REQUEST_CODE)
        finishAffinity()
    }

}

private fun checkDrawOverlayPermission(code: Int) {
    if (Build.VERSION.SDK_INT >= 23) {
        if (!Settings.canDrawOverlays(this)) {
            val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION, Uri.parse("package:$packageName"))
            startActivityForResult(intent, IMPLEMENTED_PIP_OVERLAY_REQUEST_CODE)
        } else {
            openFloatingWindow(code)
        }
    } else {
        openFloatingWindow(code)
    }
}

private fun openFloatingWindow(code: Int) {
    when (code) {
        IMPLEMENTED_PIP_OVERLAY_REQUEST_CODE -> {
            val intent = Intent(this, ImplementPipOverlayService::class.java)
            val videoUrl =
                "https://s3.amazonaws.com/data.development.momentpin.com/2019/7/3/1562152168485485-0661a550-9d83-11e9-9028-d7af09cf782e.mp4"
            val notificationTitle = "Pip Overlay"
            val notificationDescription = "Pip overlay description"
            val notificationIcon = R.drawable.ic_launcher_foreground
            val closeBtnColor = android.R.color.black
            val closeBtnBgColor = android.R.color.transparent
            intent.putExtra(ImplementPipOverlayService.KEY_STRING_VIDEO_URL, videoUrl)
            intent.putExtra(ImplementPipOverlayService.KEY_STRING_NOTIFICATION_DESCRIPTION, notificationDescription)
            intent.putExtra(ImplementPipOverlayService.KEY_STRING_NOTIFICATION_TITLE, notificationTitle)
            intent.putExtra(ImplementPipOverlayService.KEY_INT_NOTIFICATION_ICON, notificationIcon)
            intent.putExtra(ImplementPipOverlayService.KEY_INT_CLOSE_BUTTON_COLOR, closeBtnColor)
            intent.putExtra(ImplementPipOverlayService.KEY_INT_CLOSE_BUTTON_BG_COLOR, closeBtnBgColor)
            ContextCompat.startForegroundService(this, intent)
        }
    }
}

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    when (requestCode) {
        IMPLEMENTED_PIP_OVERLAY_REQUEST_CODE, RESIZEABLE_CUSTOM_WEB_OVERLAY_REQUEST_CODE,
        PIP_OVERLAY_REQUEST_CODE, RESIZEABLE_CUSTOM_VIDEO_OVERLAY_REQUEST_CODE -> {
            if (Build.VERSION.SDK_INT >= 23) {
                if (Settings.canDrawOverlays(this)) {
                    openFloatingWindow(requestCode)
                }
            } else {
                openFloatingWindow(requestCode)
            }
        }
    }
    super.onActivityResult(requestCode, resultCode, data)
}

companion object {
    const val IMPLEMENTED_PIP_OVERLAY_REQUEST_CODE = 251
    const val PIP_OVERLAY_REQUEST_CODE = 252
    const val RESIZEABLE_CUSTOM_VIDEO_OVERLAY_REQUEST_CODE = 253
    const val RESIZEABLE_CUSTOM_WEB_OVERLAY_REQUEST_CODE = 254
}
  1. ImplementPipOverlayService

    class ImplementPipOverlayService : PipOverlayService() {
    
    var videoUrl: String? = null
    var notificationTitle: String? = null
    var notificationDescription: String? = null
    var notificationIcon: Int? = null
    var closeButtonColor: Int? = null
    var closeButtonBg: Int? = null
    
    override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
        videoUrl = intent?.getStringExtra(KEY_STRING_VIDEO_URL)
        notificationTitle = intent?.getStringExtra(KEY_STRING_NOTIFICATION_TITLE)
        notificationDescription = intent?.getStringExtra(KEY_STRING_NOTIFICATION_DESCRIPTION)
        notificationIcon = intent?.getIntExtra(KEY_INT_NOTIFICATION_ICON, -1)
        closeButtonColor = intent?.getIntExtra(KEY_INT_CLOSE_BUTTON_COLOR, -1)
        closeButtonBg = intent?.getIntExtra(KEY_INT_CLOSE_BUTTON_BG_COLOR, -1)
        return super.onStartCommand(intent, flags, startId)
    }
    
    override fun getForegroundNotification(): Notification {
        val channelId =
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                    createNotificationChannel("my_service", "My Background Service")
                } else {
                    packageName
                }
        var notificationBuilder = NotificationCompat.Builder(this, channelId)
    
        notificationBuilder = notificationTitle?.let {
            notificationBuilder.setContentTitle(it)
        } ?: run {
            notificationBuilder.setContentTitle("Title")
        }
        notificationDescription?.let {
            notificationBuilder = notificationBuilder.setContentText(it)
        }
        notificationIcon?.let {
            notificationBuilder = notificationBuilder.setSmallIcon(it)
        }
    
        val notification: Notification = notificationBuilder.build()
        return notification
    }
    
    @RequiresApi(Build.VERSION_CODES.O)
    private fun createNotificationChannel(channelId: String, channelName: String): String {
        val chan = NotificationChannel(channelId,
                channelName, NotificationManager.IMPORTANCE_NONE)
        chan.lightColor = Color.BLUE
        chan.lockscreenVisibility = Notification.VISIBILITY_PRIVATE
        val service = getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
        service.createNotificationChannel(chan)
        return channelId
    }
    
    override fun getInitialWindowSize(): Point {
        return Point(100.toDp(), 100.toDp())
    }
    
    override fun getCustomLayoutId(): Int {
        return R.layout.pip_layout
    }
    
    override fun onServiceRun() {
        setOnEventListener(onFullscreen = {
            // Not implemented
        }, onClosed = {
            // Not implemented
        })
    
        pipView.removeFullscreenButton()
    
        closeButtonColor?.let {
            pipView.getCloseButton().setColorFilter(it)
        }
    
        closeButtonBg?.let {
            pipView.getCloseButton().setBackgroundColor(it)
        }
        
    }
    
    
    companion object {
        const val KEY_STRING_VIDEO_URL = "video_url"
        const val KEY_INT_CLOSE_BUTTON_COLOR = "close_button_color"
        const val KEY_INT_CLOSE_BUTTON_BG_COLOR = "close_button_background"
        const val KEY_STRING_NOTIFICATION_TITLE = "notification_title"
        const val KEY_STRING_NOTIFICATION_DESCRIPTION = "notification_description"
        const val KEY_INT_NOTIFICATION_ICON = "notification_icon"
    }
    
  2. OverlayPipCustomView

class OverlayPipCustomView : FrameLayout {
private lateinit var constraintsRoot: ConstraintLayout
private lateinit var imageFullscreenButton: ImageView
private lateinit var imageCloseButton: ImageView
private lateinit var customLayoutContent: FrameLayout
private lateinit var customView: View
private lateinit var touchView: View
private lateinit var button: Button

private var playerViewSize: Int = 0
private var sizeChangeable: Boolean = true
private var playerType: Int = 0

private var haveFullscreen = true
/**
 * Tracks if viewResizeable is fullscreen.
 */
private var fullscreenOn: Boolean = false
val isDraggable: Boolean
    get() {
        return !fullscreenOn
    }

private var onFullscreen: () -> Unit = {}
private var onClosed: () -> Unit = {}

private var canHideActionButtons = true
private val hideActionHandler = Handler()
private val HIDE_ACTION_DURATION = 2000L
private val hideActionRunnable = Runnable {
    if (!isMoving) {
        hideActions()
    }
}

var isMoving: Boolean = false

constructor(ctx: Context) : super(ctx) {
    inflate(context, R.layout.layout_pip_custom_view, this)
    initView()
}

constructor(ctx: Context, attrs: AttributeSet) : super(ctx, attrs) {
    setAttributes(attrs)
    inflate(context, R.layout.layout_pip_custom_view, this)
    initView()
}

constructor(ctx: Context, attrs: AttributeSet, defStyle: Int) : super(ctx, attrs, defStyle) {
    setAttributes(attrs)
    inflate(context, R.layout.layout_pip_custom_view, this)
    initView()
}

private fun setAttributes(attrs: AttributeSet) {
    context.theme.obtainStyledAttributes(
            attrs,
            R.styleable.OverlayCustomView,
            0, 0).apply {
        try {
            playerViewSize = getInteger(R.styleable.OverlayCustomView_ov_player_size, 0)
            playerType = getInteger(R.styleable.OverlayCustomView_ov_size_changeable, 0)
            sizeChangeable = getBoolean(R.styleable.OverlayCustomView_ov_size_changeable, true)
        } finally {
            recycle()
        }
    }

    doOnLayout {
        startHideAction()
    }
}

private fun initView() {
    button = findViewById(R.id.button)
    constraintsRoot = findViewById(R.id.constraints_root)
    imageFullscreenButton = findViewById(R.id.image_screen_action)
    imageCloseButton = findViewById(R.id.image_close)
    customLayoutContent = findViewById(R.id.custom_view)
    touchView = findViewById(R.id.touch_view)

    setListeners()
}

fun addCustomView(view: View) {
    customLayoutContent.addView(view)
}

fun addCustomView(layoutId: Int) {
    customView = inflate(context, layoutId, null)
    customLayoutContent.addView(customView)
}

fun getCloseButton() = imageCloseButton
fun getConstraintsRoot() = constraintsRoot
fun getCustomLayoutContent() = customLayoutContent
fun getCustomView() = customView
fun getFullscreenButton() = imageFullscreenButton
fun getTouchView() = touchView

fun removeFullscreenButton() {
    haveFullscreen = false
    imageFullscreenButton.invisible()
}


private fun setListeners() {
    imageFullscreenButton.setOnClickListener {
        onFullscreen.invoke()
    }

    button.setOnClickListener{
        println("pressed")
        fun alert(context: Context, text: String) {
            val intent = Intent(context, MainActivity2::class.java)
            intent.putExtra("text", text)
            context.startActivity(intent)
        }
    }


    imageCloseButton.setOnClickListener {
        onClosed.invoke()
    }
}

fun setOnEventActionListener(
        onFullscreen: () -> Unit,
        onClosed: () -> Unit
) {
    this.onFullscreen = onFullscreen
    this.onClosed = onClosed
}

private fun startHideAction() {
    if (canHideActionButtons) {
        hideActionHandler.postDelayed(hideActionRunnable, HIDE_ACTION_DURATION)
    }
}

fun restartHideAction() {
    hideActionHandler.removeCallbacks(hideActionRunnable)
    if (canHideActionButtons) {
        hideActionHandler.postDelayed(hideActionRunnable, HIDE_ACTION_DURATION)
    }
}

fun hideActions() {
    if (canHideActionButtons) {
        imageCloseButton.invisible()
        if (haveFullscreen) {
            imageFullscreenButton.invisible()
        }
    }
}

fun showActions() {
    imageCloseButton.visible()
    if (haveFullscreen) {
        imageFullscreenButton.visible()
    }
}

}

In third class I can't understand what should be placed here to to change initial first Activity to another one

    button.setOnClickListener{
        println("pressed")
        fun alert(context: Context, text: String) {
            val intent = Intent(context, MainActivity2::class.java)
            intent.putExtra("text", text)
            context.startActivity(intent)
        }
    }

enter image description here

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.