I am trying to move a imageview(ball image) using sensorchange (on accelerometer) by using TranslateAnimation in my android application. But the application does not move the imageview. My logs look like the app is not even registering the accelerometer and I only see the ball imageview on the screen constant at a place. Can anybody please help me in resolving what am I doing wrong here? My code and logs are as follow:
public class MainActivity extends Activity implements SensorEventListener {
private ImageView ball=null;
public static int nwidth, nheight;
public static float xPosition, yPosition,oldx=0,oldy=0;
private float xAcceleration=0.0f,xVelocity = 0.0f;
private float yAcceleration=0.0f,yVelocity = 0.0f;
private float zAcceleration=0.0f;
public float frameTime = 0.999f;
private float mAlpha = 0.9f;
private static final String TAG = "Readings";
String toWrite=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ball = (ImageView) findViewById(R.id.image_ball);
getScreenSize();
setContentView(R.layout.activity_main);
}
private void getScreenSize()
{
Point displaySize = new Point();
getWindowManager().getDefaultDisplay().getRealSize(displaySize);
Rect windowSize = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(windowSize);
nwidth = displaySize.x - Math.abs(windowSize.width());
nheight = displaySize.y - Math.abs(windowSize.height());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.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();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onSensorChanged(SensorEvent sensorEvent)
{
{
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
yAcceleration = lowPass(sensorEvent.values[1], yAcceleration);
xAcceleration = lowPass(sensorEvent.values[2],xAcceleration);
zAcceleration = lowPass(sensorEvent.values[0],zAcceleration);
toWrite = sensorEvent.values[0] + "," + sensorEvent.values[2] + "\n";
writeCSV(toWrite);
Log.i(TAG, "x:" + xAcceleration + " y:" + yAcceleration + "z:" + zAcceleration);
updateBall();
}
}
}
// simple low-pass filter
float lowPass(float current, float filtered) {
return mAlpha * current + (1.0f - mAlpha) * filtered;
}
private void writeCSV(String txtData)
{
try {
File myFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+ "Readings.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile,true);
OutputStreamWriter myOutWriter =
new OutputStreamWriter(fOut);
myOutWriter.append(txtData);
myOutWriter.close();
fOut.close();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
private void updateBall() {
//for landscape orientation, treating z axis as x.
xVelocity = (-zAcceleration * frameTime);
float xS = (xVelocity)*frameTime;
xPosition += xS;
// yPosition += yS;
yPosition++;
setPosition();
Log.i(TAG,"x:" + xAcceleration +" y:" + yAcceleration);
}
private void setPosition()
{
TranslateAnimation animation = new TranslateAnimation(oldx, xPosition, oldy, yPosition);
animation.setDuration(10);
animation.setFillAfter(false);
animation.setAnimationListener(new MyAnimationListener(ball));
ball.startAnimation(animation);
oldx=xPosition;
oldy=yPosition;
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
class MyAnimationListener implements Animation.AnimationListener {
ImageView imageView=null;
public MyAnimationListener(ImageView image)
{
imageView=image;
}
#Override
public void onAnimationEnd(Animation animation) {
imageView.clearAnimation();
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(imageView.getWidth(), imageView.getHeight());
// lp.setMargins(50, 100, 0, 0);
imageView.setLayoutParams(lp);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
}
08-12 01:03:21.348: I/art(3404): Late-enabling -Xcheck:jni
08-12 01:03:21.386: E/art(3404): Failed sending reply to debugger: Broken pipe
08-12 01:03:21.386: I/art(3404): Debugger is no longer active
08-12 01:03:21.516: D/OpenGLRenderer(3404): Render dirty regions requested: true
08-12 01:03:21.522: D/Atlas(3404): Validating map...
08-12 01:03:21.568: I/OpenGLRenderer(3404): Initialized EGL, version 1.4
08-12 01:03:21.609: D/OpenGLRenderer(3404): Enabling debug mode 0
Thanks!
package com.example.test;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
public class MainActivity extends Activity implements SensorEventListener {
SensorManager mSensorManager;
Sensor mSensor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mSensorManager.unregisterListener(this);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
}
}
Related
I am browsing the internet trying to find something that would be usefull in my Android App.
I have my GPS location and several markers added to Google Map. When I turn around the location arrow is ponting wherever I am facing. My concern is if there is any way to determine on which marker I am pointing at? I have made a picture to clarify this.
I presume I can get compass bearing using getRotationMatrix() method, but how can I determine angle between location and the marker?
Checkout Compass class in this project: https://github.com/iutinvg/compass
I have used it succsesfully in this app: https://play.google.com/store/apps/details?id=com.gps.build
Regards.
UPDATE:
After reading your question again, i have realized that I did not give you enough details for "pointing to marker" part. Please check full class below. To calculate pointing direction, us startBearing and stopBearing methods.
Note that bearing degrees are changing with device rotation in BringMeBack class with setBearingDegrees method. Thats is not what you need, so you just have to remove locationManager and to put static bearing coordinate. And call that method only once.
Extended compass class:
package com.gps.bitlab;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ImageView;
import com.gps.bitlab.fragment.MessageDialogFragment;
import com.gps.bitlab.util.Utility;
public class Compass implements SensorEventListener {
private static final String TAG = "Compass";
private SensorManager sensorManager;
private Sensor gsensor;
private Sensor msensor;
private float[] mGravity = new float[3];
private float[] mGeomagnetic = new float[3];
private float azimuth = 0f;
private float currectAzimuth = 0;
private boolean bearing = false;
private float bearingDegrees = -1;
// compass arrow to rotate
public ImageView arrowView = null;
FragmentActivity activity;
public Compass(FragmentActivity activity) {
this.activity = activity;
sensorManager = (SensorManager) activity.getApplicationContext()
.getSystemService(Context.SENSOR_SERVICE);
gsensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
msensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
}
public void start() {
boolean deviceSensorCompatible = true;
if(!sensorManager.registerListener(this, gsensor, SensorManager.SENSOR_DELAY_GAME))
deviceSensorCompatible = false;
if(!sensorManager.registerListener(this, msensor, SensorManager.SENSOR_DELAY_GAME))
deviceSensorCompatible = false;
if(!deviceSensorCompatible) {
Utility.ShowMessage(activity, activity.getString(R.string.erroroccured), activity.getString(R.string.deviceIncompatible), 1);
stop();
}
}
public void startBearing()
{
bearing = true;
start();
}
public void setBearingDegrees(float bearingDegrees)
{
this.bearingDegrees = bearingDegrees;
}
public void stop() {
sensorManager.unregisterListener(this);
}
public void stopBearing()
{
bearing = false;
stop();
}
private void adjustArrow() {
if (arrowView == null) {
Log.i(TAG, "arrow view is not set");
return;
}
Animation an = new RotateAnimation(-currectAzimuth, -azimuth,
Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF,
0.5f);
currectAzimuth = azimuth;
an.setDuration(250);
an.setRepeatCount(0);
an.setFillAfter(true);
arrowView.startAnimation(an);
}
#Override
public void onSensorChanged(SensorEvent event) {
final float alpha = 0.97f;
synchronized (this) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
mGravity[0] = alpha * mGravity[0] + (1 - alpha)
* event.values[0];
mGravity[1] = alpha * mGravity[1] + (1 - alpha)
* event.values[1];
mGravity[2] = alpha * mGravity[2] + (1 - alpha)
* event.values[2];
// mGravity = event.values;
// Log.e(TAG, Float.toString(mGravity[0]));
}
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
// mGeomagnetic = event.values;
mGeomagnetic[0] = alpha * mGeomagnetic[0] + (1 - alpha)
* event.values[0];
mGeomagnetic[1] = alpha * mGeomagnetic[1] + (1 - alpha)
* event.values[1];
mGeomagnetic[2] = alpha * mGeomagnetic[2] + (1 - alpha)
* event.values[2];
// Log.e(TAG, Float.toString(event.values[0]));
}
float R[] = new float[9];
float I[] = new float[9];
boolean success = SensorManager.getRotationMatrix(R, I, mGravity,
mGeomagnetic);
if (success) {
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
// Log.d(TAG, "azimuth (rad): " + azimuth);
azimuth = (float) Math.toDegrees(orientation[0]); // orientation
azimuth = (azimuth + 360) % 360;
if(bearing) {
if(bearingDegrees != -1) {
azimuth -= bearingDegrees;
adjustArrow();
}
}
else
adjustArrow();
// Log.d(TAG, "azimuth (deg): " + azimuth);
}
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
Class that use pointing to location functionality:
package com.gps.bitlab;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.MenuItem;
import android.view.View;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import com.gps.bitlab.R;
import com.gps.bitlab.fragment.OnDialogClickListener;
import com.gps.bitlab.util.Utility;
public class BringMeBack extends ActionBarActivity implements LocationListener, OnDialogClickListener {
LocationManager locMng;
Location location;
double lat;
double lon;
double alt;
String name;
Compass compass;
FrameLayout bearingParentLayout;
LinearLayout BaseLayout;
ImageView arrow;
boolean layoutReplaced = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Utility.SetLocalization(this);
setContentView(R.layout.activity_bring_me_back);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
getActionBar().setDisplayHomeAsUpEnabled(true);
bearingParentLayout = (FrameLayout)findViewById(R.id.bearingParentLayout);
BaseLayout = Utility.GetLoadingView(getLayoutInflater(), getString(R.string.waitingForLocation));
if(savedInstanceState != null)
{
lat = savedInstanceState.getDouble("lat");
lon = savedInstanceState.getDouble("lon");
alt = savedInstanceState.getDouble("alt");
name = savedInstanceState.getString("name");
}
else {
lat = getIntent().getExtras().getDouble("lat");
lon = getIntent().getExtras().getDouble("lon");
alt = getIntent().getExtras().getDouble("alt");
name = getIntent().getExtras().getString("name");
}
if(name != null && !name.equals(""))
getActionBar().setTitle(name);
locMng = (LocationManager)getSystemService(LOCATION_SERVICE);
location = new Location(LocationManager.GPS_PROVIDER);
location.setLongitude(lon);
location.setLatitude(lat);
location.setAltitude(alt);
arrow = (ImageView)findViewById(R.id.bearingArrow);
compass = new Compass(this);
compass.arrowView = arrow;
arrow.setVisibility(View.GONE);
bearingParentLayout.addView(BaseLayout);
}
#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 == android.R.id.home) {
BringMeBack.this.finish();
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onPause() {
super.onPause();
compass.stopBearing();
locMng.removeUpdates(this);
}
#Override
protected void onResume() {
super.onResume();
compass.startBearing();
RequestLocationUpdates();
}
#Override
public void onLocationChanged(Location currentLocation) {
float bearing = currentLocation.bearingTo(location);
Log.d("Location bearing", String.valueOf(bearing));
compass.setBearingDegrees(bearing);
if(!layoutReplaced) {
bearingParentLayout.removeView(BaseLayout);
arrow.setVisibility(View.VISIBLE);
layoutReplaced = true;
}
}
#Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
#Override
public void onProviderEnabled(String s) {
Log.d("GPS", "Service enabled");
RequestLocationUpdates();
}
#Override
public void onProviderDisabled(String s) {
locMng.removeUpdates(this);
Utility.ShowMessage(BringMeBack.this, getString(R.string.locationServiceDisabledMessage), getString(R.string.locationServiceDisabled), 0);
}
#Override
public void OnPositiveClick(int key, Object... args) {
startActivity(new Intent(android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
#Override
public void OnNegativeClick(int key, Object... args) {
}
private void RequestLocationUpdates()
{
if(!locMng.isProviderEnabled(LocationManager.GPS_PROVIDER))
Utility.ShowMessage(BringMeBack.this, getString(R.string.locationServiceDisabledMessage), getString(R.string.locationServiceDisabled), 0);
else
locMng.requestLocationUpdates(LocationManager.GPS_PROVIDER, 500, 0, this);
}
}
In the 'MainActivity', I create a function about when I shake the device, it will go to the 'CompassActivity'. And it works. And I want to shake it again and want to back to 'MainActivity', but it doesn't work.
Here is the code of the MainActivity
package com.lab.mapme;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Menu;
import android.widget.ImageButton;
public class MainActivity extends Activity implements SensorEventListener {
ImageButton _buttonForward = null;
ImageButton _buttonBackward = null;
ImageButton _buttonLeft = null;
ImageButton _buttonRight = null;
boolean _fisMoved = false;
boolean _bisMoved = false;
boolean _lisMoved = false;
boolean _risMoved = false;
boolean _isShaked = false;
long _lastSampleTime = 0;
private SensorManager _sensorManager;
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
handleAccelerometer(event);
}
}
private void handleAccelerometer(SensorEvent event) {
float[] values = event.values;
float x = values[0];
float y = values[1];
float z = values[2];
Acceleration_getCompress(x, y, z);
if (_isShaked) {
startActivity(new Intent(getApplicationContext(),
CompassActivity.class));
}
Acceleration_getDirectionForward(y);
if (_fisMoved) {
_buttonForward.setBackgroundColor(Color.YELLOW);
} else {
_buttonForward.setBackgroundColor(Color.TRANSPARENT);
}
Acceleration_getDirectionBackward(y);
if (_bisMoved) {
_buttonBackward.setBackgroundColor(Color.YELLOW);
} else {
_buttonBackward.setBackgroundColor(Color.TRANSPARENT);
}
Acceleration_getDirectionLeft(x);
if (_lisMoved) {
_buttonLeft.setBackgroundColor(Color.YELLOW);
} else {
_buttonLeft.setBackgroundColor(Color.TRANSPARENT);
}
Acceleration_getDirectionRight(x);
if (_risMoved) {
_buttonRight.setBackgroundColor(Color.YELLOW);
} else {
_buttonRight.setBackgroundColor(Color.TRANSPARENT);
}
}
private void Acceleration_getCompress(float x, float y, float z) {
float a = (x * x + y * y + z * z);
float aToGravity = a
/ (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
long currentTime = System.currentTimeMillis();
if (aToGravity >= 2) {
if (currentTime - _lastSampleTime < 200) {
// duration too short, ignore slight movement
return;
}
_lastSampleTime = currentTime;
_isShaked = !_isShaked;
}
}
private void Acceleration_getDirectionForward(float y) {
float a = y;
if (a > a + y) {
_fisMoved = !_fisMoved;
}
}
private void Acceleration_getDirectionBackward(float y) {
float a = y;
if (a < a + y) {
_bisMoved = !_bisMoved;
}
}
private void Acceleration_getDirectionLeft(float x) {
float a = x;
if (a < a + x) {
_lisMoved = !_lisMoved;
}
}
private void Acceleration_getDirectionRight(float x) {
float a = x;
if (a > a + x) {
_risMoved = !_risMoved;
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
_sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
_buttonForward = (ImageButton) findViewById(R.id.buttonforward);
_buttonBackward = (ImageButton) findViewById(R.id.buttonbackward);
_buttonLeft = (ImageButton) findViewById(R.id.buttonleft);
_buttonRight = (ImageButton) findViewById(R.id.buttonright);
}
#Override
protected void onResume() {
super.onResume();
_sensorManager.registerListener(this,
_sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
super.onPause();
_sensorManager.unregisterListener(this);
}
#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;
}
}
ANd it is the code for the CompassActivity
package com.lab.mapme;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.Toast;
public class CompassActivity extends Activity {
private SensorManager _sensorManager;
private Sensor _sensor;
private CompassView _compassView;
boolean _isShaked = false;
long _lastSampleTime = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
_sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
_sensor = _sensorManager.getDefaultSensor(Sensor.TYPE_ORIENTATION);
_compassView = new CompassView(this);
setContentView(_compassView);
}
private SensorEventListener _sensorEventListener = new SensorEventListener() {
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
public void onSensorChanged(SensorEvent event) {
// angle between the magnetic north direction
// 0=North, 90=East, 180=South, 270=West
float azimuth = event.values[0];
_compassView.updateData(azimuth);
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
handleAccelerometer(event);
}
}
};
private void handleAccelerometer(SensorEvent event) {
float[] values = event.values;
float x = values[0];
float y = values[1];
float z = values[2];
Acceleration_getDirection(x, y, z);
if (_isShaked) {
startActivity(new Intent(getApplicationContext(),
MainActivity.class));
}
}
private void Acceleration_getDirection(float x, float y, float z) {
float a = (x * x + y * y + z * z);
float aToGravity = a
/ (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
long currentTime = System.currentTimeMillis();
if (aToGravity >= 2) {
if (currentTime - _lastSampleTime < 200) {
// duration too short, ignore slight movement
return;
}
_lastSampleTime = currentTime;
_isShaked = !_isShaked;
}
}
#Override
protected void onResume() {
super.onResume();
if (_sensor != null) {
_sensorManager.registerListener(_sensorEventListener, _sensor,
SensorManager.SENSOR_DELAY_NORMAL);
} else {
Toast.makeText(this, "ORIENTATION Sensor not found",
Toast.LENGTH_LONG).show();
}
}
#Override
protected void onPause() {
super.onPause();
if (_sensor != null) {
_sensorManager.unregisterListener(_sensorEventListener);
}
}
}
Using startActivity(new Intent(getApplicationContext(), MainActivity.class)); will create a new activity instance - instead recycle your old activity by calling the onFinish() or onBackPressed() methods in place.
If that doesn't work ensure handleAccelerometer is being called when you shake your device during your CompassActivity.
I am making an android game that is checking the players health value when this method is being runned. But however, it's not reacting. It doesn't do anything, when the value is less than 3, it shouldn't do anything, but when it is equal to 3, it should run a method. Please help me and thanks SO much in advance! This is the code that i am using:
private void checkLivesLeftValue() {
if (livesLeftValue == 3) {
//Message to display: "You lost!
onMethod();
}
else {
livesLeftValue = livesLeftValue + 1;
}
}
Full code:
package com.mysoftwaremobileapps.ParachuteHunter;
import java.util.ArrayList;
import android.app.AlertDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.TextView;
import android.widget.Toast;
public class ExampleView extends SurfaceView implements SurfaceHolder.Callback
{
class ExampleThread extends Thread
{
private ArrayList<Parachuter> parachuters;
private Bitmap parachuter;
private Paint black;
private boolean running;
private SurfaceHolder mSurfaceHolder;
private Context mContext;
private Handler mHandler;
private GameScreenActivity mActivity;
private long frameRate;
private boolean loading;
public float x;
public float y;
public MediaPlayer mp1;
public int parachuterIndexToResetAndDelete;
public int canvasGetWidth;
public int livesLeftValue;
public ExampleThread(SurfaceHolder sHolder, Context context, Handler handler)
{
mSurfaceHolder = sHolder;
mHandler = handler;
mContext = context;
mActivity = (GameScreenActivity) context;
parachuters = new ArrayList<Parachuter>();
parachuter = BitmapFactory.decodeResource(getResources(), R.drawable.parachuteman);
black = new Paint();
black.setStyle(Paint.Style.FILL);
black.setColor(Color.WHITE);
running = true;
// This equates to 26 frames per second.
frameRate = (long) (1000 / 26);
loading = true;
}
#Override
public void run()
{
while (running)
{
Canvas c = null;
try
{
c = mSurfaceHolder.lockCanvas();
synchronized (mSurfaceHolder)
{
long start = System.currentTimeMillis();
doDraw(c);
long diff = System.currentTimeMillis() - start;
if (diff < frameRate)
Thread.sleep(frameRate - diff);
}
} catch (InterruptedException e)
{
}
finally
{
if (c != null)
{
mSurfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
protected void doDraw(Canvas canvas)
{
canvas.drawRect(0, 0, canvas.getWidth(), canvas.getHeight(), black);
canvasGetWidth = canvas.getWidth();
//Draw
for (int i = 0; i < parachuters.size(); i++)
{
canvas.drawBitmap(parachuter, parachuters.get(i).getX(), parachuters.get(i).getY(), null);
parachuters.get(i).tick();
}
//Remove
for (int i = 0; i < parachuters.size(); i++)
{
if (parachuters.get(i).getY() > canvas.getHeight()) {
parachuters.remove(i);
onPlaySound();
checkLivesLeftValue();
}
}
}
public void onPlaySound()
{
try {
mp1 = MediaPlayer.create(getContext(), R.raw.bombsound);
mp1.start();
} catch (Exception e) {
e.printStackTrace();
mp1.release();
}
}
public void onMethod() {
mHandler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getContext(), "You lost!", 15).show();
}
});
}
private void checkLivesLeftValue() {
// TODO Auto-generated method stub
if (livesLeftValue == 3) {
//Message to display: "You lost!
onMethod();
}
else {
livesLeftValue = livesLeftValue + 1;
}
}
public boolean onTouchEvent(MotionEvent event)
{
if (event.getAction() != MotionEvent.ACTION_DOWN)
return false;
float x1 = event.getX();
float y1 = event.getY();
initiateDrawParachuters();
return true;
}
public void initiateDrawParachuters()
{
drawParachuter1();
}
private void drawParachuter1() {
// TODO Auto-generated method stub
//Parachuter nr. 1
x = 68;
y = 40;
Parachuter p = new Parachuter(x, y);
parachuters.add(p);
drawParachuter2();
}
private void drawParachuter2() {
// TODO Auto-generated method stub
//Parachuter nr. 2
x = 100;
y = 80;
Parachuter p = new Parachuter(x, y);
parachuters.add(p);
drawParachuter3();
}
private void drawParachuter3() {
// TODO Auto-generated method stub
//Parachuter nr. 3
x = 150;
y = 120;
Parachuter p = new Parachuter(x, y);
parachuters.add(p);
drawParachuter4();
}
private void drawParachuter4() {
// TODO Auto-generated method stub
//Parachuter nr. 4
x = 170;
y = 150;
Parachuter p = new Parachuter(x, y);
parachuters.add(p);
drawParachuter5();
}
private void drawParachuter5() {
// TODO Auto-generated method stub
//Parachuter nr. 5
x = 180;
y = 170;
Parachuter p = new Parachuter(x, y);
parachuters.add(p);
drawParachuter6();
}
private void drawParachuter6() {
// TODO Auto-generated method stub
//Parachuter nr. 6
x = 200;
y = 180;
Parachuter p = new Parachuter(x, y);
parachuters.add(p);
}
public void drawParachuters()
{
Parachuter p = new Parachuter(x, y);
parachuters.add(p);
Toast.makeText(getContext(), "x=" + x + " y=" + y, 15).show();
}
public void setRunning(boolean bRun)
{
running = bRun;
}
public boolean getRunning()
{
return running;
}
}
/** Handle to the application context, used to e.g. fetch Drawables. */
private Context mContext;
/** Pointer to the text view to display "Paused.." etc. */
private TextView mStatusText;
/** The thread that actually draws the animation */
private ExampleThread eThread;
public ExampleView(Context context)
{
super(context);
// register our interest in hearing about changes to our surface
SurfaceHolder holder = getHolder();
holder.addCallback(this);
// create thread only; it's started in surfaceCreated()
eThread = new ExampleThread(holder, context, new Handler()
{
#Override
public void handleMessage(Message m)
{
// mStatusText.setVisibility(m.getData().getInt("viz"));
// mStatusText.setText(m.getData().getString("text"));
}
});
setFocusable(true);
}
#Override
public boolean onTouchEvent(MotionEvent event)
{
return eThread.onTouchEvent(event);
}
public ExampleThread getThread()
{
return eThread;
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3)
{
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder)
{
if (eThread.getState() == Thread.State.TERMINATED)
{
eThread = new ExampleThread(getHolder(), getContext(), getHandler());
eThread.start();
}
else
{
eThread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder)
{
boolean retry = true;
eThread.setRunning(false);
while (retry)
{
try
{
eThread.join();
retry = false;
}
catch (InterruptedException e)
{
}
}
}
}
I agree with the others, check the value via Log messages, so you can see the actual values.
Also, check if it might go over 3. I dont know what kind of game you are making but for example, say that livesLeftValue=2 for now, but something happens, and it increases by 2, reaching 4, without ever having the value 3. Lets say it never gets decreased, so you will never ever hit the value 3, thus never invoking the game over thingie, and livesLeftValue will just increase to the infinity.
put some debug in there and see if you really get the right value in here.
private void checkLivesLeftValue() {
Log.d("checkLivesLeftValue", "lives = " + livesLeftValue);
if (livesLeftValue == 3) {
Log.d("checkLivesLeftValue", "calling onMethod now");
onMethod();
} else {
livesLeftValue = livesLeftValue + 1;
Log.d("checkLivesLeftValue", "increased lives to " + livesLeftValue);
}
}
public void onMethod() {
Log.d("onMethod", "in onMethod");
mHandler.post(new Runnable() {
#Override
public void run() {
Log.d("onMethod", "showing Toast now");
Toast.makeText(getContext(), "You lost!", 15).show();
}
});
}
This might seem like a silly qustion but how do you change the picture that draws on the screen.I have already been able to program a app were it draws a little icon where you touch the screen.So natually after I completed that I want to make it better by adding a option menu and the ability to change what icon you were being drown but when I ran the code the icon picture stayed the same.When I looked at it I found that when you click on any of the menu item it does do it's job and change the image id but when you go back to the main screen and try to create a new image it revertes back to the old image.I have no idea why it doesn't change because when I look at it everything make sense for it to change icon properly.If any one has any idea on what i am doing wrong or any suggestion on how to do this it would be greatly appreciate
Main
public class main extends Activity {
/** Called when the activity is first created. */
MenuItem item2;
int item3=R.drawable.ic_launcher;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
FrameLayout sv = new FrameLayout(this);
LinearLayout ll = new LinearLayout(this);
Panel test = new Panel(this);
//ImageButton button = new ImageButton(this);
ll.setOrientation(LinearLayout.VERTICAL);
sv.addView(test);
//ll.addView(button);
sv.addView(ll);
setContentView(sv);
}
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
Log.v("test", "item3 before is: "+item3);
item3=R.drawable.box;
Log.v("test", "item3 after is: "+item3);
return super.onOptionsItemSelected(item);
}
}
Panel
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
private Bitmap image;
private ViewThread mThread;
private int x;
private int y;
private ArrayList<Element> mElements = new ArrayList<Element>();
public Panel(Context context) {
super(context );
image = BitmapFactory.decodeResource(getResources(),yantz.imageapp4.R.drawable.test);
getHolder().addCallback(this);
mThread = new ViewThread(this);
}
public void doDraw(Canvas canvas) {
canvas.drawColor(Color.CYAN);
canvas.drawBitmap(image, x, y, null);
synchronized (mElements){
for(Element element : mElements){
element.doDraw(canvas);
}
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
// TODO Auto-generated method stub
Log.v("test", "you have touched the sreen: ");
synchronized (mElements){
mElements.add(new Element(getResources(),(int) event.getX(),(int) event.getY()));
}
return super.onTouchEvent(event);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
if (!mThread.isAlive()) {
mThread = new ViewThread(this);
mThread.setRunning(true);
mThread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mThread.isAlive()) {
mThread.setRunning(false);
}
}
}
Elements
public class Element extends main{
private int mX;
private int mY;
int location ;
private Bitmap mBitmap;
public Element(Resources res, int x, int y) {
Log.v("element", "item3 before location is: "+item3);
location =item3;
mBitmap = BitmapFactory.decodeResource(res, location);
mX = x - mBitmap.getWidth() / 2;
mY = y - mBitmap.getHeight() / 2;
Log.v("element", "item3 before location is: "+item3);
}
public void doDraw(Canvas canvas) {
canvas.drawBitmap(mBitmap, mX, mY, null);
}
public void setlocation(int location2){
location=location2;
}
}
ViewThread
public class ViewThread extends Thread {
private Panel mPanel;
private SurfaceHolder mHolder;
private boolean mRun = false;
public ViewThread(Panel panel) {
mPanel = panel;
mHolder = mPanel.getHolder();
}
public void setRunning(boolean run) {
mRun = run;
}
#Override
public void run() {
Canvas canvas = null;
while (mRun) {
canvas = mHolder.lockCanvas();
if (canvas != null) {
mPanel.doDraw(canvas);
mHolder.unlockCanvasAndPost(canvas);
}
}
}
}
you can use
#Override
protected void onResume() {
super.onResume();
id="what ever you want";
//and set it to imagevIew;
}
if i have understood the uestion correctly,this happens because your activity pauses when it is not focused and resumes with default values.
onRestoreInstanceState(Bundle savedInstanceState)
is not geting called, I am pasting my code below. Actually I want to redraw all the points that are saved when my activity went in background.
package com.geniteam.mytest;
import java.util.ArrayList;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.Window;
public class Tutorial2D extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(new Panel(this));
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
Panel panel = new Panel(this);
outState.putSerializable("test", panel._graphics);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
Panel panel = new Panel(this);
panel.set_graphics((ArrayList<GraphicObject>) savedInstanceState.getSerializable("test"));
}
class Panel extends SurfaceView implements SurfaceHolder.Callback {
private TutorialThread _thread;
private ArrayList<GraphicObject> _graphics = new ArrayList<GraphicObject>();
public ArrayList<GraphicObject> get_graphics() {
return _graphics;
}
public void set_graphics(ArrayList<GraphicObject> graphics) {
_graphics = graphics;
}
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
_thread = new TutorialThread(getHolder(), this);
setFocusable(true);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
synchronized (_thread.getSurfaceHolder()) {
// if (event.getAction() == MotionEvent.ACTION_DOWN) {
GraphicObject graphic = new GraphicObject(BitmapFactory.decodeResource(getResources(), R.drawable.icon));
graphic.getCoordinates().setX((int) event.getX() - graphic.getGraphic().getWidth() / 2);
graphic.getCoordinates().setY((int) event.getY() - graphic.getGraphic().getHeight() / 2);
_graphics.add(graphic);
//}
return true;
}
}
#Override
public void onDraw(Canvas canvas) {
canvas.drawColor(Color.BLACK);
Bitmap bitmap;
GraphicObject.Coordinates coords;
for (GraphicObject graphic : _graphics) {
bitmap = graphic.getGraphic();
coords = graphic.getCoordinates();
canvas.drawBitmap(bitmap, coords.getX(), coords.getY(), null);
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
try{
_thread.setRunning(true);
_thread.start();
}catch(Exception ex){
_thread = new TutorialThread(getHolder(), this);
_thread.start();
}
}
public void surfaceDestroyed(SurfaceHolder holder) {
// simply copied from sample application LunarLander:
// we have to tell thread to shut down & wait for it to finish, or else
// it might touch the Surface after we return and explode
boolean retry = true;
_thread.setRunning(false);
while (retry) {
try {
_thread.join();
retry = false;
} catch (InterruptedException e) {
// we will try it again and again...
}
}
}
}
class TutorialThread extends Thread {
private SurfaceHolder _surfaceHolder;
private Panel _panel;
private boolean _run = false;
public TutorialThread(SurfaceHolder surfaceHolder, Panel panel) {
_surfaceHolder = surfaceHolder;
_panel = panel;
}
public void setRunning(boolean run) {
_run = run;
}
public SurfaceHolder getSurfaceHolder() {
return _surfaceHolder;
}
#Override
public void run() {
Canvas c;
while (_run) {
c = null;
try {
c = _surfaceHolder.lockCanvas(null);
synchronized (_surfaceHolder) {
_panel.onDraw(c);
}
} finally {
// do this in a finally so that if an exception is thrown
// during the above, we don't leave the Surface in an
// inconsistent state
if (c != null) {
_surfaceHolder.unlockCanvasAndPost(c);
}
}
}
}
}
class GraphicObject {
/**
* Contains the coordinates of the graphic.
*/
public class Coordinates {
private int _x = 100;
private int _y = 0;
public int getX() {
return _x + _bitmap.getWidth() / 2;
}
public void setX(int value) {
_x = value - _bitmap.getWidth() / 2;
}
public int getY() {
return _y + _bitmap.getHeight() / 2;
}
public void setY(int value) {
_y = value - _bitmap.getHeight() / 2;
}
public String toString() {
return "Coordinates: (" + _x + "/" + _y + ")";
}
}
private Bitmap _bitmap;
private Coordinates _coordinates;
public GraphicObject(Bitmap bitmap) {
_bitmap = bitmap;
_coordinates = new Coordinates();
}
public Bitmap getGraphic() {
return _bitmap;
}
public Coordinates getCoordinates() {
return _coordinates;
}
}
}
onRestoreInstanceState only gets called if the app is destroyed and re-created. Putting the app in the background then bringing it up again will call onResume, but not onRestoreInstanceState.