
在android开发中,当应用需要响应外部硬件(如usb设备)的连接事件时,通常会在androidmanifest.xml中为相应的activity声明一个intent-filter,监听特定的action,例如android.hardware.usb.action.usb_device_attached。当usb设备连接时,系统会发送一个匹配此action的intent,并尝试启动或唤醒对应的activity。
然而,默认情况下,如果Activity的launchMode为standard(默认值),即使应用已经在运行,当再次接收到相同的Intent时,系统也可能会创建一个新的Activity实例,并将其放置在任务栈的顶部。这会导致用户体验不佳,因为应用会表现为“重启”,丢失当前状态。对于需要持续与USB设备通信的应用,理想的行为是:
要实现上述理想行为,关键在于修改Activity的启动模式。android:launchMode="singleTop"是解决此问题的有效方法。
当一个Activity被设置为singleTop启动模式时:
对于USB设备连接事件,由于通常是由系统发送Intent触发,且我们希望在应用运行时直接处理,singleTop模式非常适用。当应用在运行时,其主Activity(通常也是监听USB事件的Activity)很可能就在任务栈的顶部,此时新的USB连接Intent将直接传递给onNewIntent()。
修改AndroidManifest.xml: 在监听USB_DEVICE_ATTACHED事件的Activity标签中,添加android:launchMode="singleTop"属性。
<application>
...
<activity
android:name=".YourMainActivity"
android:launchMode="singleTop"
android:exported="true"> <!-- 确保Activity可以被外部Intent启动 -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<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>
</application>注意: android:exported="true" 是为了确保Activity可以被外部应用(如系统在检测到USB设备连接时)通过Intent启动。对于监听系统广播的Activity,这通常是必需的。
在Activity中处理新的Intent: 在对应的Activity类中,重写onNewIntent(Intent intent)方法。所有通过singleTop模式传递给现有Activity的Intent都将在此方法中接收。
import android.content.Intent;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Bundle;
import androidx.appcompat.app.AppCompatActivity;
import android.util.Log;
public class YourMainActivity extends AppCompatActivity {
private static final String TAG = "YourMainActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate: Activity created.");
// 首次启动时处理Intent
handleUsbDeviceAttached(getIntent());
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
// 当Activity已在顶部时,新的Intent会通过此方法传递
Log.d(TAG, "onNewIntent: New Intent received.");
setIntent(intent); // 更新Activity的当前Intent
handleUsbDeviceAttached(intent);
}
private void handleUsbDeviceAttached(Intent intent) {
if (intent != null && UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(intent.getAction())) {
UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
if (device != null) {
Log.d(TAG, "USB Device Attached: " + device.getDeviceName());
// 在这里处理USB设备的连接逻辑,例如:
// - 获取UsbManager服务
// - 请求USB设备的权限
// - 打开USB设备进行通信
// - 更新UI显示连接状态
// 例如:
// UsbManager manager = (UsbManager) getSystemService(Context.USB_SERVICE);
// if (manager.hasPermission(device)) {
// // 打开设备
// } else {
// // 请求权限
// }
}
}
}
@Override
protected void onResume() {
super.onResume();
// 可以在onResume中再次检查USB设备状态,以防万一
Log.d(TAG, "onResume: Activity resumed.");
}
@Override
protected void onDestroy() {
super.onDestroy();
Log.d(TAG, "onDestroy: Activity destroyed.");
}
}在onNewIntent()中,调用setIntent(intent)是一个好习惯,它会将Activity的当前Intent更新为最新收到的Intent。这样,后续对getIntent()的调用将返回最新的Intent。
通过在AndroidManifest.xml中为监听USB连接事件的Activity设置android:launchMode="singleTop",并正确实现onNewIntent()方法,可以有效地防止Android应用在USB设备重新连接时重复启动。这种方法使得应用能够在保持现有状态的同时,接收并处理新的USB连接通知,从而提供更流畅、更专业的用户体验。理解并恰当运用Activity的启动模式是Android开发中优化应用行为的重要一环。
以上就是Android应用处理USB连接事件:避免Activity重复启动的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号