2

我花了几天时间试图让 android ADK 连接在服务中运行而不是在活动中运行.....有人知道它是否可能吗?

我想让服务处理 inputStream 和 outputStream,这样我就可以在后台长时间阅读我的 Arduino。

当活动返回焦点时,我将与服务绑定并更新 GUI。如果可能的话,我最终希望使用来自服务的实时数据更新网站以进行远程监控。

如果赞赏,请提供任何帮助。我是编程新手,似乎找不到关于这个主题的太多信息。

提前感谢您的帮助。

4

3 回答 3

2

我也在尝试,我发现了这一点。 http://robotgrrl.com/blog/2011/11/29/android-adk-background-service/

于 2012-04-07T07:42:18.703 回答
2

我能够以以下方式运行 ADK 连接(不是完整的代码。只有基本的构建块):

首先,我有一个接收 adk 意图广播的活动(android 系统服务基于 adk 元数据和清单)。

private static final String USB_ACCESSORY_ATTACHED = "android.hardware.usb.action.USB_ACCESSORY_ATTACHED";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    if (getIntent().getAction() != null && getIntent().getAction().equals(USB_ACCESSORY_ATTACHED)) {
        Intent service = new Intent(this, ADKservice.class);
        service.putExtras(getIntent());
        startService(service);

        Intent launch = new Intent(this, MainActivity.class);
        launch.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(launch);
    }
    this.finish();
}

如果意图与 adk 字符串匹配,它将启动 adk 服务并将意图信息传递给服务,启动用户界面活动并自行完成。

用户界面 (MainActivity) 现在像任何其他服务一样绑定到服务,因此它可以调用公共方法和/或通过服务回调接收数据(也可以使用本地广播)。

ADKservice 扩展 Runnable 以监控 USB 连接。它还为 adk disconnect 注册接收器,以便在设备断开连接时停止:

@Override
public void onCreate() {

    IntentFilter filter = new IntentFilter(UsbManager.ACTION_USB_ACCESSORY_DETACHED);
    registerReceiver(mUsbReceiver, filter);


    mNotificationManager =(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);

     mBuilder = new NotificationCompat.Builder(this)
    .setSmallIcon(R.drawable.ic_launcher)
    .setContentTitle("ADK Service")
    .setContentText("Started");
    startForeground(notifyID, mBuilder.build());

    super.onCreate();
}

在 onCreate 完成后,服务将调用 onStartCommand,adk 初始化开始的地方。

@Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        Log.d(TAG, "onStartup " + mAccessory );

        mAccessory = (UsbAccessory) intent.getParcelableExtra(UsbManager.EXTRA_ACCESSORY);
        if (mAccessory != null) {
            openAccessory(mAccessory);              
        }

        return super.onStartCommand(intent, flags, startId);
    }

private void openAccessory(UsbAccessory accessory) {
    Log.d(TAG, "openAccessory: " + accessory);
    UsbManager mUsbManager = (UsbManager) getApplicationContext().getSystemService(Context.USB_SERVICE);
    mFileDescriptor = mUsbManager.openAccessory(accessory);
    if (mFileDescriptor != null) {
        FileDescriptor fd = mFileDescriptor.getFileDescriptor();
        mInputStream = new FileInputStream(fd);
        mOutputStream = new FileOutputStream(fd);
        thread = new Thread(null, this, "ADKserviceThread");
        thread.start(); // start runnable
    }

public void run() {
 // handle adk "usb" messages here
}

    @Override
public void onDestroy() {
    closeAccessory();

    stopForeground(true);
    super.onDestroy();
}

private void closeAccessory() {
    try {
        if (mFileDescriptor != null) {
            mFileDescriptor.close();
        }
    } catch (IOException e) {
    } finally {
        mFileDescriptor = null;
        mAccessory = null;
    }
}

    private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if(UsbManager.ACTION_USB_ACCESSORY_DETACHED.equals(action)) {
                closeAccessory();

            stopSelf();


            }
        }
    };

连接的处理可能需要一些调整,但整体概念似乎有效。我希望对大家有帮助!现在看起来很容易,但我花了很长时间才到这里(我对编程一再陌生)

于 2013-08-22T18:00:41.670 回答
0

您应该像这里一样在主要活动中处理附件的加载,然后将对附件对象的引用传递给服务。

您现在可以从任何活动绑定服务并访问输入/输出流。

您还可以关闭活动,当您断开附件时,活动应该捕获意图广播并重新启动以执行 closeAccessory 例程。

于 2012-04-11T12:42:49.057 回答