カメラ実装用アクティビティ追加
(1) メニューから「ファイル」-「新規」-「アクティビティー」-「空のアクティビティー」を選択します。

(2) 以下を入力し、完了ボタンをクリックします。
- アクティビティー名 :LiveCamera
- レイアウト・ファイルを生成する :チェックする
- ソース言語 :Kotlin
- ターゲット・ソース・セット :main

MainActivityのレイアウト変更
(1) プロジェクトツリーから app/res/layout/activity_main.xml をダブルクリックします。

(2) パレットの「Buttons」を選択、「Button」を画面上にドラッグします。
※この画面が表示されていないときは「※ここをクリック!」をクリックしてください。
以下を設定してください。
- id :takeVideoBtn
- text : カメラ起動

(3) コンポーネント・ツリーの「takeVideoBtn」にエラー表示のアイコンがあるとき、画面上部の①のアイコンをクリックし、エラーを除去します。
Ctrl+sで保存します。

LiveCameraActivityのレイアウト変更
(1) プロジェクトツリーから app/res/layout/activity_live_camera.xml をダブルクリックします。

(2) 画面右上の「コード」アイコンをクリックします。

(3) 以下のコードを入力し、Ctrl+sで保存します。
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".LiveCamera">
<VideoView
android:id="@+id/videoView"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginBottom="57dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
プログラム修正
(1) プロジェクトツリーから app/manifests/AndroidManifest.xml をダブルクリックします。

(2) 以下のコードを入力し、Ctrl+sで保存します。
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.livecamera">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.STORAGE" />
<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=".LiveCamera"
android:parentActivityName=".MainActivity">
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".MainActivity" />
</activity>
<meta-data
android:name="com.google.firebase.ml.vision.DEPENDENCIES"
android:value="face" />
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
(3) プロジェクトツリーから app/java/com.example.livecamera/MainActivity をダブルクリックします。

(4) 以下のコードを入力し、Ctrl+sで保存します。
package com.example.livecamera
import android.Manifest
import android.content.Intent
import android.content.pm.PackageManager
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.widget.Button
import android.widget.Toast
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class MainActivity : AppCompatActivity() {
companion object {
const val CAMERA_PERMISSION_REQUEST_CODE = 2
}
private lateinit var takeVideoBtn: Button
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
takeVideoBtn = findViewById(R.id.takeVideoBtn)
}
override fun onResume(){
super.onResume()
takeVideoBtn.setOnClickListener{
// カメラ機能を実装したアプリが存在するかチェック
val intent = Intent(applicationContext, LiveCamera::class.java)
intent.resolveActivity(packageManager)?.let {
if (checkCameraPermission()) {
startActivity(intent)
} else {
grantCameraPermission()
}
} ?: Toast.makeText(this, "カメラを扱うアプリがありません", Toast.LENGTH_LONG).show()
}
}
private fun grantCameraPermission() =
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.CAMERA),
CAMERA_PERMISSION_REQUEST_CODE)
private fun checkCameraPermission() = PackageManager.PERMISSION_GRANTED ==
ContextCompat.checkSelfPermission(applicationContext, Manifest.permission.CAMERA)
}
(5) プロジェクトツリーから app/java/com.example.livecamera/LiveCamera をダブルクリックします。

(6) 以下のコードを入力し、Ctrl+sで保存します。
package com.example.livecamera
import android.content.Intent
import android.net.Uri
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.os.Environment.DIRECTORY_MOVIES
import android.provider.MediaStore
import android.widget.VideoView
import java.io.File
import java.io.IOException
class LiveCamera : AppCompatActivity() {
private lateinit var videoView: VideoView
private var capturedUri: Uri? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_live_camera)
videoView = findViewById(R.id.videoView)
takeVideo()
}
private fun takeVideo(){
dispatchTakeVideoIntent()
videoView.setVideoURI(intent.data)
videoView.start()
}
private fun dispatchTakeVideoIntent() {
val takeVideoIntent = Intent(MediaStore.ACTION_VIDEO_CAPTURE)
takeVideoIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
if (takeVideoIntent.resolveActivity(packageManager) != null) {
try {
takeVideoIntent.putExtra(MediaStore.EXTRA_DURATION_LIMIT, 10)
takeVideoIntent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1)
val videoFile: File = createMediaFile()
println("=============>videoFile = $videoFile")
capturedUri = Uri.fromFile(videoFile)
takeVideoIntent.putExtra(MediaStore.EXTRA_OUTPUT, capturedUri)
startActivityForResult(takeVideoIntent, 200)
} catch (e: IOException) {
e.printStackTrace()
}
}
}
private fun createMediaFile(): File {
// Create an image file name
val fileName = "VID_"
val directory:File = File(System.getProperty("java.io.tmpdir", ".") + "/" + DIRECTORY_MOVIES)
if (!directory.exists())
directory.mkdir()
return File("$directory/$fileName${System.currentTimeMillis()}.mp4")
}
}
実行
(1) メニューの「ビルド」-「プロジェクトの再ビルド」をクリックします。

(2) ステータスバーに進行状況が表示され、「ビルド出力」と「イベント・ログ」でビルドエラーなどの確認ができます。

(3) ビルドが終了するとステータスバーに「Gradleビルドが完了しました」が表示されます。
「ビルド出力」に BUILD SUCCESSFUL が表示されていることを確認します。

(4) デバッグする実機が「SHARP SH-05G」であることを確認し、「実行」アイコンをクリックします。

(5) ステータスが以下の順に表示され、実機にインストールされます。



(6) 実機で作成したアプリが実行されています。

個人的感想
分かったこと
- Activity の命名を「~Activity」にしなかったため、プロジェクト名なのかアクティビティなのか分からなくなった
- Activity から Intent を生成して 別Activityを呼び出す
- Intentしてカメラを使う
- 表示するものと用途によってViewを使い分ける必要がある
- onResumeなど、割り込み関係を overrideする
- ローカルストレージのアクセス方法
- Toastが楽しい!
分からなかったこと
- Manifest の 中身
- permissionが正しく出来ているのかわからない
- カメラ制御が古いロジック?(camera2でない)
- androidバージョン違いの他の端末で動くのか?
- カメラ終了してないので、最初の画面に戻らずハングったりする。
端末再起動しないとカメラが使えなくなる。
