NFC

2018. 10. 22. 16:23Android

반응형

o AndroidManifest.xml

<uses-sdk android:minSdkVersion="10"/>
<uses-permission android:name="android.permission.NFC"/>
<uses-feature
android:name="android.hardware.nfc"
android:required="true"/>
<activity android:name=".NFC.NFCActivity">
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/plain"/>
</intent-filter>
<meta-data
android:name="android.nfc.action.TECH_DISCOVERED"
android:resource="@xml/nfc_tech_filter" />
</activity>

o  res/xml/nfc_tech_filter.xml

<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<tech-list>
<tech>android.nfc.tech.IsoDep</tech>
<tech>android.nfc.tech.NfcA</tech>
<tech>android.nfc.tech.NfcB</tech>
<tech>android.nfc.tech.NfcF</tech>
<tech>android.nfc.tech.NfcV</tech>
<tech>android.nfc.tech.Ndef</tech>
<tech>android.nfc.tech.NdefFormatable</tech>
<tech>android.nfc.tech.MifareClassic</tech>
<tech>android.nfc.tech.MifareUltralight</tech>
</tech-list>
</resources>

o  res/layout/activity_nfc.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Write a message: ">
</TextView>

<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20sp" >

<EditText
android:id="@+id/edit_message"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="2"
android:hint="message" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="Write" />
</LinearLayout>

<TextView
android:id="@+id/nfc_contents"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>

</LinearLayout>

o NFCActivity.java

public class NFCActivity extends AppCompatActivity {

public static final String ERROR_DETECTED = "No NFC tag detected!";
public static final String WRITE_SUCCESS = "Text written to the NFC tag successfully!";
public static final String WRITE_ERROR = "Error during writing, is the NFC tag close enough to your device?";

private static final int TYPE_TEXT = 1;
private static final int TYPE_URI = 2;
private static int FILTER_TYPE;

private NfcAdapter nfcAdapter;
private PendingIntent pendingIntent;
private IntentFilter writeTagFilters[];
private boolean writeMode;
private Tag myTag;
private Context mContext;

private TextView tvNFCContent;
private TextView message;
private Button btnWrite;

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nfc);

mContext = this;

tvNFCContent = (TextView) findViewById(R.id.nfc_contents);
message = (TextView) findViewById(R.id.edit_message);
btnWrite = (Button) findViewById(R.id.button);

btnWrite.setOnClickListener(new View.OnClickListener()
{
@Override
public void onClick(View v) {
try {
if(myTag ==null) {
Toast.makeText(mContext, ERROR_DETECTED, Toast.LENGTH_LONG).show();
} else {
write(message.getText().toString(), myTag);
Toast.makeText(mContext, WRITE_SUCCESS, Toast.LENGTH_LONG ).show();
}
} catch (IOException e) {
Toast.makeText(mContext, WRITE_ERROR, Toast.LENGTH_LONG ).show();
e.printStackTrace();
} catch (FormatException e) {
Toast.makeText(mContext, WRITE_ERROR, Toast.LENGTH_LONG ).show();
e.printStackTrace();
}
}
});

nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
// Stop here, we definitely need NFC
Toast.makeText(this, "This device doesn't support NFC.", Toast.LENGTH_LONG).show();
finish();
}
if(!nfcAdapter.isEnabled()){
// 4.2.2 (API 17) 부터 NFC 설정 환경이 변경됨.
if(Build.VERSION.SDK_INT > Build.VERSION_CODES.JELLY_BEAN) {
startActivity(new Intent(android.provider.Settings.ACTION_NFC_SETTINGS));
}else{
startActivity(new Intent(android.provider.Settings.ACTION_WIRELESS_SETTINGS));
}
}

readFromIntent(getIntent());

pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
IntentFilter tagDetected = new IntentFilter(NfcAdapter.ACTION_TAG_DISCOVERED);
tagDetected.addCategory(Intent.CATEGORY_DEFAULT);
writeTagFilters = new IntentFilter[] { tagDetected };
}


/******************************************************************************
**********************************Read From NFC Tag***************************
******************************************************************************/
private void readFromIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = intent.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage[] msgs = null;
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
}
buildTagViews(msgs);
}
}
private void buildTagViews(NdefMessage[] msgs) {
if (msgs == null || msgs.length == 0) return;

String text = "";
// String tagId = new String(msgs[0].getRecords()[0].getType());
byte[] payload = msgs[0].getRecords()[0].getPayload();
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16"; // Get the Text Encoding
int languageCodeLength = payload[0] & 0063; // Get the Language Code, e.g. "en"
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");

try {
// Get the Text
text = new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
} catch (UnsupportedEncodingException e) {
Log.e("UnsupportedEncoding", e.toString());
}

tvNFCContent.setText("NFC Content: " + text);
}


/******************************************************************************
**********************************Write to NFC Tag****************************
******************************************************************************/
private void write(String text, Tag tag) throws IOException, FormatException {
// NdefRecord[] records = { createTextRecord(text) };
// NdefMessage message = new NdefMessage(records);
NdefMessage message = createTagMessage(text, FILTER_TYPE);
// Get an instance of Ndef for the tag.
Ndef ndef = Ndef.get(tag);
// Enable I/O
ndef.connect();
// Write the message
ndef.writeNdefMessage(message);
// Close the connection
ndef.close();
}

private NdefMessage createTagMessage(String msg, int type){
NdefRecord[] records = new NdefRecord[1];
if(type == TYPE_TEXT){
records[0] = createTextRecord(msg, Locale.KOREAN, true);
}else if(type == TYPE_URI){
records[0] = createUriRecord(msg.getBytes());
}

NdefMessage message = new NdefMessage(records);
return message;
}

private NdefRecord createTextRecord(String text) throws UnsupportedEncodingException {
String lang = "en";
byte[] textBytes = text.getBytes();
byte[] langBytes = lang.getBytes("US-ASCII");
int langLength = langBytes.length;
int textLength = textBytes.length;
byte[] payload = new byte[1 + langLength + textLength];

// set status byte (see NDEF spec for actual bits)
payload[0] = (byte) langLength;

// copy langbytes and textbytes into payload
System.arraycopy(langBytes, 0, payload, 1, langLength);
System.arraycopy(textBytes, 0, payload, 1 + langLength, textLength);

NdefRecord recordNFC = new NdefRecord(NdefRecord.TNF_WELL_KNOWN, NdefRecord.RTD_TEXT, new byte[0], payload);

return recordNFC;
}

/**
* https://developer.android.com/guide/topics/connectivity/nfc/nfc#java
* @param payload
* @param locale
* @param encodeInUtf8
* @return
*/
public NdefRecord createTextRecord(String payload, Locale locale, boolean encodeInUtf8) {
byte[] langBytes = locale.getLanguage().getBytes(Charset.forName("US-ASCII"));
Charset utfEncoding = encodeInUtf8 ? Charset.forName("UTF-8") : Charset.forName("UTF-16");
byte[] textBytes = payload.getBytes(utfEncoding);
int utfBit = encodeInUtf8 ? 0 : (1 << 7);
char status = (char) (utfBit + langBytes.length);
byte[] data = new byte[1 + langBytes.length + textBytes.length];
data[0] = (byte) status;
System.arraycopy(langBytes, 0, data, 1, langBytes.length);
System.arraycopy(textBytes, 0, data, 1 + langBytes.length, textBytes.length);
NdefRecord record = new NdefRecord(NdefRecord.TNF_WELL_KNOWN,
NdefRecord.RTD_TEXT, new byte[0], data);
return record;
}

private NdefRecord createUriRecord(byte[] data){
return new NdefRecord(NdefRecord.TNF_ABSOLUTE_URI, NdefRecord.RTD_URI, new byte[0], data);
}


/**
* 단말이 NFC 태그를 수신하면 NDEF메시지인지 확인하여 NDEF메시지이면 NDEF_DISCOVERED를 액션으로 가진
* Activity중 처리할 Activity를 찾아 인텐트를 전달한다.
* 만약 아니면 TECH_DISCOVERED를 가진 Activit에게 전달한다.
* 그것도 없으면 TAG_DISCOVERED를 가진 Activity를 구동한다.
* @param intent
*/
@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
readFromIntent(intent);
if(NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())){
myTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
}

if("text/plain".equals(intent.getType()))
FILTER_TYPE = 1;
else
FILTER_TYPE = 2;
}

@Override
public void onPause(){
super.onPause();
WriteModeOff();
}

@Override
public void onResume(){
super.onResume();
WriteModeOn();
}

/******************************************************************************
**********************************Enable Write********************************
******************************************************************************/
private void WriteModeOn(){
writeMode = true;
nfcAdapter.enableForegroundDispatch(this, pendingIntent, writeTagFilters, null);
}

/******************************************************************************
**********************************Disable Write*******************************
******************************************************************************/
private void WriteModeOff(){
writeMode = false;
nfcAdapter.disableForegroundDispatch(this);
}
}

https://developer.android.com/guide/topics/connectivity/nfc/nfc

https://www.codexpedia.com/android/android-nfc-read-and-write-example/

http://blog.naver.com/PostView.nhn?blogId=horajjan&logNo=220492560615

http://humble.tistory.com/34



반응형

'Android' 카테고리의 다른 글

FingerPrint(지문인증)  (0) 2018.11.06
BarCode, QRCode&Scan  (0) 2018.11.06
안드로이드 실행환경  (0) 2018.10.19
가로 막대 프로그레스바  (0) 2018.10.15
MD5, SHA1, SHA256  (0) 2018.10.03