I am trying to control a RC car using accelerometer via my own android studio app.
I managed to get the app to work through buttons by calling functions when a button is pressed.
I am trying to do the same with accelerometer by saying id the valus of x is less then this do this and call the function. but I cant connect to bluetooth the second i include my go foward function or andy functions to send the bluetooth command inside the if statement.
If connection is not success "Connection Failed. Is it a SPP Bluetooth? Try again". I keep getting this message
This is the part of the accelerometer code i have if statements.
#Override
public void onSensorChanged(SensorEvent event) {
// clean current values
displayCleanValues();
// display the current x,y,z accelerometer values
displayCurrentValues();
// display the max x,y,z accelerometer values
displayMaxValues();
// get the change of the x,y,z values of the accelerometer
deltaX =(lastX - event.values[0]);
deltaY = (lastY - event.values[1]);
deltaZ = (lastZ - event.values[2]);
// if the change is below 2, it is just plain noise
if (deltaX < 2)
DownArrow.setVisibility(View.VISIBLE);
else
DownArrow.setVisibility(View.INVISIBLE);
if ((deltaZ > vibrateThreshold) || (deltaY > vibrateThreshold) || (deltaZ > vibrateThreshold)) {
v.vibrate(50);
}
if (deltaX > -4) {
UpArrow.setVisibility(View.VISIBLE);
goForward();
}
if (deltaX < -4)
UpArrow.setVisibility(View.INVISIBLE);
if (deltaX < -7)
DownArrow.setVisibility(View.VISIBLE);
goBackward();
if (deltaX > -7)
DownArrow.setVisibility(View.INVISIBLE);
}
This is the functions I call which sends the bluetooth command.
private void goForward()
{
if (btSocket!=null)
{
try
{
btSocket.getOutputStream().write("F".toString().getBytes());
}
catch (IOException e)
{
msg("Error");
}
}
}
private void goBackward()
{
if (btSocket!=null)
{
try
{
btSocket.getOutputStream().write("B".toString().getBytes());
}
catch (IOException e)
{
msg("Error");
}
}
}
This is the Bluetooth code
#Override
protected void onPostExecute(Void result) //after the doInBackground, it checks if everything went fine
{
super.onPostExecute(result);
if (!ConnectSuccess)
{
msg("Connection Failed. Is it a SPP Bluetooth? Try again.");
finish();
}
else
{
msg("Connected.");
isBtConnected = true;
}
progress.dismiss();
}
I am doing the same in my button view and it works fine.
btnUp.setOnTouchListener(new View.OnTouchListener() {
#Override
public boolean onTouch(View v, MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
btnUp.setBackgroundResource(R.drawable.button_arrow_green_up_select);
goForward();
return true;
}
if (event.getAction() == MotionEvent.ACTION_UP) {
btnUp.setBackgroundResource(R.drawable.button_arrow_green_up);
Stop();
}
return false;
}
});
Why it keeps failing?
I did a project for fun, Turn on led when any one shake the android mobile. I used arduino and HC-05 in order to communicate android with LED. I think the problem is you are sending "F" and "8" values through bluetooth in UI thread. so create other thread for sending values through bluetooth.
I am sharing part of my code, I think this would be use full.
mmOutputstream=socket.getOutputStream();
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER){
mGravity = event.values.clone();
// Shake detection
float x = mGravity[0];
float y = mGravity[1];
float z = mGravity[2];
int check=0;
mAccelLast = mAccelCurrent;
mAccelCurrent = FloatMath.sqrt(x*x + y*y + z*z);
float delta = mAccelCurrent - mAccelLast;
mAccel = mAccel * 0.9f + delta;
Log.d("TAG",data);
// Make this higher or lower according to how much
// motion you want to detect
if(connection){
if(mAccel<-2.0f)
{
check=10;
}
if(mAccel>-2.4f){
check=0;
}
new arduinosend().execute(check);
}
}
}
class arduinosend extends AsyncTask<Integer, Integer, String>
{
#Override
protected String doInBackground(Integer... params) {
// TODO Auto-generated method stub
try {
mmOutputstream.write(params[0]);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
Related
I want to create a service which will run in background and create touch event on screen in android, as magnetic field change for my virtual reality glasses.
this my code
public void onSensorChanged(SensorEvent sensorEvent) {
synchronized (this) {
if (sensorEvent.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
magneticX.setText( Float.toString( sensorEvent.values[0]));
magneticY.setText( Float.toString( sensorEvent.values[1]));
magneticZ.setText( Float.toString( sensorEvent.values[2]));
if(sensorEvent.values[0]>100){
// Long time = System.currentTimeMillis();
// View v = getWindow().getDecorView().getRootView();
// MotionEvent event = MotionEvent.obtain(time,time,0,100f ,100f, 0);
// v.dispatchTouchEvent(event);
Process process = null;
try {
process = Runtime.getRuntime().exec("adb shell input tap 100 100 ");
((TextView)findViewById(R.id.valMag_Msg)).setText("Magnet on Left lower corner");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
}else{
((TextView)findViewById(R.id.valMag_Msg)).setText("Normal");;
}
}
}
}
I need to get head movements and according to that head turns (rotations). I need to do some work there. This is in case of inserting device in google cardboard.
I have searched the internet but I found no proper information. Please help me out here.
Thanks in advance.
Use Sensor class for this as shown below..
SensorEventListener mSensorListener = new SensorEventListener() {
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
#Override
public void onSensorChanged(SensorEvent event) {
Sensor sensor = event.sensor;
if (sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
if (event.values != null && event.values.length > 1) {
accelDataOld = rawAccelData;
rawAccelData = event.values[1];
tweenStep = (rawAccelData - accelData) / TWEEN_TIMING;
}
} else if (sensor.getType() == Sensor.TYPE_GYROSCOPE) {
if (event.values != null && event.values.length > 1) {
rawGyroData += event.values[0];
}
}
}
};
I am trying to get the azimuth of the users phone when they take a picture. However, when I put the azimuth to the screen just for debugging purposes currently, it always comes back at 0.0. I am new to using Sensors so I am trying to figure this out. My code is
private void dispatchTakePictureIntent() {
double latitude, longitude;
if (mGpsLocationTracker.canGetLocation()) {
latitude = mGpsLocationTracker.getLatitude();
longitude = mGpsLocationTracker.getLongitude();
} else {
latitude = 0;
longitude = 0;
}
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
Toast.makeText(this, "" + latitude + ", " + longitude, Toast.LENGTH_SHORT).show();
getDirection ();
Toast.makeText(this, Float.toString(degree), Toast.LENGTH_SHORT).show();
}
public void getDirection() {
SensorManager mySensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
List<Sensor> mySensors = mySensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
if(mySensors.size() > 0){
mySensorManager.registerListener(mySensorEventListener, mySensors.get(0), SensorManager.SENSOR_DELAY_UI);
}
}
/*
DOES NOT WORK. NEED TO FIX
*/
private SensorEventListener mySensorEventListener = 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
float radianValue = Math.round(event.values[0]);
degree = (float) Math.toDegrees(radianValue);
if (degree < 0.0f) {
degree += 360.0f;
}
}
};
public void takePicture (View view) {
dispatchTakePictureIntent();
}
Can anyone help me with what I'm doing wrong
Doesn't the orientation sensor return the angle in degrees? You're assuming radians and converting to degrees. Given that though, it still should't give you 0.
TYPE_ORIENTATION is depreciated and does not give the correct result
if the device is not flat. You need to use TYPE_ACCELEROMETER and TYPE_MAGNETIC_FIELD to obtain the rotation matrix and then call remapCoordinateSystem before calling getOrientation.
I am trying to implement the volume slider while casting and show the cast icon in the slider like in the Youtube app : http://imgur.com/kVxoKbM.
As of now I have overridden the dispatchKeyEvent function my activity, as explained in the cast developers documentation (shown in the code snipped below), which allows me to control the volume of the connected Chromecast perfectly. But on the device, it doesn't even show a slider at all.
#Override
public boolean dispatchKeyEvent(KeyEvent event) {
int action = event.getAction();
int keyCode = event.getKeyCode();
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
if (action == KeyEvent.ACTION_DOWN) {
if (mApiClient != null) {
double currentVolume = Cast.CastApi.getVolume(mApiClient);
if (currentVolume < 1.0) {
try {
Cast.CastApi.setVolume(mApiClient,
Math.min(currentVolume + VOLUME_INCREMENT, 1.0));
} catch (Exception e) {
Log.e(TAG, "unable to set volume", e);
}
}
} else {
Log.e(TAG, "dispatchKeyEvent - volume up");
}
}
return true;
case KeyEvent.KEYCODE_VOLUME_DOWN:
if (action == KeyEvent.ACTION_DOWN) {
if (mApiClient != null) {
double currentVolume = Cast.CastApi.getVolume(mApiClient);
if (currentVolume > 0.0) {
try {
Cast.CastApi.setVolume(mApiClient,
Math.max(currentVolume - VOLUME_INCREMENT, 0.0));
} catch (Exception e) {
Log.e(TAG, "unable to set volume", e);
}
}
} else {
Log.e(TAG, "dispatchKeyEvent - volume down");
}
}
return true;
default:
return super.dispatchKeyEvent(event);
}
}
I am not using the remoteMediaPlayer. So how can I implement a volume slider while controlling the connected Chromecast volume?
I'm trying to create an app that scans for wifi. When the player does something in the game, it "consumes" the strongest wifi signal. That signal should no longer be detected on the next scan.
Anyone who's played Metal Gear Solid Portable ops would know what I mean.
I tried to do this by creating a List of Wireless Signals that have already been used by the player and can no longer be detected again. The problem is that after scanning the best network, I scan again and it still displays the same network instead of ignoring it.
public void onClick(View arg0) {
if (arg0.getId() == R.id.bStart) {
ActivityLoader.loadMain(this);
}
if (arg0.getId() == R.id.bScan) {
Toast.makeText(this, "Searching....", Toast.LENGTH_LONG).show();
for (ScanResult selectedSpot : networkList) {
{
if (firstSignal == null || checkIfNotUsed(firstSignal)) {
firstSignal = selectedSpot;
usedNetworks.add(firstSignal.SSID);
break;
}
}
}
}
if (firstSignal != null) {
Toast.makeText(
this,
"Found Food and Ammo at the " + firstSignal.SSID
+ " store.", Toast.LENGTH_LONG).show();
// textStatus.setText(usedNetworks.toString());
textStatus.setText(networkList.toString());
} else {
Toast.makeText(this, "Found nothing!!!", Toast.LENGTH_LONG).show();
}
}
private boolean checkIfNotUsed(ScanResult selectedSpot) {
// TODO Auto-generated method stub
boolean flag = true;
if (usedNetworks.isEmpty()) {
flag = true;
} else {
for (String used : usedNetworks) {
if (selectedSpot.SSID.equals(used)) {
flag = false;
break;
}
}
}
return flag;
}