这是客户端二:
说明:这段代码实现的是nfc的读写操作。代码量看起来大,但大神其实不用管其它的,帮我看看onNewIntent这个方法的第一个if就可以了。
我用客户端一和服务端做测试,可以实现通信,服务端也打印出从客户端一获取的字符串。可当我把客户端一的代码移植到onNewIntent里的时候,就不管用了,这是为什么?我传的body不也是String类型吗?是哪里出了问题?我之前在服务端对收到的line进行判断,空就打印XXX,非空就打印XX,结果服务器端没任何反应
public class MainActivity extends Activity {
private static final String TAG = "stickynotes";
// private boolean mResumed = false;
private boolean mWriteMode = false;
NfcAdapter mNfcAdapter;
EditText mNote;
EditText mNoteRead;
PendingIntent mNfcPendingIntent;
IntentFilter[] mWriteTagFilters;
IntentFilter[] mNdefExchangeFilters; /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

// 要写入标签的文本的编辑框
mNote = ((EditText) findViewById(R.id.note));
mNote.addTextChangedListener(mTextWatcher);
// 显示 读取标签中的文本
mNoteRead = ((EditText) findViewById(R.id.noteRead));
// 获得一个默认的NFC Adapter
mNfcAdapter = NfcAdapter.getDefaultAdapter(this); if (mNfcAdapter == null) {
toast("设备不支持nfc!");
return;
}
// 给按钮设置监听
findViewById(R.id.write_tag).setOnClickListener(mTagWriter);
findViewById(R.id.read_tag).setOnClickListener(mTagRead); // Handle all of our received NFC intents in this activity.
// 创建一个PendingIntent对象,android系统可以在扫描到标签时填充标签的内容到这个对象中。
// 启动前台调度系统的第一步。(前台调度系统允许activity截取Intent并且声明自己优先处理Intent)
mNfcPendingIntent = PendingIntent.getActivity(this, 0, new Intent(this,
getClass()).addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP), 0); // Intent filters for reading a note from a tag or exchanging over p2p.
// 匹配NfcAdapter.ACTION_NDEF_DISCOVERED这个action的IntentFilter,这个action不带数据
IntentFilter ndefDetected = new IntentFilter(
NfcAdapter.ACTION_NDEF_DISCOVERED); try {
// addDataType:给这个IntentFilter添加一个新的Intent数据类型匹配
ndefDetected.addDataType("text/plain");
} catch (MalformedMimeTypeException e) {
}
mNdefExchangeFilters = new IntentFilter[] { ndefDetected }; // Intent filters for writing to a tag
IntentFilter tagDetected = new IntentFilter(
NfcAdapter.ACTION_TAG_DISCOVERED);
mWriteTagFilters = new IntentFilter[] { tagDetected };


} @Override
protected void onResume() {
super.onResume();
// mResumed = true;
// Sticky notes received from Android
// getIntent():返回启动这个Activity的intent. 这边是关键代码,获取NDEF Message!
if (NfcAdapter.ACTION_NDEF_DISCOVERED.equals(getIntent().getAction())) {
NdefMessage[] messages = getNdefMessages(getIntent());
byte[] payload = messages[0].getRecords()[0].getPayload();
// 自写方法:将从标签中读到的文本加入到view中
setNoteBody(new String(payload));
// setIntent(intent newIntent):改变由getIntent返回的intent
setIntent(new Intent()); // Consume this intent.
}
if (mNfcAdapter != null) {
enableNdefExchangeMode();
}
} @Override
protected void onPause() {
super.onPause();
// mResumed = false;
if (mNfcAdapter != null) {
mNfcAdapter.disableForegroundNdefPush(this);
}
}
//好像第一次打开app时是用的newIntent显示的标签内容
@Override
protected void onNewIntent(Intent intent) {
// NDEF exchange mode
if (!mWriteMode&& NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
NdefMessage[] msgs = getNdefMessages(intent);
final String body = new String(msgs[0].getRecords()[0].getPayload());
//发送信息到服务端
new Thread(){
public void run(){
try {
Socket socket=new Socket("192.168.1.153",30000);
OutputStream os=socket.getOutputStream();
os.write(body.getBytes());

os.close();
socket.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}
}.start()
//显示读到的信息到编辑框,这是一个自定义的方法
setNoteBody(body);
}
// Tag writing mode
if (mWriteMode
&& NfcAdapter.ACTION_TAG_DISCOVERED.equals(intent.getAction())) {
Tag detectedTag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
writeTag(getNoteAsNdef(), detectedTag);
}
} private TextWatcher mTextWatcher = new TextWatcher() { @Override
public void onTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) { } @Override
public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
int arg3) { } @Override
public void afterTextChanged(Editable arg0) {
// if (mResumed) {
// mNfcAdapter.enableForegroundNdefPush(MainActivity.this,
// getNoteAsNdef());
// }
}
};
// 监听写入编辑框
private View.OnClickListener mTagWriter = new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// Write to a tag for as long as the dialog is shown.
disableNdefExchangeMode();
enableTagWriteMode(); new AlertDialog.Builder(MainActivity.this)
.setTitle("Touch tag to write")
.setOnCancelListener(
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
disableTagWriteMode();
enableNdefExchangeMode();
}
}).create().show();
}
}; private View.OnClickListener mTagRead = new View.OnClickListener() {
@Override
public void onClick(View arg0) {
// Write to a tag for as long as the dialog is shown.
disableTagWriteMode();
enableNdefExchangeMode(); new AlertDialog.Builder(MainActivity.this)
.setTitle("Touch tag to read")
.setOnCancelListener(
new DialogInterface.OnCancelListener() {
@Override
public void onCancel(DialogInterface dialog) {
disableTagWriteMode();
enableNdefExchangeMode();
}
}).create().show();
}
}; // 添加读到的标签中的文本(body)到view中
private void setNoteBody(String body) {
Editable text = mNoteRead.getText();
text.clear();
text.append(body);
}
//加密
private NdefMessage getNoteAsNdef() {
try {
DESPlus des = new DESPlus("123456");//自定义密钥
String encrypted=des.encrypt(mNote.getText().toString());
byte[] textBytes = encrypted.getBytes();
NdefRecord textRecord = new NdefRecord(NdefRecord.TNF_MIME_MEDIA,
"text/plain".getBytes(), new byte[] {}, textBytes);
return new NdefMessage(new NdefRecord[] { textRecord });
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
return null;
}
} // 获取NDEF Message
NdefMessage[] getNdefMessages(Intent intent) {
// Parse the intent
NdefMessage[] msgs = null;
String action = intent.getAction();
if (NfcAdapter.ACTION_TAG_DISCOVERED.equals(action)
|| NfcAdapter.ACTION_NDEF_DISCOVERED.equals(action)) {
Parcelable[] rawMsgs = intent
.getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
if (rawMsgs != null) {
msgs = new NdefMessage[rawMsgs.length];
for (int i = 0; i < rawMsgs.length; i++) {
msgs[i] = (NdefMessage) rawMsgs[i];
}
} else {
// Unknown tag type
byte[] empty = new byte[] {};
NdefRecord record = new NdefRecord(NdefRecord.TNF_UNKNOWN,
empty, empty, empty);
NdefMessage msg = new NdefMessage(new NdefRecord[] { record });
msgs = new NdefMessage[] { msg };
}
} else {
Log.d(TAG, "Unknown intent.");
finish();
}
return msgs;
} private void enableNdefExchangeMode() {
// mNfcAdapter.enableForegroundNdefPush(MainActivity.this,
// getNoteAsNdef());
mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent,
mNdefExchangeFilters, null);
} private void disableNdefExchangeMode() {
mNfcAdapter.disableForegroundNdefPush(this);
mNfcAdapter.disableForegroundDispatch(this);
} private void enableTagWriteMode() {
mWriteMode = true;
IntentFilter tagDetected = new IntentFilter(
NfcAdapter.ACTION_TAG_DISCOVERED);
mWriteTagFilters = new IntentFilter[] { tagDetected };
mNfcAdapter.enableForegroundDispatch(this, mNfcPendingIntent,
mWriteTagFilters, null);
} private void disableTagWriteMode() {
mWriteMode = false;
mNfcAdapter.disableForegroundDispatch(this);
} boolean writeTag(NdefMessage message, Tag tag) {
int size = message.toByteArray().length; try {
Ndef ndef = Ndef.get(tag);
if (ndef != null) {
ndef.connect(); if (!ndef.isWritable()) {
toast("Tag is read-only.");
return false;
}
if (ndef.getMaxSize() < size) {
toast("Tag capacity is " + ndef.getMaxSize()
+ " bytes, message is " + size + " bytes.");
return false;
} ndef.writeNdefMessage(message);
toast("写入数据成功");
return true;
} else {
NdefFormatable format = NdefFormatable.get(tag);
if (format != null) {
try {
format.connect();
format.format(message);
toast("Formatted tag and wrote message");
return true;
} catch (IOException e) {
toast("Failed to format tag.");
return false;
}
} else {
toast("Tag doesn't support NDEF.");
return false;
}
}
} catch (Exception e) {
toast("写入数据失败");
} return false;
} private void toast(String text) {
Toast.makeText(this, text, Toast.LENGTH_SHORT).show();
}}

解决方案 »

  1.   

    有没有可能是编码的问题?你用客户端2不发送body,发送字母试试?
      

  2.   

    你说的我试过了,服务端还是没反应。我怀疑是不是连接都不连上。但客户端一就可以啊。我现在怀疑可能是onNewIntent这个方法的问题,我刚学安卓没多久,对安卓的运行机制理解的不是很透彻
      

  3.   

    先检测一下socket有没有连接成功
      

  4.   

    final String body = new String(msgs[0].getRecords()[0].getPayload());

    final String body = msgs[0].getRecords()[0].getPayload();
      

  5.   

    if (!mWriteMode&& NfcAdapter.ACTION_NDEF_DISCOVERED.equals(intent.getAction())) {
    进来了吗?
      

  6.   

    1.客户端是真机还是模拟器?
    2.IP的问题。客户端不能直接用那个IP;
    3.若是真机,确保开启wifi,并保证wifi网络能与服务端ping通。
      

  7.   

    应该进来了,因为new Thread这个内部类后面的那句setBodyNote方法执行了,我在手机上的编辑框里得到了想要的字符串,是用des算法加密过的,也是String类型
      

  8.   

    大神你好
    1、客户端是我的小米手机,服务端就是PC机
    2、可我用客户端一的代码在手机上运行用的就是那个IP,实现了数据传输啊
    3、嗯,手机和PC机在同一网段,之间就试过让手机加载在PC里写好的jsp页面。
      

  9.   

    应该进来了,因为new Thread这个内部类后面的那句setBodyNote方法执行了,我在手机上的编辑框里得到了想要的字符串,是用des算法加密过的,也是String类型你在服务端加一个打印。有客户端链接上时打印一下。估计你的socket没链接上。
      

  10.   

    应该进来了,因为new Thread这个内部类后面的那句setBodyNote方法执行了,我在手机上的编辑框里得到了想要的字符串,是用des算法加密过的,也是String类型你在服务端加一个打印。有客户端链接上时打印一下。估计你的socket没链接上。
    我在服务端的Socket s=ss.sccept();这句下面加了System.out.println("连接状态为:"+s.isConnected());这句。用客户端一测试,可以输出true。但用客户端二测试,服务端还是什么反应都没有,也不输出true也不输出false。。
      

  11.   

    我在服务端的Socket s=ss.sccept();这句下面加了System.out.println("连接状态为:"+s.isConnected());这句。用客户端一测试,可以输出true。但用客户端二测试,服务端还是什么反应都没有,也不输出true也不输出false。。 
      

  12.   

    貌似应该不是字符串的问题,服务端一点反应都没有,参见我其它的回复。我也试过在body后加“\n”,木有用,服务端还是什么反应都没有。
      

  13.   

    服务器的socket不用绑定端口吗?
      

  14.   

    我在服务端的Socket s=ss.sccept();这句下面加了System.out.println("连接状态为:"+s.isConnected());这句。用客户端一测试,可以输出true。但用客户端二测试,服务端还是什么反应都没有,也不输出true也不输出false。。 
    那不就证明你第二个没有执行到链接socket么
      

  15.   

    应该进来了,因为new Thread这个内部类后面的那句setBodyNote方法执行了,我在手机上的编辑框里得到了想要的字符串,是用des算法加密过的,也是String类型你这个执行了那就要跟一下线程内的代码了,看下是不是抛异常了呢!
      

  16.   

    我在服务端的Socket s=ss.sccept();这句下面加了System.out.println("连接状态为:"+s.isConnected());这句。用客户端一测试,可以输出true。但用客户端二测试,服务端还是什么反应都没有,也不输出true也不输出false。。 
    那不就证明你第二个没有执行到链接socket么
    可是为什么呢,我真的很纳闷。我这会把匿名内部类撤了,我重写了一个Thread类,然后传参过去。其实也没多大差别,就是不再像匿名内部类那样只执行一次。但依然是客户端一可以,客户端二什么反应都没有。我赶脚我快放弃了。真心搞不懂
      

  17.   

    我在服务端的Socket s=ss.sccept();这句下面加了System.out.println("连接状态为:"+s.isConnected());这句。用客户端一测试,可以输出true。但用客户端二测试,服务端还是什么反应都没有,也不输出true也不输出false。。 
    那不就证明你第二个没有执行到链接socket么
    可是为什么呢,我真的很纳闷。我这会把匿名内部类撤了,我重写了一个Thread类,然后传参过去。其实也没多大差别,就是不再像匿名内部类那样只执行一次。但依然是客户端一可以,客户端二什么反应都没有。我赶脚我快放弃了。真心搞不懂
    你把客户端二中的线程去掉试试
      

  18.   

    我在服务端的Socket s=ss.sccept();这句下面加了System.out.println("连接状态为:"+s.isConnected());这句。用客户端一测试,可以输出true。但用客户端二测试,服务端还是什么反应都没有,也不输出true也不输出false。。 
    那不就证明你第二个没有执行到链接socket么
    可是为什么呢,我真的很纳闷。我这会把匿名内部类撤了,我重写了一个Thread类,然后传参过去。其实也没多大差别,就是不再像匿名内部类那样只执行一次。但依然是客户端一可以,客户端二什么反应都没有。我赶脚我快放弃了。真心搞不懂
    你把客户端二中的线程去掉试试
    试过,报错。android不允许在UI线程中用socket,所以才新开一个线程。
    debug怎么学,求再详细点,指条明路吧。我只知道struts里的debug。android怎么用
      

  19.   

    100分都招不来能解决问题的人!我现在怀疑是nfc部分代码的问题了。