我正在实现CreateNdefMessageCallback和OnNdefPushCompleteCallback。由于某些原因,永远不要触碰回调方法,日志中也不会出现错误。

虽然我确实从API听到声音,但我正在调试的手机是运行版本4.0.4的NexusS。

这是我的活动:

public class TestActivity extends Activity implements CreateNdefMessageCallback, OnNdefPushCompleteCallback
{
  private static SoundHelper soundHelper;

  private PowerManager.WakeLock wakeLock;

  private NfcAdapter nfcAdapter;
  private PendingIntent pendingIntent = null;
  private IntentFilter[] intentFiltersArray;
  private String[][] techListsArray;

  private TextView onScreenLog;
  private List<String> uniqueTagsRead = new ArrayList<String>();

  /** handler stuff */
  private static final int MESSAGE_SENT = 1;
  private final Handler handler = new Handler()
  {
    @Override
    public void handleMessage(Message msg)
    {
      switch (msg.what)
      {
        case MESSAGE_SENT:
          if (soundHelper != null)
          {
            soundHelper.playSound(R.raw.smw_coin);
          }

          updateTagCount();
          break;
      }
    }
  };

  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState)
  {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.test);

    soundHelper = new SoundHelper(this);

    onScreenLog = (TextView) findViewById(R.id.log);

    // nfc adapter
    nfcAdapter = NfcAdapter.getDefaultAdapter(this);
    if (nfcAdapter != null)
    {
      // callbacks
      nfcAdapter.setNdefPushMessageCallback(this, this);
      nfcAdapter.setOnNdefPushCompleteCallback(this, this);

      // other stuff
      nfcAdapter = NfcAdapter.getDefaultAdapter(this);
      pendingIntent = PendingIntent.getActivity(this, 0, new Intent(this, getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0);
      IntentFilter ndef = new IntentFilter(NfcAdapter.ACTION_NDEF_DISCOVERED);
      try
      {
        ndef.addDataType("*/*");
      }
      catch (MalformedMimeTypeException e)
      {
        throw new RuntimeException("fail", e);
      }
      intentFiltersArray = new IntentFilter[] {ndef, };
      techListsArray = new String[][] {
          new String[] { IsoDep.class.getName() },
          new String[] { NfcA.class.getName() },
          new String[] { NfcB.class.getName() },
          new String[] { NfcF.class.getName() },
          new String[] { NfcV.class.getName() },
          new String[] { Ndef.class.getName() },
          new String[] { NdefFormatable.class.getName() },
          new String[] { MifareClassic.class.getName() },
          new String[] { MifareUltralight.class.getName() },
      };
    }
    else
    {
      onScreenLog.setText("NFC is not available on this device. :(");
    }
  }

  public void onPause()
  {
    super.onPause();

    // end wake lock
    wakeLock.release();

    nfcAdapter.disableForegroundDispatch(this);
  }

  public void onResume()
  {
    super.onResume();

    // start wake lock
    PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
    wakeLock = powerManager.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DoNotDimScreen");
    wakeLock.acquire();

    nfcAdapter.enableForegroundDispatch(this, pendingIntent, intentFiltersArray, techListsArray);
  }

  private void updateTagCount()
  {
    String newCount = String.valueOf(uniqueTagsRead.size());
    String text = getString(R.string.format_count);
    text = getString(R.string.format_count).replace("0", newCount);

    onScreenLog.setText(text);
  }

  @Override
  public NdefMessage createNdefMessage(NfcEvent event)
  {
    String message = "This is NFC message";
    NdefRecord mimeRecord = createMimeRecord("application/param.android.sample.beam",
    message.getBytes());
    NdefRecord appRecord = NdefRecord.createApplicationRecord("param.android.sample.beam");
    NdefRecord[] ndefRecords = new NdefRecord[] {
    mimeRecord,
    appRecord
    };
    NdefMessage ndefMessage = new NdefMessage(ndefRecords);
    return ndefMessage;

    /*
    String mimeType = "text/plain"; // "text/plain";

    NdefRecord[] data = {createMimeRecord(mimeType, TEXT_TO_WRITE.getBytes())};
    // data[data.length - 1] = NdefRecord.createApplicationRecord(); // com.test.nfc.application.activities.

    return new NdefMessage(data);
    */
  }

  /**
   * Creates a custom MIME type encapsulated in an NDEF record
   *
   * @param mimeType
   */
  public NdefRecord createMimeRecord(String mimeType, byte[] payload)
  {
    byte[] mimeBytes = mimeType.getBytes(Charset.forName("US-ASCII"));
    NdefRecord mimeRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA, mimeBytes, new byte[0], payload);

    return mimeRecord;
  }

  @Override
  public void onNdefPushComplete(NfcEvent event)
  {
    handler.obtainMessage(MESSAGE_SENT).sendToTarget();
  }
}


表现:
    
    

    <uses-sdk android:minSdkVersion="14" />

    <supports-screens android:anyDensity="true" />

    <uses-permission android:name="android.permission.NFC"/>
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />

    <uses-feature android:name="android.hardware.nfc" />

    <application android:name="com.test.nfc.application.Application"
        android:icon="@drawable/icon_launcher_nfc_droid_hdpi"
        android:theme="@android:style/Theme.Light"
        android:label="@string/app_name">

        <activity
            android:label="@string/app_name"
            android:name=".application.activities.MainActivity"
            android:configChanges="orientation|keyboardHidden">
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <activity
            android:label="@string/test"
            android:name=".application.activities.TestActivity"
            android:configChanges="orientation|keyboardHidden"
            android:launchMode="singleTop">

            <intent-filter>
              <action android:name="android.nfc.action.TECH_DISCOVERED"/>
            </intent-filter>
            <meta-data android:name="android.nfc.action.TECH_DISCOVERED" android:resource="@xml/nfc_tech_list" />

        </activity>

    </application>

</manifest>


技术员

<?xml version="1.0" encoding="utf-8"?>
<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>

最佳答案

从您的问题和示例代码中,我是否很清楚您是要接收NDEF消息,发送它们还是同时发送这两种消息。

使用NfcAdapter.enableForegroundDispatch()时,将通过调用onNewIntent()通知您的Activity有关新的NFC意图,因此您应在Activity中重写该方法以接收意图。

NfcAdapter.CreateNdefMessageCallbackNfcAdapter.OnNdefPushCompleteCallback用于通过Android Beam将NDEF数据发送到另一个NFC设备。用户需要点击屏幕以激活发送NDEF消息,这将导致呼叫createNdefMessage()onNdefPushComplete()

再说一遍:如果将null作为过滤器和techLists参数传递给NfcAdapter.enableForegroundDispatch(),它们将充当通配符(因此,您无需像现在一样声明完整的技术列表)。

关于java - 无法使用4.x Android NFC API推送NdefMessage,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/10081852/

10-11 20:12