How can I run this Android code in Background

3.8k Views Asked by At

This is a actually a collage project. The requirements are:

  1. Make an app that will change Android Profile to Ringer, Vibration and Silent using any two sensors (I used Proximity and Accelerometer).
  2. Make sure the app runs in Background even after App is closed.
  3. Continuously running sensors consumes too much battery, Do something about is so battery power can be saved as much as possible.

I already fulfilled NO: 1 and functioning as expected, Just 2 and 3 remains. What will be the easiest way to run this code in Background: I have an idea like this:

enter image description here

I want to Start and Stop the Background service using the Two Buttons.

Here is the Code for NO: 1.

public class SensorActivity extends Activity implements SensorEventListener{

private SensorManager mSensorManager;
private Sensor proxSensor,accSensor;

private TextView serviceStatus,profileStatus;
private Button startService,endService;

private boolean isObjectInFront,isPhoneFacedDown;

private AudioManager audioManager;

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

    audioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);

    mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
    proxSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    accSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);

    isObjectInFront = false;
    isPhoneFacedDown = false;

    serviceStatus = (TextView) findViewById(R.id.textView_serviceStatus);
    profileStatus = (TextView) findViewById(R.id.textView_profileStatus);
}

protected void onResume() {
    super.onResume();
    mSensorManager.registerListener(this, proxSensor, SensorManager.SENSOR_DELAY_NORMAL);
    mSensorManager.registerListener(this, accSensor, SensorManager.SENSOR_DELAY_NORMAL);
}


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

@Override
public void onSensorChanged(SensorEvent event) {

    if (event.sensor.getType() == Sensor.TYPE_PROXIMITY) {
        if(event.values[0] > 0){
            isObjectInFront = false;
        }
        else {
            isObjectInFront = true;
        }

    }
    if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
        if(event.values[2] < 0){
            isPhoneFacedDown = true;
        }
        else {
            isPhoneFacedDown = false;
        }
    }

    if(isObjectInFront && isPhoneFacedDown){
        audioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
        profileStatus.setText("Ringer Mode : Off\nVibration Mode: Off\nSilent Mode: On");
    }
    else {
        if(isObjectInFront){
            audioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
            profileStatus.setText("Ringer Mode : Off\nVibration Mode: On\nSilent Mode: Off");
        }
        else {
            audioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
            profileStatus.setText("Ringer Mode : On\nVibration Mode: Off\nSilent Mode: Off");
        }
    }



}

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

}

}

1

There are 1 best solutions below

4
On BEST ANSWER

You definitely should use a Service.

The Android user interface is restricted to perform long running jobs to make user experience smoother. A typical long running tasks can be periodic downloading of data from internet, saving multiple records into database, perform file I/O, fetching your phone contacts list, etc. For such long running tasks, Service is the alternative.

A service is an application component used to perform long running tasks in the background. A service doesn’t have any user interface and neither can it directly communicate to an activity. A service can run in the background indefinitely, even if the components that started the service is destroyed. Usually a service always performs a single operation and stops itself once intended task is complete. A service runs in the main thread of the application instance. It doesn’t create its own thread. If your service is going to do any long running blocking operation, it might cause Application Not Responding (ANR). And hence, you should create a new thread within the service.

Example

Service class

public class HelloService extends Service {

    private static final String TAG = "HelloService";

    private boolean isRunning  = false;

    @Override
    public void onCreate() {
        Log.i(TAG, "Service onCreate");

        isRunning = true;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Log.i(TAG, "Service onStartCommand");

        //Creating new thread for my service
        //Always write your long running tasks in a separate thread, to avoid ANR
        new Thread(new Runnable() {
            @Override
            public void run() {


                //Your logic that service will perform will be placed here
                //In this example we are just looping and waits for 1000 milliseconds in each loop.
                for (int i = 0; i < 5; i++) {
                    try {
                        Thread.sleep(1000);
                    } catch (Exception e) {
                    }

                    if(isRunning){
                        Log.i(TAG, "Service running");
                    }
                }

                //Stop service once it finishes its task
                stopSelf();
            }
        }).start();

        return Service.START_STICKY;
    }


    @Override
    public IBinder onBind(Intent arg0) {
        Log.i(TAG, "Service onBind");
        return null;
    }

    @Override
    public void onDestroy() {

        isRunning = false;

        Log.i(TAG, "Service onDestroy");
    }
}

Manifest declaration

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.javatechig.serviceexample" >

    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
    <activity
        android:name=".HelloActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <!--Service declared in manifest -->
    <service android:name=".HelloService"
        android:exported="false"/>
</application>

To start your service

Intent intent = new Intent(this, HelloService.class);
startService(intent);

Reference