1년에 한 번씩 NFC(FeliCa)를 안드로이드로 하는 사람들의 노트(2019년 초여름)
사실 저는 Kotlin으로 쓰고 싶은데 과거의 출처를 참고하고 싶어서 Java로 먼저 씁니다.
하고 싶은 일
규격
네트워크에 대량으로 존재하는 샘플은 대부분 NfcAdapter입니다.enable Foreground Dispatch()를 사용하여 응용 프로그램이 프론트에 있는 동안 계속 읽고 식별 후 Intende 처리를 하는 것이 많지만 이 규격이라면 읽는 시기와 기능의 On/Off를 제어하기 어려워서 NfcAdapter입니다.enableReaderMode()를 사용해 보십시오.
이벤트 구동 때문에 읽을 수 없습니까?중요한 건 onClick으로 읽고 싶은데 스마트한 방법을 몰라요.누가 말해줘요?
사양 개요
응용 프로그램의 동작은 다음과 같다.
주의사항
읽기/쓰기 기능을 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());
}
}
간단하지만 이만 마치겠습니다.
Reference
이 문제에 관하여(1년에 한 번씩 NFC(FeliCa)를 안드로이드로 하는 사람들의 노트(2019년 초여름)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/zaburo/items/6a34dfd8f87d7ffba56a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)