简体   繁体   中英

How to send notification with a delay when a condition is met in Android Studio

I'm creating an app which I want me to send a notification when I'm a certain amount of time awake.

I have done this by calculation the of acceleration the phone and adding this to in total number. This should be some kind of threshold to activate the timer.

I was beable to sent a notification when a button is pressed.

But now I would want to sent this notification when 'accelerationTotalValue > 1000' for example.

Since this is my first project in Android Studio and using java I'm fairly new to all of this.

My java activity

public class calibration extends AppCompatActivity {

    TextView txt_currentAccel, txt_prevAccel, txt_acceleration;
    TextView txt_totalAccel;
    ProgressBar prog_shakeMeter;

    private SensorManager mSensorManager;
    private Sensor mAccelerometer;
    private double accelerationPreviousValue;
    private double accelerationTotalValue;

    Button notifyBtn;

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


        // get layout ID's acceleration
        txt_acceleration = findViewById(R.id.txt_accel);
        txt_prevAccel = findViewById(R.id.txt_prevAccel);
        txt_currentAccel = findViewById(R.id.txt_currentAccel);
        txt_totalAccel = findViewById(R.id.txt_totalAccel);
        prog_shakeMeter = findViewById(R.id.prog_shakeMeter);

        // get info sensors
        mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
        mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

        // notification
            // open main page when clicking on notification
        Intent resultIntent = new Intent(this, MainActivity.class);
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addNextIntentWithParentStack(resultIntent);
        PendingIntent resultPendingIntent =
                stackBuilder.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);

            // find button to activate notification
        notifyBtn = findViewById(R.id.Notification_Button);

        if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            NotificationChannel channel = new NotificationChannel("My Notification","My Notification", NotificationManager.IMPORTANCE_DEFAULT);
            NotificationManager manager = getSystemService(NotificationManager.class);
            manager.createNotificationChannel(channel);
        }

        notifyBtn.setOnClickListener(new View.OnClickListener() {

            @Override
            public void onClick(View view) {
                NotificationCompat.Builder builder = new NotificationCompat.Builder(calibration.this,"My Notification");
                builder.setContentTitle("My Title");
                builder.setContentText("This is a simple notification");
                builder.setSmallIcon(R.mipmap.ic_launcher_foreground);
                builder.setAutoCancel(true);
                builder.setPriority(NotificationCompat.PRIORITY_HIGH);
                builder.setContentIntent(resultPendingIntent);

                NotificationManagerCompat managerCompat = NotificationManagerCompat.from(calibration.this);
                managerCompat.notify(1,builder.build());

            }
        });

    }


    // calculation acceleration
    private final SensorEventListener sensorEventListener = new SensorEventListener() {
        @SuppressLint("SetTextI18n")
        @Override
        public void onSensorChanged(SensorEvent sensorEvent) {
            float x = sensorEvent.values[0];
            float y = sensorEvent.values[1];
            float z = sensorEvent.values[2];

            double accelerationCurrentValue = Math.sqrt((x * x + y * y + z * z));

            double changeIntAcceleration = Math.abs(accelerationCurrentValue - accelerationPreviousValue);
            accelerationPreviousValue = accelerationCurrentValue;
            accelerationTotalValue = accelerationTotalValue + changeIntAcceleration;

            txt_currentAccel.setText("Current = "+ accelerationCurrentValue);
            txt_prevAccel.setText("Prev = "+ accelerationCurrentValue);
            txt_acceleration.setText("Acceleration change = "+ changeIntAcceleration);
            txt_totalAccel.setText("Total = "+ accelerationTotalValue);

            prog_shakeMeter.setProgress((int)changeIntAcceleration);
        }

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

        }
    };

    protected void onResume() {
        super.onResume();
        mSensorManager.registerListener(sensorEventListener, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
    }

    protected void onPause() {
        super.onPause();
        mSensorManager.unregisterListener(sensorEventListener);
    }
}

You could just put all the stuff that you have in your notifyBtn onClick to a separate function, let's call it notify , and then add one line in your code:

@Override
public void onSensorChanged(SensorEvent sensorEvent) {
    // Your previous code
    accelerationTotalValue = accelerationTotalValue + changeIntAcceleration;
    if (accelerationTotalValue > 1000) {
        notify();
    }
    // Rest of your code
}

Do bear in mind that your current code will only run when your application is in the foreground. I'd suggest reading up on Android's Activity Lifecycle here .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM