隔离相机 LED 灯和 java.lang.NullPointerException 的功能:尝试调用虚方法 'void android.hardware.Camera$Parameters

Function Isolating Camera's LED Light and java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera$Parameters

在我为自己的教育目的而尝试制作的应用程序中,我很难控制相机旁边的 LED 灯。我尝试遵循 http://www.mkyong.com/android/how-to-turn-onoff-camera-ledflashlight-in-android/ 中的方法,但我试图使函数更抽象和更通用,以增加可重用功能并使代码更具可读性。

创建 activity 后,我们首先使用 PackageManager 检查 LED 摄像头是否确实存在。然后我打开相机。 onClick 函数运行函数 changeScreen() 和 toggleLight()。在这里您可以看到使用抽象的明显优势,即 toggleLight() 使用其他地方设置的代码作为黑盒工作。我知道的 changeScreen 函数是正确的,在添加 toggleLight() 之前它工作正常。

由于代码应该是正确的,因为它取自示例,我相信我在变量范围方面有问题。

1) boolean isLighOn 需要在哪里声明,在函数中还是在activity?

2) 相机变量同样的问题

我还应该如何创建抽象函数 toggleLight()?我已经在这个网站上查看过了,但是很多帖子都会将您发送到上面提供的 link。此外,我相信这个问题的答案将帮助许多用户并提供可重用的代码。

到目前为止,这是我的代码,我已经发布了我再次遇到的错误。

package com.mycompany.myapplication;

import android.app.*;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.ColorDrawable;
import android.hardware.Camera;
import android.os.*;
import android.util.Log;
import android.view.*;
import android.widget.*;


public class MainActivity extends Activity {

    public RelativeLayout container;
    private boolean isLighOn = false;
    private Camera camera;

    @Override
    protected void onStop() {
        super.onStop();

        if (camera != null) {
            camera.release();
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Context context = this;
        PackageManager pm = context.getPackageManager();

        // if device support camera?
        if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            Log.e("err", "Device has no camera!");
            return;
        }

        camera = Camera.open();

        container = (RelativeLayout) findViewById(R.id.MainActivity);
        container.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View v) {
                changeScreen(v);
                toggleLight();
            }
        });
    }

    public void changeScreen(View v) {
        ColorDrawable cd = (ColorDrawable) this.container.getBackground();
        TextView ON = (TextView) findViewById(R.id.ON);
        TextView OFF = (TextView) findViewById(R.id.OFF);

        if (cd != null && cd.getColor() == getResources().getColor(R.color.BLACK)) {
            container.setBackgroundColor(getResources().getColor(R.color.WHITE));
            OFF.setVisibility(View.INVISIBLE);
            ON.setVisibility(View.VISIBLE);
        } else {
            container.setBackgroundColor(getResources().getColor(R.color.BLACK));
            OFF.setVisibility(View.VISIBLE);
            ON.setVisibility(View.INVISIBLE);
        }
    }

    public void toggleLight(){
        final Camera.Parameters p = camera.getParameters();

        if (isLighOn) {

            Log.i("info", "torch is turn off!");

            p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
            camera.setParameters(p);
            camera.stopPreview();
            isLighOn = false;

        } else {

            Log.i("info", "torch is turn on!");

            p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);

            camera.setParameters(p);
            camera.startPreview();
            isLighOn = true;
        }
    }


}

当我在我的 Android Studio 模拟器上加载应用程序时,我得到了屏幕 "ON"。但是,当您单击屏幕时,应用程序会崩溃。这只是我在 IDE 中可以找到的错误消息。我不确定如何解释此错误消息。

为了回应下面的评论,我现在发布包含权限的代码。

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.mycompany.myapplication">

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />

    <application

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

    </manifest>

不要依赖模拟器来产生可靠的相机行为。始终在真实设备上验证 camera-related 代码!