【发布时间】:2013-01-07 00:21:37
【问题描述】:
我创建了一个应用程序,它检查 NFC 标签的有效负载,当它匹配时,应用程序会切换蓝牙。
不幸的是,该应用似乎进入了一个无限循环,在该循环中,它要求用户允许操作蓝牙,忽略选择并再次启动(再次询问相同的问题/活动)。 onActivityResult 似乎没有被调用。
我的控制台日志调用的输出是:
Payload: 'quicktags-togglebluetooth'
Bluetooth should now be on
如果我继续在权限 Activity 上点击“是”,则蓝牙会无限切换,控制台日志 (logcat) 如下所示:
Payload: quicktags-togglebluetooth
Bluetooth should now be on
Bluetooth should now be off
Bluetooth should now be on
Bluetooth should now be off
Bluetooth should now be on
Bluetooth should now be off
等等。
AndroidManifest 列出了正确的权限,请看下面:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.getquicktags.qt"
android:versionCode="1"
android:versionName="1.0" android:installLocation="auto">
<uses-sdk android:minSdkVersion="14" android:targetSdkVersion="14" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-feature android:name="android.hardware.nfc" android:required="true" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".CardActivity"
android:label="@string/app_name" >
<!-- Handle a collectable card NDEF record -->
<intent-filter>
<action android:name="android.nfc.action.NDEF_DISCOVERED"/>
<data android:mimeType="application/vnd.getquicktags.qt"/>
<category android:name="android.intent.category.DEFAULT"/>
</intent-filter>
</activity>
</application>
</manifest>
CardActivity.java 文件是引发蓝牙混乱的原因,可以在下面找到:
package com.getquicktags.qt;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.Intent;
import android.nfc.NdefMessage;
import android.nfc.NdefRecord;
import android.nfc.NfcAdapter;
import android.os.Bundle;
import android.os.Parcelable;
import android.util.Log;
import android.bluetooth.*;
public class CardActivity extends Activity implements OnClickListener {
private static final String TAG = null;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.card_activity);
// see if app was started from a tag and show game console
Intent intent = getIntent();
if(intent.getType() != null && intent.getType().equals(MimeType.NFC_DEMO)) {
Parcelable[] rawMsgs = getIntent().getParcelableArrayExtra(NfcAdapter.EXTRA_NDEF_MESSAGES);
NdefMessage msg = (NdefMessage) rawMsgs[0];
NdefRecord cardRecord = msg.getRecords()[0];
String payload = new String(cardRecord.getPayload());
Log.d(TAG, "Payload: '"+ payload +"'");
if(payload.equals("quicktags-togglebluetooth")) {
toggleBluetooth();
}
}
}
private void toggleBluetooth() {
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
Log.d(TAG, "No Bluetooth on device");
closeApp();
}
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, 1);
Log.d(TAG, "Bluetooth should now be on");
} else {
// Turn it off
mBluetoothAdapter.disable();
Log.d(TAG, "Bluetooth should now be off");
closeApp();
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Close the app
Log.d(TAG, "Close the app call");
closeApp();
}
private void closeApp() {
Log.d(TAG, "And... close it. This is inside closeApp()");
android.os.Process.killProcess(android.os.Process.myPid());
}
public void onClick(DialogInterface dialog, int which) {
// TODO Auto-generated method stub
}
}
您可以看到,根据 logcat,onActivityResults 和 closeApp 不会被调用。
我在 Nexus 7 上进行测试。标签很好,我已经用各种 NFC 阅读器进行了测试。
扫描标签时 logcat 会出现一些错误,但它们对我来说似乎没有多大意义。见下文:
01-07 00:18:41.595: E/bt-btif(5830): btif_enable_service: current services:0x100020
01-07 00:18:41.605: E/bt-btif(5830): btif_enable_service: current services:0x140020
01-07 00:18:41.605: E/bt-btif(5830): btif_enable_service: current services:0x140020
01-07 00:18:42.415: E/bt-btif(5830): Calling BTA_HhEnable
01-07 00:18:42.415: E/btif_config.c(5830): ## btif_config_get assert section && *section && key && *key && name && *name && bytes && type failed at line:186 ##
01-07 00:18:42.415: E/bt-btif(5830): btif_storage_get_adapter_property service_mask:0x140020
01-07 00:18:42.435: E/btif_config.c(5830): ## btif_config_get assert section && *section && key && *key && name && *name && bytes && type failed at line:186 ##
01-07 00:18:42.445: E/bt_h4(5830): vendor lib postload completed
01-07 00:18:42.545: E/BluetoothServiceJni(5830): SOCK FLAG = 1 ***********************
01-07 00:18:42.605: E/BluetoothServiceJni(5830): SOCK FLAG = 0 ***********************
01-07 00:18:42.715: E/BtOppRfcommListener(5830): Error accept connection java.io.IOException: read failed, socket might closed, read ret: -1
01-07 00:18:42.915: E/bt-btif(5830): BTA AG is already disabled, ignoring ...
01-07 00:18:42.935: E/bt-btif(5830): btif_disable_service: Current Services:0x140020
01-07 00:18:42.945: E/bt-btif(5830): btif_disable_service: Current Services:0x100020
01-07 00:18:42.945: E/bt-btif(5830): btif_disable_service: Current Services:0x100020
非常感谢您对此提供的任何帮助。正如你可能想象的那样,它让我发疯:)
【问题讨论】:
-
正如@NFC 家伙指出的,这比 NFC 更像是蓝牙问题,但问题仍然存在
-
你为什么要杀死
closeApp()中的进程?我想这是你问题的一部分。只需在活动上调用finish()并让Android 在需要时处理清理您的进程。当你杀死你的进程时,Android 认为发生了不好的事情并试图恢复。作为此恢复的一部分,它可能会重新交付 Intent,这可能不是您想要的。 -
好的,我试试看。我打电话给
closeApp(),因为这是使应用程序看起来不可见的唯一方法。这个想法是让应用程序启动、切换蓝牙和关闭速度如此之快,以至于用户唯一注意到的是蓝牙现在处于打开/关闭状态。 -
运气好吗?请让我知道这是否有效。
-
还没试过,一个小时左右就可以了。如果可行,我会通知您,以便您将其放在答案中:)