How to detect rotation around Y axis of phone?
I am novice in android. I would like to detect 180 degrees rotation. I would like to detect for example if user flip phone which lies on a table or if user rotate his phone in his pocket.
I have read a lot of articles but I really don't understand how to get phone position and then compute angle between another position.
I have found for example this article but I don't know what to do with array named orientation:
Get device angle by using getOrientation() function
Thanks!
// Here is my solution. Not perfectly logical but works quite good:
public class FlipListener implements SensorEventListener {
SensorManager sensorMgr;
FlipEventReceiver receiver;
public FlipListener(Context context, FlipEventReceiver receiver) {
this.receiver = receiver;
sensorMgr = (SensorManager) context.getSystemService(Activity.SENSOR_SERVICE);
sensorMgr.registerListener(this, sensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_UI);
}
public void onResume() {
sensorMgr.registerListener(this, sensorMgr.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_DELAY_UI);
}
public void onPause() {
sensorMgr.unregisterListener(this);
clearStack();
}
private static final int IGNORE_FLIPS_AFTER_FLIP = 2500;
private static final int SAMPLING_INTERVAL = 60;
private static final int MINIMAL_STACK_SIZE_TO_FLIP = 2; // Shouldn't be lower than 2
private static final float FLIP_RADIANS = (float)Math.toRadians(140);
private static final int STACK_MAX_SIZE = 38;
private List<Float> stack = new ArrayList<Float>();
private long lastAdd = 0;
private long lastFlip = 0;
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_GYROSCOPE) {
rotationRateAroundYChanged((float)event.values[1]);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
private void rotationRateAroundYChanged(float rotationRateAroundY) {
long currentTime = System.currentTimeMillis();
if (lastFlip != 0 && (currentTime - lastFlip) < IGNORE_FLIPS_AFTER_FLIP) {
return;
}
if( (currentTime - lastAdd) >= SAMPLING_INTERVAL ) {
if( Math.abs(rotationRateAroundY) > 0.3 ) { // Smaller values are unimportant. They can make only mess.
addToStack(rotationRateAroundY);
checkForFlip();
}
}
}
private void checkForFlip() {
int stackSize = stack.size();
if( stackSize < MINIMAL_STACK_SIZE_TO_FLIP ) return;
float approximateAngleSummary = 0;
float val;
for(int i = 0; i < stackSize; i++) {
val = Math.abs(stack.get(i).floatValue());
// "+ Math.pow(val/4.58, 2) )" don't have a sense. Simply it works better with it.
approximateAngleSummary += ( (val + Math.pow(val/4.58, 2) ) / 1000 ) * SAMPLING_INTERVAL;
if( approximateAngleSummary >= FLIP_RADIANS ) {
triggerFlipDetected();
clearStack();
return;
}
}
}
private void clearStack() {
stack.clear();
}
private void addToStack(float val) {
lastAdd = System.currentTimeMillis();
int stackSize = stack.size();
if( stackSize > 0 && ((stack.get(stackSize-1) > 0 ? 1 : -1) != (val>0?1:-1) || stackSize > STACK_MAX_SIZE) ) {
clearStack();
}
stack.add(val);
}
private void triggerFlipDetected() {
lastFlip = System.currentTimeMillis();
receiver.onFlipDetected();
}
public interface FlipEventReceiver {
public void onFlipDetected();
}
}
Usage:
public class FlipTestActivity extends Activity implements FlipEventReceiver {
FlipListener flipListener;
boolean flipListenerActive = true;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_flip_test);
flipListener = new FlipListener(this, this);
}
public void onFlipDetected() {
// What to do when flip detected
}
#Override
protected void onResume() {
super.onResume();
if( !flipListenerActive ) {
flipListener.onResume();
flipListenerActive = true;
}
}
#Override
protected void onPause() {
super.onPause();
if( flipListenerActive ) {
flipListener.onPause();
flipListenerActive = false;
}
}
}
SensorManager is a class that lets you access the device's sensors. Check here
Here is a nice tutorial about sensors
Related
I can see a log in my consolse everytime a beacon is detected
D/BeaconService: beacon detected : id1: xxxxx-xxx-xxxxx-xxx-xxxxx id2: xxx id3: xx
But i could not figure out how to catch this function.
Which interface is needed for get this function.
Thanks
Try this,
// Y positions are relative to height of bg_distance image.
Private static final double RELATIVE_START_POS = 320.0 / 1110.0;
Private static final double RELATIVE_STOP_POS = 885.0 / 1110.0;
Private BeaconManager beaconManager;
Private Beacon beacon;
Private Region region;
Private View distance view, dotView;
Private int startY = -1;
Private int segmentLength = -1;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.distance_view);
dotView = findViewById(R.id.distance_iv_dot);
beacon = getIntent().getParcelableExtra(MainActivity.EXTRAS_BEACON);
region = new Region("regionid", beacon.getProximityUUID(), beacon.getMajor(), beacon.getMinor());
if (beacon == null) {
Toast.makeText(this, "Beacon not found in intent extras", Toast.LENGTH_LONG).show();
finish();
return;
}
beaconManager = new BeaconManager(this);
distanceview = findViewById(R.id.distance_background_view);
distanceview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onGlobalLayout() {
distanceview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
startY = (int) (RELATIVE_START_POS * distanceview.getMeasuredHeight());
int stopY = (int) (RELATIVE_STOP_POS * distanceview.getMeasuredHeight());
segmentLength = stopY - startY;
dotView.setVisibility(View.VISIBLE);
dotView.setTranslationY(computeDotPosY(beacon));
}
});
}
private void updateDistanceView(Beacon foundBeacon) {
if (segmentLength == -1) {
return ;
}
dotView.animate().translationY(computeDotPosY(foundBeacon)).start();
}
private int computeDotPosY(Beacon beacon) {
// Let's put dot at the end of the scale when it's further than 6m.
double distance = Math.min(Utils.computeAccuracy(beacon), 6.0);
return startY + (int) (segmentLength * (distance / 6.0));
}
#Override
protected void onStart() {
super.onStart();
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(Region region, final List<Beacon> rangedBeacons) {
// Note that results are not delivered on UI thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
// Just in case if there are multiple beacons with the same uuid, major, minor.
Beacon foundBeacon = null;
for (Beacon rangedBeacon : rangedBeacons) {
if (rangedBeacon.getMacAddress().equals(beacon.getMacAddress())) {
foundBeacon = rangedBeacon;
}
}
if (foundBeacon != null) {
updateDistanceView(foundBeacon);
}
}
});
}
});
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
#Override
public void onServiceReady() {
beaconManager.startRanging(region);
}
});
}
#Override
protected void onStop() {
beaconManager.stopRanging(region);
beaconManager.disconnect();
super.onStop();
} }
Write
Translate
Define
Synonyms
Favorites
Personal Trainer
Phrase of the Day
Personal Dictionary
Quick Tour
Tutorials
Settings
Send Feedback
GingerFREE
Public class DistanceBeaconActivity extends AppCompatActivity {
Private static final String TAG = DistanceBeaconActivity. class. getSimpleName ();
// Y positions are relative to height of bg_distance image.
Private static final double RELATIVE_START_POS = 320.0 / 1110.0;
Private static final double RELATIVE_STOP_POS = 885.0 / 1110.0;
Private BeaconManager beaconManager;
Private Beacon beacon;
Private Region region;
Private View distance view, dotView;
Private int startY = -1;
Private int segmentLength = -1;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.distance_view);
dotView = findViewById(R.id.distance_iv_dot);
beacon = getIntent().getParcelableExtra(MainActivity.EXTRAS_BEACON);
region = new Region("regionid", beacon.getProximityUUID(), beacon.getMajor(), beacon.getMinor());
if (beacon == null) {
Toast.makeText(this, "Beacon not found in intent extras", Toast.LENGTH_LONG).show();
finish();
return;
}
beaconManager = new BeaconManager(this);
distanceview = findViewById(R.id.distance_background_view);
distanceview.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#TargetApi(Build.VERSION_CODES.JELLY_BEAN)
#Override
public void onGlobalLayout() {
distanceview.getViewTreeObserver().removeOnGlobalLayoutListener(this);
startY = (int) (RELATIVE_START_POS * distanceview.getMeasuredHeight());
int stopY = (int) (RELATIVE_STOP_POS * distanceview.getMeasuredHeight());
segmentLength = stopY - startY;
dotView.setVisibility(View.VISIBLE);
dotView.setTranslationY(computeDotPosY(beacon));
}
});
}
private void updateDistanceView(Beacon foundBeacon) {
if (segmentLength == -1) {
return ;
}
dotView.animate().translationY(computeDotPosY(foundBeacon)).start();
}
private int computeDotPosY(Beacon beacon) {
// Let's put dot at the end of the scale when it's further than 6m.
double distance = Math.min(Utils.computeAccuracy(beacon), 6.0);
return startY + (int) (segmentLength * (distance / 6.0));
}
#Override
protected void onStart() {
super.onStart();
beaconManager.setRangingListener(new BeaconManager.RangingListener() {
#Override
public void onBeaconsDiscovered(Region region, final List<Beacon> rangedBeacons) {
// Note that results are not delivered on UI thread.
runOnUiThread(new Runnable() {
#Override
public void run() {
// Just in case if there are multiple beacons with the same uuid, major, minor.
Beacon foundBeacon = null;
for (Beacon rangedBeacon : rangedBeacons) {
if (rangedBeacon.getMacAddress().equals(beacon.getMacAddress())) {
foundBeacon = rangedBeacon;
}
}
if (foundBeacon != null) {
updateDistanceView(foundBeacon);
}
}
});
}
});
beaconManager.connect(new BeaconManager.ServiceReadyCallback() {
#Override
public void onServiceReady() {
beaconManager.startRanging(region);
}
});
}
#Override
protected void onStop() {
beaconManager.stopRanging(region);
beaconManager.disconnect();
super.onStop();
}
}
I hope it will Help you that to get the function for detecting the Beaconlist.:)
I'm trying to implement a sensor that can detect a hand wave. I found an example that can do hand hover, but not hand wave.
The following code I used is from
How to controlandroid proximity sensor?
public class AndroidProximitySensorActivity extends Activity {
TextView ProximitySensor, ProximityMax, ProximityReading;
SensorManager mySensorManager;
Sensor myProximitySensor;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ProximitySensor = (TextView)findViewById(R.id.proximitySensor);
ProximityMax = (TextView)findViewById(R.id.proximityMax);
ProximityReading = (TextView)findViewById(R.id.proximityReading);
mySensorManager = (SensorManager)getSystemService(
Context.SENSOR_SERVICE);
myProximitySensor = mySensorManager.getDefaultSensor(
Sensor.TYPE_PROXIMITY);
if (myProximitySensor == null){
ProximitySensor.setText("No Proximity Sensor!");
}else{
ProximitySensor.setText(myProximitySensor.getName());
ProximityMax.setText("Maximum Range: "
+ String.valueOf(myProximitySensor.getMaximumRange()));
mySensorManager.registerListener(proximitySensorEventListener,
myProximitySensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
}
SensorEventListener proximitySensorEventListener
= new SensorEventListener(){
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if(event.sensor.getType()==Sensor.TYPE_PROXIMITY){
ProximityReading.setText("Proximity Sensor Reading:"
+ String.valueOf(event.values[0]));
}
}
};
}
In the above code, when the event.values[0] = 0, it means my hand is hover at the sensor. However, I need my sensor to detect a hand wave. How do I do it? Thanks.
Please try this code:
private SensorManager sensorManager;
private Sensor proximitySensor;
private final int WAVE_TIME = 2000;
private final int WAVE_NEEDED_MOVEMENTS = 3;
private long lastWaveTime = 0;
private float lastSensorValue;
private float maxSensorValue;
private float numOfMovements = 0;
public void onCreate() {
super.onCreate();
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
proximitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
sensorManager.registerListener(proximitySensorEventListener, proximitySensor,SensorManager.SENSOR_DELAY_NORMAL);
maxSensorValue = proximitySensor.getMaximumRange();
}
#Override
public void onSensorChanged(SensorEvent event) {
if(lastWaveTime + WAVE_TIME > System.currentTimeMillis()) {
System.out.println("Reset timing...");
lastWaveTime = System.currentTimeMillis();
numOfMovements = 0;
lastSensorValue = event.values[0];
} else if((event.values[0] != maxSensorValue && lastSensorValue == maxSensorValue) || (event.values[0] == maxSensorValue && lastSensorValue != maxSensorValue) ){
numOfMovements++;
if(numOfMovements == WAVE_NEEDED_MOVEMENTS) {
System.out.println("WAVE EVENT");
lastWaveTime = System.currentTimeMillis();
numOfMovements = 0;
}
}
}
I have building an app, my objective is to start the camera activity from service by shaking the phone.
I can launch the toast but not an activity.
Instead of displaying a toast i want to launch the camera activity. Here is my code, how to launch an camera activity by shaking.
Background_service.java
public class Background_service extends Service implements SensorEventListener
{
boolean flag=false;
private long lastUpdate;
SensorManager sensorManager;
int count=0;
final static int cameraData = 0;
private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200;
private Uri fileUri;
ImageView iv;
Intent I;
Bitmap bmp;
#Override
public IBinder onBind(Intent intent)
{
return null;
}
public void onCreate()
{
flag=true;
Log.d(MainShake.TAG, "onCreate");
super.onCreate();
}
public void onDestroy()
{
flag=false;
Log.d(MainShake.TAG, "onDestroy");
super.onDestroy();
}
public void onStart(Intent intent, int startId)
{
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
lastUpdate = System.currentTimeMillis();
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy)
{
}
private void getAccelerometer(SensorEvent event)
{
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER)
{
float[] values = event.values;
// Movement
float x = values[0];
float y = values[1];
float z = values[2];
float accelationSquareRoot = (x * x + y * y + z * z) / (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
long actualTime = System.currentTimeMillis();
if (accelationSquareRoot >= 2)
{
if (actualTime - lastUpdate < 2000)
{
count++;
return;
}
Context context = getApplicationContext();
CharSequence text = "Please fill all the field...!";
int duration = Toast.LENGTH_SHORT;
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
}
public void onSensorChanged(SensorEvent event)
{
getAccelerometer(event);
}
protected void onResume()
{
// register this class as a listener for the orientation and
// accelerometer sensors
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
}
protected void onPause()
{
// unregister listener
sensorManager.unregisterListener(this);
}
}
ShakeEventListner.java
public class ShakeEventListener implements SensorEventListener {
/** Minimum movement force to consider. */
private static final int MIN_FORCE = 10;
/**
* Minimum times in a shake gesture that the direction of movement needs to
* change.
*/
private static final int MIN_DIRECTION_CHANGE = 3;
/** Maximum pause between movements. */
private static final int MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE = 200;
/** Maximum allowed time for shake gesture. */
private static final int MAX_TOTAL_DURATION_OF_SHAKE = 400;
/** Time when the gesture started. */
private long mFirstDirectionChangeTime = 0;
/** Time when the last movement started. */
private long mLastDirectionChangeTime;
/** How many movements are considered so far. */
private int mDirectionChangeCount = 0;
/** The last x position. */
private float lastX = 0;
/** The last y position. */
private float lastY = 0;
/** The last z position. */
private float lastZ = 0;
/** OnShakeListener that is called when shake is detected. */
private OnShakeListener mShakeListener;
/**
* Interface for shake gesture.
*/
public interface OnShakeListener {
/**
* Called when shake gesture is detected.
*/
void onShake();
}
public void setOnShakeListener(OnShakeListener listener) {
mShakeListener = listener;
}
#Override
public void onSensorChanged(SensorEvent se) {
// get sensor data
float x = se.values[SensorManager.DATA_X];
float y = se.values[SensorManager.DATA_Y];
float z = se.values[SensorManager.DATA_Z];
// calculate movement
float totalMovement = Math.abs(x + y + z - lastX - lastY - lastZ);
if (totalMovement > MIN_FORCE) {
// get time
long now = System.currentTimeMillis();
// store first movement time
if (mFirstDirectionChangeTime == 0) {
mFirstDirectionChangeTime = now;
mLastDirectionChangeTime = now;
}
// check if the last movement was not long ago
long lastChangeWasAgo = now - mLastDirectionChangeTime;
if (lastChangeWasAgo < MAX_PAUSE_BETHWEEN_DIRECTION_CHANGE) {
// store movement data
mLastDirectionChangeTime = now;
mDirectionChangeCount++;
// store last sensor data
lastX = x;
lastY = y;
lastZ = z;
// check how many movements are so far
if (mDirectionChangeCount >= MIN_DIRECTION_CHANGE) {
// check total duration
long totalDuration = now - mFirstDirectionChangeTime;
if (totalDuration < MAX_TOTAL_DURATION_OF_SHAKE) {
mShakeListener.onShake();
resetShakeParameters();
}
}
} else {
resetShakeParameters();
}
}
}
/**
* Resets the shake parameters to their default values.
*/
private void resetShakeParameters() {
mFirstDirectionChangeTime = 0;
mDirectionChangeCount = 0;
mLastDirectionChangeTime = 0;
lastX = 0;
lastY = 0;
lastZ = 0;
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
Just replace
Toast toast = Toast.makeText(context, text, duration);
toast.show();
with
Intent myIntent = new Intent(Background_service.this, YOUR_ACTIVITY.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Background_service.this.startActivity(myIntent);
FLAG_ACTIVITY_NEW_TASK is needed when you are starting Activity from a Service
I want to draw math-function like y=x^2+1 with androidPlot library.I have "SimpleXYPlot". It works but I don't know how to change it from sin to my function.
Here's the code:
public class DynamicXYPlotActivity extends Activity {
// redraws a plot whenever an update is received:
private class MyPlotUpdater implements Observer {
Plot plot;
public MyPlotUpdater(Plot plot) {
this.plot = plot;
}
#Override
public void update(Observable o, Object arg) {
plot.redraw();
}
}
private XYPlot dynamicPlot;
private MyPlotUpdater plotUpdater;
SampleDynamicXYDatasource data;
private Thread myThread;
#Override
public void onCreate(Bundle savedInstanceState) {
// android boilerplate stuff
super.onCreate(savedInstanceState);
setContentView(R.layout.dynamicxyplot_example);
// get handles to our View defined in layout.xml:
dynamicPlot = (XYPlot) findViewById(R.id.dynamicXYPlot);
plotUpdater = new MyPlotUpdater(dynamicPlot);
// only display whole numbers in domain labels
dynamicPlot.getGraphWidget().setDomainValueFormat(new DecimalFormat("0"));
// getInstance and position datasets:
data = new SampleDynamicXYDatasource();
SampleDynamicSeries sine1Series = new SampleDynamicSeries(data, 0, "Sine 1");
SampleDynamicSeries sine2Series = new SampleDynamicSeries(data, 1, "Sine 2");
LineAndPointFormatter formatter1 = new LineAndPointFormatter( Color.rgb(0, 0, 0), null, null, null );
formatter1.getLinePaint().setStrokeJoin(Paint.Join.ROUND);
formatter1.getLinePaint().setStrokeWidth(10);
dynamicPlot.addSeries( sine1Series,formatter1 );
LineAndPointFormatter formatter2 = new LineAndPointFormatter(Color.rgb(0, 0, 200), null, null, null);
formatter2.getLinePaint().setStrokeWidth(10);
formatter2.getLinePaint().setStrokeJoin(Paint.Join.ROUND);
//formatter2.getFillPaint().setAlpha(220);
dynamicPlot.addSeries(sine2Series, formatter2);
// hook up the plotUpdater to the data model:
data.addObserver(plotUpdater);
// thin out domain tick labels so they dont overlap each other:
dynamicPlot.setDomainStepMode(XYStepMode.INCREMENT_BY_VAL);
dynamicPlot.setDomainStepValue(5);
dynamicPlot.setRangeStepMode(XYStepMode.INCREMENT_BY_VAL);
dynamicPlot.setRangeStepValue(10);
dynamicPlot.setRangeValueFormat(new DecimalFormat("###.#"));
// uncomment this line to freeze the range boundaries:
dynamicPlot.setRangeBoundaries(-100, 100, BoundaryMode.FIXED);
// create a dash effect for domain and range grid lines:
DashPathEffect dashFx = new DashPathEffect(
new float[] {PixelUtils.dpToPix(3), PixelUtils.dpToPix(3)}, 0);
dynamicPlot.getGraphWidget().getDomainGridLinePaint().setPathEffect(dashFx);
dynamicPlot.getGraphWidget().getRangeGridLinePaint().setPathEffect(dashFx);
}
#Override
public void onResume() {
// kick off the data generating thread:
myThread = new Thread(data);
myThread.start();
super.onResume();
}
#Override
public void onPause() {
data.stopThread();
super.onPause();
}
class SampleDynamicXYDatasource implements Runnable {
// encapsulates management of the observers watching this datasource for update events:
class MyObservable extends Observable {
#Override
public void notifyObservers() {
setChanged();
super.notifyObservers();
}
}
private static final double FREQUENCY = 5; // larger is lower frequency
private static final int MAX_AMP_SEED = 100; //100
private static final int MIN_AMP_SEED = 10; //10
private static final int AMP_STEP = 1;
public static final int SINE1 = 0;
public static final int SINE2 = 1;
private static final int SAMPLE_SIZE = 30;
private int phase = 0;
private int sinAmp = 1;
private MyObservable notifier;
private boolean keepRunning = false;
{
notifier = new MyObservable();
}
public void stopThread() {
keepRunning = false;
}
//#Override
public void run() {
try {
keepRunning = true;
boolean isRising = true;
while (keepRunning) {
Thread.sleep(100); // decrease or remove to speed up the refresh rate.
phase++;
if (sinAmp >= MAX_AMP_SEED) {
isRising = false;
} else if (sinAmp <= MIN_AMP_SEED) {
isRising = true;
}
if (isRising) {
sinAmp += AMP_STEP;
} else {
sinAmp -= AMP_STEP;
}
notifier.notifyObservers();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public int getItemCount(int series) {
return SAMPLE_SIZE;
}
public Number getX(int series, int index) {
if (index >= SAMPLE_SIZE) {
throw new IllegalArgumentException();
}
return index;
}
public Number getY(int series, int index) {
if (index >= SAMPLE_SIZE) {
throw new IllegalArgumentException();
}
double angle = (index + (phase))/FREQUENCY;
double amp = sinAmp * Math.sin(angle);
switch (series) {
case SINE1:
return amp;
case SINE2:
return -amp;
default:
throw new IllegalArgumentException();
}
}
public void addObserver(Observer observer) {
notifier.addObserver(observer);
}
public void removeObserver(Observer observer) {
notifier.deleteObserver(observer);
}
}
class SampleDynamicSeries implements XYSeries {
private SampleDynamicXYDatasource datasource;
private int seriesIndex;
private String title;
public SampleDynamicSeries(SampleDynamicXYDatasource datasource, int seriesIndex, String title) {
this.datasource = datasource;
this.seriesIndex = seriesIndex;
this.title = title;
}
#Override
public String getTitle() {
return title;
}
#Override
public int size() {
return datasource.getItemCount(seriesIndex);
}
#Override
public Number getX(int index) {
return datasource.getX(seriesIndex, index);
}
#Override
public Number getY(int index) {
return datasource.getY(seriesIndex, index);
}
}
}
=======================================================
After what "Nick" said and other minor addition, I got this result:
but as we know :
https://www.google.com/search?q=y%3Dx%5E2%2B1&oq=y%3Dx%5E2%2B1&aqs=chrome..69i57j0l5.7056j0j7&sourceid=chrome&es_sm=93&ie=UTF-8
Now how to make the left side?
Using the code above can modify SampleDynamicXYDatasource to do what you want. All that code does is generate some data in a sine pattern. I don't know how your x values are going to be generated so here's a modified SampleDynamicXYDatasource.getY(...) that just uses the original code where x=index above and uses your function to generate the y-values:
public Number getY(int series, int index) {
if (index >= SAMPLE_SIZE) {
throw new IllegalArgumentException();
}
Number x = getX(series, index);
double y = Math.pow(x.doubleValue(), 2) + 1;
switch (series) {
case SINE1:
return y;
case SINE2:
return -y;
default:
throw new IllegalArgumentException();
}
}
You'll notice that when you make this change, the plot appears to no longer be animated. (it actually still is but that's besides the point) This is because y is now purely a function of x and the x values never change.
As far as how to stop the animation, the plot redraws whenever plot.redraw() is called, which in the example above is in response to an event being continuously fired by events generated by the thread being run on the Runnable instance of SampleDynamicXYDatasource. Using the example above, the simplest way to stop the animation is to replace:
#Override
public void onResume() {
// kick off the data generating thread:
myThread = new Thread(data);
myThread.start();
super.onResume();
}
with:
#Override
public void onResume() {
dynamicPlot.redraw();
super.onResume();
}
Try replace this>>
public Number getX(int series, int index) {
if (index >= SAMPLE_SIZE) {
throw new IllegalArgumentException();
}
return index;
}
To this>>
public Number getX(int series, int index) {
if (index >= SAMPLE_SIZE) {
throw new IllegalArgumentException();
}
return index - 15;
}
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.