SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

ExpoとEASで始める快適モバイルアプリ開発

Expoでのパーミッション管理を学び、カメラとGPS機能を活用したアプリを作成しよう

ExpoとEASで始める快適モバイルアプリ開発 第4回

QRコードリーダーの実装

 QRコードリーダーの実装における、パーミッションの扱いを見ていきましょう。スマートフォンのカメラを使ったQRコード読み取りは、モバイルアプリの中でも特に実用的な機能の一つです。

 Expoでは、expo-cameraモジュールを使用することで、簡単にQRコード読み取り機能を実装することができます。以前はバーコードスキャン専用のexpo-barcode-scannerが提供されていましたが、Expo 52ではexpo-cameraにQRコード読み取り機能が統合されました。

expo-cameraでのQRコード読み取り基本

 まずは、expo-cameraモジュールをインストールします(リスト1)。

[リスト1]expo-cameraのインストール
$ npx expo install expo-camera

 カメラのパーミッションを取得し、基本的なQRコードリーダーを実装します(リスト2)。

[リスト2]app/qr-reader.js
import React, { useState, useEffect } from 'react';
import { StyleSheet, Text, View, Alert } from 'react-native';
import { CameraView, useCameraPermissions } from 'expo-camera';

export default function App() {
  // (1) カメラのパーミッション状態を管理するstate
  const [permission, requestPermission] = useCameraPermissions();
  // (2) スキャンされたQRコードのデータを保存するstate
  const [scanned, setScanned] = useState(false);
  const [qrData, setQrData] = useState('');
  
  // (3) コンポーネントのマウント時にパーミッションを要求
  useEffect(() => {
    (async () => {
      if (!permission?.granted) {
        const { status } = await requestPermission();
        
        if (status !== 'granted') {
          Alert.alert(
            'カメラへのアクセスが必要です',
            'このアプリはQRコード読み取りのためにカメラへのアクセスが必要です。設定からパーミッションを変更してください。',
            [{ text: 'OK' }]
          );
        }
      }
    })();
  }, []);

  // (4) パーミッションの状態に応じて表示を切り替え
  if (!permission) {
    return <View style={styles.container}><Text>カメラの許可を確認中...</Text></View>;
  }
  if (!permission.granted) {
    return (
      <View style={styles.container}>
        <Text>カメラへのアクセスが拒否されました</Text>
        <Text>設定アプリからカメラへのアクセスを許可してください</Text>
      </View>
    );
  }

  // (5) QRコードがスキャンされたときのハンドラー
  const handleBarCodeScanned = ({ type, data }) => {
    setScanned(true);
    setQrData(data);
    Alert.alert(
      'QRコード読み取り成功',
      `タイプ: ${type}\nデータ: ${data}`,
      [
        { 
          text: '再スキャン', 
          onPress: () => setScanned(false) 
        }
      ]
    );
  };

  // (6) パーミッションが許可された場合、カメラを表示
  return (
    <View style={styles.container}>
      <CameraView
        style={styles.camera}
        facing="back"
        onBarcodeScanned={scanned ? undefined : handleBarCodeScanned}
        barcodeScannerSettings={{
          barcodeTypes: ["qr"],
        }}
      >
        <View style={styles.overlay}>
          <Text style={styles.text}>
            {scanned 
              ? `QRコード: ${qrData}` 
              : 'QRコードをスキャンしてください'}
          </Text>
        </View>
      </CameraView>
    </View>
  );
}

// スタイル定義は省略

 (1)では、カメラのパーミッション状態を管理するために useCameraPermissions() フックを使用しています。(2)では、スキャンされたQRコードのデータと状態を管理するための state を定義しています。

 (3)では、コンポーネントのマウント時にカメラのパーミッションを要求しています。(4)では、パーミッションの状態に応じて表示を切り替えています。

 (5)では、QRコードがスキャンされたときの処理を定義しています。handleBarCodeScanned 関数は、QRコードのタイプとデータを受け取り、それをユーザーに表示します。

 (6)では、パーミッションが許可された場合にQRコードスキャナーを表示しています。barcodeScannerSettings プロパティを使用して、QRコードのみを検出するように設定しています。

図1:カメラパーミッションの要求ダイアログ(左:iOS、右:Android)
図1:カメラパーミッションの要求ダイアログ(左:iOS、右:Android)

 ちなみに、図1のダイアログのメッセージは、app.jsonでカスタマイズできます(リスト3)。

[リスト3]app.json
{
  "expo": {
    "plugins": [
      [
        "expo-camera",
        {
          "cameraPermission": "QRコードを読み取るために $(PRODUCT_NAME) にカメラの使用を許可してください"
        }
      ]
    ]
  }
}

 $(PRODUCT_NAME) は、自動でアプリの名前に置き換えられます。iOSアプリの審査では、ダイアログのメッセージでカメラの利用用途を明確にユーザーへ伝えることを求められる場合もあります。QRコード読み取りという目的を明示することで、ユーザーの理解と信頼を得やすくなります。

 なお、本連載で次回以降に解説するEAS Buildでビルドしたアプリにはカスタマイズが反映されますが、Expo Goではカスタマイズできない点に注意してください。

 図2は、QRコードリーダーが実際に動作している様子です。QRコードを読み取ると、データ内容が画面に表示されます。

図2:QRコードリーダーが実際に動作している様子(左:iOS、右:Android)
図2:QRコードリーダーが実際に動作している様子(左:iOS、右:Android)

 このように、Expoでは簡単にQRコード読み取り機能を組み込むことができます。Webサイトへのリンクや連絡先情報など、QRコードに格納されているデータの種類に応じた処理を追加することで、より実用的なアプリケーションを開発できるでしょう。

 他にもexpo-cameraモジュールにはカメラ操作に関する便利な機能があるので、公式ドキュメントを参照してみてください。

次のページ
位置情報機能の実装

この記事は参考になりましたか?

ExpoとEASで始める快適モバイルアプリ開発連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 中川 幸哉(ナカガワ ユキヤ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/21346 2025/04/18 11:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー