Rolling ball use Accelerometer in Android - android

i have two isses
- the ball is going out of bound of the screen
- the ball movement is not smooth ( looks it disappears and re appears on the screen)
here is my code
public class GameActivity extends Activity{
private GameView GameView;
private SensorManager sensorManager;
private Sensor accelerometer;
public static Timer tmr;
public static TimerTask tsk = null;
public static Handler handler = new Handler();
public static Runnable runnable;
int mScrWidth, mScrHeight;
android.graphics.PointF mBallPos, mBallSpd;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().setFlags(0xFFFFFFFF,LayoutParams.FLAG_FULLSCREEN||LayoutParams.FLAG_KEEP_SCREEN_ON);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_game);
GameView = (GameView) findViewById(R.id.gameView);
// Add sensor listener
// Set the screen always portrait
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometer = sensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
// get screen dimensions
Display display = getWindowManager().getDefaultDisplay();
mScrWidth = display.getWidth();
mScrHeight = display.getHeight();
mBallPos = new android.graphics.PointF();
mBallSpd = new android.graphics.PointF();
// create variables for ball position and speed
mBallPos.x = mScrWidth / 2;
mBallPos.y = mScrHeight / 2;
mBallSpd.x = 0;
mBallSpd.y = 0;
// listener for accelerometer, use anonymous class for simplicity
((SensorManager) getSystemService(Context.SENSOR_SERVICE))
.registerListener(new SensorEventListener() {
#Override
public void onSensorChanged(SensorEvent event) {
// set ball speed based on phone tilt (ignore Z axis)
mBallSpd.x =-event.values[0];
mBallSpd.y = event.values[1];
// timer event will redraw ball
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
} // ignore this event
}, ((SensorManager) getSystemService(Context.SENSOR_SERVICE))
.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0),
SensorManager.SENSOR_DELAY_NORMAL);
}
}

Related

How to maintain an application that use the accelerometer sensor work correctly in lock-mode?

I have created a simple app that uses the accelerometer sensor to calculate the outside force then start a mp3 file. It seems to work well unless I turn screen off (or it automaticlly turns itself off) then it stops completely. How can i fix it. My code here, Thanks.
private MediaPlayer mediaPlayer;
private TextView textView;
private SensorManager sensorManager;
private Sensor accelerometerSensor;
private float maxf;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) this.findViewById(R.id.textView);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_UI);
}
#Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER){
return;
}
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float f = Math.round(Math.abs(x*x + y*y + z*z));
if (f>maxf ){ maxf =f;}
StringBuilder sb = new StringBuilder();
sb.append("forrce:").append(f).append("\n");
sb.append("MaxForce:").append(maxf).append("\n");
textView.setText(sb.toString());
if (maxf>150) {
mediaPlayer = MediaPlayer.create(this, R.raw.b);
mediaPlayer.start();
maxf=1;
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
Add on-lock services
[Reference][1]https://developer.android.com/guide/components/services.html
And use accelerometer in that particular activity...Hope it helps :)

Android Sensor Shake in the background

I'm trying to follow a tutorial about sensor. It works fine with an activity. However, I want this to work in the background when the phone is locked. What's the best way to do that?
Here's the link to the tutorial
http://jasonmcreynolds.com/?p=388
ShakeDetector class
public class ShakeDetector implements SensorEventListener {
/*
* The gForce that is necessary to register as shake.
* Must be greater than 1G (one earth gravity unit).
* You can install "G-Force", by Blake La Pierre
* from the Google Play Store and run it to see how
* many G's it takes to register a shake
*/
private static final float SHAKE_THRESHOLD_GRAVITY = 2.7F;
private static final int SHAKE_SLOP_TIME_MS = 500;
private static final int SHAKE_COUNT_RESET_TIME_MS = 3000;
private OnShakeListener mListener;
private long mShakeTimestamp;
private int mShakeCount;
public void setOnShakeListener(OnShakeListener listener) {
this.mListener = listener;
}
public interface OnShakeListener {
public void onShake(int count);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// ignore
}
#Override
public void onSensorChanged(SensorEvent event) {
if (mListener != null) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float gX = x / SensorManager.GRAVITY_EARTH;
float gY = y / SensorManager.GRAVITY_EARTH;
float gZ = z / SensorManager.GRAVITY_EARTH;
// gForce will be close to 1 when there is no movement.
Float f = new Float(gX * gX + gY * gY + gZ * gZ);
Double d = Math.sqrt(f.doubleValue());
float gForce = d.floatValue();
if (gForce > SHAKE_THRESHOLD_GRAVITY) {
final long now = System.currentTimeMillis();
// ignore shake events too close to each other (500ms)
if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now) {
return;
}
// reset the shake count after 3 seconds of no shakes
if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) {
mShakeCount = 0;
}
mShakeTimestamp = now;
mShakeCount++;
mListener.onShake(mShakeCount);
}
}
}
}
Main Acitivty
public class MainActivity extends AppCompatActivity {
// The following are used for the shake detection
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private ShakeDetector mShakeDetector;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent intent = new Intent(MainActivity.this, ShakeService.class);
startService(intent);
// ShakeDetector initialization
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mShakeDetector = new ShakeDetector();
mShakeDetector.setOnShakeListener(new ShakeDetector.OnShakeListener() {
#Override
public void onShake(int count) {
Toast.makeText(getApplicationContext(), "shake",Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onResume() {
super.onResume();
// Add the following line to register the Session Manager Listener onResume
mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
}
#Override
public void onPause() {
// Add the following line to unregister the Sensor Manager onPause
mSensorManager.unregisterListener(mShakeDetector);
super.onPause();
}
}
Shake Service
public class ShakeService extends Service {
private SensorManager mSensorManager;
private Sensor mAccelerometer;
private ShakeDetector mShakeDetector;
public ShakeService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public void onCreate() {
super.onCreate();
// ShakeDetector initialization
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mShakeDetector = new ShakeDetector();
mShakeDetector.setOnShakeListener(new ShakeDetector.OnShakeListener() {
#Override
public void onShake(int count) {
Intent i = getApplicationContext().getPackageManager().getLaunchIntentForPackage("com.facebook.katana");
getApplicationContext().startActivity(i);
}
});
mSensorManager.registerListener(mShakeDetector, mAccelerometer, SensorManager.SENSOR_DELAY_UI);
}
#Override
public void onDestroy() {
mSensorManager.unregisterListener(mShakeDetector);
super.onDestroy();
}
}
You need to use Threads, AsyncTask is the easiest to implement. Take a look at this, if that's what you're looking for: https://developer.android.com/guide/components/processes-and-threads.html
here is a goog example
http://joerichard.net/android/android-shake-detector/
Steps: create a sensor event listener and then get from Activity. Create a service that fires when shake event happen.

SensorEventListener temporarily not working

I've implemented SensorEventListener in my MainActivity, and it works quite well, i'd even say most of the time very well.
But weirdly, sometimes it completely stops working, I need to shake it in every direction for 5-10 seconds and it's magically back on.
It seems to be after the phone as idle/asleep for a long time.
I did implemented the register/unregister on onResume/onPause.
Here is my code, mostly coming from stackoverflow:
SensorManager sensorManager;
private float accel; // acceleration apart from gravity
private float accelCurrent; // current acceleration including gravity
private float accelLast; // last acceleration including gravity
private static final float SHAKE_THRESHOLD = 12.f;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initSensor();
}
private void initSensor() {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
registerSensor();
}
private void registerSensor() {
HandlerThread handlerThread = new HandlerThread(HANDLER_THREAD_NAME_SENSOR);
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL, handler);
accel = 0.00f;
accelCurrent = SensorManager.GRAVITY_EARTH;
accelLast = SensorManager.GRAVITY_EARTH;
}
#Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
#Override
protected void onResume() {
super.onResume();
registerSensor();
}
#Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
accelLast = accelCurrent;
accelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
float delta = accelCurrent - accelLast;
accel = accel * 0.9f + delta; // perform low-cut filter
//Log.d(TAG, ">>> ALL shake accel = "+ accel);
if (accel > SHAKE_THRESHOLD) {
Log.d(TAG, "shake accel = "+ accel);
runOnUiThread(new Runnable() {
#Override
public void run() {
// Do stuffs in the UI
}
});
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Nothing do to here
}
It was fixed by changing the sensor delay to SensorManager.SENSOR_DELAY_FASTEST;
The registration now looks like :
// Global
private static final String HANDLER_THREAD_NAME_SENSOR = "sensorThread";
// ...Registration
HandlerThread handlerThread = new HandlerThread(HANDLER_THREAD_NAME_SENSOR);
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_FASTEST,
handler);

Displaying Compass At specific location on Device

I want to display the compass(Image View) on device at a specific location.I tried Like this below code to display the compass view on device but the thing is i need to display at Specific location and small view only but it occupies entire screen space.Can you help me to fix an compass image at specific location.Using this line of code i am getting an image form Drawable folder. this.setImageResource(R.drawable.compassrose); So how to fix that image at specific location.
Class1:-
public class Compass extends Activity implements SensorListener {
SensorManager sensorManager;
static final int sensor = SensorManager.SENSOR_ORIENTATION;
Rose rose;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//http://ofps.oreilly.com/titles/9781449390501/Android_System_Services.html
// Set full screen view
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
//FLAG_FULLSCREEN
//FLAG_SCALED
rose = new Rose(this);
setContentView(rose);
// get sensor manager
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
}
// register to listen to sensors
#Override
public void onResume() {
super.onResume();
sensorManager.registerListener(this, sensor);
}
// unregister
#Override
public void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
// Ignore for now
public void onAccuracyChanged(int sensor, int accuracy) {
}
// Listen to sensor and provide output
public void onSensorChanged(int sensor, float[] values) {
if (sensor != Compass.sensor)
return;
int orientation = (int) values[0];
rose.setDirection(orientation);
}
}
Class 2:-
public class Rose extends ImageView {
Paint paint;
int direction = 0;
public Rose(Context context) {
super(context);
paint = new Paint();
paint.setColor(Color.WHITE);
paint.setStrokeWidth(2);
paint.setStyle(Style.STROKE);
this.setImageResource(R.drawable.compassrose);
}
#Override
public void onDraw(Canvas canvas) {
int height = this.getHeight();
int width = this.getWidth();
canvas.rotate(direction, width / 2, height / 2);
super.onDraw(canvas);
}
public void setDirection(int direction) {
this.direction = direction;
this.invalidate();
}
}
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
rose = new Rose(this);
txtorientation = (TextView) findViewById(R.id.textView1);
compassLayout = (RelativeLayout)findViewById(R.id.CompassLayout);
compassLayout.addView(rose);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
Log.d("Compass", "onCreated");
}
Are you asking how to position an ImageView in an Android layout? Have you tried with XML, or does it need to be set programmatically?
If you are just trying to position an ImageView, then try going through some of the layout tutorials: http://developer.android.com/resources/tutorials/views/index.html
If not, then please add more detail to your question

How can I access the accelerometer properly in Android 1.5?

I have seen a few code examples of 1.0 / 1.1 but since a lot of that is deprecated now I was hoping to find a nice 1.5+ example. I have some code here that I wrote but it doesn't really work properly. Any help would be great, thanks!
public class collectAccel extends Activity implements SensorEventListener,
OnClickListener{
private SensorManager sensorMgr;
private TextView xLabel, yLabel, zLabel;
private Button StartBtn;
private List<Sensor> sensorList;
private float x, y, z;
private long lastUpdate = -1;
// deltas for calibration
private float cx, cy, cz;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
xLabel = (TextView) findViewById(R.id.x_label);
yLabel = (TextView) findViewById(R.id.y_label);
zLabel = (TextView) findViewById(R.id.z_label);
StartBtn = (Button) findViewById(R.id.Button1);
StartBtn.setOnClickListener(this);
}
#Override
public void onClick(View arg0) {
if (xLabel.getVisibility() != 1)
xLabel.setVisibility(1);
if (yLabel.getVisibility() != 1)
yLabel.setVisibility(1);
if (zLabel.getVisibility() != 1)
zLabel.setVisibility(1);
}
#Override
protected void onPause() {
super.onPause();
sensorMgr.unregisterListener((SensorEventListener)this, sensorList.get(0));
sensorMgr = null;
cx = 0;
cy = 0;
cz = 0;
}
#Override
protected void onResume() {
super.onResume();
sensorMgr = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorList = sensorMgr.getSensorList(Sensor.TYPE_ACCELEROMETER);
boolean accelSupported = sensorMgr.registerListener((SensorEventListener)this,
sensorList.get(0),
SENSOR_DELAY_UI);
if (!accelSupported) {
// on accelerometer on this device
sensorMgr.unregisterListener((SensorEventListener)this, sensorList.get(0));
}
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
cx = 0;
cy = 0;
cz = 0;
}
#Override
public void onSensorChanged(SensorEvent arg0) {
if (arg0.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
long curTime = System.currentTimeMillis();
// only allow one update every 100ms, otherwise updates
// come way too fast and the phone gets bogged down
// with garbage collection
if (lastUpdate == -1 || (curTime - lastUpdate) > 100) {
lastUpdate = curTime;
x = arg0.values[0];
y = arg0.values[1];
z = arg0.values[2];
xLabel.setText(String.format("X: %+2.5f (%+2.5f)", (x+cx), cx));
yLabel.setText(String.format("Y: %+2.5f (%+2.5f)", (y+cy), cy));
zLabel.setText(String.format("Z: %+2.5f (%+2.5f)", (z+cz), cz));
}
}
}
}
You can look it up in the Android Reference but It looks like you'll need
SensorManager mgr = Context.getSystemService(SENSOR_SERVICE);
IList<Sensor> sensorList = mgr.getSensorList(SensorManager.SENSOR_ACCELEROMETER);
If you really want the list, but I think you are actually meant to use SensorManager.RegisterListener(SensorListener listener, int sensors, int rate) or another version of that method.

Categories

Resources