2014-11-06 114 views
1

我試圖讓人們使用我的應用程序寫入NFC標籤,以便使用自定義參數啓動我的應用程序。我希望能夠重新編程已經有數據的NFC標籤。如何寫NFC標籤,同時防止WP啓動當前存儲在NFC標籤上的動作

我正在使用下面的代碼,但問題是,WP總是識別已經在NFC標籤上的動作,並因爲它想要啓動之前任何時候寫入的NFC標籤動作而中斷。

如何告訴操作系統停止觸發標籤的操作,以便我可以立即重寫它?

public enum NfcHelperState 
{ 
    Initializing, 
    Waiting, 
    Ready, 
    Writing, 
    Finished, 
    Error, 
    NoDeviceFound 
} 
public class NfcHelper 
{ 
    private NfcHelperState _state = NfcHelperState.Initializing; 

    public NfcHelperState State 
    { 
     get { return _state; } 
    } 


    private ProximityDevice _nfcDevice; 

    private long _subscriptionId; 
    public NfcHelper() 
    { 
     Init(); 
    } 

    public void Init() 
    { 
     UpdateState(); 
     _nfcDevice = ProximityDevice.GetDefault(); 
     if (_nfcDevice == null) 
     { 
      UpdateState(NfcHelperState.NoDeviceFound); 
      return; 
     } 
     UpdateState(NfcHelperState.Waiting); 
    } 

    private void UpdateState(NfcHelperState? state = null) 
    { 
     if (state.HasValue) 
     { 
      _state = state.Value; 
     } 
     if (OnStatusMessageChanged != null) 
     { 
      OnStatusMessageChanged(this, _state); 
     } 
    } 

    public void WriteToTag() 
    { 
     UpdateState(NfcHelperState.Ready); 
     _subscriptionId = _nfcDevice.SubscribeForMessage("WriteableTag", WriteableTagDetected); 
    } 

    private void WriteableTagDetected(ProximityDevice sender, ProximityMessage message) 
    { 
     UpdateState(NfcHelperState.Writing); 
     try 
     { 
      var str = "action=my_custom_action"; 
      str += "\tWindowsPhone\t"; 
      str += CurrentApp.AppId; 
      _nfcDevice.PublishBinaryMessage("LaunchApp:WriteTag", GetBufferFromString(str), 
       WriteToTagComplete); 
     } 
     catch (Exception e) 
     { 
      UpdateState(NfcHelperState.Error); 
      StopWaitingForTag(); 
     } 
    } 

    private void WriteToTagComplete(ProximityDevice sender, long messageId) 
    { 
     sender.StopPublishingMessage(messageId); 
     UpdateState(NfcHelperState.Finished); 
     StopWaitingForTag(); 
    } 

    private void StopWaitingForTag() 
    { 
     _nfcDevice.StopSubscribingForMessage(_subscriptionId); 
    } 

    private static IBuffer GetBufferFromString(string str) 
    { 
     using (var dw = new DataWriter()) 
     { 
      dw.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE; 
      dw.WriteString(str); 
      return dw.DetachBuffer(); 
     } 
    } 

    public delegate void NfcStatusMessageChangedHandler(object myObject, NfcHelperState newState); 

    public event NfcStatusMessageChangedHandler OnStatusMessageChanged; 
} 

WriteToTag當我的應用程序的按鈕被竊聽被調用,應用程序等待一個可寫標籤。如果可識別標籤被識別,WriteableTagDetected被調用並立即開始寫入過程。但是,這會被詢問是否執行NFC操作的WP對話框中斷。寫完後,應調用WriteToTagComplete,其中調用StopWaitingForTag並結束寫入過程。

我希望你們能幫助我:)

回答

1

原來我以爲是錯誤的方式。我不需要等待標籤到達以重寫它。事實上,寫作之前不需要做_nfcDevice.SubscribeForMessage("WriteableTag", WriteableTagDetected);。只需開始使用PublishBinaryMessage,它會在標籤到達設備時寫入標籤。

我的最終代碼如下所示:

public enum NfcHelperState 
{ 
    Initializing, 
    Ready, 
    WaitingForWriting, 
    FinishedWriting, 
    ErrorWriting, 
    NoDeviceFound 
} 
public class NfcHelper 
{ 
    private NfcHelperState _state = NfcHelperState.Initializing; 

    public NfcHelperState State 
    { 
     get { return _state; } 
    } 


    private ProximityDevice _nfcDevice; 
    private long? _writingMessageId; 

    public NfcHelper() 
    { 
     Init(); 
    } 

    public void Init() 
    { 
     UpdateState(); 
     _nfcDevice = ProximityDevice.GetDefault(); 
     if (_nfcDevice == null) 
     { 
      UpdateState(NfcHelperState.NoDeviceFound); 
      return; 
     } 


     UpdateState(NfcHelperState.Ready); 
    } 

    private void UpdateState(NfcHelperState? state = null) 
    { 
     if (state.HasValue) 
     { 
      _state = state.Value; 
     } 
     if (OnStatusMessageChanged != null) 
     { 
      OnStatusMessageChanged(this, _state); 
     } 
    } 

    public void WriteToTag() 
    { 
     StopWritingMessage(); 
     UpdateState(NfcHelperState.WaitingForWriting); 
     try 
     { 
      var str = new StringBuilder(); 
      str.Append("action=my_custom_action"); 
      str.Append("\tWindowsPhone\t{"); 
      str.Append(CurrentApp.AppId); 
      str.Append("}"); 
      _writingMessageId = _nfcDevice.PublishBinaryMessage("LaunchApp:WriteTag", GetBufferFromString(str.ToString()), 
       WriteToTagComplete); 
     } 
     catch 
     { 
      UpdateState(NfcHelperState.ErrorWriting); 
      StopWritingMessage(); 
     } 
    } 

    private void WriteToTagComplete(ProximityDevice sender, long messageId) 
    { 
     UpdateState(NfcHelperState.FinishedWriting); 
     StopWritingMessage(); 
    } 

    private void StopWritingMessage() 
    { 
     if (_writingMessageId.HasValue) 
     { 
      _nfcDevice.StopPublishingMessage(_writingMessageId.Value); 
      _writingMessageId = null; 
     } 
    } 

    private static IBuffer GetBufferFromString(string str) 
    { 
     using (var dw = new DataWriter()) 
     { 
      dw.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf16LE; 
      dw.WriteString(str); 
      return dw.DetachBuffer(); 
     } 
    } 

    public delegate void NfcStatusMessageChangedHandler(object myObject, NfcHelperState newState); 

    public event NfcStatusMessageChangedHandler OnStatusMessageChanged; 
}