Pavan Putra Boy Pavan Putra Boy - 1 month ago 10
Android Question

Starting app when it shakes using broadcast

What I want is that when my app is in background and I shake the phone the app should start and come on foreground!

To achieve this I have used broadcast receiver as follows :

public class BootReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
mSensorManager = (SensorManager) arg0.getSystemService(arg0.SENSOR_SERVICE);
mSensorManager.registerListener( mSensorIntentListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
}

}


I have registered it also as follows :

<receiver

android:name=".BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>


Now for shake event I am using this code as given below :

private final SensorEventListener mSensorIntentListener = new SensorEventListener() {

public void onSensorChanged(SensorEvent se) {
float x = se.values[0];
float y = se.values[1];
float z = se.values[2];
mAccelLast = mAccelCurrent;
mAccelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
float delta = mAccelCurrent - mAccelLast;
mAccel = mAccel * 0.9f + delta; // perform low-cut filter
if (mAccel > 12) {
Toast.makeText(getApplicationContext(), "Device has shaken.", Toast.LENGTH_LONG).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}

}

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub

}


};


Now when I try to run the app and put it on background and shake it doesn't works !

So what is the logical error and how to make my app come foreground on shake ?

One more thing I am using nested classes concept so all classes are in MainActivity class !

code full !
:

package com.example.sensorlist;



public class MainActivity extends ActionBarActivity {
TextView tv1=null;
static File file = null;
private String outputFile = null;
private float mAccel; // acceleration apart from gravity
private float mAccelCurrent; // current acceleration including gravity
private float mAccelLast; // last acceleration including gravity
Button play,stop,record;
MediaRecorder myAudioRecorder;
public SensorManager mSensorManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
play=(Button)findViewById(R.id.button3);
stop=(Button)findViewById(R.id.button2);
record=(Button)findViewById(R.id.button);


stop.setEnabled(false);
play.setEnabled(false);

final File path =
Environment.getExternalStoragePublicDirectory
(
//Environment.DIRECTORY_PICTURES
//Environment.DIRECTORY_DCIM
Environment.DIRECTORY_DCIM + "/Utkarshrecord/"
);

// Make sure the sound directory exists.
if(!path.exists())
{
path.mkdirs();
}

try {
file= File.createTempFile("sound", ".3gp", path);

myAudioRecorder=new MediaRecorder();
myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
myAudioRecorder.setOutputFile(file.getAbsolutePath());

} catch (IOException e2) {
// TODO Auto-generated catch block
e2.printStackTrace();
}





mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);

if( mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)!=null){
Toast.makeText(getBaseContext(), "Yes it is there ", Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getBaseContext(), "Sry no accelerometer", Toast.LENGTH_LONG).show();
}
mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
mAccel = 0.00f;
mAccelCurrent = SensorManager.GRAVITY_EARTH;
mAccelLast = SensorManager.GRAVITY_EARTH;
record.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
try {
myAudioRecorder.prepare();
myAudioRecorder.start();
}

catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

record.setEnabled(false);
stop.setEnabled(true);

Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_LONG).show();
}
});
stop.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) throws IllegalArgumentException,SecurityException,IllegalStateException {
try{
myAudioRecorder.stop();
myAudioRecorder.release();
myAudioRecorder = null;




}catch(Exception e){
e.printStackTrace();
}
Toast.makeText(getApplicationContext(), "Audio recorded successfully",Toast.LENGTH_LONG).show();
stop.setEnabled(false);
play.setEnabled(true);
}
});
play.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) throws IllegalArgumentException,SecurityException,IllegalStateException {
MediaPlayer m = new MediaPlayer();

try {
m.setDataSource(file.getAbsolutePath());
m.prepare();
}

catch (IOException e) {
e.printStackTrace();
}



m.start();
Toast.makeText(getApplicationContext(), "Playing audio", Toast.LENGTH_LONG).show();
}
});

}


private final SensorEventListener mSensorListener = new SensorEventListener() {

public void onSensorChanged(SensorEvent se) {
float x = se.values[0];
float y = se.values[1];
float z = se.values[2];
mAccelLast = mAccelCurrent;
mAccelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
float delta = mAccelCurrent - mAccelLast;
mAccel = mAccel * 0.9f + delta; // perform low-cut filter
if (mAccel > 12) {
Toast.makeText(getApplicationContext(), "Device has shaken.", Toast.LENGTH_LONG).show();
try {
myAudioRecorder.prepare();
myAudioRecorder.start();
record.setEnabled(false);
stop.setEnabled(true);

} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

Toast.makeText(getBaseContext(), "recording has started", Toast.LENGTH_SHORT).show();

}
}

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub

}


};
private final SensorEventListener mSensorIntentListener = new SensorEventListener() {

public void onSensorChanged(SensorEvent se) {
float x = se.values[0];
float y = se.values[1];
float z = se.values[2];
mAccelLast = mAccelCurrent;
mAccelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
float delta = mAccelCurrent - mAccelLast;
mAccel = mAccel * 0.9f + delta; // perform low-cut filter
if (mAccel > 12) {
Toast.makeText(getApplicationContext(), "Device has shaken.", Toast.LENGTH_LONG).show();
Intent intent = new Intent(getApplicationContext(), MainActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}

}

@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub

}


};

@Override
protected void onPause() {
mSensorManager.unregisterListener(mSensorListener);
super.onPause();
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class ShakeRec extends Service{

@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}

@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();


}



@Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();

}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub

return super.onStartCommand(intent, flags, startId);
}



}

public class BootReceiver extends BroadcastReceiver {

@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
mSensorManager = (SensorManager) arg0.getSystemService(arg0.SENSOR_SERVICE);
mSensorManager.registerListener( mSensorIntentListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
}

}


}

Answer

Your <receiver> element will not work. If you were to look at LogCat on a reboot, you would see warnings or errors from Android, saying that it cannot find your BootReceiver class. A manifest-registered receiver cannot be a nested class inside of an activity.

Get rid of the <receiver> element. Get rid of BootReceiver. Register your SensorEventListener in onCreate() of your activity. So long as your process is running (which may not be very long), and so long as the device is turned on, you should receive sensor events.