BookmarkSubscribeRSS Feed
LucasAcuna
Calcite | Level 5

Hi, I’m integrating CI360 SDK in React Native, specifically the android part, and when I launch de app locally everything seems to work fine. I can see the spot, I receive notifications, etc. But when I create an APK I got the following logs in Android Studio:

Captura de pantalla 2023-03-28 a la(s) 17.54.30.png

The SDK seems to not be able to send events to the tenant.

I’m not sure why this behavior is happening in the APK. If I analyze the APK with Android Studio and I’ve got:

 

Captura de pantalla 2023-03-27 a la(s) 17.38.20.png

 

As you can see the location of SASCollector.properties is different from the others files.properties in the APK.

 

Can this difference in locations affect the sending of events to the tenant?

 

I followed the steps provided in the official React Native SAS Cookbook.

 

Thank you in advance!

PD: Sorry for my English level, I’m still learning the language.

14 REPLIES 14
wwen
SAS Employee

Hi @LucasAcuna  Thank you for reporting the issue. We will look at what is causing it and getting back to you when we find out.

wwen
SAS Employee

Hi @LucasAcuna I did a release build, and then installed the release APK on a simulator. I can still get all the functionalities. I didn't have the issue that you had. I wonder if you created a release APK? If it is a debug APK, then you need to have Metro running first. Here is my release APK structure.

Screenshot 2023-04-03 at 8.49.10 AM.png

wwen
SAS Employee

@LucasAcuna I see that your APK is also a release APK. So that is not the issue. But from your log, I can see "Session not yet established, deferring...". That indicates a problem. Can you get the log at the start of running your app? That may contain information on why initialization was not successful. You can look for information such as:
1. Context is null, unable to initialize.

2. Mobile spots not supported on Android OS version: ...

3. Context is neither Application nor Activity, unable to initialize

4. SASCollector SDK failed to initialize: App does not have internet permissions.

5. GSON Parsing library not available, please include it in your project dependencies.

6. Unable to load SASCollector.properties configuration file.

7. Error initializing SASCollector: (your app name)  (error message)

There may be other initialization errors in log.

 

 

A successful initialization will have a log like this:


2023-04-05 08:42:41.804 9762-9762/? I/SASCollector::SASCOLLECTOR_API: initialize: [ com.mobile_sdk_test.MainApplication@841b58b]
2023-04-05 08:42:41.804 9762-9762/? D/SASCollector::SASCollector: SASCollector initializing (com.mobile_sdk_test.MainApplication@841b58b)
2023-04-05 08:42:41.805 9762-9762/? D/SASCollector::AppEnvironment: AppEnvironment initialized. Internet=true Location=false PlayServices=true SDKIntentService=true
2023-04-05 08:42:41.822 9762-9762/? I/SASCollector::SASCollector: Loading configuration from assets/SASCollector.properties
2023-04-05 08:42:41.822 9762-9762/? I/SASCollector::SASCollector: Properties (3):
2023-04-05 08:42:41.822 9762-9762/? I/SASCollector::SASCollector: application.id=react_native_test_sdk
2023-04-05 08:42:41.822 9762-9762/? I/SASCollector::SASCollector: tenant.id=5f301a8a070001019cc023d7
2023-04-05 08:42:41.822 9762-9762/? I/SASCollector::SASCollector: tag.server=https://eventsingest-dev.cidev.sas.us/t/mobile
2023-04-05 08:42:41.823 9762-9762/? D/SASCollector::SASCollector: DeviceID from SharedPreferences: c8550524-8ecc-4e6a-bf7a-a733e2149fd3
2023-04-05 08:42:41.823 9762-9762/? D/SASCollector::SASCollector: DeviceID seed is c8d3
2023-04-05 08:42:41.827 9762-9762/? D/SASCollector::SASCollector: SASCollector initialized.

 

LucasAcuna
Calcite | Level 5

Hi @wwen, thank you for you answer! Sorry for the delay in answering! Yes the apk was built in release mode. I’ll take a look to the logs in Android Studio when the app starts, maybe I’m doing the sdk initialization in the wrong place.

If I’ve got another problem I’ll let you know.

I’ll notify you if I solve the problem.

 

Thank you for your time.

LucasAcuna
Calcite | Level 5

Hi @wwen 

I was doing some test with my apk and the logs I got in Android Studio when the app starts are:

 

I/SASCollector::SASCOLLECTOR_API: setPushNotificationChannelId: [ ReactNativePushChannel2]
W/SASCollector::e: SASCollector is not initialized, unable to set push notificiation channel.
I/SASCollector::SASCOLLECTOR_API: setMobileMessagingDelegate2: [ com.services.movistar.ar.MainActivity$a@40e09fe]
I/SASCollector::SASCOLLECTOR_API: initialize: [ com.services.movistar.ar.MainApplication@f1c9521]
D/SASCollector::e: SASCollector initializing (com.services.movistar.ar.MainApplication@f1c9521)
D/SASCollector::b: AppEnvironment initialized.  Internet=true Location=false PlayServices=true SDKIntentService=true
I/SASCollector::e: Loading configuration from assets/SASCollector.properties
I/SASCollector::e: Properties (3):
I/SASCollector::e: application.id=Test.AppMobile.Desa
I/SASCollector::e: tenant.id=a8a352b2d200011483d50aec
I/SASCollector::e: tag.server=https://execution-ci360.nop.movistar.com.ar/t/mobile
D/SASCollector::e: Generated new device ID: d96f8fd5-0614-4de4-8d9c-a6385d8c06e4
D/SASCollector::e: DeviceID seed is d9e4
D/SASCollector::e: SASCollector initialized.
D/SASCollector::k: Executing e.u.b.a.a.p.c
D/SASCollector::a: Event Manager is running.
D/SASCollector::b: Using base server URL: https://execution-ci360.nop.movistar.com.ar/t/mobile
D/SASCollector::b: Resolving host execution-ci360.nop.movistar.com.ar
D/SASCollector::c: Begin remote image cleanup...
D/SASCollector::c: Remote image dir does not exist: /data/user/0/com.services.movistar.ar.integration/cache/sas/remote_files
D/SASCollector::c: Cleanup completed.  Deleted 0
D/SASCollector::a: Activity destroyed: com.zoontek.rnbootsplash.RNBootSplashActivity
D/SASCollector::b: Resolved to 13.227.83.19
D/SASCollector::a: Server is available.
D/SASCollector::a: Buffer was empty.
D/SASCollector::a: Events data source is open with 1 connections.
D/SASCollector::a: Retrieved 0 recent events.
D/SASCollector::a: All events are deleted.
D/SASCollector::a: Events data source is closed.
D/SASCollector::a: Pulled 0 from DB
D/SASCollector::a: No more events to send, entering deep sleep.
I/SASCollector::SASCOLLECTOR_API: registerForMobileMessages: [ ee4XOdJDQRWKuJIV3vfhvT:APA91bGbIvbI0F95Jhg2wH9wpqKsp5Du_ISzuR1-EHmx5kkPTEbO3qIl8zd0ojzcrfKFxJvcPOmyUgB9quwLGSRtZIeqq0u-kjh3Z0AnWSSEMliYhvylfGEWR-9l6GUSjfS66VQN8A0s]
D/SASCollector::k: Executing e.u.b.a.a.p.l
D/SASCollector::l: Sending token ee4XOdJDQRWKuJIV3vfhvT:APA91bGbIvbI0F95Jhg2wH9wpqKsp5Du_ISzuR1-EHmx5kkPTEbO3qIl8zd0ojzcrfKFxJvcPOmyUgB9quwLGSRtZIeqq0u-kjh3Z0AnWSSEMliYhvylfGEWR-9l6GUSjfS66VQN8A0s for device d96f8fd5-0614-4de4-8d9c-a6385d8c06e4
D/SASCollector::b: Outbound request: PUT https://execution-ci360.nop.movistar.com.ar/t/mobile/tokens/a8a352b2d200011483d50aec/d96f8fd5-0614-4de4-8d9c-a6385d8c06e4
D/SASCollector::b: JSON data for e.u.b.a.a.j.l : {"a":"d96f8fd5-0614-4de4-8d9c-a6385d8c06e4","b":"Android-ee4XOdJDQRWKuJIV3vfhvT:APA91bGbIvbI0F95Jhg2wH9wpqKsp5Du_ISzuR1-EHmx5kkPTEbO3qIl8zd0ojzcrfKFxJvcPOmyUgB9quwLGSRtZIeqq0u-kjh3Z0AnWSSEMliYhvylfGEWR-9l6GUSjfS66VQN8A0s","c":"Test.AppMobile.Desa"}
D/SASCollector::b: Content-Length: 248
E/SASCollector::NEW_TOKEN: ee4XOdJDQRWKuJIV3vfhvT:APA91bGbIvbI0F95Jhg2wH9wpqKsp5Du_ISzuR1-EHmx5kkPTEbO3qIl8zd0ojzcrfKFxJvcPOmyUgB9quwLGSRtZIeqq0u-kjh3Z0AnWSSEMliYhvylfGEWR-9l6GUSjfS66VQN8A0s
I/SASCollector::SASCOLLECTOR_API: registerForMobileMessages: [ ee4XOdJDQRWKuJIV3vfhvT:APA91bGbIvbI0F95Jhg2wH9wpqKsp5Du_ISzuR1-EHmx5kkPTEbO3qIl8zd0ojzcrfKFxJvcPOmyUgB9quwLGSRtZIeqq0u-kjh3Z0AnWSSEMliYhvylfGEWR-9l6GUSjfS66VQN8A0s]
D/SASCollector::k: Executing e.u.b.a.a.p.l
D/SASCollector::a: Activity paused: com.services.movistar.ar.MainActivity
D/SASCollector::b: Response Code: 400
D/SASCollector::b: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/tokens/a8a352b2d200011483d50aec/d96f8fd5-0614-4de4-8d9c-a6385d8c06e4 AWSALB=vg0NF//ygR/IWXZX8hlvJjvU1M512fUHKpLMWE9kQWOjmgbcbC41j49c+CszMoGwaUFDRsXszfBvlNUcLHN5T9mDYehv7uCvdZIAZisU8LsuO93nBUq9PcZ5+ehD; Expires=Fri, 21 Apr 2023 13:22:15 GMT; Path=/
D/SASCollector::b: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/tokens/a8a352b2d200011483d50aec/d96f8fd5-0614-4de4-8d9c-a6385d8c06e4 AWSALBCORS=vg0NF//ygR/IWXZX8hlvJjvU1M512fUHKpLMWE9kQWOjmgbcbC41j49c+CszMoGwaUFDRsXszfBvlNUcLHN5T9mDYehv7uCvdZIAZisU8LsuO93nBUq9PcZ5+ehD; Expires=Fri, 21 Apr 2023 13:22:15 GMT; Path=/; SameSite=None; Secure
E/SASCollector::b: Unexpected status code from server: 400
2023-04-14 10:22:15.101 14652-14848/com.services.movistar.ar.integration D/SASCollector::l: Sending token ee4XOdJDQRWKuJIV3vfhvT:APA91bGbIvbI0F95Jhg2wH9wpqKsp5Du_ISzuR1-EHmx5kkPTEbO3qIl8zd0ojzcrfKFxJvcPOmyUgB9quwLGSRtZIeqq0u-kjh3Z0AnWSSEMliYhvylfGEWR-9l6GUSjfS66VQN8A0s for device d96f8fd5-0614-4de4-8d9c-a6385d8c06e4
D/SASCollector::b: Outbound request: PUT https://execution-ci360.nop.movistar.com.ar/t/mobile/tokens/a8a352b2d200011483d50aec/d96f8fd5-0614-4de4-8d9c-a6385d8c06e4
D/SASCollector::b: JSON data for e.u.b.a.a.j.l : {"a":"d96f8fd5-0614-4de4-8d9c-a6385d8c06e4","b":"Android-ee4XOdJDQRWKuJIV3vfhvT:APA91bGbIvbI0F95Jhg2wH9wpqKsp5Du_ISzuR1-EHmx5kkPTEbO3qIl8zd0ojzcrfKFxJvcPOmyUgB9quwLGSRtZIeqq0u-kjh3Z0AnWSSEMliYhvylfGEWR-9l6GUSjfS66VQN8A0s","c":"Test.AppMobile.Desa"}
D/SASCollector::b: Content-Length: 248
D/SASCollector::b: Response Code: 400
D/SASCollector::b: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/tokens/a8a352b2d200011483d50aec/d96f8fd5-0614-4de4-8d9c-a6385d8c06e4 AWSALB=qR+cN+C5Wqe3Yx52jJDkTsTQP+GdI993fhVqhGbn8vteEBldecZyJptRIq/L4tHa2lLfhk2D/0rOOZ6N/5Ic9FpdrwXs6CHFpV/e9MsT1gxiIgMFJOYvfqVQXnrn; Expires=Fri, 21 Apr 2023 13:22:16 GMT; Path=/
D/SASCollector::b: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/tokens/a8a352b2d200011483d50aec/d96f8fd5-0614-4de4-8d9c-a6385d8c06e4 AWSALBCORS=qR+cN+C5Wqe3Yx52jJDkTsTQP+GdI993fhVqhGbn8vteEBldecZyJptRIq/L4tHa2lLfhk2D/0rOOZ6N/5Ic9FpdrwXs6CHFpV/e9MsT1gxiIgMFJOYvfqVQXnrn; Expires=Fri, 21 Apr 2023 13:22:16 GMT; Path=/; SameSite=None; Secure
E/SASCollector::b: Unexpected status code from server: 400
D/SASCollector::a: Activity resumed: com.services.movistar.ar.MainActivity

If I filter the android studio logs by the key word "initialized" I got:

 

I/FA: App measurement initialized, version: 42004 
W/SASCollector::e: SASCollector is not initialized, unable to set push notificiation channel.
I/RNFusedLocation: RNFusedLocation initialized
D/SASCollector::b: AppEnvironment initialized. Internet=true Location=false PlayServices=true SDKIntentService=true
D/SASCollector::e: SASCollector initialized.
W/Adjust: Adjust not initialized, can't perform onResume
W/SASCollector::e: SASCollector is not initialized, ignoring request to start location monitoring.
W/SASCollector::e: SASCollector is not initialized, discarding events
W/SASCollector::e: SASCollector is not initialized, discarding events
W/SASCollector::SASCollectorAd: SASCollector is not initialized, unable to load spot.
W/SASCollector::SASCollectorInterstitialAd: SASCollector is not initialized, unable to load spot.
W/SASCollector::e: SASCollector is not initialized, discarding events

As you can see, at first SASCollector is initialized, then SASCollector in not initialized and after that SASCollector is not initialized again.

wwen
SAS Employee

Hi @LucasAcuna  I suspect that something went wrong with your internet? Can you please check if there are logs like these:

1. SSLException (“error”) in HTTPS comms: msg

2. Error in background task: msg

In above logs, error and msg are placeholders. If you did see one or both logs, then that explains why SASCollector was shut down and was set back to uninitialized.

 

In addition, I also saw that registerForMobileMessages returned a 400 error. You can check the token to see if it is valid or anything else that could cause this.

What more I found in your first screenshot is that you tried to set push notification channel before SASCollector was initialized. Can you please make sure that you do it after initialization?

 

LucasAcuna
Calcite | Level 5

Hi @wwen , I did some test in the release apk and I wasn't able to find any error related to "SSLException" and "Error in background task". I also changed the set up of push notifications after the SDK initialization as you mentioned. 

 

In addition I also did another tests in order to try to find out whats happening with my apk. I create a debug apk and everything works fine, and its folder structure include:

Captura de pantalla 2023-04-17 a la(s) 16.20.51.png

As you can see in the path com.sas.mkt.mobile.sdk it has got the SASCollector module.

If I build an apk in release mode and inspect its content I'm not able to find the SASCollector module:

Captura de pantalla 2023-04-17 a la(s) 16.23.53.png

I'm not sure why this is happening in release mode, we have no problem with another SDKs in the app. 

Do you think you need information on how I made the configuration of the SDK in the app? Maybe I did some mistakes.

 

Thank you!

wwen
SAS Employee

Hi @LucasAcuna , I took a look at my release and debug APKs. I don't have any of the java classes. In fact, there are no java classes even in other libraries like okhttp3. If I build a native Android APK (not React Native), there won't be any java classes either. Most are just .properties, or image files (png), or other resource files. Please see my screenshots below. As you can see, there's no difference in the files under com.sas between debug and release APKs. I used Android Studio to create the APKs. How did you create your APKs?

 

If possible, could you please provide a full list of the logs for debugging? Yes, your configuration of the SDK is helpful too.

 

 

Screenshot 2023-04-18 at 9.17.07 AM.png


Screenshot 2023-04-18 at 9.13.30 AM.png

LucasAcuna
Calcite | Level 5

Hi @wwen , I saw inside of my apk in release mode and in the root directory I also have got a folder called com, and inside of it there is practically the same content that you show me before (red and yellow rectangles):

Captura de pantalla 2023-04-18 a la(s) 14.00.49.png

But also I have (in the root directory) a .dex file in my case called classes2.dex (green rectangle). Inside of it there are some files and folders. One of these folders is com, and it contains the sas folder with the SDK dependencies. In this folder I couldn't find the SASCollector class that allows the app initialize the apk. In the path com/sas/mkt/mobile/sdk there is no SASCollector module, so I think (I'm not sure) that when the MainApplication.java run this import:

 

import com.sas.mkt.mobile.sdk.SASCollector;

 it isn't able to processing it correctly.

 

In the debug apk the SASCollector class is inside of the path described above.

 

When the apk in debug mode starts the app logs are:

 

 

I/SASCollector::SASCOLLECTOR_API: initialize: [ com.services.movistar.ar.MainApplication@9de060e]
D/SASCollector::SASCollector: SASCollector initializing (com.services.movistar.ar.MainApplication@9de060e)
D/SASCollector::AppEnvironment: AppEnvironment initialized.  Internet=true Location=false PlayServices=true SDKIntentService=true
I/SASCollector::SASCollector: Loading configuration from assets/SASCollector.properties
I/SASCollector::SASCollector: Properties (3):
I/SASCollector::SASCollector: application.id=Test.AppMobile.Desa
I/SASCollector::SASCollector: tenant.id=a8a352b2d200011483d50aec
I/SASCollector::SASCollector: tag.server=https://execution-ci360.nop.movistar.com.ar/t/mobile
D/SASCollector::SASCollector: DeviceID from SharedPreferences: 10ac7910-69b2-4077-bcc4-e31d21464843
D/SASCollector::SASCollector: DeviceID seed is 1043
D/SASCollector::OfflineEventManager: Event Manager is running.
D/SASCollector::SASCollector: SASCollector initialized.
D/SASCollector::SASCollectorExecutor: Executing com.sas.mkt.mobile.sdk.tasks.CleanRemoteImagesTask
D/SASCollector::CleanRemoteImagesTask: Begin remote image cleanup...
D/SASCollector::CleanRemoteImagesTask: Remote image dir does not exist: /data/user/0/com.services.movistar.ar.integration/cache/sas/remote_files
D/SASCollector::CleanRemoteImagesTask: Cleanup completed.  Deleted 0
D/SASCollector::MidtierServices: Using base server URL: https://execution-ci360.nop.movistar.com.ar/t/mobile
D/SASCollector::MidtierServices: Resolving host execution-ci360.nop.movistar.com.ar
I/SASCollector::SASCOLLECTOR_API: setPushNotificationChannelId: [ ReactNativePushChannel2]
D/SASCollector::ActivityLifecycleListener: Activity created: com.zoontek.rnbootsplash.RNBootSplashActivity
D/SASCollector::MidtierServices: Resolved to 3.160.119.101
D/SASCollector::OfflineEventManager: Server is available.
D/SASCollector::OfflineEventManager: Buffer was empty.
D/SASCollector::EventsDataSource: Events data source is open with 1 connections.
D/SASCollector::EventsDataSource: Retrieved 0 recent events.
D/SASCollector::ActivityLifecycleListener: Activity created: com.services.movistar.ar.MainActivity
D/SASCollector::EventsDataSource: All events are deleted.
D/SASCollector::EventsDataSource: Events data source is closed.
D/SASCollector::OfflineEventManager: Pulled 0 from DB
I/SASCollector::SASCOLLECTOR_API: setMobileMessagingDelegate2: [ com.services.movistar.ar.MainActivity$1@be5e863]
D/SASCollector::ActivityLifecycleListener: Activity started: com.services.movistar.ar.MainActivity
D/SASCollector::SASCollectorExecutor: Executing com.sas.mkt.mobile.sdk.tasks.QueueEventTask
D/SASCollector::ActivityLifecycleListener: Foreground counter : 1
D/SASCollector::QueueEventTask: Queuing event: focus
D/SASCollector::OfflineEventManager: Session timed out.
D/SASCollector::OfflineEventManager: Session indicator is NONE
D/SASCollector::OfflineEventManager: Starting new session. 1681838104797 1681838104797 120000 600000 null 10ac7910-69b2-4077-bcc4-e31d21464843
I/SASCollector::DeviceAndApplicationInfoHelper: SDK Version: 1.79.0
D/SASCollector::ActivityLifecycleListener: Activity resumed: com.services.movistar.ar.MainActivity
D/SASCollector::OfflineEventManager: Adding event (focus) to buffer.
I/SASCollector::SASCOLLECTOR_API: registerForMobileMessages: [ cHQg-UXURzuV2F6M1Rekv7:APA91bG_RY3-BTYAJwyjwJXgkk3wU45Ld1LEw1vADw-n1Z47jRGYrfnLM5osqGuX-dPuSErdp3zfxW9H5W-DWVm2qqY6tGXDd_euNW83LMfcIBaFEto57vIZxmrkOOZQUWs8mYozbS-x]
D/SASCollector::SASCollectorExecutor: Executing com.sas.mkt.mobile.sdk.tasks.UpdateToken
D/SASCollector::UpdateToken: Sending token cHQg-UXURzuV2F6M1Rekv7:APA91bG_RY3-BTYAJwyjwJXgkk3wU45Ld1LEw1vADw-n1Z47jRGYrfnLM5osqGuX-dPuSErdp3zfxW9H5W-DWVm2qqY6tGXDd_euNW83LMfcIBaFEto57vIZxmrkOOZQUWs8mYozbS-x for device 10ac7910-69b2-4077-bcc4-e31d21464843
D/SASCollector::MidtierServices: Outbound request: PUT https://execution-ci360.nop.movistar.com.ar/t/mobile/tokens/a8a352b2d200011483d50aec/10ac7910-69b2-4077-bcc4-e31d21464843
D/SASCollector::MidtierServices: JSON data for com.sas.mkt.mobile.sdk.domain.TokenData : {"appId":"Test.AppMobile.Desa","deviceId":"10ac7910-69b2-4077-bcc4-e31d21464843","token":"Android-cHQg-UXURzuV2F6M1Rekv7:APA91bG_RY3-BTYAJwyjwJXgkk3wU45Ld1LEw1vADw-n1Z47jRGYrfnLM5osqGuX-dPuSErdp3zfxW9H5W-DWVm2qqY6tGXDd_euNW83LMfcIBaFEto57vIZxmrkOOZQUWs8mYozbS-x"}
D/SASCollector::MidtierServices: Content-Length: 263
D/SASCollector::ActivityLifecycleListener: Activity destroyed: com.zoontek.rnbootsplash.RNBootSplashActivity
D/SASCollector::MidtierServices: Using base server URL: https://execution-ci360.nop.movistar.com.ar/t/mobile
D/SASCollector::MidtierServices: Resolving host execution-ci360.nop.movistar.com.ar
D/SASCollector::MidtierServices: Resolved to 3.160.119.101
D/SASCollector::OfflineEventManager: Server is available.
D/SASCollector::OfflineEventManager: Flushing 1 buffered events.
D/SASCollector::PostEventsTask: PostEventsTask created.
D/SASCollector::SASCollectorExecutor: Executing com.sas.mkt.mobile.sdk.tasks.PostEventsTask
D/SASCollector::OfflineEventManager: DB is clean.
D/SASCollector::MidtierServices: Response Code: 200
D/SASCollector::MidtierServices: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/tokens/a8a352b2d200011483d50aec/10ac7910-69b2-4077-bcc4-e31d21464843 AWSALB=1vctTBA00OZyjzL/VMZpdmbKK6G//Fz6Nqa+UGIgAk90n1n0s1ZbkUnQEpvOAxA/BqzqXZB7k2FUyP8+l9c/hcpjLXbmvJGbm18DLYxW8glk3wgIalM95CuMYFlXOuQnfPoqu/RtnJVNS4tWF1qrZXEEb1Ds75Lr0wp6w0MIWZxstyXempEas4JMFoMD0w==; Expires=Tue, 25 Apr 2023 17:15:05 GMT; Path=/
D/SASCollector::MidtierServices: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/tokens/a8a352b2d200011483d50aec/10ac7910-69b2-4077-bcc4-e31d21464843 AWSALBCORS=1vctTBA00OZyjzL/VMZpdmbKK6G//Fz6Nqa+UGIgAk90n1n0s1ZbkUnQEpvOAxA/BqzqXZB7k2FUyP8+l9c/hcpjLXbmvJGbm18DLYxW8glk3wgIalM95CuMYFlXOuQnfPoqu/RtnJVNS4tWF1qrZXEEb1Ds75Lr0wp6w0MIWZxstyXempEas4JMFoMD0w==; Expires=Tue, 25 Apr 2023 17:15:05 GMT; Path=/; SameSite=None; Secure
D/SASCollector::MidtierServices: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/tokens/a8a352b2d200011483d50aec/10ac7910-69b2-4077-bcc4-e31d21464843 _SI_M_DID.a8a352b2d200011483d50aec=f67c9ea7-ae5f-3422-9653-7ddb686bd5a2; Path=/t/mobile; Secure; HttpOnly; SameSite=None
D/SASCollector::PostEventsTask: Execute PostEventsTask.
D/SASCollector::PostEventsTask: Posting 1 events for CSI: 1681838104798
D/SASCollector::MidtierServices: Outbound request: POST https://execution-ci360.nop.movistar.com.ar/t/mobile/e/a8a352b2d200011483d50aec
D/SASCollector::MidtierServices: JSON data for com.sas.mkt.mobile.sdk.domain.EventList : [{"appId":"Test.AppMobile.Desa","csi":1681838104798,"deviceId":"10ac7910-69b2-4077-bcc4-e31d21464843","eventAttributes":{"mobile_device_model":"Android SDK built for arm64","mobile_device_language":"en","mobile_sdk_version":"1.79.0","mobile_screen_height":"2872","mobile_platform":"Android","mobile_carrier_name":"Android","flags":"ns|nl","mobile_country_code":"310","uri":"Test.AppMobile.Desa/","visitor_state":"returning","mobile_platform_version":"10","mobile_device_type":"phone","mobile_screen_width":"1440","mobile_app_version":"412110700","mobile_device_mfg":"Google","mobile_network_code":"260","mobile_app_language":"en"},"eventDateTime":"2023-04-18T17:15:04.797Z","eventType":"focus","loadId":"b24e0324441043661a7c40a9"}]
D/SASCollector::MidtierServices: Content-Length: 731
D/SASCollector::MidtierServices: Response Code: 200
D/SASCollector::MidtierServices: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/e/a8a352b2d200011483d50aec AWSALB=bcrfQ7EJraIc96DfxRBVe9K9P33AeLHKa71LK6uhcjioIga2+O2LnVJyud5ANzLbNxtTJMAdlrRglt4viwGm6cTcsbbyKHFFNojEvpYNmnOV3utgktBw9nCST0rLQ2Vk7QzvWQB2CW6kNte+u8tcNCHrVR7FK3bPfV5ilink6fXA3IH8XH+KiLWF9OIJ1Q==; Expires=Tue, 25 Apr 2023 17:15:05 GMT; Path=/
D/SASCollector::MidtierServices: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/e/a8a352b2d200011483d50aec AWSALBCORS=bcrfQ7EJraIc96DfxRBVe9K9P33AeLHKa71LK6uhcjioIga2+O2LnVJyud5ANzLbNxtTJMAdlrRglt4viwGm6cTcsbbyKHFFNojEvpYNmnOV3utgktBw9nCST0rLQ2Vk7QzvWQB2CW6kNte+u8tcNCHrVR7FK3bPfV5ilink6fXA3IH8XH+KiLWF9OIJ1Q==; Expires=Tue, 25 Apr 2023 17:15:05 GMT; Path=/; SameSite=None; Secure
D/SASCollector::MidtierServices: Part _SI_M_SID=69a9dd7a6dfb2a5fb0b9c805.30.720 2
D/SASCollector::MidtierServices: Subpart 69a9dd7a6dfb2a5fb0b9c805.30.720 3
D/SASCollector::MidtierServices: Timeout update session: 1800000 max: 43200000
D/SASCollector::MidtierServices: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/e/a8a352b2d200011483d50aec _SI_M_SID=69a9dd7a6dfb2a5fb0b9c805.30.720; Max-Age=1800; Expires=Tue, 18 Apr 2023 17:45:05 GMT; Path=/; Secure; HttpOnly
D/SASCollector::MidtierServices: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/e/a8a352b2d200011483d50aec _SI_M_VID=10ac791069b24077bcc4e31d21464843; Max-Age=1800; Expires=Tue, 18 Apr 2023 17:45:05 GMT; Path=/; Secure; HttpOnly
D/SASCollector::MidtierServices: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/e/a8a352b2d200011483d50aec _SI_M_DLT=893; Max-Age=1800; Expires=Tue, 18 Apr 2023 17:45:05 GMT; Path=/; Secure; HttpOnly
D/SASCollector::MidtierServices: Setting cookie https://execution-ci360.nop.movistar.com.ar/t/mobile/e/a8a352b2d200011483d50aec _SI_M_DID.a8a352b2d200011483d50aec=f67c9ea7-ae5f-3422-9653-7ddb686bd5a2; Path=/t/mobile; Secure; HttpOnly
D/SASCollector::OfflineEventManager: 1 Events successfully posted.
D/SASCollector::OfflineEventManager: No more events to send, entering deep sleep.
D/SASCollector::ActivityLifecycleListener: Activity paused: com.services.movistar.ar.MainActivity
D/SASCollector::ActivityLifecycleListener: Activity resumed: com.services.movistar.ar.MainActivity

We are using React Native, and inside of the path android/app/libs we've got the SASCollector.jar, and inside of the path android/app/src/main/assets we've got the SASCollector.properties

 

Captura de pantalla 2023-04-18 a la(s) 15.01.38.png

In our build.gradle file we've got:

apply plugin: "com.android.application"
// project.ext.envConfigFiles = [
//   production: ".env.production",
//   certification: ".env.certification",
//   integration: ".env.integration",
//   local: ".env.local",
// ]
// apply from: project(':react-native-config').projectDir.getPath() + "/dotenv.gradle"
// apply plugin: 'com.google.gms.google-services'
apply from: "../../node_modules/react-native-vector-icons/fonts.gradle"
import com.android.build.OutputFile

/**
 * The react.gradle file registers a task for each build variant (e.g. bundleDebugJsAndAssets
 * and bundleReleaseJsAndAssets).
 * These basically call `react-native bundle` with the correct arguments during the Android build
 * cycle. By default, bundleDebugJsAndAssets is skipped, as in debug/dev mode we prefer to load the
 * bundle directly from the development server. Below you can see all the possible configurations
 * and their defaults. If you decide to add a configuration block, make sure to add it before the
 * `apply from: "../../node_modules/react-native/react.gradle"` line.
 *
 * project.ext.react = [
 *   // the name of the generated asset file containing your JS bundle
 *   bundleAssetName: "index.android.bundle",
 *
 *   // the entry file for bundle generation. If none specified and
 *   // "index.android.js" exists, it will be used. Otherwise "index.js" is
 *   // default. Can be overridden with ENTRY_FILE environment variable.
 *   entryFile: "index.android.js",
 *
 *   // https://reactnative.dev/docs/performance#enable-the-ram-format
 *   bundleCommand: "ram-bundle",
 *
 *   // whether to bundle JS and assets in debug mode
 *   bundleInDebug: false,
 *
 *   // whether to bundle JS and assets in release mode
 *   bundleInRelease: true,
 *
 *   // whether to bundle JS and assets in another build variant (if configured).
 *   // See http://tools.android.com/tech-docs/new-build-system/user-guide#TOC-Build-Variants
 *   // The configuration property can be in the following formats
 *   //         'bundleIn${productFlavor}${buildType}'
 *   //         'bundleIn${buildType}'
 *   // bundleInFreeDebug: true,
 *   // bundleInPaidRelease: true,
 *   // bundleInBeta: true,
 *
 *   // whether to disable dev mode in custom build variants (by default only disabled in release)
 *   // for example: to disable dev mode in the staging build type (if configured)
 *   devDisabledInStaging: true,
 *   // The configuration property can be in the following formats
 *   //         'devDisabledIn${productFlavor}${buildType}'
 *   //         'devDisabledIn${buildType}'
 *
 *   // the root of your project, i.e. where "package.json" lives
 *   root: "../../",
 *
 *   // where to put the JS bundle asset in debug mode
 *   jsBundleDirDebug: "$buildDir/intermediates/assets/debug",
 *
 *   // where to put the JS bundle asset in release mode
 *   jsBundleDirRelease: "$buildDir/intermediates/assets/release",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in debug mode
 *   resourcesDirDebug: "$buildDir/intermediates/res/merged/debug",
 *
 *   // where to put drawable resources / React Native assets, e.g. the ones you use via
 *   // require('./image.png')), in release mode
 *   resourcesDirRelease: "$buildDir/intermediates/res/merged/release",
 *
 *   // by default the gradle tasks are skipped if none of the JS files or assets change; this means
 *   // that we don't look at files in android/ or ios/ to determine whether the tasks are up to
 *   // date; if you have any other folders that you want to ignore for performance reasons (gradle
 *   // indexes the entire tree), add them here. Alternatively, if you have JS files in android/
 *   // for example, you might want to remove it from here.
 *   inputExcludes: ["android/**", "ios/**"],
 *
 *   // override which node gets called and with what additional arguments
 *   nodeExecutableAndArgs: ["node"],
 *
 *   // supply additional arguments to the packager
 *   extraPackagerArgs: []
 * ]
 */

project.ext.react = [
    enableHermes: true,  // clean and rebuild if changing
]

apply from: "../../node_modules/react-native/react.gradle"

/**
 * Set this to true to create two separate APKs instead of one:
 *   - An APK that only works on ARM devices
 *   - An APK that only works on x86 devices
 * The advantage is the size of the APK is reduced by about 4MB.
 * Upload all the APKs to the Play Store and people will download
 * the correct one based on the CPU architecture of their device.
 */
def enableSeparateBuildPerCPUArchitecture = false

/**
 * Run Proguard to shrink the Java bytecode in release builds.
 */
def enableProguardInReleaseBuilds = true

/**
 * The preferred build flavor of JavaScriptCore.
 *
 * For example, to use the international variant, you can use:
 * `def jscFlavor = 'org.webkit:android-jsc-intl:+'`
 *
 * The international variant includes ICU i18n library and necessary data
 * allowing to use e.g. `Date.toLocaleString` and `String.localeCompare` that
 * give correct results when using with locales other than en-US.  Note that
 * this variant is about 6MiB larger per architecture than default.
 */
def jscFlavor = 'org.webkit:android-jsc:+'

/**
 * Whether to enable the Hermes VM.
 *
 * This should be set on project.ext.react and mirrored here.  If it is not set
 * on project.ext.react, JavaScript will not be compiled to Hermes Bytecode
 * and the benefits of using Hermes will therefore be sharply reduced.
 */
def enableHermes = project.ext.react.get("enableHermes", false);

def keystorePropertiesFile = rootProject.file("keystore.properties");
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))


def keysPropertiesFile = rootProject.file("keys.properties")
def keysProperties = new Properties()
keysProperties.load(new FileInputStream(keysPropertiesFile))

android {
    compileSdkVersion rootProject.ext.compileSdkVersion

    compileOptions {
        sourceCompatibility JavaVersion.VERSION_1_8
        targetCompatibility JavaVersion.VERSION_1_8
    }

    dexOptions {
       javaMaxHeapSize "4g"
    }

    defaultConfig {
        applicationId "com.services.movistar.ar"
        minSdkVersion rootProject.ext.minSdkVersion
        targetSdkVersion rootProject.ext.targetSdkVersion
        multiDexEnabled true
        versionCode 412110700
        versionName "12.0.23"
        vectorDrawables.useSupportLibrary = true
        resValue "string", "build_config_package", "com.services.movistar.ar"
        setProperty("archivesBaseName", "MiMovistar-$versionName")
    }
    splits {
        abi {
            reset()
            enable enableSeparateBuildPerCPUArchitecture
            universalApk false  // If true, also generate a universal APK
            include "armeabi-v7a", "x86", "arm64-v8a", "x86_64"
        }
    }
    signingConfigs {
        debug {
            storeFile file('debug.keystore')
            storePassword 'android'
            keyAlias 'androiddebugkey'
            keyPassword 'android'
        }
        release {
            if(keystorePropertiesFile.exists()){
                storeFile file(keystoreProperties['MYAPP_UPLOAD_STORE_FILE'])
                storePassword keystoreProperties['MYAPP_UPLOAD_STORE_PASSWORD']
                keyAlias keystoreProperties['MYAPP_UPLOAD_KEY_ALIAS']
                keyPassword keystoreProperties['MYAPP_UPLOAD_KEY_PASSWORD']
                enableV3Signing = true
                // v1SigningEnabled false
            }
        }
    }
    
    buildTypes {
        debug {
            signingConfig signingConfigs.debug
            debuggable true
            matchingFallbacks = ['debug', 'release']
        }
       
        release {
            // Caution! In production, you need to generate your own keystore file.
            // see https://reactnative.dev/docs/signed-apk-android.
            debuggable false
            signingConfig signingConfigs.release
            minifyEnabled enableProguardInReleaseBuilds
            shrinkResources enableProguardInReleaseBuilds
            zipAlignEnabled enableProguardInReleaseBuilds
            proguardFiles getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro"
        }
    
    }
    flavorDimensions "default"
    productFlavors {
        production {
            buildConfigField("String", "SWRVE_API_KEY", keysProperties['SWRVE_API_KEY'])
            buildConfigField("int", "SWRVE_APP_ID", keysProperties['SWRVE_APP_ID'])
            buildConfigField "boolean", "IS_DEBUGGABLE", "false"
            buildConfigField("String", "FIREBASE_APP_ID", keysProperties['FIREBASE_APP_ID'])
            buildConfigField("String", "FIREBASE_API_KEY", keysProperties['FIREBASE_API_KEY'])
            buildConfigField("String", "FIREBASE_SENDER_ID", keysProperties['FIREBASE_SENDER_ID'])
            buildConfigField("String", "FIREBASE_STORAGE_BUCKET", keysProperties['FIREBASE_STORAGE_BUCKET'])
            buildConfigField("String", "FIREBASE_PROJECT_ID", keysProperties['FIREBASE_PROJECT_ID'])        
            buildConfigField("String", "AES_SECRET_KEY", keysProperties['AES_SECRET_KEY'])
            buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", keysProperties['IS_NEW_ARCHITECTURE_ENABLED'])
        }
        f5 {
            applicationIdSuffix '.f5'
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            resValue "string", "build_config_package", "com.services.movistar.ar"
            buildConfigField("String", "SWRVE_API_KEY", keysProperties['SWRVE_API_KEY'])
            buildConfigField("int", "SWRVE_APP_ID", keysProperties['SWRVE_APP_ID'])
            buildConfigField "boolean", "IS_DEBUGGABLE", "false"
            buildConfigField("String", "FIREBASE_APP_ID", keysProperties['FIREBASE_APP_ID'])
            buildConfigField("String", "FIREBASE_API_KEY", keysProperties['FIREBASE_API_KEY'])
            buildConfigField("String", "FIREBASE_SENDER_ID", keysProperties['FIREBASE_SENDER_ID'])
            buildConfigField("String", "FIREBASE_STORAGE_BUCKET", keysProperties['FIREBASE_STORAGE_BUCKET'])
            buildConfigField("String", "FIREBASE_PROJECT_ID", keysProperties['FIREBASE_PROJECT_ID'])
            buildConfigField("String", "AES_SECRET_KEY", keysProperties['AES_SECRET_KEY'])
            buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", keysProperties['IS_NEW_ARCHITECTURE_ENABLED'])
        }
        certification {
            applicationIdSuffix '.certification'
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            resValue "string", "build_config_package", "com.services.movistar.ar"            
            buildConfigField("String", "SWRVE_API_KEY", keysProperties['SWRVE_API_KEY_CERT'])
            buildConfigField("int", "SWRVE_APP_ID", keysProperties['SWRVE_APP_ID_CERT'])
            buildConfigField "boolean", "IS_DEBUGGABLE", "false"
            buildConfigField("String", "FIREBASE_APP_ID", keysProperties['FIREBASE_APP_ID_CERT'])
            buildConfigField("String", "FIREBASE_API_KEY", keysProperties['FIREBASE_API_KEY_CERT'])
            buildConfigField("String", "FIREBASE_SENDER_ID", keysProperties['FIREBASE_SENDER_ID_CERT'])
            buildConfigField("String", "FIREBASE_STORAGE_BUCKET", keysProperties['FIREBASE_STORAGE_BUCKET_CERT'])
            buildConfigField("String", "FIREBASE_PROJECT_ID", keysProperties['FIREBASE_PROJECT_ID_CERT'])
            buildConfigField("String", "AES_SECRET_KEY", keysProperties['AES_SECRET_KEY'])
            buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", keysProperties['IS_NEW_ARCHITECTURE_ENABLED'])
        }
        hotfix {
            applicationIdSuffix '.hotfix'
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            resValue "string", "build_config_package", "com.services.movistar.ar"
            buildConfigField("String", "SWRVE_API_KEY", keysProperties['SWRVE_API_KEY_CERT'])
            buildConfigField("int", "SWRVE_APP_ID", keysProperties['SWRVE_APP_ID_CERT'])
            buildConfigField "boolean", "IS_DEBUGGABLE", "true"
            buildConfigField("String", "FIREBASE_APP_ID", keysProperties['FIREBASE_APP_ID_CERT'])
            buildConfigField("String", "FIREBASE_API_KEY", keysProperties['FIREBASE_API_KEY_CERT'])
            buildConfigField("String", "FIREBASE_SENDER_ID", keysProperties['FIREBASE_SENDER_ID_CERT'])
            buildConfigField("String", "FIREBASE_STORAGE_BUCKET", keysProperties['FIREBASE_STORAGE_BUCKET_CERT'])
            buildConfigField("String", "FIREBASE_PROJECT_ID", keysProperties['FIREBASE_PROJECT_ID_CERT'])
            buildConfigField("String", "AES_SECRET_KEY", keysProperties['AES_SECRET_KEY'])
            buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", keysProperties['IS_NEW_ARCHITECTURE_ENABLED'])
        }
        bugfix {
            applicationIdSuffix '.bugfix'
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            resValue "string", "build_config_package", "com.services.movistar.ar"
            buildConfigField("String", "SWRVE_API_KEY", keysProperties['SWRVE_API_KEY_CERT'])
            buildConfigField("int", "SWRVE_APP_ID", keysProperties['SWRVE_APP_ID_CERT'])
            buildConfigField "boolean", "IS_DEBUGGABLE", "true"
            buildConfigField("String", "FIREBASE_APP_ID", keysProperties['FIREBASE_APP_ID_CERT'])
            buildConfigField("String", "FIREBASE_API_KEY", keysProperties['FIREBASE_API_KEY_CERT'])
            buildConfigField("String", "FIREBASE_SENDER_ID", keysProperties['FIREBASE_SENDER_ID_CERT'])
            buildConfigField("String", "FIREBASE_STORAGE_BUCKET", keysProperties['FIREBASE_STORAGE_BUCKET_CERT'])
            buildConfigField("String", "FIREBASE_PROJECT_ID", keysProperties['FIREBASE_PROJECT_ID_CERT'])
            buildConfigField("String", "AES_SECRET_KEY", keysProperties['AES_SECRET_KEY'])
            buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", keysProperties['IS_NEW_ARCHITECTURE_ENABLED'])
        }
        integration {
            applicationIdSuffix '.integration'
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            resValue "string", "build_config_package", "com.services.movistar.ar"
            buildConfigField("String", "SWRVE_API_KEY", keysProperties['SWRVE_API_KEY_CERT'])
            buildConfigField("int", "SWRVE_APP_ID", keysProperties['SWRVE_APP_ID_CERT'])
            buildConfigField "boolean", "IS_DEBUGGABLE", "true"
            buildConfigField("String", "FIREBASE_APP_ID", keysProperties['FIREBASE_APP_ID_CERT'])
            buildConfigField("String", "FIREBASE_API_KEY", keysProperties['FIREBASE_API_KEY_CERT'])
            buildConfigField("String", "FIREBASE_SENDER_ID", keysProperties['FIREBASE_SENDER_ID_CERT'])
            buildConfigField("String", "FIREBASE_STORAGE_BUCKET", keysProperties['FIREBASE_STORAGE_BUCKET_CERT'])
            buildConfigField("String", "FIREBASE_PROJECT_ID", keysProperties['FIREBASE_PROJECT_ID_CERT'])
            buildConfigField("String", "AES_SECRET_KEY", keysProperties['AES_SECRET_KEY'])
            buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", keysProperties['IS_NEW_ARCHITECTURE_ENABLED'])
        }
        local {
            applicationIdSuffix '.local'
            minSdkVersion rootProject.ext.minSdkVersion
            targetSdkVersion rootProject.ext.targetSdkVersion
            resValue "string", "build_config_package", "com.services.movistar.ar"
            buildConfigField("String", "SWRVE_API_KEY", keysProperties['SWRVE_API_KEY_CERT'])
            buildConfigField("int", "SWRVE_APP_ID", keysProperties['SWRVE_APP_ID_CERT'])
            buildConfigField "boolean", "IS_DEBUGGABLE", "false"
            buildConfigField("String", "FIREBASE_APP_ID", keysProperties['FIREBASE_APP_ID_CERT'])
            buildConfigField("String", "FIREBASE_API_KEY", keysProperties['FIREBASE_API_KEY_CERT'])
            buildConfigField("String", "FIREBASE_SENDER_ID", keysProperties['FIREBASE_SENDER_ID_CERT'])
            buildConfigField("String", "FIREBASE_STORAGE_BUCKET", keysProperties['FIREBASE_STORAGE_BUCKET_CERT'])
            buildConfigField("String", "FIREBASE_PROJECT_ID", keysProperties['FIREBASE_PROJECT_ID_CERT'])
            buildConfigField("String", "AES_SECRET_KEY", keysProperties['AES_SECRET_KEY'])
            buildConfigField("boolean", "IS_NEW_ARCHITECTURE_ENABLED", keysProperties['IS_NEW_ARCHITECTURE_ENABLED'])
        }
  }


    // applicationVariants are e.g. debug, release
    applicationVariants.all { variant ->
        variant.outputs.each { output ->
            // For each separate APK per architecture, set a unique version code as described here:
            // https://developer.android.com/studio/build/configure-apk-splits.html
            def versionCodes = ["armeabi-v7a": 1, "x86": 2, "arm64-v8a": 3, "x86_64": 4]
            def abi = output.getFilter(OutputFile.ABI)
            if (abi != null) {  // null for the universal-debug, universal-release variants
                output.versionCodeOverride =
                        versionCodes.get(abi) * 1048576 + defaultConfig.versionCode
            }

        }
    }
}

dependencies {

    implementation 'com.swrve.sdk.android:swrve-firebase:10.8.0'
    implementation platform('com.google.firebase:firebase-bom:28.0.1')
    implementation("com.google.firebase:firebase-iid")
    
    implementation fileTree(dir: "libs", include: ["*.jar", "*.aar"])
    //noinspection GradleDynamicVersion
    implementation "com.facebook.react:react-native:+"  // From node_modules

    implementation "androidx.swiperefreshlayout:swiperefreshlayout:1.0.0"
    
    implementation project(':react-native-splash-screen')

    implementation 'com.google.android.gms:play-services-tagmanager:17.0.0'

    implementation 'com.android.installreferrer:installreferrer:2.2'
    
    // Add the following if you are using the Adjust SDK inside web views on your app
    implementation 'com.adjust.sdk:adjust-android-webbridge:4.28.2'

    implementation 'com.android.volley:volley:1.2.1'

    implementation 'com.google.android.gms:play-services-ads-identifier:17.0.1'
    
    // Libreria para IVR
    //implementation(name: 'DialMyAppLib-release', ext: 'aar')
    implementation files('libs/DialMyAppLib-release.aar')
    implementation 'com.googlecode.libphonenumber:libphonenumber:8.10.6' 
    implementation 'org.apache.cordova:framework:8.1.0'
    implementation 'com.google.guava:guava:27.0.1-android' 
    implementation 'commons-io:commons-io:2.6'
    implementation 'com.google.android.gms:play-services-maps:17.0.0' 
    implementation 'com.google.android.gms:play-services-location:19.0.1' 
    implementation 'androidx.legacy:legacy-support-v4:1.0.0' 
    implementation 'androidx.legacy:legacy-support-v13:1.0.0'
    implementation 'org.greenrobot:eventbus:3.1.1'
    implementation 'androidx.work:work-runtime:2.5.0'
    implementation 'com.google.guava:listenablefuture:9999.0-empty-to-avoid-conflict-with-guava'
    implementation 'com.android.installreferrer:installreferrer:2.2'
    implementation 'com.google.android.gms:play-services-auth-api-phone:17.4.0'

    //CI360
implementation files('libs/SASCollector.jar') implementation 'com.google.firebase:firebase-core' implementation 'com.google.firebase:firebase-messaging' implementation 'com.google.code.gson:gson:2.8.9' debugImplementation("com.facebook.flipper:flipper:${FLIPPER_VERSION}") { exclude group:'com.facebook.fbjni' } debugImplementation("com.facebook.flipper:flipper-network-plugin:${FLIPPER_VERSION}") { exclude group:'com.facebook.flipper' exclude group:'com.squareup.okhttp3', module:'okhttp' } debugImplementation("com.facebook.flipper:flipper-fresco-plugin:${FLIPPER_VERSION}") { exclude group:'com.facebook.flipper' } if (enableHermes) { def hermesPath = "../../node_modules/hermes-engine/android/"; debugImplementation files(hermesPath + "hermes-debug.aar") releaseImplementation files(hermesPath + "hermes-release.aar") } else { implementation jscFlavor } } // Run this once to be able to run the application with BUCK // puts all compile dependencies into folder libs for BUCK to use task copyDownloadableDepsToLibs(type: Copy) { from configurations.compile into 'libs' } apply from: file("../../node_modules/@react-native-community/cli-platform-android/native_modules.gradle"); applyNativeModulesAppBuildGradle(project)

MainApplication.java:

package com.services.movistar.ar;

import com.google.firebase.FirebaseApp;
import com.google.firebase.FirebaseOptions;
import com.sas.mkt.mobile.sdk.util.SLog;
import com.swrve.reactnative.SwrvePlugin;
import com.swrve.sdk.SwrveNotificationConfig;
import com.swrve.sdk.config.SwrveConfig;
import com.swrve.sdk.config.SwrveStack;
import android.app.Application;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.soloader.SoLoader;
import java.lang.reflect.InvocationTargetException;
import java.util.List;

import android.content.res.Configuration;
import android.graphics.Color;
import android.webkit.WebView;
import android.util.Log;

import androidx.annotation.RequiresApi;

import com.sas.mkt.mobile.sdk.SASCollector;

public class MainApplication extends Application implements ReactApplication {

    private final ReactNativeHost mReactNativeHost = new ReactNativeHost(this) {
        @Override
        public boolean getUseDeveloperSupport() {
            Log.v("Swrve", "swrve_api_key=" + BuildConfig.SWRVE_API_KEY);
            Log.v("Swrve", "swrve_app_id=" + BuildConfig.SWRVE_APP_ID);
            Log.v("Mi Movistar", "IS_DEBUGGABLE=" + BuildConfig.IS_DEBUGGABLE);

            return BuildConfig.DEBUG;
        }

        @Override
        protected List<ReactPackage> getPackages() {
            @SuppressWarnings("UnnecessaryLocalVariable")
            List<ReactPackage> packages = new PackageList(this).getPackages();
            // Packages that cannot be autolinked yet can be added manually here, for
            // example:
            // packages.add(new MyReactNativePackage());
            packages.add(new MyAppPackage());
            return packages;
        }

        @Override
        protected String getJSMainModuleName() {
            return "index";
        }
    };

    @Override
    public ReactNativeHost getReactNativeHost() {
        return mReactNativeHost;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        SLog.setLevel(SLog.VERBOSE);
        SASCollector.getInstance().initialize(this);
        initializeFirebase(this);
        org.mbte.dialmyapp.app.InjectingRef.defineApplication(this, org.mbte.dialmyapp.app.DialMyAppComponent.class);
        SwrveConfig swrveConfig = new SwrveConfig();
        // To use the EU stack, include this in your config
        swrveConfig.setSelectedStack(SwrveStack.EU);

        NotificationChannel channel = null;
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            channel = new NotificationChannel("123", "Devapp swrve default channel",
                    NotificationManager.IMPORTANCE_DEFAULT);
            channel.setLockscreenVisibility(Notification.VISIBILITY_PUBLIC);
            if (getSystemService(Context.NOTIFICATION_SERVICE) != null) {
                NotificationManager notificationManager = (NotificationManager) getSystemService(
                        Context.NOTIFICATION_SERVICE);
                notificationManager.createNotificationChannel(channel);
            }
        }

        SwrveNotificationConfig.Builder notificationConfig = new SwrveNotificationConfig.Builder(
                R.mipmap.ic_launcher_round, R.mipmap.ic_launcher_round, channel)
                .activityClass(MainActivity.class)
                .largeIconDrawableId(R.mipmap.ic_launcher_round)
                .accentColorHex("#00a9e0");
        swrveConfig.setNotificationConfig(notificationConfig.build());

        SwrvePlugin.createInstance(this, BuildConfig.SWRVE_APP_ID, BuildConfig.SWRVE_API_KEY, swrveConfig);
        SoLoader.init(this, /* native exopackage */ false);
        initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
        //WebView.setWebContentsDebuggingEnabled(true); // WEBVIEW DEBUG
        WebView.setWebContentsDebuggingEnabled(false); // WEBVIEW RELEASE

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            setPushChannel();
        }
    }

    @Override
    public void onConfigurationChanged(Configuration newConfiguration) {
        super.onConfigurationChanged(newConfiguration);
        SASCollector.getInstance().onConfigurationChanged(newConfiguration);
    }

    /**
     * Loads Flipper in React Native templates. Call this in the onCreate method
     * with something like
     * initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
     *
     * @param context
     * @param reactInstanceManager
     */
    private static void initializeFlipper(
            Context context, ReactInstanceManager reactInstanceManager) {
        if (BuildConfig.DEBUG) {
            try {
                /*
                 * We use reflection here to pick up the class that initializes Flipper,
                 * since Flipper library is not available in release mode
                 */
                Class<?> aClass = Class.forName("com.services.ReactNativeFlipper");
                aClass
                        .getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
                        .invoke(null, context, reactInstanceManager);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }

    public void initializeFirebase(Context context) {
        Log.v("Firebase", "Inicializando SDK: " + BuildConfig.FIREBASE_PROJECT_ID);
        // .setApiKey(Utils.decryptKey(BuildConfig.FIREBASE_API_KEY,
        // BuildConfig.AES_SECRET_KEY))
        if (FirebaseApp.getApps(context).isEmpty()) {
            FirebaseOptions firebaseOptions = new FirebaseOptions.Builder()
                    .setApplicationId(BuildConfig.FIREBASE_APP_ID)
                    .setApiKey(BuildConfig.FIREBASE_API_KEY)
                    .setGcmSenderId(BuildConfig.FIREBASE_SENDER_ID)
                    .setStorageBucket(BuildConfig.FIREBASE_STORAGE_BUCKET)
                    .setProjectId(BuildConfig.FIREBASE_PROJECT_ID)
                    .build();
            FirebaseApp.initializeApp(context, firebaseOptions);
        }
    }

    @RequiresApi(api = android.os.Build.VERSION_CODES.O)
    private void setPushChannel() {
        NotificationManager notificationManager =
                (NotificationManager) this.getSystemService(this.NOTIFICATION_SERVICE);

        String customAndroidChannel = "ReactNativePushChannel2";
        CharSequence channelName = "React Native Channel2";
        int importance = NotificationManager.IMPORTANCE_HIGH;
        NotificationChannel notificationChannel = new NotificationChannel(customAndroidChannel, channelName, importance);
        notificationChannel.enableLights(true);
        notificationChannel.setLightColor(Color.RED);
        notificationChannel.enableVibration(true);
        notificationChannel.setShowBadge(true);
        notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400});
        notificationManager.createNotificationChannel(notificationChannel);

        SASCollector.getInstance().setPushNotificationChannelId(customAndroidChannel);
    }
}

Our native module is called CI360AndroidModule.java:

package com.services.movistar.ar;

import android.os.Handler;
import android.os.Looper;
import android.util.Log;

import androidx.annotation.NonNull;

import com.facebook.react.bridge.Callback;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;
import com.facebook.react.bridge.ReadableMap;
import com.sas.mkt.mobile.sdk.SASCollector;

import java.util.HashMap;
import java.util.Map;

public class CI360AndroidModule extends ReactContextBaseJavaModule {
    public static final String NAME = "CI360AndroidModule";

    CI360AndroidModule(ReactApplicationContext context) {
        super(context);
        if(!SASCollector.getInstance().isInitialized()) {
            SASCollector.getInstance().initialize(context.getApplicationContext());
        }
    }

    @Override
    @NonNull
    public String getName() {
        return NAME;
    }

    @ReactMethod
    public void newPage(String uri) {
        SASCollector.getInstance().newPage(uri);
    }

    @ReactMethod
    public void addAppEvent(String eventKey, ReadableMap data) {
        if (data == null) {
            SASCollector.getInstance().addAppEvent(eventKey, null);
            return;
        }
        HashMap<String, Object> rawData = data.toHashMap();
        HashMap<String, String> convertedData = new HashMap<>();
        for (Map.Entry<String, Object> entry : rawData.entrySet()) {
            if(entry.getValue() instanceof String) {
                convertedData.put(entry.getKey(), (String)entry.getValue());
            }
        }
        SASCollector.getInstance().addAppEvent(eventKey, convertedData);
    }

    @ReactMethod
    public void sendCI360EventAndroid(String eventId, String keyEventName, String eventValue) {
        Map <String, String> myEventAttributeMap = new HashMap<>();
        myEventAttributeMap.put("Start_Button", "Botón Comenzar fué presionado");
        SASCollector.getInstance().addAppEvent("Button_Pressed", myEventAttributeMap);
        Log.d("EventID", eventId);
        Log.d("KeyEventName", keyEventName);
        Log.d("EventValue", eventValue);
    }

    @ReactMethod
    public void sendCI360EventAndroidInApp() {
        Map <String, String> myEventAttributeMap = new HashMap<>();
        SASCollector.getInstance().addAppEvent("test_event_for_in_app", null);
        Log.d("EventInApp: ", "Fired");
    }

    @ReactMethod
    public void identity(String value, String type, Promise promise) {
        SASCollector.getInstance().identity(value, SASCollector.IDENTITY_TYPE_CUSTOMER_ID, new SASCollector.IdentityCallback() {
            @Override
            public void onComplete(boolean b) {
                Log.d("Identity", "Identity called with: " + (b ? "success" : "failure"));
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        promise.resolve(b);
                    }
                });
            }
        });
    }

    @ReactMethod
    public void detachIdentity(Promise promise) { //SASCollector.DetachIdentityCallback callback
        SASCollector.getInstance().detachIdentity(new SASCollector.DetachIdentityCallback() {
            @Override
            public void onComplete(boolean b) {
                new Handler(Looper.getMainLooper()).post(new Runnable() {
                    @Override
                    public void run() {
                        promise.resolve(b);
                    }
                });
            }
        });
    }

    @ReactMethod
    public void startMonitoringLocation() {
        SASCollector.getInstance().startMonitoringLocation();
    }

    @ReactMethod
    public void disableLocationMonitoring() {
        SASCollector.getInstance().disableLocationMonitoring();
    }

    @ReactMethod
    public void resetDeviceID() {
        SASCollector.getInstance().resetDeviceID();
    }

    @ReactMethod
    public void getDeviceID(Callback callback) {
        callback.invoke(SASCollector.getInstance().getDeviceID());
    }

    @ReactMethod
    public void getTenantID(Callback callback) {
        callback.invoke(SASCollector.getInstance().getTenantID());
    }

    @ReactMethod
    public void getAppVersion(Callback callback) {
        callback.invoke(SASCollector.getInstance().getApplicationVersion());
    }

    @ReactMethod
    public void getTagServer(Callback callback) {
        callback.invoke(SASCollector.getInstance().getTagServer());
    }

    @ReactMethod
    public void registerForMobileMessage(String token) {
        SASCollector.getInstance().registerForMobileMessages(token);
    }

    @ReactMethod
    public void handleMobileMessage(Map<String, String> data) {
        SASCollector.getInstance().handleMobileMessage(data);
    }
}

And we also include the native module in the package in order to use it from react native:

package com.services.movistar.ar;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class MyAppPackage implements ReactPackage {

    @Override
    public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
        //return Collections.emptyList();
        return Arrays.<ViewManager>asList(
                new CI360InlineAdViewManager(reactContext),
                new CI360InterstitialAdViewManager(reactContext)
        );
    }

    @Override
    public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
        List<NativeModule> modules = new ArrayList<>();
        modules.add(new SharedPreferencesModule(reactContext));
        modules.add(new OpenAppModule(reactContext));
        modules.add(new AdditionalPermissionsModule(reactContext));
        modules.add(new CI360AndroidModule(reactContext));
        return modules;
    }
}

As you can see, we also have another native SDK integrated in our app called DialMyAppLib-release.aar inside of the libs folder and its native module AdditionalPermissionsModule.java. The configuration of this SDK is so similar to CI360, and we have no problem with DialMyApp in our apk in release mode.  I'm not telling you that CI360 sdk is the problem, but it's strange why in the release apk it isn´t working correctly.

wwen
SAS Employee

Hi @LucasAcuna Now I see you were referring to the contents of the dex files in debug and release APKs. Yes, they are the same in both my  debug and release dex files. I agree that is an indication something is not right with your release APK.

 

Looking at your project structure in VSCode, I see you put SASCollector.jar in your app's android/app/libs folder. This is not what I do. I wonder if you create your CI360 Module as a separate library project? If you did like in the cookbook, you will have put SASCollector.jar in your CI360 module project. From your app project, you simply reference your CI360 module's SASCollector.jar. It's not recommended to use two copies of SASCollector.jar. Here is what I did in my app project's app level build.gradle:

implementation files('../../../mobile-sdk-react-native/android/libs/SASCollector.jar')

Here is my project structure. You can see that I have my CI360 library (module-sdk-react-native) in my project:

Screenshot 2023-04-19 at 8.38.20 AM.png

LucasAcuna
Calcite | Level 5

Hi @wwen , thank you for your answer.

I did the sdk integration (in the same way I showed you) in another react native application in order to see if the original application has some configuration that generates problems when I build an apk in release mode. 

The result has surprised me, the sdk in this react native test application works perfectly in the release apk:

Captura de pantalla 2023-04-18 a la(s) 17.28.06.png

As you can see the folder structure and configuration is practically the same with the original application:

 

Captura de pantalla 2023-04-20 a la(s) 10.25.29.png

So I think that there is something wrong with the configuration of the original project when it tries to generate an apk in release mode. I'll try to figure out what's happening.  

If I have no success I'll try to implement the sdk integration in the way you showed me and I'll let you know.

 

Thank you for your time!

 

LucasAcuna
Calcite | Level 5

Hi @wwen , I did some test with my project and I finally solved the problem.

 

This behavior happens because sometimes when the android compiler creates a release apk, it makes some optimizations in order to reduce the apk’s size, deleting unused code and renaming classes and methods.

 

You can avoid this default behavior of the compiler setting up a rule in the proguard-rules.pro file in the path: android/app.

 

In our case the rule is:

 

-keep class com.sas.mkt.mobile.sdk.** { *; }

 

And that’s all! Everything works as I expected:

 

Captura de pantalla 2023-04-21 a la(s) 17.48.56.png

 

Thank you for your time!

wwen
SAS Employee

Hi @LucasAcuna  I am so glad that you solved your problem, and thank you for letting me know of your solution.

 

If you also build iOS app, there is a bug I want you to be aware of. It is in identity and detachIdentity. If you try to log in without an internet connection, the app will crash. We will have an updated cookbook to address this issue soon. So please keep an eye on it.

LucasAcuna
Calcite | Level 5

Hi @wwen , thank you for the information about the sdk integration on the IOS platform, I'll keep an eye on it when I start to implement that part.

 

Have a good day!

How to improve email deliverability

SAS' Peter Ansbacher shows you how to use the dashboard in SAS Customer Intelligence 360 for better results.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 14 replies
  • 1961 views
  • 1 like
  • 2 in conversation