ACRCloud integration to android app

2019-08-27 03:58发布

问题:

I have the following code for music recognition. I am using intent service to do all the music recognition in the service. I have done all the basic steps like adding all the permissions required and adding the ACRCloud android SDK in the project.

class SongIdentifyService(discoverPresenter : DiscoverPresenter? = null) : IACRCloudListener , IntentService("SongIdentifyService") {

private val callback : SongIdentificationCallback? = discoverPresenter
private val mClient : ACRCloudClient by lazy { ACRCloudClient() }
private val mConfig : ACRCloudConfig by lazy { ACRCloudConfig() }
private var initState : Boolean = false
private var mProcessing : Boolean = false


override fun onHandleIntent(intent: Intent?) {

    Log.d("SongIdentifyService", "onHandeIntent called" )

    setUpConfig()
    addConfigToClient()

    if (callback != null) {
        startIdentification(callback)
    }

}


public fun setUpConfig(){

    Log.d("SongIdentifyService", "setupConfig called")

    this.mConfig.acrcloudListener = this@SongIdentifyService

    this.mConfig.host = "some-host"
    this.mConfig.accessKey = "some-accesskey"
    this.mConfig.accessSecret = "some-secret"
    this.mConfig.protocol = ACRCloudConfig.ACRCloudNetworkProtocol.PROTOCOL_HTTP // PROTOCOL_HTTPS
    this.mConfig.reqMode = ACRCloudConfig.ACRCloudRecMode.REC_MODE_REMOTE

}

// Called to start identifying/discovering the song that is currently playing
fun startIdentification(callback: SongIdentificationCallback)
{

    Log.d("SongIdentifyService", "startIdentification called")

    if(!initState)
    {
        Log.d("AcrCloudImplementation", "init error")
    }
    if(!mProcessing) {

        mProcessing = true
        if (!mClient.startRecognize()) {

            mProcessing = false
            Log.d("AcrCloudImplementation" , "start error")

        }
    }
}

// Called to stop identifying/discovering song
fun stopIdentification()
{

    Log.d("SongIdentifyService", "stopIdentification called")
    if(mProcessing)
    {
        mClient.stopRecordToRecognize()
    }

    mProcessing = false
}

fun cancelListeningToIdentifySong()
{
    if(mProcessing)
    {
        mProcessing = false
        mClient.cancel()
    }
}

fun addConfigToClient(){

    Log.d("SongIdentifyService", "addConfigToClient called")


    this.initState = this.mClient.initWithConfig(this.mConfig)

    if(this.initState)
    {
        this.mClient.startPreRecord(3000)
    }
}


override fun onResult(result: String?) {

    Log.d("SongIdentifyService", "onResult called")
    Log.d("SongIdentifyService",result)

    mClient.cancel()
    mProcessing = false

    val result = Gson().fromJson(result, SongIdentificationResult :: class.java)

    if(result.status.code == 3000)
    {
        callback!!.onOfflineError()
    }
    else if(result.status.code == 1001)
    {
        callback!!.onSongNotFound()
    }
    else if(result.status.code == 0 )
    {
        callback!!.onSongFound(MusicDataMapper().convertFromDataModel(result))

        //callback!!.onSongFound(Song("", "", ""))
    }
    else
    {
        callback!!.onGenericError()
    }


}

override fun onVolumeChanged(p0: Double) {
    TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
}


interface SongIdentificationCallback {

    // Called when the user is offline and music identification failed
    fun onOfflineError()

    // Called when a generic error occurs and music identification failed
    fun onGenericError()

    // Called when music identification completed but couldn't identify the song
    fun onSongNotFound()

    // Called when identification completed and a matching song was found
    fun onSongFound(song: Song)

}

}

Now when I am starting the service I am getting the following error:

回答1:

I checked the implementation of the ACRCloudClient and its extends android Activity. Also ACRCloudClient uses shared preferences(that's why I am getting a null pointer exception).

Since keeping a reference to an activity in a service is not a good Idea its best to Implement the above code in the activity. All the implementation of recognizing is being done in a separate thread anyway in the ACRCloudClient class so there is no point of creating another service for that.