[Solved] Android SDK: How to receive more than one variable in async task?

Hello Particle Users,

I am right now having the problem of not knowing how to receive more than one variable (one variable works fine) with my Android app and the SDK.

Is this possible to do this in one Async task or do i need one task for each variable i want to get from the cloud?

I am not that experience in Android Studio and especially Java as I previously only worked with C and I hope for somebody to help me.

Thanks for everybody responding,
David

My code right now:

public void onClickAkt (View view)
{
Async.executeAsync(ParticleCloud.get(MainActivity.this), new Async.ApiWork<ParticleCloud, String>() {

        private ParticleDevice mDevice;

        TextView TINSval_txt = (TextView)findViewById(R.id.TINSval_txt);

        @Override
        public String callApi(ParticleCloud sparkCloud) throws ParticleCloudException, IOException {
            sparkCloud.logIn("-----", "------");
            sparkCloud.getDevices();
            mDevice = sparkCloud.getDevice("------");
            String value = null;

            try {
                value = mDevice.getStringVariable("TEMP");
                Toaster.s(MainActivity.this, value + "°C");
            } catch (ParticleDevice.VariableDoesNotExistException e) {
                Toaster.s(MainActivity.this, "Error reading variable");
            }

            return value;
        }

        @Override
        public void onSuccess(String value) {

            TINSval_txt.setText(value + "°C");
            Toaster.l(MainActivity.this, "TEMP finished");

        }

        @Override
        public void onFailure(ParticleCloudException e) {
            Toaster.l(MainActivity.this, e.getBestMessage());
            e.printStackTrace();
            Log.d("info", e.getBestMessage());
        }
    });
}

@izmevid yep, you can grab as many variables as you need. Just change the return value of callApi() to something like List<String> or Map<String, String> (etc), make all the calls you need and build up the composite return value as you go.

e.g.:

(warning: I’m doing this from memory, so this snippet may not actually compile, but you get the picture :wink: )

Async.executeAsync(ParticleCloud.get(MainActivity.this), new Async.ApiWork() {

    @Override
    public Map<String, String> callApi(ParticleCloud sparkCloud) throws ParticleCloudException, IOException {
        sparkCloud.logIn("-----", "------");
        sparkCloud.getDevices();
        mDevice = sparkCloud.getDevice("------");
        Map<String, String> returnVals = new ArrayMap<>();

        for (String var : new String[] {"foo", "bar"}) {
	        try {
	            value = mDevice.getStringVariable(var);
	            returnVals.put(var, value);
	        } catch (ParticleDevice.VariableDoesNotExistException e) {
	            Toaster.s(MainActivity.this, "Error reading variable " + var);
	        }
        }

        return returnVals;
    }

    @Override
    public void onSuccess(Map<String, String> values) {
    	// do whatever with returned values
    }

    @Override
    public void onFailure(ParticleCloudException e) {
        Toaster.l(MainActivity.this, e.getBestMessage());
        e.printStackTrace();
        Log.d("info", e.getBestMessage());
    }
});
1 Like

Thank you for the answer. I appreciate your help.
David

Hello jensck,

I just tried out your code and with a little bit of modification it worked fine when compiling but when using this app instead of the one, which was just reading one variable, the Electron turns into blinking red when I want to get the variables (did work fine with one variable). Maybe something is wrong with my Electrons program which doesn’t quite make sense for me because it worked out fine with one variable as well. Do you know what the problem could be?

Thanks for the great help,
David

Electrons code:

void loop() {
    
  double t = sht31.readTemperature();
  delay(200);
  double h = sht31.readHumidity();
  delay(100);
  
  String StrTEMP = String(t).substring(0,4);
  String StrHUMID = String(h).substring(0,4);
  
  
  Particle.variable("TEMP", &StrTEMP, STRING);
  Particle.variable("HUMID", &StrHUMID, STRING);
  
  delay(5000);
}

Android code:

Async.executeAsync(ParticleCloud.get(MainActivity.this), new Async.ApiWork<ParticleCloud, Map<String, String>>() {

            private ParticleDevice mDevice;

            TextView TINSval_txt = (TextView)findViewById(R.id.TINSval_txt);
            TextView HINSval_txt = (TextView)findViewById(R.id.HINSval_txt);

            @Override
            public Map<String, String> callApi(ParticleCloud sparkCloud) throws ParticleCloudException, IOException {
                sparkCloud.logIn("-----------", "-----------");
                sparkCloud.getDevices();
                mDevice = sparkCloud.getDevice("-------------");
                Map<String, String> returnVals = new ArrayMap<>();
                String value=null;

                for (String var : new String[] {"TEMP", "HUMID"}) {
                    try {
                        value = mDevice.getStringVariable(var);
                        returnVals.put(var, value);
                    } catch (ParticleDevice.VariableDoesNotExistException e) {
                        Toaster.s(MainActivity.this, "Error reading variable " + var);
                    }
                }

                return returnVals;
            }

            @Override
            public void onSuccess(Map<String, String> returnVals) {


                TINSval_txt.setText(returnVals.get("TEMP") + "°C");
                Toaster.l(MainActivity.this, "TEMP finished");

                HINSval_txt.setText(returnVals.get("HUMID") + "%");
                Toaster.l(MainActivity.this, "HUMID finished");
            }

            @Override
            public void onFailure(ParticleCloudException e) {
                Toaster.l(MainActivity.this, e.getBestMessage());
                e.printStackTrace();
                Log.d("info", e.getBestMessage());
            }

        });

Particle.variable() mustnot be used in loop()

You need to make the base variables global and setup the Particle.variable() in setup().
And the three parameter overload of Particle.variable() is outdated anyway (and didn’t work on String objects either).

3 Likes

Okay thanks and what would you recommend doing instead of the “outdated” Particle.variable() function?

Just tested the app and everthing works fine now… :smile: thanks

Not the function is outdated but the three parameter overload

Particle.variable("varName", strVar, STRING); // outdated/deprecated (and without ampersand for strings!)
Particle.variable("varName", strVar);         //that's the way to do it now

Ohh okay…thanks for making this clear to me