├── 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 |
33 |
34 |
41 |
42 |
49 |
55 |
56 |
64 |
65 |
66 |
--------------------------------------------------------------------------------
/res/layout/simplerow.xml:
--------------------------------------------------------------------------------
1 |
2 |
9 |
--------------------------------------------------------------------------------
/res/menu/menu.xml:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swift2891/Fall_Detection/4e5eccb4ee99c6347116733066644af105fbcf41/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swift2891/Fall_Detection/4e5eccb4ee99c6347116733066644af105fbcf41/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swift2891/Fall_Detection/4e5eccb4ee99c6347116733066644af105fbcf41/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swift2891/Fall_Detection/4e5eccb4ee99c6347116733066644af105fbcf41/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/swift2891/Fall_Detection/4e5eccb4ee99c6347116733066644af105fbcf41/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | Smart-Helmet
3 | 1637212606573987
4 | start
5 | stop
6 | Main2Activity
7 | 22
8 | Contacts
9 | Settings
10 | ContactsActivity
11 | EmergencyContacts
12 |
13 |
--------------------------------------------------------------------------------
/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------