Kudan AR SDK で Android アプリを作ってみよう〜マーカー上に画像を表示

こんにちは。エクセルソフトの田淵です。

取り扱いを開始した Kudan ですが、AR をスマホで行う SDK です。

こちらのクイックスタートを私の勉強を兼ねて Kotlin でやってみました。

現時点でのサンプルコードは ytabuchi の Github にアップしてあります。この後もコミット追加していくのでスナップショットです。

事前準備

まずは Kudan AR Framework をダウンロードします

ダウンロードページで Developer License Key をメモしておいてください。

プロジェクト作成

Android プロジェクトを作成します。

作成する際に「Package name」 を eu.kudan.ar に変更してください。

今回は Empty Activity を作成しました。

Kudan AR SDK のインポート

次にプロジェクトにダウンロードした KudanAR.aar をインポートします。

File>New>New Module を選択し、

Import .JAR/.AAR Package を選択します。

「File name」でダウンロードした KudanAR.aar を指定します。

で、インポートすると、本来はそのままインポートされるようなのですが、私の環境では IDE Error で読み込めませんでした。

Android Studio 3.1.1 – unable to add module (import gradle project) – Stack Overflow

にあるように、手動で読み込む必要があります。

「Gradle Scripts」内の Settings.gradle を開き、以下のように KudanAR の参照を追加します。

include ':app', ':KudanAR'

保存すると表示される通知バーで Sync Now をクリックすると、プロジェクトに「Kudan AR」が読み込まれているはずです。

File>Project Structure をクリックします。

左の項目から app を選択し、Dependencies をクリックして、左下の「+」ボタンから「Module dependencies」を選択し、

「Kudan AR」を追加します。次の画像のように追加されていれば OK です。

Android manifest 変更

まずは Permission の設定を追加します。

<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />

Activity のエレメントに以下を追加します。

android:configChanges="orientation|screenSize"
android:screenOrientation="fullSensor"

現時点での Android.manifest は以下のようになっています。

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

    <uses-permission android:name="android.permission.CAMERA" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />

    <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"
            android:configChanges="orientation|screenSize"
            android:screenOrientation="fullSensor">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

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

</manifest>

Gradle 設定の変更

app の Gradle 設定(Build.gradle (Module: app))のandroid` ブロックに以下を追加します。

aaptOptions 
{
   noCompress 'KARMarker'
   noCompress 'armodel'
}

現在の Build.gradle の全体は次のようになっています。

apply plugin: 'com.android.application'

apply plugin: 'kotlin-android'

apply plugin: 'kotlin-android-extensions'

android {
    compileSdkVersion 27
    defaultConfig {
        applicationId "eu.kudan.ar"
        minSdkVersion 19
        targetSdkVersion 27
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
    aaptOptions
    {
        noCompress 'KARMarker'
        noCompress 'armodel'
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jre7:$kotlin_version"
    implementation 'com.android.support:appcompat-v7:27.1.1'
    implementation 'com.android.support.constraint:constraint-layout:1.1.2'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation project(':KudanAR')
}

プロジェクトの設定は以上です。

ARActivity を作る

無事 Kudan AR SDK が読み込めたので、Activity を作っていきます。

ARAPIkey の追加

まずは最初にメモっておいた API Key を追加します。

package eu.kudan.ar

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import eu.kudan.kudan.ARAPIKey;

class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // setContentView(R.layout.activity_main)

        val key = ARAPIKey.getInstance()
        key.setAPIKey("<Put API Key here>")
    }
}

変更箇所は次の通りです。

  • import eu.kudan.kudan.ARAPIKey; を追加
  • val key = ARAPIKey.getInstance() を追加
  • key.setAPIKey("") を追加
        - ここにコピーしたキーを入れてください。

次に ARActivity の設定です。

import eu.kudan.kudan.ARActivity; を追加し、CompatiActivity から ARActivity に継承元を変更します。以下のようになります。

package eu.kudan.ar

import android.support.v7.app.AppCompatActivity
import android.os.Bundle
import eu.kudan.kudan.ARAPIKey;
import eu.kudan.kudan.ARActivity;

class MainActivity : ARActivity() {
    ...
}

続いて ARActivity の Setup メソッドを override します。以下を追加します。

override fun setup() {
    super.setup()

    // AR Content to be set up here
}

やっと Marker を読み込む準備ができました!!

が、その前にカメラのランタイムパーミッションを設定しましょう。

Permission 設定

クラスの下に以下の3つのメソッドを追加します。

// Permission のリクエストを OS 標準の requestPermissions メソッドで行う
private fun permissionsRequest(){
    if (ContextCompat.checkSelfPermission(this,
                    Manifest.permission.INTERNET) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this,
                    Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED || ContextCompat.checkSelfPermission(this,
                    Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this,
                arrayOf(Manifest.permission.INTERNET, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.CAMERA), 111)

    }
}

// ダイアログを表示して、本サンプルアプリの設定画面に遷移する
private fun permissionsNotSelected() {
    val builder = AlertDialog.Builder(this)
    builder.setTitle("Permissions required")
    builder.setMessage("Please enable the requested permissions in the app settings in order to use this demo app")
    builder.setPositiveButton("Set permission", DialogInterface.OnClickListener { dialog, id ->
        dialog.cancel()
        val intent = Intent()
        intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
        intent.data = Uri.parse("package:eu.kudan.ar")
        startActivity(intent)
    })
    val noPermission = builder.create()
    noPermission.show()
}

// requestPermissions ダイアログの結果を受け、全て許可されていなければ、permissionsNotSelected を呼び出し
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults)

    when (requestCode) {
        111 -> {
            if (grantResults.isNotEmpty() &&
                    grantResults[0] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[1] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[2] == PackageManager.PERMISSION_GRANTED &&
                    grantResults[3] == PackageManager.PERMISSION_GRANTED) {
                // パーミッションが必要な処理
            } else {
                permissionsNotSelected()
            }
        }
    }
}

その後、onCreate メソッドに permissionRequest() を追加してください。

最終的な onCreate メソッドは以下のようになります。

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.activity_main)

    val key = ARAPIKey.getInstance()
    key.setAPIKey("")

    permissionsRequest()
}

Marker を読み込む

Marker 画像、マーカーの上に表示するコンテンツ画像は こちら からダウンロードしてください。

ダウンロードした zip を展開して、Android Studio の Assets として読み込む必要があります。まずは 「File>New>Folder>Assets Folder」 から Assets フォルダを作成します。

その際に必ず「Main」に作成してください。

Assets への画像のコピーですが、私は macOS の Finder で画像ファイルをコピーして Android Studio の Assets フォルダーでペーストしました。

画像をマーカーとして利用するには、ARImageTrackable オブジェクトを作成し、画像を読み込ませる必要があります。Setup 内に以下のコードを追加します。(ファイル名を lego.jpg にしています。)

override fun setup() {
    super.setup()

    // Initialise the image trackable and load the image.
    val imageTrackable = ARImageTrackable("Lego")
    imageTrackable.loadFromAsset("lego.jpg")

    // Get the single instance of the image tracker.
    val imageTracker = ARImageTracker.getInstance()
    imageTracker.initialise()

    //Add the image trackable to the image tracker.
    imageTracker.addTrackable(imageTrackable)
}

ImageNode をセットする

マーカーの上にオブジェクトを表示する方法はいくつかありますが、今回は画像を表示する ARImageNode を使用します。Setup 内に以下のコードを追加します。

// Initialise the image node with our image
val imageNode = ARImageNode("cow.png")

// Add the image node as a child of the trackable's world
imageTrackable.world.addChild(imageNode)

// imageNode のサイズを Trackable のサイズに合わせる
val textureMaterial = imageNode.material as ARTextureMaterial
val scale = imageTrackable.width / textureMaterial.texture.width
imageNode.scaleByUniform(scale)

デプロイ

お疲れ様でした。これで動作するはずですので、実機にデプロイしてみましょう!

Emulator は使えません

Kudan SDK のライブラリ aar は、現時点では armv7 のみ(32bit のみです…)の対応なので、x86 で動くエミュレーターでは動作しません。AR なので当たり前なのですがカメラも使いますので、実機にデプロイしてください。

こんな感じでマーカー上に cow.jpg が表示されていれば成功です!

この後は

次は動画や 3D オブジェクトを表示してみましょう。あ、先に iOS 用のクイックスタートをやるかも…笑

Kudan の製品概要やダウンロードは こちら からどうぞ。開発用の SDK で遊ぶ分には無料です。

Google Play にアップしたいな!って時も、個人開発者、年商1億円以内の会社であれば無料でご利用いただけます。(起動時に Kudan のスプラッシュスクリーンは表示されます。(Unity と同じ感じです))

Kudan AR SDK エントリー一覧

iOS
Android

以上です。

シェアする

  • このエントリーをはてなブックマークに追加

フォローする