Home > Blockchain >  Application run in background and UI also
Application run in background and UI also

Time:06-16

I am making a project where I read in sensor data and send them to a CSV file. The problem is, as soon as the application is not open anymore in the front, the application doesn't work anymore. I have read that I need some kind of service. The question is, which service should I use, and how exactly, so that my sensor acquisition and writing to a CSV file works also when the application is not open, but is also able to show some of these sensor data on the user interface?

If the application is fully closed, it doesn't needs to run anymore and i want to start and stop that all with a button as it can be seen in the code-snippet. I am not sure if then foreground service is the right one.

Code-snippet where you can see how the application is built:

private SensorEventListener OrientSensorEventListener = new SensorEventListener() {
        @Override
        public void onSensorChanged(SensorEvent sensorEvent) {
                OrientX = (int) sensorEvent.values[0];
                OrientY = (int) sensorEvent.values[1];
                OrientZ = (int) sensorEvent.values[2];
        }

        @Override
        public void onAccuracyChanged(Sensor sensor, int i) {

        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        //User Interface
        time = findViewById(R.id.Time1);
        //Steps UI
        Stepstxt = findViewById(R.id.Stepstxt);
        Walkingtxt = findViewById(R.id.Walkingtxt);
        FastStepstxt = findViewById(R.id.FastStepstxt);
        //Orientation UI
        OrientXtxt = findViewById(R.id.OrientXtxt);
        OrientYtxt = findViewById(R.id.OrientYtxt);
        OrientZtxt = findViewById(R.id.OrientZtxt);

        // Set Date for CSV File name and User Interface
        Date currentTime = Calendar.getInstance().getTime();
        String formattedDate = DateFormat.getDateInstance(DateFormat.FULL).format(currentTime);
        time.setText(formattedDate);

        // Initializing
        SensorSwitch = findViewById(R.id.SensorSwitch);

        //Sensor Initializing
        //Acceleration
        AccSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mAccelerometer = AccSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        //Amb Light
        AmbLightSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mAmbLight = AmbLightSensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
        //Orientation
        OrientSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        mOrientation = OrientSensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);

        // Record Data to CSV and SwitchFlag
        SensorSwitch.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
            @Override
            public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
                if (b == true) {
                    // CSV Raw Data Open

                    Log.d(TAG, "Writing to "   getStorageDir());
                    try {
                        writer = new FileWriter(new File(getStorageDir(), "RawSensors_"   formattedDate   ".csv"));
                    } catch (
                            IOException e) {
                        e.printStackTrace();
                    }

                    //CSV Feature Data Open
                    Log.d(TAG, "Writing to "   getStorageDir());
                    try {
                        fwriter = new FileWriter(new File(getStorageDir(), "FeatureSensors_"   formattedDate   ".csv"));
                    } catch (
                            IOException e) {
                        e.printStackTrace();
                    }

                    SwitchFlag = true;
                } else {
                    //CSV Raw Data Close
                    try {
                        writer.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    //CSV Feature Data Close
                    try {
                        fwriter.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                    SwitchFlag = false;
                }
            }
        });
    }

    // Next Activity
    public void openMainActivity2(){
        Intent intentMain2 = new Intent(this, MainActivity2.class);
        startActivity(intentMain2);
    }

    // Start Sensor Events
    protected void onResume() {
        super.onResume();
        AccSensorManager.registerListener(AccSensorEventListener, mAccelerometer, 1000000, 1000000);
        AmbLightSensorManager.registerListener(AmbLightSensorEventListener, mAmbLight, 1000000, 1000000);
        OrientSensorManager.registerListener(OrientSensorEventListener, mOrientation,1000000, 1000000);
    }

    protected void onPause() {
        super.onPause();
        AccSensorManager.unregisterListener(AccSensorEventListener);
        AmbLightSensorManager.unregisterListener(AmbLightSensorEventListener);
        OrientSensorManager.unregisterListener(OrientSensorEventListener);
    }


   // CSV File Creation
    private String getStorageDir() {
        return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath();
    }

    // CSV Write Function
    private void CsvWrite(){
        try {
            writer.write(String.format("DateTime; %s;AccX; %f; AccY; %f; AccZ; %f; AccSum; %f; AmbLight; %d; OrientX; %d; OrientY; %d; OrientZ; %d \n", dateTime, AccX, AccY, AccZ , AccSum, AmbLight, OrientX, OrientY, OrientZ));
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void FeatureCsv(){
        try {
            fwriter.write(String.format("DateTime; %s; GoSteps; %d; RunSteps; %d; StepSum; %d; Position; %s; Location; %s \n", dateTime, stepCount, RunCount, StepSum, position, location));
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void FeatureCalc(){
        // Step Calculation
        if (AccChange > 40 && AccChange < 150){
            stepCount  ;
            StepSum  ;
        } else if (AccChange > 150){
            RunCount  ;
            StepSum  ;
        }
         //Display Steps on UI
        Stepstxt.setText("You have currently made: "   StepSum   " Steps");
        Walkingtxt.setText("Thereof: "   stepCount   " Walking Steps");
        FastStepstxt.setText("And: "   RunCount   " Faster Walking or Running Steps");

        // Phone Orientation Feature
        if(OrientY <= -5 && OrientY > -25){
            position = "Standing";
        }else if(OrientY <= -25 && OrientY >= - 90){
            position = "Sitting";
        }else if (OrientY <= -90 && OrientY >= -180 && AmbLight > 13){
            position = "Laying";
        }
        else{
            position = "None/NotUsed";
        }

        //Display Orientation on UI
        OrientXtxt.setText("Azimuth: "   OrientX   "°");
        OrientYtxt.setText("Pitch: "   OrientY   "°");
        OrientZtxt.setText("Roll: "   OrientZ   "°");

        // Location Feature
        AbsOrient = Math.abs(OrientY);
        if(AmbLight <= 13 && AbsOrient >= 60 && AbsOrient <= 120){
            location = "Pocket";
        }else if((AmbLight <= 13 && OrientY <= -170 && OrientY >= -190) || (OrientY > -5 && OrientY < 5)){
            location = "Table";
        }else if(AmbLight <= 25){
            location = "Night/Indoor";
        }else if(AmbLight > 25 && AmbLight <= 800){
            location = "Day/Indoor";
        }else if(AmbLight > 800){
            location = "Day/Outside";
        }else{
            location = "None/Unknown";
        }
    }
}

CodePudding user response:

For any kind of service, you can communicate between your activity and the service using intents or binding. More about it here

Foreground service

A foreground service performs some operation that is noticeable to the user.

A foreground service will display a notification to the user, showing that something is happening, here your measurements. Learn more about it here.

You could for instance, allowing the user to stop the measurements from the notification.

Background service

A background service performs an operation that isn't directly noticed by the user.

If you do not want your user to know that you are making measurements, then a background service could be used.

However, since Android 8.0 serious restrictions are made on the usage of Background services, making it hard to use.

WorkManager Tasks

A more recent approach would be to create a task, which can be periodic if you need to repeat your measurements, or one time only using the WorkManager. More about it here.

CodePudding user response:

I reccomend you to create REST and UI app, so you app will read data from REST and your senzor can send data to REST service.

  • Related