Long running ADK Accessory (Service?)

隐身守侯 提交于 2019-12-06 11:24:41

问题


I've spent days trying to get the android ADK connection running in a service rather then activity..... Anyone know if its even possible?

I would like to have the service handled inputStream and outputStream so I can read my Arduino for extended periods in the background.

When the activity returns to focus I will bind with the service and update the GUI. If this is possible I would eventually like to update a website with the live data from the service for remote monitoring.

Any help if appreciated. I'm new to programming and can't seem to find much info on this topic.

Thank you in advace for the help.


回答1:


I'm also trying it and I've found out this. http://robotgrrl.com/blog/2011/11/29/android-adk-background-service/




回答2:


I was able to get a ADK connection running in the following way (not complete code. Only the basic building blocks):

First I have an activity that the receives adk intent broadcasts (android system service bases on the adk meta data and the manifest).

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();
}

If the intent matches the adk string it will start the adk service and pass the intent information to the service, launch the user interface activity and finish itself.

The user interface (MainActivity) now binds to the service just like any other service so it can call public methods and/or receive data via the service callbacks (local broadcast's can also be used).

The ADKservice extends Runnable to monitor the usb connection. It also registers a receiver for adk disconnect so it can stop if the device gets disconnected:

@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();
}

After onCreate has finished the service will call onStartCommand where the adk initialization starts.

@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();


            }
        }
    };

The handling of the connection might need some tweaks but the overall concept seems to work. I hope that helps everyone! It seems easy now but it took me a long time to here (I'm repetitively new to programming)




回答3:


You should handle the loading of the accessory in the main activity like here, and then pass a reference to the accessory object to a service.

You can now bind the service from any activity and get access to the input/output streams.

You can also close the activity, and when you disconnect the accessory, the activity should catch the intent broadcast and relaunch to perform the closeAccessory routine.



来源:https://stackoverflow.com/questions/9873261/long-running-adk-accessory-service

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!