Long running ADK Accessory (Service?)

寵の児 提交于 2019-12-04 17:41:31

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

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)

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.

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