├── AndroidManifest.xml ├── README.md ├── java └── com │ └── example │ └── vishu │ └── sampleapp │ ├── ContactActivity.java │ ├── ContactContract.java │ ├── DBHelper.java │ ├── IService2.java │ └── MainActivity.java └── res ├── drawable └── images.jpg ├── layout ├── activity_contact.xml ├── activity_main.xml └── simplerow.xml ├── menu └── menu.xml ├── mipmap-hdpi └── ic_launcher.png ├── mipmap-mdpi └── ic_launcher.png ├── mipmap-xhdpi └── ic_launcher.png ├── mipmap-xxhdpi └── ic_launcher.png ├── mipmap-xxxhdpi └── ic_launcher.png ├── values-w820dp └── dimens.xml └── values ├── colors.xml ├── dimens.xml ├── strings.xml └── styles.xml /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 28 | 31 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Fall_Detection 2 | An Android App, which detects User fall using Accelerometer, Gyroscope and Magnetometer and send SMS to the Mobile Numbers Stored in the SQLite Database. A service runs in background, continuously monitoring the user, when started tracking. 3 | 4 | Algorithm: 5 | The three-axis Acceleration from Accelerometer will be accumulated as Single Magnitude Vector(SMV) and a threshold value was fixed. Based onthis, if the user falls, the SMV will cross the threshold vector and we can detect fall. 6 | In addition to that, we are calculating the Degree of phone at that time, if the Degree is greater than 35 degrees, it's considered a danger to user.(Because assuming this phone is on Helmet and normal inclination of user head being zero, if the head inclination crosses some degree mark (here 35) along with a threshold breach by SMV, concludes that there was a Fall. 7 | 8 | After fall, a toast message displayed and SMS sent to the contacts in SQLite DB. 9 | 10 | -------------------------------------------------------------------------------- /java/com/example/vishu/sampleapp/ContactActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.vishu.sampleapp; 2 | 3 | import android.os.Bundle; 4 | import android.preference.Preference; 5 | import android.preference.PreferenceActivity; 6 | import android.widget.ListView; 7 | import android.widget.Toast; 8 | 9 | public class ContactActivity extends PreferenceActivity implements Preference.OnPreferenceChangeListener{ 10 | 11 | ListView listView; 12 | @Override 13 | protected void onCreate(Bundle savedInstanceState) { 14 | super.onCreate(savedInstanceState); 15 | //setContentView(R.layout.activity_contact); 16 | Toast.makeText(this,"Here im in contact activity",Toast.LENGTH_SHORT).show(); 17 | 18 | } 19 | 20 | @Override 21 | public boolean onPreferenceChange(Preference preference, Object o) { 22 | return false; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /java/com/example/vishu/sampleapp/ContactContract.java: -------------------------------------------------------------------------------- 1 | package com.example.vishu.sampleapp; 2 | 3 | import android.provider.BaseColumns; 4 | 5 | /** 6 | * Created by Dell PC on 31-01-2017. 7 | */ 8 | 9 | public class ContactContract { 10 | public static final String TABLE_NAME = "ContactList"; 11 | public static final String COLUMN_CONTACT = "contact"; 12 | public static final String _ID = "id"; 13 | public static final class ContactContractList implements BaseColumns{ 14 | 15 | 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /java/com/example/vishu/sampleapp/DBHelper.java: -------------------------------------------------------------------------------- 1 | package com.example.vishu.sampleapp; 2 | import android.content.Context; 3 | import android.database.sqlite.SQLiteDatabase; 4 | import android.database.sqlite.SQLiteOpenHelper; 5 | 6 | /** 7 | * Created by Dell PC on 31-01-2017. 8 | */ 9 | 10 | public class DBHelper extends SQLiteOpenHelper { 11 | 12 | private static final String DATABASE_NAME = "contactList.db"; 13 | private static final int DATABASE_VERSION = 1; 14 | 15 | public DBHelper(Context context){ 16 | super(context, DATABASE_NAME, null, DATABASE_VERSION); 17 | } 18 | @Override 19 | public void onCreate(SQLiteDatabase sqLiteDatabase) { 20 | final String SQL_CREATE_TABLE = "CREATE TABLE " + 21 | ContactContract.TABLE_NAME + "("+ 22 | ContactContract._ID + " INTEGER PRIMARY KEY AUTOINCREMENT" +","+ 23 | ContactContract.COLUMN_CONTACT + " TEXT NOT NULL" + ");"; 24 | sqLiteDatabase.execSQL(SQL_CREATE_TABLE); 25 | } 26 | 27 | @Override 28 | public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) { 29 | onCreate(sqLiteDatabase); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /java/com/example/vishu/sampleapp/IService2.java: -------------------------------------------------------------------------------- 1 | package com.example.vishu.sampleapp; 2 | 3 | import android.Manifest; 4 | import android.app.Activity; 5 | import android.app.Service; 6 | import android.content.Context; 7 | import android.content.Intent; 8 | import android.content.pm.PackageManager; 9 | import android.database.Cursor; 10 | import android.database.sqlite.SQLiteDatabase; 11 | import android.database.sqlite.SQLiteOpenHelper; 12 | import android.hardware.Sensor; 13 | import android.hardware.SensorEvent; 14 | import android.hardware.SensorEventListener; 15 | import android.hardware.SensorManager; 16 | import android.location.Location; 17 | import android.location.LocationListener; 18 | import android.location.LocationManager; 19 | import android.os.Bundle; 20 | import android.os.Handler; 21 | import android.os.IBinder; 22 | import android.os.Looper; 23 | import android.support.annotation.Nullable; 24 | import android.support.v4.app.ActivityCompat; 25 | import android.support.v4.content.ContextCompat; 26 | import android.telephony.SmsManager; 27 | import android.util.Log; 28 | import android.widget.ArrayAdapter; 29 | import android.widget.Toast; 30 | 31 | import com.google.android.gms.appindexing.AppIndex; 32 | import com.google.android.gms.common.api.GoogleApiClient; 33 | 34 | import java.util.ArrayList; 35 | import java.util.Iterator; 36 | import java.util.List; 37 | import java.util.Timer; 38 | import java.util.TimerTask; 39 | 40 | public class IService2 extends Service implements SensorEventListener { 41 | 42 | private SQLiteDatabase sql; 43 | String[] projection = { 44 | ContactContract.COLUMN_CONTACT 45 | }; 46 | 47 | Handler handler = new Handler(Looper.getMainLooper()); 48 | private Handler mPeriodicEventHandler = new Handler(); 49 | private final int PERIODIC_EVENT_TIMEOUT = 3000; 50 | 51 | private Timer fuseTimer = new Timer(); 52 | private int sendCount = 0; 53 | private char sentRecently = 'N'; 54 | //Three Sensor Fusion - Variables: 55 | // angular speeds from gyro 56 | private float[] gyro = new float[3]; 57 | private float degreeFloat; 58 | private float degreeFloat2; 59 | // rotation matrix from gyro data 60 | private float[] gyroMatrix = new float[9]; 61 | 62 | // orientation angles from gyro matrix 63 | private float[] gyroOrientation = new float[3]; 64 | 65 | // magnetic field vector 66 | private float[] magnet = new float[3]; 67 | 68 | // accelerometer vector 69 | private float[] accel = new float[3]; 70 | 71 | // orientation angles from accel and magnet 72 | private float[] accMagOrientation = new float[3]; 73 | 74 | // final orientation angles from sensor fusion 75 | private float[] fusedOrientation = new float[3]; 76 | 77 | // accelerometer and magnetometer based rotation matrix 78 | private float[] rotationMatrix = new float[9]; 79 | 80 | public static final float EPSILON = 0.000000001f; 81 | 82 | public static final int TIME_CONSTANT = 30; 83 | public static final float FILTER_COEFFICIENT = 0.98f; 84 | 85 | private static final float NS2S = 1.0f / 1000000000.0f; 86 | private float timestamp; 87 | private boolean initState = true; 88 | 89 | //Sensor Variables: 90 | private SensorManager senSensorManager; 91 | private Sensor senAccelerometer; 92 | private Sensor senProximity; 93 | private SensorEvent mSensorEvent; 94 | 95 | //GPS 96 | double latitude, longitude; 97 | LocationManager locationManager; 98 | LocationListener locationListener; 99 | 100 | //SMS Variables 101 | SmsManager smsManager = SmsManager.getDefault(); 102 | String phoneNum = "8503391620"; 103 | String textMsg; 104 | private String prevNumber; 105 | private Float x, y, z; 106 | private static final int MY_PERMISSIONS_REQUEST_SEND_SMS = 0; 107 | 108 | private Runnable doPeriodicTask = new Runnable() { 109 | public void run() { 110 | Log.d("Delay", "Delay Ended**********"); 111 | Log.d("Updating flag", "run: "); 112 | sentRecently = 'N'; 113 | // mPeriodicEventHandler.postDelayed(doPeriodicTask, PERIODIC_EVENT_TIMEOUT); 114 | } 115 | }; 116 | 117 | 118 | @Nullable 119 | @Override 120 | public IBinder onBind(Intent intent) { 121 | return null; 122 | } 123 | 124 | @Override 125 | public void onCreate() { 126 | 127 | Log.d("Initialing Service", "OnCreate"); 128 | super.onCreate(); 129 | } 130 | 131 | @Override 132 | public void onDestroy() { 133 | super.onDestroy(); 134 | mPeriodicEventHandler.removeCallbacks(doPeriodicTask); 135 | Log.d("Stopping Service", "OnDestroy"); 136 | senSensorManager.unregisterListener(this); 137 | sendCount = 0; 138 | Toast.makeText(this, "Stopped Tracking", Toast.LENGTH_SHORT).show(); 139 | if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 140 | 141 | }else { 142 | locationManager.removeUpdates(locationListener); 143 | } 144 | } 145 | 146 | @Override 147 | public int onStartCommand(Intent intent, int flag, int startId) { 148 | Log.d("Starting work", "OnStart"); 149 | 150 | DBHelper dpHelper = new DBHelper(this); 151 | sql = dpHelper.getReadableDatabase(); 152 | 153 | // Acquire a reference to the system Location Manager 154 | locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); 155 | 156 | // Define a listener that responds to location updates 157 | locationListener = new LocationListener() { 158 | @Override 159 | public void onLocationChanged(Location location) { 160 | latitude = location.getLatitude(); 161 | longitude = location.getLongitude(); 162 | Log.d("latitude changed", "" + latitude); 163 | Log.d("longitude changed", "" + longitude); 164 | } 165 | 166 | @Override 167 | public void onStatusChanged(String provider, int status, Bundle extras) { 168 | 169 | } 170 | 171 | @Override 172 | public void onProviderEnabled(String provider) { 173 | } 174 | 175 | @Override 176 | public void onProviderDisabled(String provider) { 177 | 178 | } 179 | }; 180 | 181 | // Register the listener with the Location Manager to receive location updates 182 | if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 183 | handler.post(new Runnable() { 184 | 185 | @Override 186 | public void run() { 187 | Toast.makeText(IService2.this.getApplicationContext(), "No GPS Permission!!", Toast.LENGTH_SHORT).show(); 188 | } 189 | }); 190 | } 191 | locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 5000, 0, locationListener); 192 | 193 | String locationProvider = LocationManager.NETWORK_PROVIDER; 194 | if (ActivityCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 195 | handler.post(new Runnable() { 196 | 197 | @Override 198 | public void run() { 199 | Toast.makeText(IService2.this.getApplicationContext(), "No GPS Permission", Toast.LENGTH_SHORT).show(); 200 | } 201 | }); 202 | } 203 | latitude = locationManager.getLastKnownLocation(locationProvider).getLatitude(); 204 | longitude = locationManager.getLastKnownLocation(locationProvider).getLongitude(); 205 | Log.d("latitude", ""+latitude); 206 | Log.d("longitude", ""+longitude); 207 | 208 | onTaskRemoved(intent); 209 | senSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); 210 | senAccelerometer = senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); 211 | initListeners(); 212 | 213 | fuseTimer.scheduleAtFixedRate(new calculateFusedOrientationTask(), 214 | 1000, TIME_CONSTANT); 215 | 216 | return START_STICKY; 217 | } 218 | 219 | public void initListeners() { 220 | senSensorManager.registerListener(this, 221 | senSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), 222 | SensorManager.SENSOR_DELAY_FASTEST); 223 | 224 | senSensorManager.registerListener(this, 225 | senSensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), 226 | SensorManager.SENSOR_DELAY_FASTEST); 227 | 228 | senSensorManager.registerListener(this, 229 | senSensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD), 230 | SensorManager.SENSOR_DELAY_FASTEST); 231 | } 232 | 233 | @Override 234 | public void onSensorChanged(SensorEvent sensorEvent) { 235 | Sensor mySensor = sensorEvent.sensor; 236 | 237 | switch (sensorEvent.sensor.getType()) { 238 | case Sensor.TYPE_ACCELEROMETER: 239 | // copy new accelerometer data into accel array 240 | // then calculate new orientation 241 | System.arraycopy(sensorEvent.values, 0, accel, 0, 3); 242 | 243 | 244 | calculateAccMagOrientation(); 245 | break; 246 | 247 | case Sensor.TYPE_GYROSCOPE: 248 | // process gyro data 249 | gyroFunction(sensorEvent); 250 | break; 251 | 252 | case Sensor.TYPE_MAGNETIC_FIELD: 253 | // copy new magnetometer data into magnet array 254 | System.arraycopy(sensorEvent.values, 0, magnet, 0, 3); 255 | break; 256 | } 257 | } 258 | 259 | @Override 260 | public void onAccuracyChanged(Sensor sensor, int i) { 261 | // Log.d("MY_APP", sensor.toString() + "-" + i); 262 | } 263 | 264 | public void calculateAccMagOrientation() { 265 | if (SensorManager.getRotationMatrix(rotationMatrix, null, accel, magnet)) { 266 | SensorManager.getOrientation(rotationMatrix, accMagOrientation); 267 | } 268 | } 269 | 270 | private void getRotationVectorFromGyro(float[] gyroValues, 271 | float[] deltaRotationVector, 272 | float timeFactor) { 273 | float[] normValues = new float[3]; 274 | 275 | // Calculate the angular speed of the sample 276 | float omegaMagnitude = 277 | (float) Math.sqrt(gyroValues[0] * gyroValues[0] + 278 | gyroValues[1] * gyroValues[1] + 279 | gyroValues[2] * gyroValues[2]); 280 | 281 | // Normalize the rotation vector if it's big enough to get the axis 282 | if (omegaMagnitude > EPSILON) { 283 | normValues[0] = gyroValues[0] / omegaMagnitude; 284 | normValues[1] = gyroValues[1] / omegaMagnitude; 285 | normValues[2] = gyroValues[2] / omegaMagnitude; 286 | } 287 | 288 | // Integrate around this axis with the angular speed by the timestep 289 | // in order to get a delta rotation from this sample over the timestep 290 | // We will convert this axis-angle representation of the delta rotation 291 | // into a quaternion before turning it into the rotation matrix. 292 | float thetaOverTwo = omegaMagnitude * timeFactor; 293 | float sinThetaOverTwo = (float) Math.sin(thetaOverTwo); 294 | float cosThetaOverTwo = (float) Math.cos(thetaOverTwo); 295 | deltaRotationVector[0] = sinThetaOverTwo * normValues[0]; 296 | deltaRotationVector[1] = sinThetaOverTwo * normValues[1]; 297 | deltaRotationVector[2] = sinThetaOverTwo * normValues[2]; 298 | deltaRotationVector[3] = cosThetaOverTwo; 299 | } 300 | 301 | public void gyroFunction(SensorEvent event) { 302 | // don't start until first accelerometer/magnetometer orientation has been acquired 303 | if (accMagOrientation == null) 304 | return; 305 | 306 | // initialisation of the gyroscope based rotation matrix 307 | if (initState) { 308 | float[] initMatrix = new float[9]; 309 | initMatrix = getRotationMatrixFromOrientation(accMagOrientation); 310 | float[] test = new float[3]; 311 | SensorManager.getOrientation(initMatrix, test); 312 | gyroMatrix = matrixMultiplication(gyroMatrix, initMatrix); 313 | initState = false; 314 | } 315 | 316 | // copy the new gyro values into the gyro array 317 | // convert the raw gyro data into a rotation vector 318 | float[] deltaVector = new float[4]; 319 | if (timestamp != 0) { 320 | final float dT = (event.timestamp - timestamp) * NS2S; 321 | System.arraycopy(event.values, 0, gyro, 0, 3); 322 | getRotationVectorFromGyro(gyro, deltaVector, dT / 2.0f); 323 | } 324 | 325 | // measurement done, save current time for next interval 326 | timestamp = event.timestamp; 327 | 328 | // convert rotation vector into rotation matrix 329 | float[] deltaMatrix = new float[9]; 330 | SensorManager.getRotationMatrixFromVector(deltaMatrix, deltaVector); 331 | 332 | // apply the new rotation interval on the gyroscope based rotation matrix 333 | gyroMatrix = matrixMultiplication(gyroMatrix, deltaMatrix); 334 | 335 | // get the gyroscope based orientation from the rotation matrix 336 | SensorManager.getOrientation(gyroMatrix, gyroOrientation); 337 | } 338 | 339 | private float[] getRotationMatrixFromOrientation(float[] o) { 340 | float[] xM = new float[9]; 341 | float[] yM = new float[9]; 342 | float[] zM = new float[9]; 343 | 344 | float sinX = (float) Math.sin(o[1]); 345 | float cosX = (float) Math.cos(o[1]); 346 | float sinY = (float) Math.sin(o[2]); 347 | float cosY = (float) Math.cos(o[2]); 348 | float sinZ = (float) Math.sin(o[0]); 349 | float cosZ = (float) Math.cos(o[0]); 350 | 351 | // rotation about x-axis (pitch) 352 | xM[0] = 1.0f; 353 | xM[1] = 0.0f; 354 | xM[2] = 0.0f; 355 | xM[3] = 0.0f; 356 | xM[4] = cosX; 357 | xM[5] = sinX; 358 | xM[6] = 0.0f; 359 | xM[7] = -sinX; 360 | xM[8] = cosX; 361 | 362 | // rotation about y-axis (roll) 363 | yM[0] = cosY; 364 | yM[1] = 0.0f; 365 | yM[2] = sinY; 366 | yM[3] = 0.0f; 367 | yM[4] = 1.0f; 368 | yM[5] = 0.0f; 369 | yM[6] = -sinY; 370 | yM[7] = 0.0f; 371 | yM[8] = cosY; 372 | 373 | // rotation about z-axis (azimuth) 374 | zM[0] = cosZ; 375 | zM[1] = sinZ; 376 | zM[2] = 0.0f; 377 | zM[3] = -sinZ; 378 | zM[4] = cosZ; 379 | zM[5] = 0.0f; 380 | zM[6] = 0.0f; 381 | zM[7] = 0.0f; 382 | zM[8] = 1.0f; 383 | 384 | // rotation order is y, x, z (roll, pitch, azimuth) 385 | float[] resultMatrix = matrixMultiplication(xM, yM); 386 | resultMatrix = matrixMultiplication(zM, resultMatrix); 387 | return resultMatrix; 388 | } 389 | 390 | private float[] matrixMultiplication(float[] A, float[] B) { 391 | float[] result = new float[9]; 392 | 393 | result[0] = A[0] * B[0] + A[1] * B[3] + A[2] * B[6]; 394 | result[1] = A[0] * B[1] + A[1] * B[4] + A[2] * B[7]; 395 | result[2] = A[0] * B[2] + A[1] * B[5] + A[2] * B[8]; 396 | 397 | result[3] = A[3] * B[0] + A[4] * B[3] + A[5] * B[6]; 398 | result[4] = A[3] * B[1] + A[4] * B[4] + A[5] * B[7]; 399 | result[5] = A[3] * B[2] + A[4] * B[5] + A[5] * B[8]; 400 | 401 | result[6] = A[6] * B[0] + A[7] * B[3] + A[8] * B[6]; 402 | result[7] = A[6] * B[1] + A[7] * B[4] + A[8] * B[7]; 403 | result[8] = A[6] * B[2] + A[7] * B[5] + A[8] * B[8]; 404 | 405 | return result; 406 | } 407 | 408 | class calculateFusedOrientationTask extends TimerTask { 409 | public void run() { 410 | float oneMinusCoeff = 1.0f - FILTER_COEFFICIENT; 411 | fusedOrientation[0] = 412 | FILTER_COEFFICIENT * gyroOrientation[0] 413 | + oneMinusCoeff * accMagOrientation[0]; 414 | // Log.d("X:", ""+fusedOrientation[0]); 415 | 416 | fusedOrientation[1] = 417 | FILTER_COEFFICIENT * gyroOrientation[1] 418 | + oneMinusCoeff * accMagOrientation[1]; 419 | // Log.d("Y:", ""+fusedOrientation[1]); 420 | fusedOrientation[2] = 421 | FILTER_COEFFICIENT * gyroOrientation[2] 422 | + oneMinusCoeff * accMagOrientation[2]; 423 | // Log.d("Z:", ""+fusedOrientation[2]); 424 | 425 | //**********Sensing Danger********** 426 | double SMV = Math.sqrt(accel[0] * accel[0] + accel[1] * accel[1] + accel[2] * accel[2]); 427 | // Log.d("SMV:", ""+SMV); 428 | if (SMV > 25) { 429 | if (sentRecently == 'N') { 430 | Log.d("Accelerometer vector:", "" + SMV); 431 | degreeFloat = (float) (fusedOrientation[1] * 180 / Math.PI); 432 | degreeFloat2 = (float) (fusedOrientation[2] * 180 / Math.PI); 433 | if (degreeFloat < 0) 434 | degreeFloat = degreeFloat * -1; 435 | if (degreeFloat2 < 0) 436 | degreeFloat2 = degreeFloat2 * -1; 437 | // Log.d("Degrees:", "" + degreeFloat); 438 | if (degreeFloat > 30 || degreeFloat2 > 30) { 439 | Log.d("Degree1:", "" + degreeFloat); 440 | Log.d("Degree2:", "" + degreeFloat2); 441 | handler.post(new Runnable() { 442 | 443 | @Override 444 | public void run() { 445 | Toast.makeText(IService2.this.getApplicationContext(), "Sensed Danger! Sending SMS", Toast.LENGTH_SHORT).show(); 446 | } 447 | }); 448 | // Toast.makeText(getApplicationContext(), "Sensed Danger! Sending SMS", Toast.LENGTH_SHORT).show(); 449 | 450 | Cursor cursor = sql.query(ContactContract.TABLE_NAME, projection, null, null, null, null, null); 451 | List itemIds = new ArrayList<>(); 452 | while (cursor.moveToNext()) { 453 | long itemId = cursor.getLong( 454 | cursor.getColumnIndexOrThrow(ContactContract.COLUMN_CONTACT)); 455 | itemIds.add(itemId); 456 | } 457 | cursor.close(); 458 | Iterator it = itemIds.iterator(); 459 | 460 | while (it.hasNext()) { 461 | // if (sendCount < 5) { 462 | // textMsg = "Sensed Danger here => "+"http://maps.google.com/?q=<"+latitude+">,<"+longitude+">"; 463 | 464 | phoneNum = it.next().toString(); 465 | if (phoneNum != prevNumber && phoneNum != null) { 466 | textMsg = "Sensed Danger here => " + "http://maps.google.com/?q=<" + String.valueOf(latitude) + ">,<" + String.valueOf(longitude) + ">"; 467 | Log.d("Sending-MSG", "onSensorChanged: " + sendCount); 468 | smsManager.sendTextMessage(phoneNum, null, textMsg, null, null); 469 | prevNumber = phoneNum; 470 | sendCount++; 471 | } 472 | // } 473 | } 474 | } else { 475 | handler.post(new Runnable() { 476 | @Override 477 | public void run() { 478 | Toast.makeText(IService2.this.getApplicationContext(), "Sudden Movement! But looks safe", Toast.LENGTH_SHORT).show(); 479 | } 480 | }); 481 | sendCount++; 482 | } 483 | sentRecently='Y'; 484 | Log.d("Delay", "Delay Start**********"); 485 | mPeriodicEventHandler.postDelayed(doPeriodicTask, PERIODIC_EVENT_TIMEOUT); 486 | } 487 | } 488 | gyroMatrix = getRotationMatrixFromOrientation(fusedOrientation); 489 | System.arraycopy(fusedOrientation, 0, gyroOrientation, 0, 3); 490 | } 491 | } 492 | } -------------------------------------------------------------------------------- /java/com/example/vishu/sampleapp/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.vishu.sampleapp; 2 | 3 | import android.Manifest; 4 | import android.content.ContentValues; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.pm.PackageManager; 8 | import android.database.Cursor; 9 | import android.database.sqlite.SQLiteDatabase; 10 | import android.hardware.Sensor; 11 | import android.hardware.SensorEvent; 12 | import android.hardware.SensorEventListener; 13 | import android.hardware.SensorManager; 14 | import android.location.Location; 15 | import android.location.LocationListener; 16 | import android.location.LocationManager; 17 | import android.net.Uri; 18 | import android.os.Bundle; 19 | import android.support.v4.app.ActivityCompat; 20 | import android.support.v4.content.ContextCompat; 21 | import android.support.v7.app.AppCompatActivity; 22 | import android.telephony.SmsManager; 23 | import android.util.Log; 24 | import android.view.Menu; 25 | import android.view.MenuItem; 26 | import android.view.View; 27 | import android.widget.AdapterView; 28 | import android.widget.ArrayAdapter; 29 | import android.widget.Button; 30 | import android.widget.EditText; 31 | import android.widget.ImageButton; 32 | import android.widget.ListView; 33 | import android.widget.Toast; 34 | 35 | import com.google.android.gms.appindexing.Action; 36 | import com.google.android.gms.appindexing.Thing; 37 | import com.google.android.gms.common.api.GoogleApiClient; 38 | 39 | import java.util.ArrayList; 40 | import java.util.List; 41 | 42 | public class MainActivity extends AppCompatActivity { 43 | 44 | private static final int MY_PERMISSIONS_REQUEST_FINE = 2; 45 | 46 | private Button start,stop,addContacts; 47 | ListView lv; 48 | EditText edit; 49 | private SQLiteDatabase sql; 50 | String provider; 51 | 52 | @Override 53 | protected void onCreate(Bundle savedInstanceState) { 54 | 55 | super.onCreate(savedInstanceState); 56 | setContentView(R.layout.activity_main); 57 | 58 | Log.d("Before Permission Check", "onCreate: "); 59 | 60 | //SMS and GPS Permission 61 | if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED && 62 | ActivityCompat.checkSelfPermission(this, Manifest.permission.SEND_SMS) != PackageManager.PERMISSION_GRANTED) { 63 | 64 | int PERMISSION_ALL = 1; 65 | String[] PERMISSIONS = {Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.SEND_SMS}; 66 | ActivityCompat.requestPermissions(this, PERMISSIONS, PERMISSION_ALL); 67 | // return; 68 | } 69 | Log.d("After Permission Check", "onCreate:"); 70 | 71 | start = (Button) findViewById(R.id.start); 72 | stop = (Button) findViewById(R.id.stop); 73 | lv = (ListView) findViewById(R.id.contacts); 74 | edit = (EditText) findViewById(R.id.editText); 75 | addContacts = (Button) findViewById(R.id.add); 76 | 77 | DBHelper dpHelper = new DBHelper(this); 78 | sql = dpHelper.getWritableDatabase(); 79 | Cursor cursor = getAllContacts(); 80 | final ArrayAdapter arrayAdapter; 81 | 82 | Toast.makeText(getApplicationContext(),"Wear Your Helmet and Start Tracking",Toast.LENGTH_SHORT).show(); 83 | 84 | 85 | start.setOnClickListener(new View.OnClickListener(){ 86 | @Override 87 | public void onClick(View view) { 88 | Log.d("Start Button", "Pressed"); 89 | String count = "SELECT count(*) FROM "+ContactContract.TABLE_NAME; 90 | Cursor mcursor = sql.rawQuery(count, null); 91 | mcursor.moveToFirst(); 92 | int icount = mcursor.getInt(0); 93 | if(icount>0){ 94 | Toast.makeText(getApplicationContext(),"Safe riding! We track you for safety",Toast.LENGTH_SHORT).show(); 95 | Intent intent= new Intent(getApplicationContext(), IService2.class); 96 | startService(intent); 97 | }else{ 98 | Toast.makeText(getApplicationContext(),"Add at least one contact then try again",Toast.LENGTH_SHORT).show(); 99 | } 100 | mcursor.close(); 101 | } 102 | }); 103 | stop.setOnClickListener(new View.OnClickListener(){ 104 | @Override 105 | public void onClick(View view) { 106 | Log.d("Stop Button", "Pressed"); 107 | Intent intent= new Intent(getApplicationContext(), IService2.class); 108 | stopService(intent); 109 | } 110 | }); 111 | 112 | ArrayList list = new ArrayList(); 113 | addContacts.setOnClickListener(new View.OnClickListener(){ 114 | @Override 115 | public void onClick(View view) { 116 | ArrayList list = new ArrayList(); 117 | Log.d("Adding Contacts", addContacts.toString()); 118 | //Insert into db 119 | if(edit.getText().toString().length() != 10 ){ 120 | Toast.makeText(getApplicationContext(),"Please enter again!",Toast.LENGTH_SHORT).show(); 121 | }else{ 122 | addNewContact(edit.getText().toString()); 123 | Toast.makeText(getApplicationContext(),"Contact Added",Toast.LENGTH_SHORT).show(); 124 | Cursor cursor = getAllContacts(); 125 | if (cursor.moveToFirst()){ 126 | do{ 127 | String data = cursor.getString(cursor.getColumnIndex("contact")); 128 | list.add(data); 129 | // do what ever you want here 130 | }while(cursor.moveToNext()); 131 | } 132 | cursor.close(); 133 | ArrayAdapter arrayAdapter = new ArrayAdapter(getApplicationContext(), R.layout.simplerow); 134 | arrayAdapter.addAll(list); 135 | lv.setAdapter(arrayAdapter); 136 | } 137 | edit.setText(""); 138 | } 139 | }); 140 | lv.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() { 141 | @Override 142 | public boolean onItemLongClick(AdapterView adapterView, View view, int i, long l) { 143 | Log.v("long clicked","pos: " + i + " long value is :"+l); 144 | //Toast.makeText(getApplicationContext(),lv.getItemAtPosition(i).toString(), Toast.LENGTH_LONG).show(); 145 | removeContact(lv.getItemAtPosition(i).toString()); 146 | //lv.remove(i); 147 | Object remove = lv.getAdapter().getItem(i); 148 | ArrayAdapter arrayAdapter1 = (ArrayAdapter)lv.getAdapter(); 149 | arrayAdapter1.remove(remove); 150 | return false; 151 | } 152 | }); 153 | if (cursor.moveToFirst()){ 154 | do{ 155 | String data = cursor.getString(cursor.getColumnIndex("contact")); 156 | list.add(data); 157 | // do what ever you want here 158 | }while(cursor.moveToNext()); 159 | } 160 | arrayAdapter = new ArrayAdapter(getApplicationContext(), R.layout.simplerow); 161 | arrayAdapter.addAll(list); 162 | lv.setAdapter(arrayAdapter); 163 | } 164 | 165 | public Cursor getAllContacts(){ 166 | return sql.query(ContactContract.TABLE_NAME,null,null,null,null,null,ContactContract.COLUMN_CONTACT); 167 | } 168 | 169 | @Override 170 | public boolean onCreateOptionsMenu(Menu menu) { 171 | getMenuInflater().inflate(R.menu.menu,menu); 172 | return true; 173 | } 174 | 175 | @Override 176 | public boolean onOptionsItemSelected(MenuItem item) { 177 | int menuItemThatwasSelected = item.getItemId(); 178 | if(menuItemThatwasSelected == R.string.action_contacts){ 179 | Context context = MainActivity.this; 180 | startActivity(new Intent(this, ContactActivity.class)); 181 | return true; 182 | } 183 | return super.onOptionsItemSelected(item); 184 | } 185 | 186 | public long addNewContact(String contact){ 187 | ContentValues cv = new ContentValues(); 188 | cv.put(ContactContract.COLUMN_CONTACT,contact); 189 | return sql.insert(ContactContract.TABLE_NAME,null,cv); 190 | } 191 | 192 | public void removeContact(String contact){ 193 | sql.delete(ContactContract.TABLE_NAME, "contact"+"=?",new String[]{contact}); 194 | Toast.makeText(getApplicationContext(),"Number Deleted!!",Toast.LENGTH_SHORT).show(); 195 | } 196 | } 197 | -------------------------------------------------------------------------------- /res/drawable/images.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/swift2891/Fall_Detection/4e5eccb4ee99c6347116733066644af105fbcf41/res/drawable/images.jpg -------------------------------------------------------------------------------- /res/layout/activity_contact.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 13 | 22 | 23 | -------------------------------------------------------------------------------- /res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 20 | 21 | 27 |