1년에 한 번씩 NFC(FeliCa)를 안드로이드로 하는 사람들의 노트(2019년 초여름)

18550 단어 FeliCaAndroidJavaNFC
펠리카의 일은 오랫동안 하지 않았기 때문에 필기를 한다.
사실 저는 Kotlin으로 쓰고 싶은데 과거의 출처를 참고하고 싶어서 Java로 먼저 씁니다.

하고 싶은 일

  • IDm를 취득하고 싶습니다
  • 먼저 Java를 사용합니다
  • 개발 환경은 Android Studio(3.4는 Mac에서 사용)입니다
  • 규격


    네트워크에 대량으로 존재하는 샘플은 대부분 NfcAdapter입니다.enable Foreground Dispatch()를 사용하여 응용 프로그램이 프론트에 있는 동안 계속 읽고 식별 후 Intende 처리를 하는 것이 많지만 이 규격이라면 읽는 시기와 기능의 On/Off를 제어하기 어려워서 NfcAdapter입니다.enableReaderMode()를 사용해 보십시오.
    이벤트 구동 때문에 읽을 수 없습니까?중요한 건 onClick으로 읽고 싶은데 스마트한 방법을 몰라요.누가 말해줘요?

    사양 개요


    응용 프로그램의 동작은 다음과 같다.
  • READER MODE ON 버튼(btn01)을 읽기 시작합니다
  • TextView(txt01)에 읽기 전용으로 표시됩니다
  • READER MODE OFF 버튼(btn02) 읽기 중지
  • 다음 동작

    주의사항


    읽기/쓰기 기능을 ON으로 설정


    Reader/Writer 기능을 사용하는 응용 프로그램을 개발할 때 Android(9.0시)의 설정에서 [설정]->[연결 장치]->[연결 설정]->NFC [NFC/지갑 핸드폰 설정]->[Reader/Write, P2P] 기능을 On으로 설정해야 합니다.

    기존 애플리케이션 제거 (가능한 경우)


    다른 NFC 기능을 사용하는 응용 프로그램, 특히 백그라운드에서 Intent가 생성되기를 기다리는 응용 프로그램(예를 들어 지갑 핸드폰 응용 프로그램)은 개발에 영향을 미치므로 필요하지 않으면 삭제하는 것이 좋다.
    다른 한편, 일반인을 위한 응용 프로그램의 경우 사용자가 다른 NFC 응용 프로그램을 설치한 것을 전제로 규격을 고려해야 한다.

    실시


    낭비는 많지만 각종 주요 코드를 붙여야 한다.

    AndroidManifest.xml


    NFC 권한이 추가되었습니다.
    AndroidManifest.xml
    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="jp.bluecode.buttontest">
    
        <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">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
    
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>
    
    +   <uses-permission android:name="android.permission.NFC" />
    
    </manifest>
    

    activity_main.xml


    참고 가치는 없지만 어쨌든.
    화면은 스스로 적당히 배치하는 것이 비교적 빠르다.
    activity_main.xml
    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.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=".MainActivity">
    
        <TextView
            android:id="@+id/txt01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_marginTop="8dp"
            android:text="Read ID ..."
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintLeft_toLeftOf="parent"
            app:layout_constraintRight_toRightOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.308" />
    
        <Button
            android:id="@+id/btn01"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text=" Reader Mode On"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/txt01"
            app:layout_constraintVertical_bias="0.107" />
    
        <Button
            android:id="@+id/btn02"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Reader Mode Off"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintHorizontal_bias="0.498"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/btn01"
            app:layout_constraintVertical_bias="0.116" />
    
    </android.support.constraint.ConstraintLayout>
    

    MainActivity


    가능한 한 요점을 줄이기 위해 생략했다.
    IDm를 취득할 때까지 NfcAdapter를 만들고 Tag를 취득하면 Tag가 됩니다.getId()의 느낌은 IDm를 얻을 수 있습니다.
    자바는 byte열을 String 함수로 설정하는 표준이 없기 때문에 사용자 정의 함수로 준비하지만 거기는 비교적 길다.
    MainActivity.java
    package jp.bluecode.buttontest;
    
    import android.nfc.NfcAdapter;
    import android.nfc.Tag;
    import android.os.Handler;
    import android.os.Looper;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.util.Log;
    import android.view.View;
    import android.widget.Button;
    import android.widget.TextView;
    
    import java.util.Formatter;
    import java.util.Locale;
    
    public class MainActivity extends AppCompatActivity {
    
        //Viewで使う変数を初期化(別にここじゃなくてもいいけど)
        TextView txt01;
        Button btn01;
        Button btn02;
    
        //NfcAdapterを初期化
        NfcAdapter nfcAdapter;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            //UIのマーツをマッピング
            txt01 = findViewById(R.id.txt01);
            btn01 = findViewById(R.id.btn01);
            btn02 = findViewById(R.id.btn02);
    
            //nfcAdapter初期化
            nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    
            //Reader Mode Offボタンのenabledをfalseに(トグルにするため)
            btn02.setEnabled(false);
    
            btn01.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    //トグル機能
                    btn01.setEnabled(false);
                    btn02.setEnabled(true);
    
                    //Redermode On
                    nfcAdapter.enableReaderMode(MainActivity.this,new MyReaderCallback(),NfcAdapter.FLAG_READER_NFC_F,null);
                }
            });
    
            btn02.setOnClickListener(new View.OnClickListener(){
                @Override
                public void onClick(View v) {
                    //トグル機能
                    btn01.setEnabled(true);
                    btn02.setEnabled(false);
    
                    //Readermode Off
                    nfcAdapter.disableReaderMode(MainActivity.this);
    
                    //表示初期化
                    txt01.setText("Read ID ...");
                }
            });
        }
    
        //Callback Class
        private class MyReaderCallback implements NfcAdapter.ReaderCallback{
            @Override
            public void onTagDiscovered(Tag tag){
    
                Log.d("Hoge","Tag discoverd.");
    
                //get idm
                byte[] idm = tag.getId();
                final String idmString = bytesToHexString(idm);
    
                //idm取るだけじゃなくてread,writeしたい場合はtag利用してごにょごにょする
    
                //親スレッドのUIを更新するためごにょごにょ
                final Handler mainHandler = new Handler(Looper.getMainLooper());
                mainHandler.post(new Runnable() {
                    @Override
                    public void run() {
                        txt01.setText(idmString);
                    }
                });
    
            }
        }
    
        //bytes列を16進数文字列に変換(めんどい)
        public static String bytesToHexString(byte[] bytes) {
            StringBuilder sb = new StringBuilder();
    
            Formatter formatter = new Formatter(sb);
            for (byte b : bytes) {
                formatter.format("%02x", b);
            }
    
            return sb.toString().toUpperCase(Locale.getDefault());
        }
    }
    
    간단하지만 이만 마치겠습니다.

    좋은 웹페이지 즐겨찾기