/ location based service

Create an Android app with Matchmore

In this previous post, we described how to set up Matchmore integration for iOS. In this post we will show you how to use Matchmore SDK on Android.

Requirements

  • You need a Matchmore account. Register here for free.
  • You need to know how to use Android studio
  • You need to know Kotlin programming language

Get API key

As for iOS, you will need an API key, to get it login into your Matchmore account:

alt text

Android studio mobile app

Let's create a new Android studio project with Kotlin support. Set minimum SDK to Phone and Tablet API 22 and add empty Activity.

Next lets edit build.gradle file for module app and add dependencies for Matchmore SDK.

    //for SDK
    implementation 'com.github.matchmore.android-sdk:sdk:0.7.0'
    implementation 'com.github.matchmore.android-sdk:rx:0.7.0'

After you save the changes Android studio will ask you if you want to sync the project, click yes.

Request permission for Location Services

Depending on your needs, your app may require Location Services to work in the background, which means we need to set up Location Services usage description. This description will be shown to the user when asking them about allowing the app to access their location.

Users must grant permission for an app to access personal information, including the current location. Although people appreciate the convenience of using an app that has access to this information, they also expect to have control over their private data.

In the project navigator, find the file AndroidManifest.xml (App/manifests), double click on it . Then, inside tag, add the following lines:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

When opening app for the first time, the system will prompt authorization alert with the filled description. Users can decide whether to accept or reject the request permission.

Good practice

Request permission at launch only when necessary for your app to function. Users won’t be bothered by this request if it’s obvious that your app depends on their personal information to operate. For example, an app might only request access to the current location when activating a location tracking feature.

After the update to Android 6.0 Marshmallow, to be able to request the location, the user have to grant the permission at the runtime. Since the user can also revoke the permission at any moment (in the application settings), we have to add some methods in our app core to check if our app have the right to access the user location. If it's disabled, we should request the permissions again.

There are many ways to do it, we can make our own permission check logic like this, which is complex or we can use a library that allows us to do it easily. For this tutorial, we will use TedPermission which allows us to check and request android permissions with few lines of codes.

To import the library in our project, we have to edit our gradle file build.gradle:

dependencies {
implementation 'gun0912.ted:tedpermission:2.2.0'
}

SDK configuration

Next, you have to configure SDK with your API key, and you can do this in onCreate method of main activity of your app.

    private val API_KEY = "key_here"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        Matchmore.config(context = this, apiKey = API_KEY, debugLog = false)
    }

Simple UI

Now let's create a view with two buttons and a label to make testing easier.

It can look like this:

alt text

Main device setup

Before you will be able to create a publication or a subscription you have to have a device that you can attach them on. For that, you will use device representing your mobile phone.

While setting up the primary device for your phone, you can also set up match listener - the function that application calls when there is a match between publication and subscription.

The code may look like this:

private fun setupDevice() {
        Matchmore.instance.apply {
            startUsingMainDevice({ device ->
                Log.i(TAG, "start using main device ${device.name} ${device.id}")
                // Start fetching matches
                matchMonitor.addOnMatchListener { matches, _ ->
                    Log.i(TAG, "Matches found: ${matches.size}")
                    matches.map { m -> Log.i(TAG, "${m.createdAt}") }
                    matchText?.text = "⛰️got ${matches.size} matches⛰️"
                }
                matchMonitor.startPollingMatches(1000)
            }, Throwable::printStackTrace)
        }
    }

The registered listener will change the text of the label in your UI to the number of matches that your app received.

Create publications and subscriptions

Now you are ready to create a publication:

    fun addPub() {
        Matchmore.instance.apply {
            val publication = Publication("Test Topic", 2.0, 600.0)
            publication.properties = hashMapOf("color" to "red")
            createPublicationForMainDevice(publication, { result ->
                Log.i(TAG, "Publication created ${result.topic}")
            }, Throwable::printStackTrace)
        }
    }

This creates a publication on the primary device with a range of 2 meters and 10 minutes duration, and this publication will have property color set to red.

You set this method as on click listener for publish button.

Next, create a similar method for subscription:

    fun addSub() {
        Matchmore.instance.apply {
            val subscription = Subscription("Test Topic", 2.0, 600.0)
            subscription.selector = "color = 'red'"
            createSubscriptionForMainDevice(subscription, { result ->
                Log.i(TAG, "Subscription created ${result.topic}")
            }, Throwable::printStackTrace)
        }
    }

A subscription does not have properties, instead it has a selector which uses SQL like syntax to define which publication will match with this subscription.

If the match happens, a device with given subscription will get it.

As both publications and subscriptions are on the same topic, and properties in publications satisfy conditions in the subscription selector, we should get a match.

Since match for a mobile device is calculated based on its location, the last thing to do is to start updating phone location base on GPS.

But to get that information we have to request for GPS permission first, you can use tedpermissions to request it and code can look like this:

private fun checkLocationPermission() {
        val permissionListener = object : PermissionListener {
            @SuppressLint("MissingPermission")
            override fun onPermissionGranted() {
                Matchmore.instance.apply {
                    startUpdatingLocation()
                    startRanging()
                }
            }

            override fun onPermissionDenied(deniedPermissions: ArrayList<String>) {
                Toast.makeText(this@MainActivity, R.string.if_you_reject, Toast.LENGTH_SHORT).show()
            }
        }
        TedPermission.with(this)
                .setPermissionListener(permissionListener)
                .setDeniedMessage(R.string.if_you_reject)
                .setPermissions(Manifest.permission.ACCESS_FINE_LOCATION)
                .check()
    }

This method also starts location updates and beacons ranging (in case you want to use publications attached to beacons).

Since publications and subscriptions are created at the same device, the distance between them is 0 meters, they will match instantly.

Now let's hook up everything together, this is how onCreate looks like:

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        Matchmore.config(context = this, apiKey = API_KEY, debugLog = false)
        val pub_btn = findViewById(R.id.pub) as Button
        val sub_btn = findViewById(R.id.sub) as Button
        setupDevice()

        pub_btn.setOnClickListener {
            addPub()
        }
        sub_btn.setOnClickListener {
            addSub()
        }
        matchText = findViewById(R.id.match_text) as TextView
        checkLocationPermission()
    }

Final result

Next, start the application in the simulator and check if you got a match:

alt text

Android SDK is similar to iOS SDK. As you saw it is easy to use, produce great results and works smoothly.

Code for the post is here.

Happy hacking and see you in next post!

Create an Android app with Matchmore
Share this

Subscribe to Matchmore Blog