Contents
Overview
Analysis SDK is part of the Poilabs` Proximity Marketing and Indoor Analytics Solution.
Analysis SDK integrates with an app to scan Poi beacons around. Send these beacons’ information to our signal processing structure. The signals are then forwarded to app owners’ real-time marketing systems. The data includes the mobile users id (unique_id), location (node_id), timestamp, and type of the data (passby, visit and windowshopping). The app owner can use the location data to send location-based offers and information. Every day all the data is processed and sent to app owners data base.
To integrate and run the applications, the following variables are needed. For Appstore and Google Play submissions please read the related document.
Token Variable Name | Description |
APPLICATION_ID | Application ID for Customer`s application, Provided by Poilabs. |
APPLICATION_SECRET_KEY | Access Token for Customer`s application, Provided by Poilabs. |
UNIQUE_ID | User ID to identify your app user. It must be unique for every app user. |
JITPACK_TOKEN | Jitpack token for adding jitpack dependencies. If you have your own token, you can remove it. |
iOS Native
iOS Native
To integrate PoilabsNavigation into your Xcode project using CocoaPods, specify it in your Podfile
:
pod 'PoilabsAnalysis'
You can add PoilabsAnalysis.xcframework file to your "Frameworks, Libaries, and Embedded Content" in your Project’s General Tab.
To Integrate this framework you should add some features to your project info.plist file.
This framework give support both Always and WhenInUse authorization.
-
Privacy - Location Usage Description
-
Privacy - Location When In Use Usage Description
-
Privacy - Location Always Usage Description
-
Privacy - Location Always and When In Use Usage Description
You should add "Location updates" and "Uses Bluetooth LE accessories" Background Modes from Project's Signing & Capabilities tab.
You should import framework in your AppDelegate
import PoilabsAnalysis
In applicationDidBecomeActive: method you should activate the framework:
PLAnalysisSettings.sharedInstance().applicationId = APPLICATION_ID
PLAnalysisSettings.sharedInstance().applicationSecret = APPLICATION_SECRET_KEY
PLAnalysisSettings.sharedInstance().analysisUniqueIdentifier = UNIQUE_ID
PLConfigManager.sharedInstance().getReadyForTracking(completionHandler: { error in
if error != nil {
if let anError = error {
print("Error Desc \(anError)")
}
} else {
print("Error Nil")
PLSuspendedAnalysisManager.sharedInstance()?.stopBeaconMonitoring()
PLStandardAnalysisManager.sharedInstance()?.startBeaconMonitoring()
PLStandardAnalysisManager.sharedInstance().delegate = self as? PLAnalysisManagerDelegate
}
})
In didFinishLaunchingWithOptions: method you should activate the framework:
if launchOptions?[UIApplication.LaunchOptionsKey.location] != nil {
if application.applicationState == UIApplication.State.background {
PLSuspendedAnalysisManager.sharedInstance()?.startBeaconMonitoring()
}
}
If you want to close all location services and regions for SDK you can call this method:
PLAnalysisSettings.sharedInstance()?.closeAllActions()
You can only test PoilabsAnalysis sdk with real device. You can run on simulator but for testing you should run on a iPhone.
Some test cases are only for versions 3.8.2 or above. For better test cases, please update PoilabsAnalysis if you integrated a lower version.
Error of below method should be nil.
PLConfigManager.sharedInstance().getReadyForTracking(completionHandler: { error in
})
- Request failed: forbidden (403)
- Please check APPLICATION ID and APPLICATION SECRET KEY
- Your Application id is Unavailable
- Set PLAnalysisSettings.sharedInstance().applicationId
- Your Application secret is Unavailable
- Set PLAnalysisSettings.sharedInstance().applicationSecret
- Your Analysis uniqueId is Unavailable
- Set PLAnalysisSettings.sharedInstance().analysisUniqueIdentifier
Foreground monitoring means scaning beacon and returning relevant node's id when application is active. If you initilize PoilabsAnalysis sdk with nil error and start beacon monitoring of PLStandartAnalysisManager, node ids will return to callback below.
extension AppDelegate: PLAnalysisManagerDelegate {
func analysisManagerResponse(forBeaconMonitoring response: [AnyHashable : Any]!) {
print(response)
}
}
For getting response, you have to be nearby of a beacon with data which are shared by PoiLabs.
Trigger of this callback can take time, please wait for minumun 30 seconds after start monitoring.
You can see an example of response below.
{
"data": [
["nodeid1", "nodeid2", ...],
["nodeid1", ...],
["nodeid1", ...],
...
],
"status": 1
}
If you can get a reponse like this, foreground monitoring is successfully integrated.
Background monitoring means scaning beacon when application is killed.
Before start to test please make sure always location permission is given.
To activate background mode, you should kill application and lock the screen. After you show the lock screen or unlock your iPhone, background monitoring will start if you entegrate it, like in the section USAGE/For background tracking.
For getting response, you have to be nearby of a beacon with data which are shared by PoiLabs.
You can test background monitoring on Console. Open Console application on your Mac. Type PLAnalysisSdk to search field. Select your iPhone from Devices section on the left. Press start button.
First you will see start log and then if sdk find any beacon and get its id, you will see response log. Examples of logs are below.
PLAnalysisSdk <PLSuspendedAnalysisManager: 0x...>->SuspendedAnalysisManager startBeaconMonitoring
PLAnalysisSdk <PLSuspendedAnalysisManager: 0x...>->Response {
data = ( ( "nodeid1", "nodeid2", ... ),
( "nodeid1", ... ),
( "nodeid1", ... )
);
status = 1;
}
If you get these log, background monitoring is successfully integrated.
Android Native
Android Native
PoiLabs Analysis SDK is a data analysis library. It provides data for analysing POI Beacons data.
You can download our SDK via Gradle with following below steps
- Add jitpack dependency to your project level build.gradle file with their tokens.
JITPACK_TOKEN is a token that PoiLabs will provide for you it will allow you to download our sdk.
repositories {
jcenter()
maven { url "https://jitpack.io"
credentials { username = 'JITPACK_TOKEN' }
}
} }
- Add PoiLabs Analysis SDK dependency to your app level build.gradle file
dependencies {
implementation 'com.github.poiteam:Android-Analysis-SDK:v3.11.4'
}
In order to our SDK can work properly we need location permission and bluetooth usage for scanning for beacons by following below steps you can implement these runtime permissions in your app
- Android Manifest file:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" android:foregroundServiceType="location"/>
- Asking for permissions on run time in kotlin language:
companion object {
private const val REQUEST_FOREGROUND_LOCATION_REQUEST_CODE = 56
private const val REQUEST_BACKGROUND_LOCATION_REQUEST_CODE = 57
private const val REQUEST_COARSE_LOCATION = 58
private const val REQUEST_BLUETOOTH_PERMISSION = 59
private const val TAG = "MainActivity"
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.main)
askRuntimePermissionsIfNeeded()
}
private fun askRuntimePermissionsIfNeeded() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // For Android 10 and above
val hasFineLocation: Int =
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
val hasBackgroundLocation: Int = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION)
if (hasFineLocation != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_FOREGROUND_LOCATION_REQUEST_CODE
)
}
if (hasBackgroundLocation != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
arrayOf(
Manifest.permission.ACCESS_BACKGROUND_LOCATION
),
REQUEST_BACKGROUND_LOCATION_REQUEST_CODE
)
}
} else { // For Android 9 and below
val hasLocalPermission: Int =
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
if (hasLocalPermission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.ACCESS_COARSE_LOCATION),
REQUEST_COARSE_LOCATION
)
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // For Android 12 and above
checkBluetoothPermission()
}
startScanIfPermissionsGranted()
}
@RequiresApi(Build.VERSION_CODES.S)
fun checkBluetoothPermission() {
val hasBluetoothPermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED
if (!hasBluetoothPermission) {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.BLUETOOTH_CONNECT, Manifest.permission.BLUETOOTH_SCAN),
REQUEST_BLUETOOTH_PERMISSION
)
}
startScanIfPermissionsGranted()
}
private fun startScanIfPermissionsGranted(): Boolean {
val hasLocalPermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED
val hasFineLocation = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { // Android 12 and above
val hasBackgroundLocation = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED
val hasBluetoothPermission = ActivityCompat.checkSelfPermission(this, Manifest.permission.BLUETOOTH_CONNECT) == PackageManager.PERMISSION_GRANTED
if (hasBluetoothPermission && hasFineLocation && hasBackgroundLocation) {
startPoiSdk()
return true
}
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { // Android 10 and above
val hasBackgroundLocation = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_BACKGROUND_LOCATION) == PackageManager.PERMISSION_GRANTED
if (hasFineLocation && hasBackgroundLocation) {
startPoiSdk()
return true
}
} else if (hasLocalPermission) { // Android 9 and below
startPoiSdk()
return true
}
return false
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<out String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (grantResults.isEmpty()) {
return
}
if (grantResults[0] == PackageManager.PERMISSION_GRANTED && !startScanIfPermissionsGranted()) {
askRuntimePermissionsIfNeeded()
}
}
private fun startPoiSdk() {
PoiAnalysis.getInstance().enable()
PoiAnalysis.getInstance().startScan(applicationContext)
}
-
Enable multi dex in your android project
https://developer.android.com/studio/build/multidex -
Minimum requirements
Supported Minimum Android |
---|
Android 4.3 (API level 18) |
After getting permissions you can now use PoiLabs Analysis SDK.
In this section we will introduce our SDK methods for you
In this class you provide your configuration settings for SDK to work. it's constructer take
"APPLICATION_ID", "APPLICATION_SECRET_KEY", "UNIQUE_ID" and they are mandatory
val poiAnalysisConfig = PoiAnalysisConfig("APPLICATION_ID", "APPLICATION_SECRET_KEY", "UNIQUE_ID")
setEnabled(true/false)
Takes a boolen as parameter and with this method you can enable or disable the SDK functionality in your app.
poiAnalysisConfig.setEnabled(ENABLE_SCAN)
setOpenSystemBluetooth(true/false)
Takes a boolen as parameter and with this method you can enable or disable the auto openning bluetooth SDK funcionality.
Using this method need request BLUETOOTH_CONNECT permission and without this permission, your app will crash on Android 12, Use this method with caution
poiAnalysisConfig.setOpenSystemBluetooth(OPEN_BLUETOOTH_AUTOMATICALLY)
setForegroundServiceIntent(Intent)
Takes a Intent object as parameter and with this method you should specify which activity should open when user clicks on the forground service notification.
poiAnalysisConfig.setForegroundServiceIntent(new Intent(this, YOUR_CLASS_TO_OPEN_ON_FOREGROUND_SERVICE_CLICK.class))
enableForegroundService()
If you call this method on the config object you are enabling SDK forground service functionality which will show a foreground service notification when app is in the background to scan for beacons.
poiAnalysisConfig.enableForegroundService()
setServiceNotificationTitle(String)
Takes a string as parameter and with this method you can specify the text on the foreground service notification.
poiAnalysisConfig.setServiceNotificationTitle(FORE_GROUND_SERVICE_NOTIFICATION_TITLE)
setForegroundServiceNotificationChannelProperties(String,String)
Takes two strings as parameter and with this method you can specify the foreground service notification channel title and description.
poiAnalysisConfig.setForegroundServiceNotificationChannelProperties(FORE_GROUND_SERVICE_NOTIFICATION_CHANNEL_NAME,FORE_GROUND_SERVICE_NOTIFICATION_CHANNEL_DESCRIPTION)
setForegroundServiceNotificationIconResourceId(Int)
Takes a drawable resource id as an integer and will show this drawable on foreground service notification small icon.
poiAnalysisConfig.setForegroundServiceNotificationIconResourceId(FORE_GROUND_SERVICE_NOTIFICATION_ICON)
With this singleton class you can access to SDK functions. On first access you should provide your app Context and an instance of PoiAnalysisConfig.
This First Access to this class should happen in your application class onCreate function otherwise SDK will not work properly.
PoiAnalysis.getInstance(this, config);
Once you called getInstance with these parameters you can call it without any parameter in your further usages.
For get callbacks from SDK you should implement PoiResponseCallback interface.
PoiResponseCallback
it has two methods:
-
onResponse(nodeId: String)
on this call back you can see the node id of detected beacon -
onFail(exception: Exception)
on this callback you can see the exception if any error has happened inside SDK.
After setting SDK up in your application class you can set this listener inside any class of your applicaiton
PoiAnalysis.getInstance().setPoiResponseListener(object : PoiResponseCallback { override fun onResponse(nodeIds: List<String>?) { TODO("Not yet implemented") }
override fun onFail(cause: Exception?) { TODO("Not yet implemented") }
})
As described in previous section after setting up in application class you can call the singleton class and start or stop SDK inside any class of your application.
Disclaimer: THE ANALYSIS SDK WILL BE WORK ONLY IF YOU START SCAN
PoiAnalysis.getInstance().enable(); PoiAnalysis.getInstance().startScan(getApplicationContext()); PoiAnalysis.getInstance().stopScan();
In case that your application has some user authentication after login, you should update the Unique Id in the SDK for getting a better classification, With the code snippet shown below you can achieve this.
PoiAnalysis.getInstance().updateUniqueId(NEW_UNIQUE_ID)
This method takes a string as parameter and after calling this method all beacon data will be stored with new unique id that you provided.
-printmapping out.map
-keepparameternames
-renamesourcefileattribute SourceFile
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,SourceFile,LineNumberTable,EnclosingMethod
# Preserve all annotations.
-keepattributes *Annotation*
# Preserve all public classes, and their public and protected fields and
# methods.
-keep public class * {
public protected *;}
# Preserve all .class method names.
-keepclassmembernames class * {
java.lang.Class class$(java.lang.String); java.lang.Class class$(java.lang.String, boolean);}
# Preserve all native method names and the names of their classes.
-keepclasseswithmembernames class * {
native <methods>;}
# Preserve the special static methods that are required in all enumeration
# classes.
-keepclassmembers class * extends java.lang.Enum {
public static **[] values(); public static ** valueOf(java.lang.String);}
# Explicitly preserve all serialization members. The Serializable interface
# is only a marker interface, so it wouldn't save them.
# You can comment this out if your library doesn't use serialization.
# If your code contains serializable classes that have to be backward
# compatible, please refer to the manual.
-keepclassmembers class * implements java.io.Serializable {
static final long serialVersionUID; static final java.io.ObjectStreamField[] serialPersistentFields; private void writeObject(java.io.ObjectOutputStream); private void readObject(java.io.ObjectInputStream); java.lang.Object writeReplace(); java.lang.Object readResolve();}
# Your library may contain more items that need to be preserved;
# typically classes that are dynamically created using Class.forName:
-keep public class getpoi.com.poibeaconsdk.PoiAnalysis
-keep public interface getpoi.com.poibeaconsdk.models.BeaconScanCallback
-keep public interface getpoi.com.poibeaconsdk.models.PoiResponseCallback
-keep class getpoi.com.poibeaconsdk.PoiScanner* { *; }
-keep class getpoi.com.poibeaconsdk.Models** { *; }
-keep class getpoi.com.poibeaconsdk.PoiAnalysis { *; }
-keep class getpoi.com.poibeaconsdk.models.** { *; }
-keep class getpoi.com.poibeaconsdk.models.PoiAnalysisConfig { *; }
-dontwarn getpoi.com.poibeaconsdk.**
-dontwarn com.poilabs.poiutil.**
- Why am I getting
failed to resolve
error in Gradle? - Will my app crash if user rejects permissions?
- Which permissions do app need for this SDK?
There could could be a number of reasons so we need to find the cause of this error. The first thing to check is if the jitpack token is correctly placed in your project.
To get more details run Gradle from command line with --info --refresh-dependencies flags. The output should contain a line “HTTP Could not get” with the full URL and HTTP Status Code.
Possible reasons:
- 404 - File not found. Build failed, tag does not exist or there is no such file in build artifacts.
- 401 - Unauthorized. No token was supplied.
- 403 - Forbidden. The token doesn’t have access to the Git repository.
If the error is unclear, feel free to contact Support.
the most common error code is 401 and it is because probably the jitpack token is not provided correctly. to check how to insert jitpack token click here.
Actually NO. Basically if you enable Analytics SDK in your application class if necessary permissions is not granted it basically freezes itself and The SDK will start working again in the next session of the application once the user grants the required permissions.
Basically to let the SDK work properly you need to get these permissions from user:
- Location Permission (Precise location)
- Background Location Permission
- BLUETOOTH_SCAN Permission
- BLUETOOTH_CONNECT Permission ( If you want to auto enable bluetooth)
- Push notification Permission ( If you want to enable foreground scan)
Note that it does not effect SDK in anyway that how you get these permissions. The samples in documentation are just samples. Feel free to get permissions however you want
React Native
React Native Implementation
To integrate PoilabsAnalysis into your Xcode project using CocoaPods, specify it in your Podfile.
pod 'PoilabsAnalysis'
To Integrate this framework you should add some features to your project info.plist file.
Privacy - Location Usage Description
Privacy - Location When In Use Usage Description
Privacy - Location Always Usage Description
Privacy - Location Always and When In Use Usage Description
You should create a header file called PoilabsAnalysisModule.h and a Objective-C file called PoilabsAnalysisModule.m with content below.
#ifndef PoilabsAnalysisModule_h
#define PoilabsAnalysisModule_h
#import "PoilabsAnalysis/PoilabsAnalysis.h"
#import <React/RCTBridgeModule.h>
@interface PoilabsAnalysisModule : NSObject <RCTBridgeModule, PLAnalysisManagerDelegate>
@end
#endif /* PoilabsAnalysisModule_h */
#import <Foundation/Foundation.h>
#import "PoilabsAnalysisModule.h"
@implementation PoilabsAnalysisModule
RCT_EXPORT_MODULE(PoilabsAnalysisModule);
RCT_EXPORT_METHOD(stopPoilabsAnalysis) {
[[PLAnalysisSettings sharedInstance] closeAllActions];
}
RCT_EXPORT_METHOD(startPoilabsAnalysis:(NSString *)applicationId applicationSecret:(NSString *) secret uniqueIdentifier:(NSString *) uniqueId) {
[[PLAnalysisSettings sharedInstance] setApplicationId:applicationId];
[[PLAnalysisSettings sharedInstance] setApplicationSecret:secret];
[[PLAnalysisSettings sharedInstance] setAnalysisUniqueIdentifier:uniqueId];
[[PLConfigManager sharedInstance] getReadyForTrackingWithCompletionHandler:^(PLError *error) {
if (error) {
NSLog(@"Error Desc %@",error.errorDescription);
}
else
{
[[PLSuspendedAnalysisManager sharedInstance] stopBeaconMonitoring];
[[PLStandardAnalysisManager sharedInstance] startBeaconMonitoring];
[[PLStandardAnalysisManager sharedInstance] setDelegate:self];
}
}];
}
-(void)analysisManagerDidFailWithPoiError:(PLError *)error
{
NSLog(@"Error Desc %@",error);
}
-(void)analysisManagerResponseForBeaconMonitoring:(NSDictionary *)response
{
NSLog(@"Response %@",response);
}
@end
#import "PoilabsAnalysis/PoilabsAnalysis.h"
To start suspended mode that allows track location when application is killed, you should call method below in didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
.....
if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey] && [UIApplication sharedApplication].applicationState == UIApplicationStateBackground) {
[[PLSuspendedAnalysisManager sharedInstance] startBeaconMonitoring];
}
.......
}
You can download our SDK via Gradle with following below steps
- Add jitpack dependency to your project level build.gradle file with their tokens.
JITPACK_TOKEN is a token that PoiLabs will provide for you it will allow you to download our sdk.
allprojects {
repositories {
maven {
url "https://jitpack.io"
credentials { username = 'JITPACK_TOKEN' }
}
}
}
- Add PoiLabs Analysis SDK dependency to your app level build.gradle file
dependencies {
implementation 'com.github.poiteam:Android-Analysis-SDK:v3.11.4'
}
- In order to our SDK can work properly we need location permission and bluetooth usage for scanning for beacons by following below steps you can implement these runtime permissions in your app
Android Manifest file
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" android:foregroundServiceType="location"/>
MainActivity
private var requestPermissionLauncher: ActivityResultLauncher<String> =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted ->
handleNextPermission()
}
fun setPermissionLaunchers() {
requestPermissionLauncher.launch(Manifest.permission.ACCESS_FINE_LOCATION)
}
fun handleNextPermission() {
when {
Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q && !isPermissionGranted(Manifest.permission.ACCESS_BACKGROUND_LOCATION) -> {
requestPermissionLauncher.launch(Manifest.permission.ACCESS_BACKGROUND_LOCATION)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !isPermissionGranted(Manifest.permission.BLUETOOTH_SCAN) -> {
requestPermissionLauncher.launch(Manifest.permission.BLUETOOTH_SCAN)
}
Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && !isPermissionGranted(Manifest.permission.BLUETOOTH_CONNECT) -> {
requestPermissionLauncher.launch(Manifest.permission.BLUETOOTH_CONNECT)
}
else -> {
startPoiSdk()
}
}
}
fun isPermissionGranted(permission: String): Boolean {
return ActivityCompat.checkSelfPermission(this, permission) == PackageManager.PERMISSION_GRANTED
}
fun startPoiSdk() {
PoiAnalysis.getInstance().enable()
PoiAnalysis.getInstance().startScan(applicationContext)
}
import android.content.pm.PackageManager
import android.os.Build
import androidx.core.app.ActivityCompat
import com.facebook.react.ReactActivity
import com.facebook.react.ReactActivityDelegate
import com.facebook.react.defaults.DefaultNewArchitectureEntryPoint.fabricEnabled
import com.facebook.react.defaults.DefaultReactActivityDelegate
import getpoi.com.poibeaconsdk.PoiAnalysis
import android.Manifest
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import android.content.Intent
import android.util.Log
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.bridge.ReactContextBaseJavaModule
import com.facebook.react.bridge.ReactMethod
import getpoi.com.poibeaconsdk.PoiAnalysis
import getpoi.com.poibeaconsdk.models.PoiAnalysisConfig
import getpoi.com.poibeaconsdk.models.PoiResponseCallback
class PoilabsAnalysisModule internal constructor(context: ReactApplicationContext?) :
ReactContextBaseJavaModule(context) {
override fun getName(): String {
return "PoilabsAnalysisModule"
}
@ReactMethod
fun startPoilabsAnalysis(applicationId: String, applicationSecret: String, uniqueIdentifier: String) {
currentActivity?.let { activity ->
val poiAnalysisConfig = PoiAnalysisConfig(applicationId, applicationSecret, uniqueIdentifier)
PoiAnalysis.getInstance(activity.applicationContext, poiAnalysisConfig)
poiAnalysisConfig.setForegroundServiceIntent(Intent(activity.applicationContext, MainActivity::class.java))
poiAnalysisConfig.setServiceNotificationTitle("Test1")
poiAnalysisConfig.setForegroundServiceNotificationChannelProperties("name1" , "desc1")
poiAnalysisConfig.enableForegroundService()
PoiAnalysis.getInstance().setPoiResponseListener(object : PoiResponseCallback {
override fun onResponse(nodeIds: List<String>?) {
}
override fun onFail(cause: Exception?) {
}
})
(activity as MainActivity).setPermissionLaunchers()
}
}
@ReactMethod
fun stopPoilabsAnalysis() {
PoiAnalysis.getInstance().stopScan()
}
}
import com.facebook.react.ReactPackage
import com.facebook.react.bridge.NativeModule
import com.facebook.react.bridge.ReactApplicationContext
import com.facebook.react.uimanager.ViewManager
class PoilabsPackage : ReactPackage {
override fun createNativeModules(reactApplicationContext: ReactApplicationContext): List<NativeModule> {
val modules: MutableList<NativeModule> = ArrayList()
modules.add(PoilabsAnalysisModule(reactApplicationContext))
return modules
}
override fun createViewManagers(reactApplicationContext: ReactApplicationContext): List<ViewManager<*, *>> {
return emptyList();
}
}
override fun getPackages(): List<ReactPackage> =
PackageList(this).packages.apply {
add(PoilabsPackage())
}
You should import NativeModules
import {
NativeModules,
} from 'react-native';
You can start PoilabsAnalysis with calling bridge method
NativeModules.PoilabsAnalysisModule.startPoilabsAnalysis(APPLICATION_ID, APPLICATION_SECRET, UNIQUE_ID);
You can stop PoilabsAnalysis with calling bridge method
NativeModules.PoilabsAnalysisModule.stopPoilabsAnalysis;
Important Information on Store Submission
For AppStore (iOS)
You have to explain why you need the collect location. Sample info is provided below.
XXXXX is a retailer with more than 30 stores across Turkey. The mobile application is designed to inform users about promotions and also provide shopping list creation when they are not in the store. By using ibeacon technology we are planning to create a better customer experience in the store, show them related offers specific to that place, send surveys about their visits, and also gamification features to motivate users to visit our stores.
Sometime AppStore requires additional information and answers to questions. You can find the additional answers;
– How frequently is the users’ location collected?
The app uses a beacon region monitoring feature. The app searches for beacons that have our UUID and if there is no such beacon the location is not collected. We use beacons inside our stores across Turkey. Location collection is limited in those places. The location is generally collected every 30 seconds in the store. When the user leaves the store the location collection is stopped since the location collection depends on the beacons inside the stores.
– Can the users see their location in the app?
Yes, they can see their location as a bluedot inside the store. They can get navigation to products or categories.
– Can the users see the locations they have been in the app?
Since the app only collects locations in-store and in-mall the user does not see his/her locations.
– Does this app track and show users’ distance traveled in the app?
No.
– What are the specific persistent background location features that cannot be attained by significant-change location service or the region monitoring location service?
The user’s location is only collected when they are in the beacon range and the beacons are installed in our stores and in some malls. Since we use beacons we must use persistent background location otherwise users can not get in-store notifications about the stores, offers, welcome messages, and surveys. We will also introduce limited-time offers when a user enters the stores.
Additionally, what features in the app require persistent location updates while the app is in the background? Please provide us with detailed steps to locate this feature within your app. The app uses ibeacon signals to provide location-based offers inside the stores. Users can not locate the feature in the app since the user only sees the nearby offers and also get notification related to their location. But they can use the indoor navigation feature to see their location inside the store.
For Google Play Store (Android)
Firstly you need to prepare additional notifications while you are asking the location permission. Then you need the take a screen recording showing all the requirements.
You can also check Google Play guide: https://support.google.com/googleplay/android-developer/answer/9799150?hl=en#zippy=
Sample Video:
XXXXX is a retailer with more than 30 stores across Turkey. The mobile application is designed to inform users about promotions and also provide shopping list creation when they are not in the store. By using ibeacon technology we are planning to create a better customer experience in the store, show them related offers specific to that place, send surveys about their visits and also gamification features to motivate users to visit our supermarkets
In the application, the following feature requires background location and it is crucial for the users.
- – Real time location based offers. When a user pass by a store inside , they can learn the offers and get promotions in real time.
- – Indoor navigation inside the store. The users can get navigation to products or categories.
- – The user can create a shopping list and get a optimum route to collect the items.
Privacy Policy must include why you use the location and must be updated.
Sample information that should be added to the privacy policy.
“Genel veya size özel kişiselleştirilmiş kampanyalar, avantajlar, promosyonlar, reklamların oluşturulması ve sağlanması, segmentasyon ve pazarlama analiz çalışmalarının yapılması, lokasyon paylaşımına yapılacak tercihe göre (her zaman kullanım/uygulama açıkken kullanım/tek seferlik kullanım) izin verilmesi halinde tercihinize göre lokasyon bilgisi, bluetooth özelliğinin açık olması halinde beacon (yer belirleyici) cihazları aracılığıyla tespit edilen lokasyon bilgisi, lokasyon bilgisi kaydedilerek oluşturulacak teklifler için bilgileriniz kullanılmaktadır. “