1

我在 android 应用程序中使用 HMS ML Kit 来分析来自后台服务的人脸检测。我无法初始化 MLFaceAnalyzer。下面是服务类代码片段

@Suppress("未使用") 类 TestService : Service() {

private val TAG: String = "FaceDetectionPresenterHw"
private var faceDetectionPresenterhw: FaceDetectionPresenterHw? = null
private var isNotificationCalled = false

private fun createNotification() {

    isNotificationCalled = true

    val notificationIntent = Intent(this, MyActivity::class.java)
    notificationIntent.putExtra(Constants.INTENT_EXTRA_TYPE, "Background Service")
    notificationIntent.putExtra(Constants.INTENT_EXTRA_CHILD_ID, childId)

    val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, PendingIntent.FLAG_CANCEL_CURRENT)

    val notificationManager = applicationContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
    val channelId = getString(R.string.default_notification_channel_id)
    val channelName = getString(R.string.channel_name)// The user-visible name of the channel.

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        val importance = NotificationManager.IMPORTANCE_DEFAULT
        val mChannel = NotificationChannel(
            channelId, channelName, importance
        )
        mChannel.setSound(null, null)
        mChannel.enableVibration(false)
        notificationManager.createNotificationChannel(mChannel)
    }

    val notification = NotificationCompat.Builder(this, channelId)
        .setSmallIcon(R.drawable.ic_stat_notification)
        .setContentTitle(“MyApp”)
        .setDefaults(0)
        .setContentText("MyApp is running")
        .setContentIntent(pendingIntent).build()

    startForeground(1337, notification)
}

override fun onCreate() {
    super.onCreate()

    if (!isNotificationCalled) {
        createNotification()
    }

   faceDetectionPresenterhw = FaceDetectionPresenterHw(this@TestService)
   

}

@SuppressLint("MissingPermission")
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {

    Log.d(TAG,"Service started")

  
    if (!isNotificationCalled) {
        createNotification()

    }

    if (Utils.permissionCheck(this@TestService)) {
      faceDetectionPresenterhw!!.startCamera()
    } else {
        stopSelf()
    }
    return START_STICKY
}

override fun onDestroy() {
    isNotificationCalled = false
    isDestroyCalled = true

    faceDetectionPresenterhw!!.stopCamera()


    super.onDestroy()
}

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

FaceDetectionPresenter 类代码片段如下

class FaceDetectionPresenterHw(private val context: Context) : FaceDetectionInterface, KoinComponent {

private var cameraConfiguration: CameraConfiguration? = null
private var lensEngine: LensEngine? = null
private var preview: LensEnginePreview? = null

init {
    faceDetectorCreate(false)
}

override fun faceDetectorCreate(orientation: Boolean) {
    Log.d(TAG, "faceDetectorCreate()")
    cameraConfiguration = CameraConfiguration()
    createCameraSource()
}


private fun createCameraSource() {
    if (lensEngine == null) {
        Log.d(TAG, "createCameraSource() ${context ==null} ${cameraConfiguration ==null} ")
        lensEngine = LensEngine(context, this.cameraConfiguration)
    }

    setDetectorOptions()

}


private fun setDetectorOptions() {

    Log.d(TAG, "Option 1")
    val options: MLFaceAnalyzerSetting = MLFaceAnalyzerSetting.Factory()
            .setPerformanceType(MLFaceAnalyzerSetting.TYPE_SPEED)
            .setFeatureType(MLFaceAnalyzerSetting.TYPE_FEATURES)
            .setShapeType(MLFaceAnalyzerSetting.TYPE_SHAPES)
            .setKeyPointType(MLFaceAnalyzerSetting.TYPE_KEYPOINTS)
            .setTracingAllowed(true, MLFaceAnalyzerSetting.MODE_TRACING_FAST)
            .allowTracing(MLFaceAnalyzerSetting.MODE_TRACING_FAST)
            .create()


    Log.d(TAG, "Option  ${lensEngine != null} -- ${context==null} ")
    lensEngine?.setMachineLearningFrameTransactor(LocalFaceTransactor(options, context))
}

override fun startCamera() {
    Log.d(TAG, "Start Camera")
    if (lensEngine != null) {
        try {
            Log.d(TAG, "Start Camera inside")
            preview = LensEnginePreview(context)
            preview!!.start(lensEngine, true)
        } catch (e: IOException) {
            Log.e("FaceDetectionPr", "Unable to start lensEngine.", e)
            lensEngine!!.release()
            lensEngine = null
        }
    }
}


private inner class LocalFaceTransactor(options: MLFaceAnalyzerSetting?, context: Context) : BaseTransactor<List<MLFace?>?>() {

    init {

        detector = MLAnalyzerFactory.getInstance().getFaceAnalyzer(options)

    }
}
}

下面的问题来了

android.content.Context com.huawei.agconnect.AGConnectInstance.getContext()' on a null object reference

日志猫

2021-07-07 13:20:28.051 16868-16868/? E/AndroidRuntime: FATAL EXCEPTION: main

facedetection.FaceDetectionPresenterHw.(FaceDetectionPresenterHw.kt:43) 在 co.sample.services.sampleService.onCreate(sampleService.kt:81) 在 android.app.ActivityThread.handleCreateService(ActivityThread.java:4150) 在 android.app.ActivityThread。在 android.os.Handler.dispatchMessage(Handler.java:112) 在 android.app.ActivityThread$H.handleMessage(ActivityThread.java:2055) 在 android.os.Looper.loop( Looper.java:216) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run( RuntimeInit.java:524) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:987) 2021-07-07 13:20:28.078 1486-7158/?I/chatty: uid=1000(system) Binder:1486_1D expire 1 line 2021-07-07 13:20:28.091 1486-6494/? 我/健谈:uid=1000(system) Binder:1486_1C expire 6 lines 2021-07-07 13:20:28.095 1915-4243/? I/BoosterSwitchP:notifyUidState 什么都不做 2021-07-07 13:20:28.095 1915-4243/? I/DeepNoDisturbP: notifyUidState 2021-07-07 13:20:28.095 1915-4243/? I/BrowserChrP: notifyUidState 2021-07-07 13:20:29.423 16932-16932/? D/ActivityThread:将线程附加到应用程序 2021-07-07 13:20:30.122 16932-16932/?E/AndroidRuntime:致命异常:主进程:co.sample:sampleService,PID:16932 java.lang.RuntimeException:无法创建服务 co.sample.services.sampleService:java.lang.NullPointerException:尝试调用虚拟方法'android .content.Context com.huawei.agconnect.AGConnectInstance.getContext()' 在 android.app.ActivityThread 的 android.app.ActivityThread.handleCreateService(ActivityThread.java:4169) 的空对象引用上。

这里有什么问题?

4

4 回答 4

1

要从后台服务使用 HMS ML Kit,我们需要在应用程序的OnCreate()方法中初始化 AGConnect 实例,如下所述

class MyApplication : Application(){

override fun onCreate() {
    super.onCreate()

    if (AGConnectInstance.getInstance() == null) {
        AGConnectInstance.initialize(applicationContext)
    }
}
于 2021-07-09T02:35:32.507 回答
1

该错误是由上下文为空引起的,这是尚未准备好的主要上下文。

因为当上下文创建尚未完成时,它试图在 onCreate 中获取 FaceDetectionPresenterHw。

所以不要在 onCreate 中调用使用 FaceDetectionPresenterHw。只声明变量,然后及时调用getInstance,然后使用它。所以那个时间 Context 不为空。

==============

附加编辑:

在开始使用分析器的服务中使用以下代码

在此处输入图像描述

于 2021-07-07T22:38:00.690 回答
0

​检查 

isNotificationCalled = true

变量已经是真的。

if (!isNotificationCalled) {
    createNotification()

}

在上面的代码中,仅当变量为 false时才创建通知。所以条件不成立。通过设置 isNotificationCalled = false来检查它 

然后将创建通知。

确保您已在 app 目录中添加了 ag-connect.json 文件

​</p>

于 2021-07-08T08:04:30.323 回答
0

后台服务是否执行Service类中的以下代码?

MLFaceAnalyzer analyzer = MLAnalyzerFactory.getInstance().getFaceAnalyzer(setting);

如下所示:

在此处输入图像描述

如果MLFaceAnalyzer对象是在Service类中创建的,则测试结果是正确的。请详细描述您的问题,以便我们为您提供适当的帮助。

于 2021-07-07T07:32:09.800 回答