I'm having trouble recording the Z-axis data from the accelerometer in an array.
I think I'm probably failing on some basic java rules, but here's what I'm trying to do:
private ArrayList<Float[]> z = new ArrayList<Float[]>();
protected void onCreate(Bundle savedInstanceState) {
SensorManager manager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor accelerometer = manager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
z.add(event.values[2]);
}
But whenever I try to add to the arraylist I get:
"The method add(Float[]) in the type ArrayList is not applicable for the arguments (float)"
How can I add the z axis data to an array?
Its because your ArrayList of Float[] type.
Replace the following,
private ArrayList<Float[]> z = new ArrayList<Float[]>();
with
ArrayList<Float> z = new ArrayList<Float>();
Related
I have the following code to get the x and y angle of my device and it is working fine on my phone, but not my tablet (Samsung galaxy tab e). I was wondering if anyone had any idea as to what could be causing it to work on one device but not another.
I did also ensure that screen rotation was enabled on both. My assumption is that the tablet is lacking a sensor, and what I'm looking for most is a workaround. Any help would be much appreciated. Thanks in advance!
Source code:
double yAngle;
double xAngle;
#Override
protected void onResume() {
super.onResume();
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR),RATE);
}
#Override
public void onSensorChanged(SensorEvent event) {
float[] rotationMatrix;
rotationMatrix = new float[16];
SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values);
determineOrientation(rotationMatrix);
lblY.setText(String.format("%.1f", yAngle));
lblX.setText(String.format("%.1f", xAngle));
}
private void determineOrientation(float[] rotationMatrix){
//CREATING FLOAT ARRAY OF ORIENTATION VALUES
float [] orientationValues = new float[3];
SensorManager.getOrientation(rotationMatrix, orientationValues);
yAngle = Math.toDegrees(orientationValues[2]);
xAngle = Math.toDegrees(orientationValues[1]);
}
You can use adb shell pm list features to check all sensors and other features supported.
I´m not very good at programming, but I need to build an App where you can type in Datapoints and after clicking a button the datapoint should be added to a graph.
I started with a bar graph and it works, but for some reason the labels are in doubles, even if I type in 1 the bar is between 0.8 an 1.2 on the xaxis and the first 3 datapoints I type in doesn't show up.
Please excuse my bad english (and my bad programming).
public class BalkenActivity extends AppCompatActivity implements View.OnClickListener{
GraphView bargraph;
BarGraphSeries<DataPoint> series;
double xval = 1;
double yval;
TextView texty;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_balken);
Button button1 = findViewById(R.id.addbtn);
button1.setOnClickListener(this);
texty = findViewById(R.id.yvalue);
bargraph = findViewById(R.id.bargraph);
series = new BarGraphSeries<>(getDataPoint());
}
private DataPoint[] getDataPoint() {
DataPoint[] dp = new DataPoint[]
{
new DataPoint(0,0),
};
return dp;
}
public void onClick (View v) {
yval = new Double(texty.getText().toString()).doubleValue();
series.appendData(new DataPoint(xval++,yval),true,100);
bargraph.addSeries(series);
bargraph.getViewport().setScalable(true);
bargraph.getViewport().setMinX(0);
series.setSpacing(50);
series.setDrawValuesOnTop(true);
series.setValuesOnTopColor(Color.BLACK);
}
}
Without either a DefaultLabelFormatter or a GridLabelFormatter, GraphView will automatically format the graphs labels so that is why you are seeing double values.
I am working on a project in which the content on the screen changes with the direction of mobile's axis. For this, I created a class which calculates azimuthal angle by accessing sensor data. This class also has a method setLine which gives back a,b,c in line equation a.x + b.y + c = 0 when supplied gps co-ordinates. This line is the z-axis of mobile.
So I created an object of this class from another class. But whenever I am accessing setLine, By seeing the log I got to know that azimuthal = NULL and oldAzimuthal = Math.PI/180 which is what I set.
I don't understand this. When I created the ViewAngleActivity object, this should have already initialized sensors and I shouldn't be getting NULL for azimuthal .
Earlier when I used ThisViewAngleActivity as the main class I didn't face such issue. I was properly getting azimthal.
Am I missing some concepts? Please help.
I am uploading the code for ViewAngleActivity
public class ViewAngleActivity extends Activity implements SensorEventListener {
Float azimuth;
Float pitch;
Float roll;
float oldAzimuth;
private SensorManager mSensorManager;
Sensor accelerometer;
Sensor magnetometer;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Log.d("gettingViewAngle:","in onCreateSensor got Created");
}
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(this, magnetometer, SensorManager.SENSOR_DELAY_UI);
}
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
public void onAccuracyChanged(Sensor sensor, int accuracy) { }
float[] mGravity;
float[] mGeomagnetic;
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
mGravity = event.values;
if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD)
mGeomagnetic = event.values;
if (mGravity != null && mGeomagnetic != null) {
float R[] = new float[9];
float I[] = new float[9];
if (SensorManager.getRotationMatrix(R, I, mGravity, mGeomagnetic)) {
// orientation contains azimut, pitch and roll
float orientation[] = new float[3];
SensorManager.getOrientation(R, orientation);
oldAzimuth = azimuth;
azimuth = orientation[0];
pitch = orientation[1];
roll = orientation[2];
// at this point, orientation contains the azimuth(direction), pitch and roll values.
Log.d("onSensorChanged:", "azimuth = "+ azimuth);
Log.d("onSensorChanged:", "oldAzimuth = "+ oldAzimuth);
}
}
}
/**
* This method calculates line equation of mobile axis
* #param currentLatitude
* #param currentLongitude
* #return co-efficients of the line a.x + b.y + c = 0
*/
public double[] setLine(Double currentLatitude, Double currentLongitude){
double angle = 1;
double a,b,c;
double[] coEfficients = {1, 1, 0};
Log.d("setLine:", "azimuth = "+ azimuth);
Log.d("setLine:", "oldAzimuth = "+ oldAzimuth);
if(azimuth!= null) {
angle = (float) azimuth;
if (angle == 0){
angle = Math.PI/180;
}
if ( angle%((Math.PI)/2) ==0){
a = 0;
b = 1;
c = ( - currentLongitude);
}
else {
a = -(Math.tan((double) angle));
b = 1;
c = (Math.tan((double) angle) * currentLatitude) - currentLongitude;
}
Log.d("setLine:Using azimuth", "azimuth = "+ angle);
coEfficients[0] = a ;
coEfficients[1] = b ;
coEfficients[2] = c ;
}
else{
angle = (float) oldAzimuth;
if (angle == 0){
angle = Math.PI/180;
}
if ( angle%((Math.PI)/2) ==0){
a = 0;
b = 1;
c = ( - currentLongitude);
}
else {
a = -(Math.tan((double) angle));
b = 1;
c = (Math.tan((double) angle) * currentLatitude) - currentLongitude;
}
Log.d("setLine:UsingOldAzimuth", "oldAzimuth = "+ angle);
coEfficients[0] = a ;
coEfficients[1] = b ;
coEfficients[2] = c ;
}
return coEfficients;
}
}
The object I created from other class is as follows
private ViewAngleActivity viewAngleActivity;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
viewAngleActivity = new ViewAngleActivity();
//other parts of the code//
}
#Override
public void method1{
method2;
}
public void method1{
double[] coEfficients = viewAngleActivity.setLine(currentLatitude,currentLongitude);
}
You're only creating an instance of ViewAngleActivity, it's never really added to the window.
Your onCreate() and onResume() methods never get called, they are only called when your Activity is added to the window and goes through the Activity Lifecycle
Since you're instantiating your mSensorManager instance inside onCreate(), it never gets created and is still null.
Since onResume() isn't called (see second point up there), then your viewAngleActivity instance (which is also your SensorEventListener interface) never gets registered to mSensorManager, and as such the method onSensorChanged(SensorEvent evt) inside your ViewAngleActivity instance never gets called. Since that's where you're setting azimuth it's still going to be NULL cause that method is never called.
You might want to try a different approach, probably move all the code in your ViewAngleActivity's onCreateView() methods to a constructor like so:
//note the context parameter, pass this one when you create your ViewAngleActivity instance
public ViewAngleActivity(Context context){
mSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
accelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
magnetometer = mSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
Log.d("gettingViewAngle:","in onCreateSensor got Created");
//then you use your context to reg.
mSensorManager.registerListener(context, accelerometer, SensorManager.SENSOR_DELAY_UI);
mSensorManager.registerListener(context, magnetometer, SensorManager.SENSOR_DELAY_UI);
}
Please read more about Android's Activity Lifecycle and how they are added on screen. Note that with the above approach, you'd have to handle unregistering your SensorEventListener, cause obviously onPause() would never be called in ViewAngleActivity.
//this is how you'd probably go about it:
viewAngleActivty.mSensorManager.unregisterListener(viewAngleActivity);
Or instead, implement what you're trying to do in the new Activity you're using as your MainActivity, that would be even easier.
I am not expert in programming. I have implemented acceleration sensor in Android program.
I have used textview to display acceleration data for x, y & z axis.
Now using this sensor data I want to plot a real time graph. So is it good idea to put the textview in an array list & than plot graph?? Or some one has a better solution.
How to add textview's data into arraylist?
How to plot graph of this real time sensor data??
This is my program.
public class HelloAndroid extends Activity implements SensorEventListener {
private SensorManager sensorManager;
TextView xCoor; // declare X axis object
TextView yCoor; // declare Y axis object
TextView zCoor; // declare Z axis object
#Override
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
xCoor=(TextView)findViewById(R.id.xcoor); // create X axis object
yCoor=(TextView)findViewById(R.id.ycoor); // create Y axis object
zCoor=(TextView)findViewById(R.id.zcoor); // create Z axis object
sensorManager=(SensorManager)getSystemService(SENSOR_SERVICE);
// add listener. The listener will be HelloAndroid (this) class
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
public void onAccuracyChanged(Sensor sensor,int accuracy){
}
public void onSensorChanged(SensorEvent event){
if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){
// assign directions
float x=event.values[0];
float y=event.values[1];
float z=event.values[2];
xCoor.setText("X: "+x);
yCoor.setText("Y: "+y);
zCoor.setText("Z: "+z);
}
}
}
You can watch for Changes in your TextView and run your code eg. :
editText.addTextChangedListener(new TextWatcher() {
public void afterTextChanged(Editable s) {
}
public void beforeTextChanged(CharSequence s, int start, int count,
int after) {
}
public void onTextChanged(CharSequence s, int start, int before, int count) {
String[] array = new String[] {TextView.getText().toString() , TextView1.getText().toString()
//Correct me if iam Wrong ... }
}
});
If you just want to put TextView into arrayList
List<TextView> textViews= new ArrayList<TextView>();
textViews.add(TextView1);
textViews.add(TextView2);
textViews.add(TextView3);
I have read through a lot of code but I do not understand how you can make an image move using the accelerometer sensor, I understand how to register it but I do not understand how to actually make an image or a shape draw move in sync with the accelerometer axis, I am using android java to do this. Please can someone help me as I am really struggling. Thank you for your time and help.
So, here's the code to register a listener (I know you said you've done this already, but it can never hurt):
private void enableAccelerometerListening() {
sensorManager = (SensorManager) getSystemService(COntext.SENSOR_SERVICE);
sensorManager.registerListener(sensorEventListener), sensorManager.getDefaultSensor(
Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
}
private void disableAccelerometerListening() {
if (sensorManager != null) {
sesnsorManager.unregisterListener(sensorEVentListener, sensorManager.getDefaultSensor(SensorManager.SENSOR_ACCELEROMETER));
sensorManager = null;
}}
You will need a couple fields just below your class declaration:
private SesnsorManager sensorManager;
private float acceleration;
private float currentAcceleration;
private float lastAcceleration;
private static final int ACCELERATION_THRESHOLD = 15000;
Here is the event handler, which gets very close to what you need help with:
private SensorEventListener sensorEventListener = new SensorEventListener() {
public void onSesnsorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
lastAcceleration = currentAcceleration; //save previous accel value
currentAcceleration = x*x + y*y + z*z;
acceleration = currentAcceleration * (currentAcceleration - lastAcceleration); // calc the change in acceleration
//if the accel is above a certain threshold:
if (acceleration > ACCELERATION_THRESHOLD) {
//MAKE YOUR CODE HERE THAT RESPONDS TO ACCELERATION EVENTS
//Note, your accel threshold should be determined by trial and error on a number of devices
}
}
public void onAccuracyChanged(Sensor sensor, int accuracy {}
};
Also, I'll try to address some of your animation needs, though I am much more spotty in this area. I imagine that what you need to do is make your image move as the accelerometer detects moves. The image will have to be moved via an animation, rather than the accelerometer directly. So say 'spot' is your image, okay? (the code below both adds a spot and sets up its animations(which are not directly tied to the accelerometer, but I hope this will be helpful nonetheless):
public void addSpot() {
int x = random.nextInt(viewWidth - SPOT_DIAMETER);
int y = random.nextInt(viewHeight = SPOT_DIAMETER);
int x2 = random.nextInt(viewWidth - SPOT_DIAMETER);
int y2 = random.nextInt(viewWidth - SPOT_DIAMETER);
final ImageView spot = (ImageView) layoutFinlater.inflate(R.layout.untouched, null);
spot.setLayoutParams(new RelativeLayout.LayoutParams(SPOT_DIAMETER, SPOT_DIAMETER));
spot.setX(x);
spot.setY(y);
Well right here is where I think you could start doing something with the accelerometer events...
As you saw in my other response above,
if (acceleration > ACCELERATION_THRESHOLD) {
spot.animate().x(x2).y(y2).setDuration(animationTime);
animationTime will just be something in milliseconds that you feel is appropriate, and don't forget to take care of importing the necessary packages.