目前我正在编写一个扫描NFC标签的应用程序,并告诉您在标签上写了什么。
但现在我遇到了问题。我在菜单中写了一个Intent,以便从菜单中进入该Scan-Page。但是当我粘贴扫描NFC标签的代码时,意图突然停止工作。
我可以毫无问题地安装应用程序并且没有错误,但是当我点击菜单中的按钮时,我应该将我带到我扫描NFC标签的页面,应用程序就会崩溃。
我真的不知道错误在哪里,如果你能帮助我,我会很高兴。
我将提供目前为止的代码:
Menu with Intents:
package com.example.kristian.nfcproject;
import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
public class nfc_menu extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nfc_menu);
getSupportActionBar().hide();
Button buttonLogout = (Button) findViewById(R.id.buttonLogout);
Button buttonProfil = (Button) findViewById(R.id.buttonProfil);
Button buttonAssets = (Button) findViewById(R.id.buttonAssets);
Button buttonNfcid = (Button) findViewById(R.id.buttonNfcid);
Button buttonNfcscan = (Button) findViewById(R.id.buttonNfcscan);
buttonLogout.setOnClickListener(
new Button.OnClickListener()
{
public void onClick(View v)
{
Intent logoutI = new Intent(v.getContext(), MainActivity.class);
startActivity(logoutI);
}
}
);
buttonProfil.setOnClickListener(
new Button.OnClickListener()
{
public void onClick(View v)
{
Intent meinprofilI = new Intent(v.getContext(), meinprofil.class);
startActivity(meinprofilI);
}
}
);
buttonAssets.setOnClickListener(
new Button.OnClickListener()
{
public void onClick(View v)
{
Intent assetsI = new Intent(v.getContext(), meineassets.class);
startActivity(assetsI);
}
}
);
buttonNfcid.setOnClickListener(
new Button.OnClickListener()
{
public void onClick(View v)
{
Intent nfcidI = new Intent(v.getContext(), nfcidhinzu.class);
startActivity(nfcidI);
}
}
);
buttonNfcscan.setOnClickListener(
new Button.OnClickListener()
{
public void onClick(View v)
{
Intent nfcscannI = new Intent(v.getContext(), nfctagscann.class);
startActivity(nfcscannI);
}
}
);
}
}
NFC扫描活动:
package com.example.kristian.nfcproject;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentFilter;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.nfc.Tag;
import android.nfc.tech.Ndef;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;
import android.content.IntentFilter.MalformedMimeTypeException;
import android.view.View;
import android.widget.Button;
import com.example.kristian.nfcproject.R;
import java.io.UnsupportedEncodingException;
import java.util.Arrays;
public class nfctagscann extends AppCompatActivity {
TextView text;
NfcAdapter nfcAdapter;
public static final String MIME_TEXT_PLAIN = "text/plain";
public static final String TAG = "NfcDemo";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nfcidhinzu);
getSupportActionBar().hide();
text = (TextView) findViewById(R.id.textView);
nfcAdapter = NfcAdapter.getDefaultAdapter(this);
if (nfcAdapter == null) {
Toast.makeText(this, "This Device doesn't support NFC", Toast.LENGTH_LONG).show();
finish();
}
if (!nfcAdapter.isEnabled()) {
text.setText("Please enable NFC in your settings.");
} else {
text.setText(R.string.explanation);
}
handleIntent(getIntent());
}
@Override
protected void onResume() {
super.onResume();
/**
* It's important, that the activity is in the foreground (resumed). Otherwise
* an IllegalStateException is thrown.
*/
setupForegroundDispatch(this, nfcAdapter);
}
@Override
protected void onPause() {
/**
* Call this before onPause, otherwise an IllegalArgumentException is thrown as well.
*/
stopForegroundDispatch(this, nfcAdapter);
super.onPause();
}
@Override
protected void onNewIntent(Intent intent) {
/**
* This method gets called, when a new Intent gets associated with the current activity instance.
* Instead of creating a new activity, onNewIntent will be called. For more information have a look
* at the documentation.
*
* In our case this method gets called, when the user attaches a Tag to the device.
*/
handleIntent(intent);
}
public static void setupForegroundDispatch(final Activity activity, NfcAdapter adapter) {
final Intent intent = new Intent(activity.getApplicationContext(), activity.getClass());
intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
final PendingIntent pendingIntent = PendingIntent.getActivity(activity.getApplicationContext(), 0, intent, 0);
IntentFilter[] filters = new IntentFilter[1];
String[][] techList = new String[][]{};
// Notice that this is the same filter as in our manifest.
filters[0] = new IntentFilter();
filters[0].addAction(NfcAdapter.ACTION_NDEF_DISCOVERED);
filters[0].addCategory(Intent.CATEGORY_DEFAULT);
try {
filters[0].addDataType(MIME_TEXT_PLAIN);
} catch (MalformedMimeTypeException e) {
throw new RuntimeException("Check your mime type.");
}
adapter.enableForegroundDispatch(activity, pendingIntent, filters, techList);
}
public static void stopForegroundDispatch(final Activity activity, NfcAdapter adapter) {
adapter.disableForegroundDispatch(activity);
}
private void handleIntent(Intent intent) {
String action = intent.getAction();
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
String type = intent.getType();
if (MIME_TEXT_PLAIN.equals(type)) {
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
new NdefReaderTask().execute(tag);
} else {
Log.d(TAG, "Wrong mime type: " + type);
}
} else if (NfcAdapter.ACTION_TECH_DISCOVERED.equals(action)) {
// In case we would still use the Tech Discovered Intent
Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
String[] techList = tag.getTechList();
String searchedTech = Ndef.class.getName();
for (String tech : techList) {
if (searchedTech.equals(tech)) {
new NdefReaderTask().execute(tag);
break;
}
}
}
}
private class NdefReaderTask extends AsyncTask<Tag, Void, String> {
@Override
protected String doInBackground(Tag... params) {
Tag tag = params[0];
Ndef ndef = Ndef.get(tag);
if (ndef == null) {
// NDEF is not supported by this Tag.
return null;
}
NdefMessage ndefMessage = ndef.getCachedNdefMessage();
NdefRecord[] records = ndefMessage.getRecords();
for (NdefRecord ndefRecord : records) {
if (ndefRecord.getTnf() == NdefRecord.TNF_WELL_KNOWN && Arrays.equals(ndefRecord.getType(), NdefRecord.RTD_TEXT)) {
try {
return readText(ndefRecord);
} catch (UnsupportedEncodingException e) {
Log.e(TAG, "Unsupported Encoding", e);
}
}
}
return null;
}
private String readText(NdefRecord record) throws UnsupportedEncodingException {
/*
* See NFC forum specification for "Text Record Type Definition" at 3.2.1
*
* http://www.nfc-forum.org/specs/
*
* bit_7 defines encoding
* bit_6 reserved for future use, must be 0
* bit_5..0 length of IANA language code
*/
byte[] payload = record.getPayload();
// Get the Text Encoding
String textEncoding = ((payload[0] & 128) == 0) ? "UTF-8" : "UTF-16";
// Get the Language Code
int languageCodeLength = payload[0] & 0063;
// String languageCode = new String(payload, 1, languageCodeLength, "US-ASCII");
// e.g. "en"
// Get the Text
return new String(payload, languageCodeLength + 1, payload.length - languageCodeLength - 1, textEncoding);
}
@Override
protected void onPostExecute(String result) {
if (result != null) {
text.setText("NFC INHALT" + result);
}
}
}
}
在将预先编写的代码粘贴到App中之前,Intent工作正常,现在当我点击按钮进入扫描活动时,应用程序崩溃了。
我感谢各种帮助:)
日志:
03-19 18:34:27.669 22810-22810/com.example.kristian.nfcproject E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.kristian.nfcproject, PID: 22810
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.kristian.nfcproject/com.example.kristian.nfcproject.nfctagscann}: java.lang.IllegalStateException: Already attached
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2924)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2985)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)
Caused by: java.lang.IllegalStateException: Already attached
at android.support.v4.app.FragmentManagerImpl.attachController(FragmentManager.java:3146)
at android.support.v4.app.FragmentController.attachHost(FragmentController.java:95)
at android.support.v4.app.FragmentActivity.onCreate(FragmentActivity.java:283)
at android.support.v7.app.AppCompatActivity.onCreate(AppCompatActivity.java:84)
at com.example.kristian.nfcproject.nfctagscann.onCreate(nfctagscann.java:42)
at android.app.Activity.performCreate(Activity.java:6912)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1126)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2877)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2985)
at android.app.ActivityThread.-wrap14(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1635)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6692)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)