Pin Pin - Pin for a Person In Need

Richard Yang

CSC 491/492 | Spring 2018


Introduction


PinPin (Pin for a Person In Need) is a mobile app that is designed to help the millions of homeless people in the world.
Unemployment levels and the homeless population are on the rise. Homeless shelters and other types of homeless aid are failing to meet these peoples' needs. PinPin aims to help alleviate this problem by allowing its users to mark the location of homeless people asking for food, money, first aid, or a ride.
Other users will then be able to see the Pins that they or other users have placed. Now that they know where the homeless people are, they can bring aid to.

Source (direct link)


Android APK
IOS APK

How to use PinPin


Placing a Pin:

Place a Pin when you want to share the homeless person's location so that other people may come help them.

1. Launch the app when you see a homeless person who is asking for help.
2. Locate the person's location on the map and tap on the map.
3. Choose the need that they are asking for: Food (🍗), Money (💵), First Aid (🚑), or a Ride (🚕).
4. A new Pin will appear on the map in the form of that person's need.
5. You and other users will now be able to locate homeless people and bring them the help that they need.

Find and help homeless people:

Locate homeless people and bring them what they desperately need.

1. Launch the app and look for any Pins that are near your location.
2. You may also use the search bar to look for Pins in a specific location.
3. You can identify the persons' need based on the appearance of the Pin: Food (🍗), Money (💵), First Aid (🚑), or a Ride (🚕).
4. If you need directions to a Pin, tap on the Pin and an option to switch to your phone's map app will appear.

Deleting a Pin:

Delete a Pin when you have placed a Pin in the wrong location or when there is no one at that location anymore.

1. Tap and hold on the invalid Pin.
2. An alert will pop up asking for confirmation to delete the Pin.
3. Tap "Yes" to delete the Pin.
4. Tap "No" or tap anywhere outside the pop up to cancel the deletion.

Note: Please respect other peoples' privacy! Some people do not like to be tracked 24/7. PinPin automatically deletes Pins that are older than 6 hours or placed after 10:00 P.M.

Implementation


The Front-end:

This app uses the Google Maps API and the Google Places API. To ensure that this app easy to use, it only contains one screen, which is the map initially centered on the user's current location. The user can do just about everything that they can do in any map application such as zooming out/in, scrolling to a different location, searching for a different location using the search bar, etc. Pins in the form of 🍗, 💵, 🚑, or 🚕 are shown on the map, indicating the location and need of homeless people. To add a Pin, the user taps on any available space on the map. A pop up then appears asking for the need. To delete a pin, the user taps and holds on an existing Pin and a pop up appears to confirm the delete action.

Getting Pins from the Database

Fig. 1: Getting Pins from the Database and marking them on the map.

To put other user's pins onto the map, PinPin needs to read in Pin entries from the database. Every minute, PinPin sends a HTTP request to the server (Fig. 1: Line 70). This request to http://129.65.221.101/php/getPinPinGPSdata.php will send every entry in the database formatted as:

[Latitude] [Longitude] [Need] [ServerTime]

The app then reads in each of these entries from the server and adds them to a global set of Pins called dbCoords (Fig. 1: Lines 74 - 91). After it has read in every entry from the server, it goes on to the addMarkers function (Fig. 1: Line 100) which adds the Pins onto the map.


Fig. 2: The Pin Class.

The Pin Class serves as the data structure for the Pins and simply contains a coords variable (Fig. 2: Line 6), which is used to locate where to put the Pin on the map, and the need variable (Fig. 2: Line 7), which is used to determine what the Pin icon will be. The equals function and the hashCode function (Fig. 2: Lines 14 - 30) are required as part of a Java Set Interface.


Fig. 3: Adding the Pins to the map from the dbCoords Set.

This function takes in all of the Pins in the dbCoords set and adds them to the map. To avoid unnecessary load times, only the Pins that are within 20 km of the user's current location are added to the map. The switch statement determines which icon (🍗, 💵, 🚑, 🚕) the Pin will have based on the need (Fig. 3: Lines 159 - 172).

Adding a Pin

Fig. 4: Adding a Pin to the map and database on user tap.

The onMapClick (Fig. 4: Line 243) function is called when the user taps anywhere on the map. First, an AlertDialog (Fig. 4: Line 248) pops up querying for the type of need (🍗, 💵, 🚑, 🚕). After the user selects the need, the new Pin gets added to the map (Fig. 4: Lines 251 - 272). Second, the new Pin is added to the database so that other users can see the new Pin (Fig. 4: Lines 275 - 288). This is achieved by sending a HTTP SEND request formatted as:

http://129.65.221.101/php/sendPinPinGPSdata.php?gps=[Latitude] [Longitude] [Need]

Deleting a Pin

Fig. 5: Deleting a Pin from the map and database on user tap & hold.

The onMapLongClick (Fig. 5: Line 303) function is called when the user taps and holds anywhere on the map. Unfortunately, the Google Maps API does not have a way to get the Pin coordinates from a long click; it only gives the coordinates of the location that the user tapped. Therefore, I had to determine the closest Pin in the dbCoords relative to the user's tapped location (Fig. 5: Lines 306 - 314). After the closest Pin to the long click is set, an AlertDialog (Fig. 5: Line 323) pops up confirming the delete action. If the user taps "Yes", the Pin is first removed from the map (Fig. 5: Lines 330 - 332) and then the Pin is removed from the database (Fig. 5: Lines 335 - 351). This is done via a HTTP SEND request formatted as:

http://129.65.221.101/php/deleteFlaggedEntry.php?gps=[Latitude] [Longitude]

To avoid having the AlertDialog pop up if the user long clicked too far away from any Pins, a check to see if the closest distance of the user's tapped location and the nearest pin is performed (Fig. 5: Lines 317 - 319). If the distance is greater than 30 meters, an early return from the function is performed. I tested this distance extensively and it seems like 30 meters was the best fit for determining if the user long click was close enough to the actual Pin location. If this distance is too small, it is almost impossible to long click on a Pin because the user tapped location will not be that close to the true Pin location when tapping on a zoomed out map.

The Back-end:

This app uses an Apache HTTP Server running on Windows 10, located in the Mixed Reality Lab in California Polytechnic State University, San Luis Obispo. The IP address for this server is: 129.65.221.101. If the server is down, log onto the computer located in the right corner of the room when you enter the door, then navigate to the C:\Apache24\bin folder and run the httpd.exe program. To ensure that the server keeps running, DO NOT log off or shut down the computer after starting the httpd.exe program. Instead, click on the Power Off button in the Start Menu and select the Switch Accounts option.

All of the code for the back-end is located on the computer and can be viewed at C:\Apache24\bin\htdocs\php. The back-end consists of five files:

PinPinGPSdata.txt

Fig. 6: Example contents of PinPinGPSdata.txt.

This text file stores all of the coordinates that users add from the PinPin apps on their phones. Coordinates are written to this text file from the sendPinPinGPSdata.php program. Every coordinate is stored with the format:

[Latitude] [Longitude] [Need] [ServerTime]

sendPinPinGPSdata.php

Fig. 7: sendPinPinGPSdata PHP program.

This PHP program gets the Pins that users have entered from the PinPin mobile app and adds it to the PinPinGPSdata.txt file. $msg (Fig. 7: Line 2) is an array that contains the Latitude, Longitude, and Need located after the gps= in the HTTP SEND request talked about in the previous Adding a Pin section:

http://129.65.221.101/php/sendPinPinGPSdata.php?gps=[Latitude] [Longitude] [Need]

The program then appends the current datetime (in milliseconds since epoch) to the $msg and then appends $msg to $current (Fig. 7: Line 5), which contains the current contents of the PinPinGPSdata.txt file. Finally, it writes $current to the PinPinGPSdata.txt file, replacing everything already in there.

getPinPinGPSdata.php

Fig. 8: getPinPinGPSData PHP program.

This PHP program simply writes the contents of the PinPinGPSdata.txt file to the output buffer via the readfile (Fig. 8: Line 6) function. The PinPin mobile app reads in this buffer, parses the coordinates, and adds these coordinates to the map, talked about in the Getting Pins from the Database section.

deleteFlaggedEntry.php

Fig. 9: deleteFlaggedEntry PHP program.

This PHP program deletes the Pin that a user has deleted from the PinPin app from the PinPinGPSdata.txt file. $delete (Fig. 9: Line 3) is an array that contains the Latitude and Longitude located after the gps= in the HTTP SEND request talked about in the previous Deleting a Pin section:

http://129.65.221.101/php/deleteFlaggedEntry.php?gps=[Latitude] [Longitude]

The program then iterates through every line in the PinPinGPSdata.txt file, checks for the matching latitude and longitude (Fig. 9: Lines 5 - 20), and appends it to the $newEntries variable. (Fig. 9: Line 2). After the loop, it writes $newEntries to the PinPinGPSdata.txt file, replacing everything already in there.

deleteOldEntries.py

Fig. 10: deleteOldEntries python program.

Due to privacy concerns, PinPin automatically deletes Pins from the database that are older than 6 hours or placed after 10:00 P.M. The program first reads in the contents of the PinPinGPSdata.txt file and stores it into the lines variable (Fig. 10: Lines 7 - 9). Then, it iterates through lines and only writes lines to PinPinGPSdata.txt if each Pin's time placed has not been more than 6 hours ago, or if the current time is before 10:00 P.M. (Fig. 10: Lines 11 - 25).

This program runs on the computer at the start of every hour, using the built-in Windows Task Scheduler program. I used a YouTube tutorial to implement this.

Future Improvements


There are still things that need improving and things to add to PinPin. In the future, I would like to implement a settings page where the user can modify things such as the database update interval, the radius around the user to show Pins, and more. The process to delete pins could also be improved if Google ever adds the functionality to tap and hold a marker to get its information, instead of having to determine which Pin is the closest to the user's tap. Another idea that I had was to implement Street View, and when someone enters Street View, they would be able to see a 3D Pin at its exact location so that Users can locate homeless people in hard to navigate environment.

Download


Android: GitHub Android APK
iOS: GitHub
Note: I do not own an iPhone, which is required to create an iOS .ipa file (The equivalent of an Android .apk file). If you have an iPhone and want to download the .ipa file, clone the iOS github link and follow these instructions: https://stackoverflow.com/questions/5499125/how-to-create-ipa-file-using-xcode.