使用Kotlin或Java在我的活动中访问InCallService或其他Android系统服务

时间:2019-07-15 08:34:13

标签: java android kotlin

我的应用程序是电话拨号程序用户界面。我想使麦克风静音。因此,我需要执行类似InCallService.setMuted(true)的操作,但是我无法访问此android“系统”服务?问题是我无法访问Android系统服务。

这是代码:

Manifest file:

    <application
      android:allowBackup="true"
      android:icon="@mipmap/ic_launcher"
      android:label="@string/app_name"
      android:roundIcon="@mipmap/ic_launcher_round"
      android:supportsRtl="true"
      android:theme="@style/AppTheme">
    <activity android:name="MainActivity">
      <intent-filter>
        <action android:name="android.intent.action.MAIN"/>

        <category android:name="android.intent.category.LAUNCHER"/>
      </intent-filter>

      <intent-filter>
        <action android:name="android.intent.action.VIEW"/>
        <action android:name="android.intent.action.DIAL"/>

        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.BROWSABLE"/>

        <data android:scheme="tel"/>
      </intent-filter>
      <intent-filter>
        <action android:name="android.intent.action.DIAL"/>

        <category android:name="android.intent.category.DEFAULT"/>
      </intent-filter>

    </activity>

    <activity
        android:name=".CallActivity"
        android:theme="@style/AppTheme.CallScreen"/>

    <service
        android:name=".CallService"
        android:permission="android.permission.BIND_INCALL_SERVICE">
      <meta-data
          android:name="android.telecom.IN_CALL_SERVICE_UI"
          android:value="true"/>

      <intent-filter>
        <action android:name="android.telecom.InCallService"/>
      </intent-filter>
    </service>

  </application>

</manifest>
</code>

<code>

class CallActivity : AppCompatActivity() {

    companion object {
        private const val LOG_TAG = "CallActivity"
    }

    private var updatesDisposable = Disposables.empty()
    private var timerDisposable = Disposables.empty()

    private var inCallService: InCallService? = null

/* A VER2
// Variable to hold service class name
val serviceClass = CallService::class.java

// Initialize a new Intent instance
val intentService = Intent(applicationContext, serviceClass)

* /

private val myConnection = object : ServiceConnection {
    override fun onServiceConnected(className: ComponentName, service: IBinder) {
        val binder = service as CallService.CallBinder
        inCallService = binder.getService()
        Log.i("SERV_BOUND", "Service in Call Bound!")

    }

    override fun onServiceDisconnected(name: ComponentName) {
        Log.i("SERV_UNBOUND", "Service in Call Unbound!")
    }
}



//    val inCallService: InCallService = getSystemService(Context.TELECOM_SERVICE)


    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
//        audioManager = getSystemService(Context.AUDIO_SERVICE) as AudioManager
        setContentView(R.layout.activity_call)

        val intent = Intent(this, CallService::class.java)

        hideBottomNavigationBar()

        buttonHangup.setOnClickListener { CallManager.cancelCall() }
        buttonAnswer.setOnClickListener { CallManager.acceptCall() }
        buttonMute.setOnClickListener { muteCall() }
    }


    override fun onResume() {
        super.onResume()
        updatesDisposable = CallManager.updates()
                .doOnEach { Log.i(LOG_TAG, "updated call: $it") }
                .doOnError { throwable -> Log.e(LOG_TAG, "Error processing 
     call", throwable) }
                .subscribe { updateView(it) }
    }


    private fun updateView(gsmCall: GsmCall) {
        textStatus.visibility = when (gsmCall.status) {
            GsmCall.Status.ACTIVE -> View.GONE
            else -> View.VISIBLE
        }
        textStatus.text = when (gsmCall.status) {
            GsmCall.Status.CONNECTING -> "Connecting…"
            GsmCall.Status.DIALING -> "Calling…"
            GsmCall.Status.RINGING -> "Incoming call"
            GsmCall.Status.ACTIVE -> ""
            GsmCall.Status.DISCONNECTED -> "Finished call"
            GsmCall.Status.UNKNOWN -> ""
        }
        textDuration.visibility = when (gsmCall.status) {
            GsmCall.Status.ACTIVE -> View.VISIBLE
            else -> View.GONE
        }
        buttonHangup.visibility = when (gsmCall.status) {
            GsmCall.Status.DISCONNECTED -> View.GONE
            else -> View.VISIBLE
        }

        if (gsmCall.status == GsmCall.Status.DISCONNECTED) {
            buttonHangup.postDelayed({ finish() }, 3000)
        }

        when (gsmCall.status) {
            GsmCall.Status.ACTIVE -> startTimer()
            GsmCall.Status.DISCONNECTED -> stopTimer()
            else -> Unit
        }

        textDisplayName.text = gsmCall.displayName ?: "Unknown"

        buttonAnswer.visibility = when (gsmCall.status) {
            GsmCall.Status.RINGING -> View.VISIBLE
            else -> View.GONE
        }
    }

    override fun onPause() {
        super.onPause()
        updatesDisposable.dispose()
    }

    private fun hideBottomNavigationBar() {
        window.decorView.systemUiVisibility = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
    }

    private fun startTimer() {
        timerDisposable = Observable.interval(1, TimeUnit.SECONDS)
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe { textDuration.text = it.toDurationString() }
    }

    private fun stopTimer() {
        timerDisposable.dispose()
    }

    private fun Long.toDurationString() = String.format("%02d:%02d:%02d", this / 
    3600, (this % 3600) / 60, (this % 60))


    fun muteCall() {
        Log.i(CallManager.LOG_TAG, "muteCall")
        inCallService!!.setMuted(!inCallService!!.callAudioState.isMuted)
    }

Class CallService:InCallService(){

// This is the object that receives interactions from clients.  See
// RemoteService for a more complete example.

//  private val myBinder = CallBinder()
//
//    override fun onBind(intent: Intent): IBinder? {
 //        return this.mBinder
 //    }

/**
 * Class for clients to access.  Because we know this service always
 * runs in the same process as its clients, we don't need to deal with
 * IPC.
 */
inner class CallBinder : Binder() {
    fun getService(): CallService {
        return this@CallService
    }
}


  override fun onCallAdded(call: Call) {  //app receives a new incoming call via onCallAdded
    super.onCallAdded(call)
    Log.i(LOG_TAG, "onCallAdded: $call")
    call.registerCallback(callCallback)
    val i = Intent(this, CallActivity::class.java)
    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
    startActivity(i)
    CallManager.updateCall(call)
}

override fun onCallRemoved(call: Call) {
    super.onCallRemoved(call)
    Log.i(LOG_TAG, "onCallRemoved: $call")
    call.unregisterCallback(callCallback)
    CallManager.updateCall(null)
}

private val callCallback = object : Call.Callback() {
    override fun onStateChanged(call: Call, state: Int) {
        Log.i(LOG_TAG, "Call.Callback onStateChanged: $call, state: $state")
        CallManager.updateCall(call)
    }
}

}

在CallActivity中,我需要获取“正在运行的” InCallService实例,以使其静音。我该怎么办?

该错误在一行中是onBind:val活页夹=服务为CallService.CallBinder

进程:com.mbarrben.dialer,PID:6923     java.lang.ClassCastException:android.telecom.InCallService $ InCallServiceBinder无法强制转换为com.delphi.dialer.CallService $ CallBinder         在com.delphi.dialer.CallActivity $ myConnection $ 1.onServiceConnected(CallActivity.kt:46)         在android.app.LoadedApk $ ServiceDispatcher.doConnected(LoadedApk.java:1730)         在android.app.LoadedApk $ ServiceDispatcher $ RunConnection.run(LoadedApk.java:1762)         在android.os.Handler.handleCallback(Handler.java:873)

在坠毁的瞬间,我会附上一张带有观察对象的图像。

类强制转换错误绑定服务1

0 个答案:

没有答案