Android APIレベル23 での Fail to connect to camera service の解決方法


参考サイト:
素人のアンドロイドアプリ開発日記
androidでカメラを使ってみる。


targetSdkVersion を変更したらエラーが出たのでgradleのappcompatのバージョン指定を変更した話。
http://qiita.com/NaokiOgawa/items/9e4fb031e2a0fb1dbbf5


完成したソースは一番下にあります。

再現手順

2015年9月2日、APIレベル23にて確認。


Activity は Blank Activity を選択します。


最初からセットされている処理(Hello World)を
エミュレーターで実行します。成功します。APIレベルは23です。


次に実機(ZenPhone1, Android 4.4)で実行します。成功します。
APIレベルは19です。


素人のアンドロイドアプリ開発日記 を参考に以下の処理を組み込みます。
androidでカメラを使ってみる。


AndroidManifest.xmlの変更

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

を追加。


android:screenOrientation="landscape"

を追加。


クラス CameraView の追加

参照元サイトをご確認ください。


クラス MainActivity の変更

setContentView(R.layout.activity_main);

コメントアウトして

CameraView view = new CameraView(this);
setContentView(view);

を追加。


エミュレーターで実行します。
すると
java.lang.RuntimeException: Fail to connect to camera service
のエラーになります。


エラーの原因

APIレベル23では、Camera.open(); が使えないことが原因です。
APIレベル23では
https://github.com/googlesamples/android-Camera2Basic
を参考に、Camera2 APIを使用します。



解決方法

APIレベルを下げます。ここでは実機のAPIレベル19にします。
以下を実施します。


参考サイト
targetSdkVersion を変更したらエラーが出たのでgradleのappcompatのバージョン指定を変更した話。
http://qiita.com/NaokiOgawa/items/9e4fb031e2a0fb1dbbf5


build.gradleの変更

Gradle Script の下にあるBuild.gradeleを以下のよう変更します。

targetSdkVersion 23

targetSdkVersion 19



compile 'com.android.support:appcompat-v7:23.0.0'

compile 'com.android.support:appcompat-v7:19+'



実行すると以下のエラーになります。


Error:(3, 30) エラー: シンボルを見つけられません
シンボル: クラス AppCompatActivity
場所: パッケージ android.support.v7.app


エラーの原因

APIレベル19ではクラス AppCompatActivityが存在しないことが原因です。


MainActivity.javaの変更

import android.support.v7.app.AppCompatActivity;

import android.app.Activity;



public class MainActivity extends AppCompatActivity {

public class MainActivity extends Activity {

に変更します。


エミュレータで実行します。APIレベルが低いことの警告が出ますが、OKを押します。

起動が成功します。



しかし、実機で起動すると以下のエラーになります。
java.lang.RuntimeException: setParameters failed


エラーの原因

setParameters のエラーで、プレビューのサイズを指定する必要があります。


CameraView.javaの変更

parameters.setPreviewSize(width, height);

List<Camera.Size> previewSizes = myCamera.getParameters().getSupportedPreviewSizes();
Camera.Size size = previewSizes.get(0);
parameters.setPreviewSize(size.width, size.height);

に変更します。


実機での起動が成功します。



補足 AndroidManifest.xmlの変更(フルスクリーンにしたい場合)

android:theme="@style/AppTheme" 

android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" 

に変更します。
APIレベル23の場合の、以下の記述と同じです。
android:theme="@style/Theme.AppCompat.NoActionBar" )


AndroidManifest.xml

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

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@android:style/Theme.Black.NoTitleBar.Fullscreen" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:screenOrientation="landscape" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

MainActivity.java

package com.github.fumio_shimamura.image04;

//import android.support.v7.app.AppCompatActivity;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;

public class MainActivity extends Activity {

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

        CameraView view = new CameraView(this);
        setContentView(view);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

build.gradle

apply plugin: 'com.android.application'

android {
    compileSdkVersion 23
    buildToolsVersion "23.0.0"

    defaultConfig {
        applicationId "com.github.fumio_shimamura.image04"
        minSdkVersion 15
        targetSdkVersion 19
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:19+'
}