Làm sao để chạy hai service cùng lúc

Chào mọi người em đang sử dụng mediaproject để làm hai công việc là chụp màn hình và ghi âm thanh từ loa,khi em bắt đầu ghi màn hình thì hoạt động ghi âm tắt và ngược lại. Có lẽ vì em đã gọi if cho mỗi request code vậy có cách nào để cả hai hoạt động cùng chạy không ạ. Đây là code em gọi hai service với REQUEST_CODEMEDIA_PROJECTION_REQUEST_CODE:

class MainActivity : AppCompatActivity() {
    companion object{
        private val REQUEST_CODE = 100
        private const val RECORD_AUDIO_PERMISSION_REQUEST_CODE = 42
        private const val MEDIA_PROJECTION_REQUEST_CODE = 13}
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        title = "Endless Service"

        findViewById<Button>(R.id.btnStartService).let {
            it.setOnClickListener {
                log("START THE FOREGROUND SERVICE ON DEMAND")
                startCapturing()
            }
        }

        findViewById<Button>(R.id.btnStopService).let {
            it.setOnClickListener {
                log("STOP THE FOREGROUND SERVICE ON DEMAND")
                stopCapturing()
                stopProjection()
            }
        }

        // start projection
        val startButton =
            findViewById<Button>(R.id.startButton)
        startButton.setOnClickListener { startProjection() }


    }
    private fun startCapturing() {
        if (!isRecordAudioPermissionGranted()) {
            requestRecordAudioPermission()
        } else {
            startMediaProjectionRequest()
        }
    }
    private fun requestRecordAudioPermission() {
        ActivityCompat.requestPermissions(
            this,
            arrayOf(Manifest.permission.RECORD_AUDIO),
            RECORD_AUDIO_PERMISSION_REQUEST_CODE
        )
    }
    private fun isRecordAudioPermissionGranted(): Boolean {
        return ContextCompat.checkSelfPermission(
            this,
            Manifest.permission.RECORD_AUDIO
        ) == PackageManager.PERMISSION_GRANTED
    }
    private fun startMediaProjectionRequest() {
        mediaProjectionManager =
            applicationContext.getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        startActivityForResult(
            mediaProjectionManager.createScreenCaptureIntent(),
            MEDIA_PROJECTION_REQUEST_CODE
        )
    }
    override fun onActivityResult(
        requestCode: Int,
        resultCode: Int,
        data: Intent?
    ) {
        if (requestCode == com.robertohuertas.endless.MainActivity.REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                startService(
                    com.robertohuertas.endless.ScreenCaptureService.getStartIntent(
                        this,
                        resultCode,
                        data
                    )
                )
            }
        }
        if (requestCode == MEDIA_PROJECTION_REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                Toast.makeText(
                    this,
                    "MediaProjection permission obtained. Foreground service will be started to capture audio.",
                    Toast.LENGTH_SHORT
                ).show()

                val audioCaptureIntent = Intent(this, EndlessService::class.java).apply {
                    action = EndlessService.ACTION_START
                    putExtra(EndlessService.EXTRA_RESULT_DATA, data!!)
                }
                startService(audioCaptureIntent)

                setButtonsEnabled(isCapturingAudio = true)
            } else {
                Toast.makeText(
                    this, "Request to obtain MediaProjection denied.",
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
    }
    private fun startProjection() {
        val mProjectionManager =
            getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        startActivityForResult(
            mProjectionManager.createScreenCaptureIntent(),
            com.robertohuertas.endless.MainActivity.REQUEST_CODE
        )
    }
    private fun stopProjection() {
        startService(com.robertohuertas.endless.ScreenCaptureService.getStopIntent(this))
    }
    private fun setButtonsEnabled(isCapturingAudio: Boolean) {
        findViewById<Button>(R.id.btnStartService).isEnabled = !isCapturingAudio
        findViewById<Button>(R.id.btnStopService).isEnabled = isCapturingAudio
    }
    private fun stopCapturing() {
        setButtonsEnabled(isCapturingAudio = false)

        startService(Intent(this, EndlessService::class.java).apply {
            action = EndlessService.ACTION_STOP
        })
    }
}

A post was merged into an existing topic: Topic lưu trữ các post off-topic - version 3

Hi there,

Tớ không phải chuyên gia về mobile nên không thể nói cậu có thể chạy 2 hoạt động đó cùng lúc không, nhưng best bet của cậu có lẽ là spawn 2 thread để chạy 2 hoạt động đó cùng lúc.
Tuy nhiên, cậu sẽ có thể gặp vấn đề hệ điều hành không cho phép app của cậu làm 1 lúc 2 việc, nhưng đó sẽ là vấn đề sau khi cậu thất bại khi spawn 2 thread như đề cập ở trên.

Hope it helps!

5 Likes

Vấn đề là khi dịch vụ tắt do HĐH hay do bạn, nếu do HĐH tắt thì tức là không cho phép bạn cùng lúc thực hiện 2 thao tác.
Ngược lại bạn xem xét lại có chỗ nào bạn vô tình tắt không.

Thử qua các ứng dụng ghi màn hình thì Android cho phép ghi (chiếu) màn hình và âm thanh (kể cả từ mic) cùng 1 lúc.
Bạn nên xem lại.

4 Likes

Cảm ơn bạn đã trả lời, khi mình thu âm từ mic và chụp màn hình thì hai hoạt động này thực hiện cùng lúc được,lúc đó mình đặt nó ở hai hàm khác nhau, nhưng bây giời mình thu âm từ loa thì phải dùng mediaproject như chụp ảnh màn hình và đó là cách bắt đầu service mình tìm được và có lẽ vì đặt code như vậy nên nó chỉ chạy được một cái if không biết có cách nào khác để bắt đầy service mediaproject không ạ(thông tin đầu vào yêu cầu requestcode,intent?,resultcode như hàm onActivityResult), xin lỗi vì mình không chuyên về android và mình đang có hack mọi thứ để tạo ra một ứng dụng mong bạn có thể hiểu cách diễn dải của mình. Đây là đoạn code trước ghi âm từ mic và chụp màn hình:

class MainActivity : AppCompatActivity() {
    lateinit var compName: ComponentName
    lateinit var deviceManger: DevicePolicyManager
    companion object{
        private val REQUEST_CODE = 100}
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        title = "Endless Service"

        findViewById<Button>(R.id.btnStartService).let {
            it.setOnClickListener {
                log("START THE FOREGROUND SERVICE ON DEMAND")
                actionOnService(Actions.START)
            }
        }

        findViewById<Button>(R.id.btnStopService).let {
            it.setOnClickListener {
                log("STOP THE FOREGROUND SERVICE ON DEMAND")
                actionOnService(Actions.STOP)
                stopProjection()
            }
        }

        // start projection
        val startButton =
            findViewById<Button>(R.id.startButton)
        startButton.setOnClickListener { startProjection() }

        // stop projection

        // stop projection
//        val stopButton = findViewById<Button>(R.id.stopButton)
//        stopButton.setOnClickListener { stopProjection() }
    }

    private fun actionOnService(action: Actions) {
        if (getServiceState(this) == ServiceState.STOPPED && action == Actions.STOP) return
        deviceManger=getSystemService(DEVICE_POLICY_SERVICE) as DevicePolicyManager
        compName= ComponentName(this, DeviceAdmin::class.java)


        Intent(this, EndlessService::class.java).also {
            it.action = action.name
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                log("Starting the service in >=26 Mode")
                startForegroundService(it)
                val permission = Manifest.permission.RECORD_AUDIO

                val intent=Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
                intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, compName)
                intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "If you only activate, this app can perform screen off !!!")
                startActivity(intent)

                if (checkSelfPermission(permission) != PackageManager.PERMISSION_GRANTED) {
                    ActivityCompat.requestPermissions(this, arrayOf(permission), 3)
                    return
                }
            log("Starting the service in < 26 Mode")

            startService(it)
            }
        }
    }
    override fun onActivityResult(
        requestCode: Int,
        resultCode: Int,
        data: Intent?
    ) {
        if (requestCode == com.robertohuertas.endless.MainActivity.REQUEST_CODE) {
            if (resultCode == Activity.RESULT_OK) {
                startService(
                    com.robertohuertas.endless.ScreenCaptureService.getStartIntent(
                        this,
                        resultCode,
                        data
                    )
                )
            }
        }
    }
    private fun startProjection() {
        val mProjectionManager =
            getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
        startActivityForResult(
            mProjectionManager.createScreenCaptureIntent(),
            com.robertohuertas.endless.MainActivity.REQUEST_CODE
        )
    }
    private fun stopProjection() {
        startService(com.robertohuertas.endless.ScreenCaptureService.getStopIntent(this))
    }

}```

actionOnService để bắt đầu ghi từ mic, onActivityResult để bắt đầu chụp màn hình.

Cảm ơn bạn đã trả lời mình. Mình nghĩ vấn đề ở phần logic code @@ mình đang cố hack mọi thứ mà không có kiến thức.

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?