Creativefusion

Proximity based notifications

Like in my other post about how to get push notifications working from your CoronaSDK app with Parse we covered the topic on how to get remote push notifications. This article is about how to trigger how to trigger proximity based notifications.

So what if you were developing an app for a client and they would like to drive nearby customers to their shop/restaurant etc. Well, this is what we could use it for.

Grab the entire code here.

This is pretty simple, first we need to write the function for calculating the distance between two locations.

-- Earth radius in meters.
local earthRad = 6378137
 
-- Works for short distances.
local function distanceApproximation(lat1, long1, lat2, long2)
 
	if not lat1 or not long1 or not lat2 or not long2 then
	   print(" ===>>> Missing latitudes and longitudes")
	   return
	end 
 
	local l1, lng1 = math.rad(lat1), math.rad(long1)
	local l2, lng2 = math.rad(lat2), math.rad(long2)
	local x = (lng2-lng1) * math.cos((l1+l2)*0.5)
	local y = (l2-l1)
	local d = math.sqrt(x * x + y * y) * earthRad
 
	print(" ===>>> distanceApproximation: "..d.." meters")
 
	return d
end

Now let’s set up the location handler function but before that we need to make some forward declarations and setup som variables.

-- lat/long of the location you wish to trigger the notification for.
local myLat, myLong = 0,0 
-- Our timer
local proximityTimer 
-- Delay for the notification
local alertDelay = 5 
-- Meters, max range.
local myProximity = 200 
 
local message = {
	alert = "You are within range of location!",
	badge = 1,
	sound = "alarm.caf"
}
 
local function updateLocation()
	local function locationHandler(event)
	    if event.errorCode then
	      print(" ===>>> LOCATION HANDLER ERROR : " .. tostring(event.errorMessage) )
	    else
	      print(" ===>>> CURRENT LOCATION COORDS, LAT : "..event.latitude..", LONG : "..event.longitude)
 
	      local distance = distanceApproximation(event.latitude, event.longitude, myLat, myLong)
 
	      if distance < myProximity then 	      	
                  print(" ===>>> PING!!! WE ARE WITHIN RANGE OF OUR LOCATION ("..distance.."m), SHOW LOCAL NOTIFICATION. : "..message.alert)
		 system.scheduleNotification( os.date( "!*t", os.time() + alertDelay) , message) 
 
		-- Cancel the proximityTimer if we are within range.
		timer.cancel(proximityTimer)
	      else
	        print(" ===>>> PING!!! NOT YET WITHIN RANGE OF OUR LOCATION ("..distance.."m)")
	      end
 
	    end
	  Runtime:removeEventListener("location", locationHandler)
	end
	Runtime:addEventListener("location", locationHandler)
end
 
-- Update location once upon startup.
updateLocation()
 
-- Fire the timer every 5 sec.
proximityTimer = timer.performWithDelay(5000, updateLocation, 0 )

 

local function notificationListener(event)
 
     if (event.type == "local") then
 
	 local badgeNum = native.getProperty("applicationIconBadgeNumber")
               badgeNum = badgeNum - 1
 
         native.setProperty("applicationIconBadgeNumber", badgeNum)
	 native.showAlert( "Hello", message.alert, { "OK" } )
         print(" ===>>> LOCAL NOTIFICATION, CLEAR BADGE!!")
     end
end
 
Runtime:addEventListener("notification", notificationListener)

Now that we have almost everything done, we need to setup some launchArgs.
Add this line at the very top of your main.lua

local launchArgs = ...

Now add this after the notificationListener.

if (launchArgs and launchArgs.notification) then
    print(" ===>>> EVENT launchArgs...")
    notificationListener(launchArgs.notification)
end

Push notifications with Parse

I came across the mod_parse module a while ago when I was implementing push notifications into an app. I really like the module and I decided to use the analytical parts in my app but unfortunately, the module doesn’t have push yet so I started hacking away and found it was easier and faster than I could ever imagined.

To save everyone the hassle of writing your own code I decided to share mine with the Corona community. Just add it to your main.lua, sign up with parse and get your appID and REST key and your good to go.

After you got your parse keys, build for device and launch the app, go to your parse and see the data browser for your device. I have only run this code on iOS.

Grab the code here and get your push notifications with parse going too!

local appID = "Your appID"
local RESTapiKey = "Your REST ApiKey"
local function notificationListener(event)
 
      if (event.type == "local") then
 
      local badgeNum = native.getProperty( "applicationIconBadgeNumber" )
            badgeNum = badgeNum - 1
            native.setProperty( "applicationIconBadgeNumber", badgeNum )
 
      elseif (event.type == "remote") then
 
           if (event.badge and event.badge > 0) then
              native.setProperty("applicationIconBadgeNumber", event.badge - 1)
           end
 
      elseif (event.type == "remoteRegistration") then
 
           local platform = "ios"
 
           if (system.getInfo("platformName") == "Android") then
                 platform = "android"
           end
 
       local function networkListener(event)
            if (event.isError) then
                print(" ===>>> PARSE LISTENER ERROR RESPONSE : ", event.response)
            else
                print(" ===>>> PARSE LISTENER RESPONSE: ", event.response)
            end
        end
 
        local headers = {
              ["X-Parse-Application-Id"] = appID,
              ["X-Parse-REST-API-Key"] = RESTapiKey,
              ["Content-Type"] = "application/json"
             }
 
        local bodyData = {
            -- These two fields must be added at parse.com first.
              ["deviceName"]  = tostring( system.getInfo("name") ),
              ["deviceModel"] = tostring( system.getInfo("architectureInfo") ),
 
              ["deviceType"]  = platform,
              ["deviceToken"] = event.token,
              ["badge"] = native.getProperty("applicationIconBadgeNumber"),
              ["timeZone"] = -3600,
              ["channels"] = {"MyPushChannel"}
             }
 
       local body = json.encode(bodyData)
 
       local params = {
             headers = headers,
             body = body
        }
        network.request( "https://api.parse.com/1/installations" ,"POST", networkListener, params)
 
     end
 
end
 
Runtime:addEventListener("notification", notificationListener )

Copyright © 2016 Creativefusion

Theme by Anders NorenUp ↑