Gok*_* NC 4 android android-intent android-broadcast android-broadcastreceiver
我正在尝试检测我的应用程序中的USB连接,即USB是否连接到设备。
正在棉花糖6.0.1(sdk23)上进行测试
但是我无法接收广播动作ACTION_USB_DEVICE_ATTACHED或ACTION_USB_DEVICE_DETACHED。
我尝试同时使用动态方式和AndroidManifest.xml方式,但均无效。
这是我的代码:
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.gokulnc.blah_blah"
android:installLocation="auto"
android:versionCode="15"
android:versionName="1.5.1">
<uses-feature android:name="android.hardware.usb.host" />
<uses-sdk
android:minSdkVersion="14"
android:targetSdkVersion="23" />
<android:uses-permission android:name="android.permission.USB_PERMISSION" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:vmSafeMode="false">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/DrawerTheme">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<receiver android:name="mUsbReceiver">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_DETACHED" />
</intent-filter>
</receiver>
</activity>
</application>
</manifest>
Run Code Online (Sandbox Code Playgroud)
MainActivity.java:
public class MainActivity extends AppCompatActivity {
BroadcastReceiver mUsbReceiver;
public void onCreate(Bundle savedInstanceState) {
.....
setBroadcastReceivers();
}
void setBroadcastReceivers() {
//Reference: http://www.codepool.biz/how-to-monitor-usb-events-on-android.html
mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(LOG_TAG, "Received Broadcast: "+action);
if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action) || UsbManager.ACTION_USB_ACCESSORY_ATTACHED.equals(action)) {
updateUSBstatus();
Log.d(LOG_TAG, "USB Connected..");
} else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action) || UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
UsbDevice device = (UsbDevice)intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
updateUSBstatus();
}
Log.d(LOG_TAG, "USB Disconnected..");
}
}
};
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
//filter.addAction(UsbManager.ACTION_USB_ACCESSORY_ATTACHED);
//filter.addAction(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
registerReceiver(mUsbReceiver , filter);
Log.d(LOG_TAG, "mUsbReceiver Registered");
}
@Override
public void onResume() {
super.onResume();
Log.d(LOG_TAG, "App Resumed..");
//Refernce: /sf/ask/1261095951/
Intent intent = getIntent();
if (intent != null) {
if (intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)) {
Toast.makeText(getApplicationContext(), "Attached", Toast.LENGTH_SHORT).show();
} else if(intent.getAction().equals(UsbManager.ACTION_USB_DEVICE_DETACHED)) {
Toast.makeText(getApplicationContext(), "Detached", Toast.LENGTH_SHORT).show();
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
我还检查了这个答案:无法接收UsbManager.ACTION_USB_DEVICE_ATTACHED / UsbManager.ACTION_USB_DEVICE_DETACHED的广播Intent,但这没有帮助。
有人可以指出我错了吗?
也许不起作用的原因是,从Android 6.0开始,默认的USB模式为Charging,并且ACTION_USB_DEVICE_ATTACHED在以该模式连接时可能不会启动。
相反,现在我有另一个解决方案:
String usbStateChangeAction = "android.hardware.usb.action.USB_STATE";
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(LOG_TAG, "Received Broadcast: "+action);
if(action.equalsIgnoreCase(usbStateChangeAction)) { //Check if change in USB state
if(intent.getExtras().getBoolean("connected")) {
// USB was connected
} else {
// USB was disconnected
}
}
}
Run Code Online (Sandbox Code Playgroud)
也就是说,android.hardware.usb.action.USB_STATE只要USB状态有切换,就发送广播。
android.hardware.usb.action.USB_DEVICE_ATTACHED与之不同的是,仅当启用了MTP模式之类的android.hardware.usb.action.USB_STATE广播时,它才会广播,它会在检测到能够连接到主机(例如计算机)的USB连接时广播,而不考虑其当前的USB模式(如充电,MTP或其他任何类型)。称为USB配置(更精确)
这是检查 Android 活动中是否存在外部 USB 连接的完美步骤。只需按照步骤一一进行即可。
在 Android 清单文件中:
<uses-feature android:name="android.hardware.usb.host" />
<uses-permission android:name="android.permission.USB_PERMISSION" />
Run Code Online (Sandbox Code Playgroud)
在您的 USB 检查活动标签内:
<activity android:name=".USBEnabled">
<intent-filter>
<action android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED" />
</intent-filter>
<meta-data
android:name="android.hardware.usb.action.USB_DEVICE_ATTACHED"
android:resource="@xml/device_filter" />
</activity>
Run Code Online (Sandbox Code Playgroud)
在连接检查 USBEnabled 类中:
public class USBEnabled extends AppCompatActivity {
private static final String TAG = "UsbHost";
TextView mDeviceText;
Button mConnectButton;
UsbManager mUsbManager;
UsbDevice mDevice;
PendingIntent mPermissionIntent;
private static final int REQUEST_TYPE = 0x80;
private static final int REQUEST = 0x06;
private static final int REQ_VALUE = 0x200;
private static final int REQ_INDEX = 0x00;
private static final int LENGTH = 64;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_usbenabled);
mDeviceText = (TextView) findViewById(R.id.text_status);
mConnectButton = (Button) findViewById(R.id.button_connect);
mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
}
@Override
protected void onRestart() {
super.onRestart();
recreate();
}
@Override
protected void onResume() {
super.onResume();
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);
updateDeviceList();
}
@Override
protected void onPause() {
super.onPause();
unregisterReceiver(mUsbReceiver);
}
public void onConnectClick(View v) {
if (mDevice == null) {
return;
}
mUsbManager.requestPermission(mDevice, mPermissionIntent);
}
private static final String ACTION_USB_PERMISSION = "com.android.recipes.USB_PERMISSION";
private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (ACTION_USB_PERMISSION.equals(action)) {
UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)
&& device != null) {
getDeviceStatus(device);
} else {
Log.d(TAG, "permission denied for device " + device);
}
}
}
};
private void getDeviceStatus(UsbDevice device) {
UsbDeviceConnection connection = mUsbManager.openDevice(device);
byte[] buffer = new byte[LENGTH];
connection.controlTransfer(REQUEST_TYPE, REQUEST, REQ_VALUE, REQ_INDEX,
buffer, LENGTH, 2000);
connection.close();
}
private void updateDeviceList() {
HashMap<String, UsbDevice> connectedDevices = mUsbManager
.getDeviceList();
if (connectedDevices.isEmpty()) {
mDevice = null;
mDeviceText.setText("No Devices Currently Connected");
mConnectButton.setEnabled(false);
} else {
for (UsbDevice device : connectedDevices.values()) {
mDevice = device;
}
mDeviceText.setText("USB Device connected");
mConnectButton.setEnabled(true);
}
}}
Run Code Online (Sandbox Code Playgroud)
在你的类 xml 文件中:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<Button
android:id="@+id/button_connect"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="onConnectClick"
android:text="Connect" />
<TextView
android:id="@+id/text_status"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="22dp" />
<TextView
android:id="@+id/text_data"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="22dp" />
</LinearLayout>
Run Code Online (Sandbox Code Playgroud)
现在创建一个名为 xml 的新资源目录,并使用以下代码创建名为device_filter.xml的新 xml 文件。
<?xml version="1.0" encoding="utf-8"?>
<resources>
<usb-device />
</resources>
Run Code Online (Sandbox Code Playgroud)
调试并运行应用程序,它将显示外部 USB 设备的连接状态,没有任何错误。我希望你能得到适合你的场景的输出。
享受!!
| 归档时间: |
|
| 查看次数: |
8257 次 |
| 最近记录: |