Possible to flash firmware remotely through the AndroidSDK?

I’m currently experimenting with Particle’s Android SDK and was wondering how I could remotely flash a file to a Particle device from the app itself.

I’m assuming it’s possible since the firmware files are pretty small, but had trouble understanding Particle’s android app code on re-flashing tinker. I only need to flash one file, and I already have the selected particle device in class variable.

@SuppressLint("StaticFieldLeak")
    public void cloudCommand(String command){
        final ParticleDevice device = selected_device;
        final List<String> command_format = new ArrayList<>();
        command_format.add(command);
        new AsyncTask<Void, Void, String>(){
            @Override
            protected String doInBackground(Void... voids) {
                if(command_format.get(0) == "flash"){
                    try{
                        ClassLoader classLoader = this.getClass().getClassLoader();
                        File file = new File("@Resources" ,"firmware.bin");
                        DataInputStream inputStream = new DataInputStream(new FileInputStream(file));
                        selected_device.flashBinaryFile(inputStream);
                        return null;
                    }
                    catch(IOException | ParticleCloudException e){
                        return e.getMessage();
                    }
                }
                else{...

I started Java last week, so much of the code I have is from what I have been able to gather from the documentation and google searches.

You can make the cloud flash the device.
AFAICT you cannot upload a binary from your Android device.

The respective functions (flashKnownApp() and flashFile()) can be found here

But for more background I guess @mstanley can hook you up with the Android dev.

I was afraid of that.

My initial idea was to flash the firmware through the app, so that when the android app updated, the scooter’s firmware could update.My goal is to be able to share the app and firmware easily. I would like for people to be able to buy a Particle device, set up a Particle account, download my app, and start using the app to control the Particle device (after they installed the firmware through the app).

Is it possible to instruct Particle to flash firmware that is not in the user’s IDE files, say a URL?

The way things are looking, I might have to create a dummy Particle account with all the up-to-date files, and instruct the Android app to temporarily reassign the device so that it can access the file for flashing. The only problem with this solution is that I don’t see a way I could share the source code as it will contain the dummy account user info.

For what you are describing I’d think you want to create a Particle product and have the devices automatically pull the latest version from the cloud.
https://docs.particle.io/tutorials/product-tools/device-groups/

1 Like

Scruff is correct, the functionality you are looking for is through a Product.

As far as accounts go, you may want to consider looking into two-legged auth

2 Likes

In regards to pushing firmware from the Android device through the SDK. I believe it is possible as my understanding, this is how Tinker is pushed to our apps from mobile devices–but I’m uncertain if it’s a cloud proxy or from the device.

@jensck_particle would be able to provide more information about being able to flash your own binaries from the Android SDK and whether or not that is feasible.

Realistically though, I suspect the preferred approach would be through the cloud and using Products.

1 Like

Other than during setup, there is no direct mobile to device interaction. Everything – firmware updates included – happens through the cloud.

3 Likes

So I after finishing up my school work, I began working on uploading the binary to the cloud and succeeded.

There’s a method flashBinaryFile that doesn’t seem to be used in the app, which allows me to upload the binary file from the app to the cloud for flashing (I think that’s how it works - not too sure, but it works).

new AsyncTask<Void, Void, String>(){
    @Override
    protected String doInBackground(Void... voids) {
        if(command_format.get(0) == "flash"){
            try{
                InputStream stream = getResources().openRawResource(R.raw.firmware);
                selected_device.flashBinaryFile(stream);
                return null;
            }
            catch(IOException | ParticleCloudException e){
                return e.getMessage();
            }
        }
        else{
            try {
                Integer returnValue = device.callFunction("CloudCommand", command_format);
                String result = returnValue.toString();
                return result;
            } catch (ParticleDevice.FunctionDoesNotExistException | ParticleCloudException | IOException e) {
                return e.getMessage();
            }
        }
    }
    @Override
    protected void onPostExecute(@NonNull String mst) {
        Toaster.l(MainActivity.this, mst);
	//etc.

    }
}.execute();