「Countly」
1、引入countly源码,高度为09d7817a38074cae8a6c34f94c04356b29f6a80f,引入原因是因为gradle、kotlin版本太高了,无法直接使用。需要自己定制化
1
libraries/countly/app-benchmark/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
27
libraries/countly/app-benchmark/agconnect-services.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"agcgw":{
|
||||
"backurl":"connect-dre.dbankcloud.cn",
|
||||
"url":"connect-dre.hispace.hicloud.com"
|
||||
},
|
||||
"client":{
|
||||
"cp_id":"5190090000025014013",
|
||||
"product_id":"9105385871708592148",
|
||||
"client_id":"325901171304694848",
|
||||
"client_secret":"31C4D18185700B855D33F575B241288BB0FB884861427DB05A297E54424A601F",
|
||||
"app_id":"101926031",
|
||||
"package_name":"ly.count.android.demo",
|
||||
"api_key":"CV8FgFUqn8qlzRxUglEUhnjcTT7/ca5efyLkxaqzxV8N26kvPX/tnu+XXH4eGCvN2pi1llG6NvRKzmhiAp5QTKpSz6ya"
|
||||
},
|
||||
"service":{
|
||||
"analytics":{
|
||||
"collector_url":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
|
||||
"resource_id":"p1",
|
||||
"channel_id":""
|
||||
},
|
||||
"ml":{
|
||||
"mlservice_url":"ml-api-dre.ai.dbankcloud.com,ml-api-dre.ai.dbankcloud.cn"
|
||||
}
|
||||
},
|
||||
"region":"DE",
|
||||
"configuration_version":"1.0"
|
||||
}
|
||||
56
libraries/countly/app-benchmark/build.gradle
Normal file
@@ -0,0 +1,56 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.android.compileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId "ly.count.android.benchmark"
|
||||
minSdkVersion rootProject.ext.android.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.android.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file('keys')
|
||||
keyAlias 'HWDemo'
|
||||
keyPassword 'countly'
|
||||
storePassword 'countly'
|
||||
v1SigningEnabled true
|
||||
v2SigningEnabled true
|
||||
}
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
debug {
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled false
|
||||
//shrinkResources true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled true
|
||||
//shrinkResources true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
implementation 'com.android.installreferrer:installreferrer:2.2'
|
||||
implementation project(path: ':libraries:countly:sdk')
|
||||
}
|
||||
39
libraries/countly/app-benchmark/google-services.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "355395217058",
|
||||
"project_id": "countlydemo-7d8d0",
|
||||
"storage_bucket": "countlydemo-7d8d0.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:355395217058:android:130d09fdf6bebd941c99fb",
|
||||
"android_client_info": {
|
||||
"package_name": "ly.count.android.demo"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "969412419457-07du4kv6e2m9ttjrn40063mcv7erhf0p.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAYxUHbqnotLwParY0UR_fmhaTgx-ahUbc"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "969412419457-07du4kv6e2m9ttjrn40063mcv7erhf0p.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
BIN
libraries/countly/app-benchmark/keys
Normal file
31
libraries/countly/app-benchmark/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /projects/android-sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
-renamesourcefileattribute SourceFile
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# Rules recommended for Huawei PushKit
|
||||
-ignorewarnings
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes Exceptions
|
||||
-keepattributes InnerClasses
|
||||
-keepattributes Signature
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keep class com.hianalytics.android.**{*;}
|
||||
-keep class com.huawei.updatesdk.**{*;}
|
||||
-keep class com.huawei.hms.**{*;}
|
||||
32
libraries/countly/app-benchmark/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="ly.count.android.benchmark">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
|
||||
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="false"
|
||||
android:icon="@mipmap/icon"
|
||||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme"
|
||||
android:usesCleartextTraffic="true">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:configChanges="orientation|screenSize"
|
||||
android:exported="true"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
@@ -0,0 +1,69 @@
|
||||
package ly.count.android.benchmark;
|
||||
|
||||
import android.app.Application;
|
||||
import ly.count.android.sdk.Countly;
|
||||
import ly.count.android.sdk.CountlyConfig;
|
||||
import ly.count.android.sdk.CountlyStore;
|
||||
import ly.count.android.sdk.ModuleLog;
|
||||
import ly.count.android.sdk.PerformanceCounterCollector;
|
||||
|
||||
public class App extends Application {
|
||||
private final static String COUNTLY_SERVER_URL = "https://xxx.count.ly";
|
||||
private final static String COUNTLY_APP_KEY = "YOUR_APP_KEY";
|
||||
private final static String DEVICE_ID = "YOUR_DEVICE_ID";
|
||||
|
||||
public static PerformanceCounterCollector appPcc;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
CountlyConfig config = new CountlyConfig(this, COUNTLY_APP_KEY, COUNTLY_SERVER_URL)
|
||||
.setDeviceId(DEVICE_ID)
|
||||
.setLoggingEnabled(true)
|
||||
.giveAllConsents()
|
||||
.setRequestDropAgeHours(10)//to trigger the age blocks
|
||||
.setEventQueueSizeToSend(100)//for testing the main use case
|
||||
.setParameterTamperingProtectionSalt("test-benchmark-salt");
|
||||
|
||||
appPcc = new PerformanceCounterCollector();
|
||||
config.pcc = appPcc;
|
||||
|
||||
Countly.sharedInstance().init(config);
|
||||
|
||||
//clear initial state to erase past data
|
||||
Countly.sharedInstance().requestQueue().flushQueues();
|
||||
|
||||
Benchmark.countlyStore = new CountlyStore(this, new ModuleLog());
|
||||
}
|
||||
|
||||
/*
|
||||
* Benchmark scenario - 1
|
||||
* Generate events and not requests: yes
|
||||
* wait: yes
|
||||
* EQ threshold: 10
|
||||
* segm values per event: 5
|
||||
* Generated request count: value doesn't matter
|
||||
* Event count: 10000
|
||||
* Fill to 1000 requests which equals to 10000 events generated
|
||||
*
|
||||
* steps:
|
||||
* 1) turn off internet
|
||||
* 2) clear counters
|
||||
* 3) Fill RQ/EQ
|
||||
* 4) turn on internet
|
||||
* 5) send requests
|
||||
* 6) wait till all sent
|
||||
* 7) print counters
|
||||
*
|
||||
* Scenario 2
|
||||
* RQ size 1000
|
||||
* Generate a mix of 1200 requests
|
||||
* EQ threshold 100
|
||||
* 4 direct requests : 1 event request
|
||||
* direct requests - 960
|
||||
* event requests - 240
|
||||
* events generated - 24000
|
||||
* segm values per event: 6
|
||||
*/
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
package ly.count.android.benchmark;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import ly.count.android.sdk.Countly;
|
||||
import ly.count.android.sdk.CountlyStore;
|
||||
import ly.count.android.sdk.UtilsTime;
|
||||
import org.json.JSONException;
|
||||
|
||||
public class Benchmark {
|
||||
private final BenchmarkUtil benchmarkUtil;
|
||||
protected static CountlyStore countlyStore;
|
||||
|
||||
protected Benchmark() {
|
||||
benchmarkUtil = new BenchmarkUtil();
|
||||
}
|
||||
|
||||
public void fillRequestQueue(int rqSize, int eventSize, int segmentSize) {
|
||||
//Countly.sharedInstance().requestQueue().flushQueues();
|
||||
print("[Benchmark] fillRequestQueue, Filling request queue, rq is flushed");
|
||||
for (int i = 0; i < rqSize; i++) {
|
||||
Map<String, String> additionalParams = null;
|
||||
if (eventSize < 1) {
|
||||
additionalParams = new ConcurrentHashMap<>();
|
||||
additionalParams.put("number", "1");
|
||||
}
|
||||
try {
|
||||
Map<String, String> request = benchmarkUtil.generateRequest(eventSize, segmentSize, additionalParams);
|
||||
Countly.sharedInstance().requestQueue().addDirectRequest(request);
|
||||
} catch (JSONException e) {
|
||||
print("[Benchmark] fillRequestQueue, Failed to generate request: " + e);
|
||||
}
|
||||
}
|
||||
print("[Benchmark] fillRequestQueue, Request queue size: " + countlyStore.getRequests().length);
|
||||
}
|
||||
|
||||
public void fillEventQueue(int eventSize, int segmentSize) {
|
||||
//Countly.sharedInstance().requestQueue().flushQueues();
|
||||
|
||||
print("[Benchmark] fillEventQueue, Filling event queue, rq is flushed");
|
||||
for (int i = 0; i < eventSize; i++) {
|
||||
long tsStartGen = UtilsTime.getNanoTime();
|
||||
Object[] randomEvent = benchmarkUtil.generateRandomEventBase(segmentSize);
|
||||
App.appPcc.TrackCounterTimeNs("Benchmark_genTime", UtilsTime.getNanoTime() - tsStartGen);
|
||||
|
||||
long tsStartAction = UtilsTime.getNanoTime();
|
||||
Countly.sharedInstance().events().recordEvent(randomEvent[0].toString(), (Map<String, Object>) randomEvent[1], (int) randomEvent[2], (double) randomEvent[3], (double) randomEvent[4]);
|
||||
App.appPcc.TrackCounterTimeNs("Benchmark_recordEventTime", UtilsTime.getNanoTime() - tsStartAction);
|
||||
}
|
||||
print("[Benchmark] fillEventQueue, Request queue size: " + countlyStore.getRequests().length);
|
||||
}
|
||||
|
||||
public void GenerateBenchmarkDataset(int eventSize, int segmentSize) {
|
||||
Countly.sharedInstance().requestQueue().flushQueues();
|
||||
|
||||
int eventsPerChunk = 100;
|
||||
//int eventChunks = eventSize / eventsPerChunk;
|
||||
|
||||
int eventsRecorded = 0;
|
||||
|
||||
print("[Benchmark] fillEventQueue, Filling event queue, rq is flushed");
|
||||
while (eventsRecorded < eventSize) {
|
||||
//larger RQ filler
|
||||
long tsStartGenDRequests = UtilsTime.getNanoTime();
|
||||
fillRequestQueue(4, 2, 2);
|
||||
App.appPcc.TrackCounterTimeNs("Benchmark_recordDirectRequests", UtilsTime.getNanoTime() - tsStartGenDRequests);
|
||||
|
||||
//filling it up by individual events
|
||||
for (int i = 0; i < eventsPerChunk; i++) {
|
||||
long tsStartGen = UtilsTime.getNanoTime();
|
||||
Object[] randomEvent = benchmarkUtil.generateRandomEventBase(segmentSize);
|
||||
App.appPcc.TrackCounterTimeNs("Benchmark_genTime", UtilsTime.getNanoTime() - tsStartGen);
|
||||
|
||||
long tsStartAction = UtilsTime.getNanoTime();
|
||||
Countly.sharedInstance().events().recordEvent(randomEvent[0].toString(), (Map<String, Object>) randomEvent[1], (int) randomEvent[2], (double) randomEvent[3], (double) randomEvent[4]);
|
||||
App.appPcc.TrackCounterTimeNs("Benchmark_recordEventTime", UtilsTime.getNanoTime() - tsStartAction);
|
||||
eventsRecorded++;
|
||||
}
|
||||
}
|
||||
print("[Benchmark] fillEventQueue, Request queue size: " + countlyStore.getRequests().length);
|
||||
}
|
||||
|
||||
protected void print(String message) {
|
||||
System.err.println(message);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
package ly.count.android.benchmark;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import ly.count.android.sdk.UtilsTime;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class BenchmarkUtil {
|
||||
private final RandomUtil random;
|
||||
|
||||
protected BenchmarkUtil() {
|
||||
random = new RandomUtil();
|
||||
}
|
||||
|
||||
protected Map<String, String> generateRequest(int eventSize, int segmentSize, Map<String, String> additionalParams) throws JSONException {
|
||||
Map<String, String> request = new ConcurrentHashMap<>();
|
||||
List<JSONObject> events = new ArrayList<>();
|
||||
for (int i = 0; i < eventSize; i++) {
|
||||
events.add(generateRandomEvent(segmentSize));
|
||||
}
|
||||
|
||||
if (!events.isEmpty()) {
|
||||
request.put("events", new JSONArray(events).toString());
|
||||
}
|
||||
|
||||
if (additionalParams != null && !additionalParams.isEmpty()) {
|
||||
request.putAll(additionalParams);
|
||||
}
|
||||
|
||||
return request;
|
||||
}
|
||||
|
||||
protected Map<String, Object> generateSegmentationMap(int segmentSize) {
|
||||
Map<String, Object> segment = new ConcurrentHashMap<>();
|
||||
|
||||
for (int i = 0; i < segmentSize; i++) {
|
||||
String key = random.generateRandomString(8);
|
||||
|
||||
while (segment.containsKey(key)) {
|
||||
key = random.generateRandomString(8);
|
||||
}
|
||||
segment.put(key, random.generateRandomImmutable());
|
||||
}
|
||||
|
||||
return segment;
|
||||
}
|
||||
|
||||
protected Object[] generateRandomEventBase(int segmentSize) {
|
||||
Object[] values = new Object[5];
|
||||
values[0] = random.generateRandomString(8); // key
|
||||
values[1] = generateSegmentationMap(segmentSize); // segmentation
|
||||
values[2] = random.generateRandomInt(1000) + 1; // count
|
||||
values[3] = random.generateRandomDouble() * 1000; // sum
|
||||
values[4] = random.generateRandomDouble() * 1000; // dur
|
||||
return values;
|
||||
}
|
||||
|
||||
protected JSONObject generateRandomEvent(int segmentSize) throws JSONException {
|
||||
JSONObject event = new JSONObject();
|
||||
Object[] values = generateRandomEventBase(segmentSize);
|
||||
event.put("key", values[0]);
|
||||
event.put("count", values[2]);
|
||||
event.put("sum", values[3]);
|
||||
event.put("dur", values[4]);
|
||||
UtilsTime.Instant instant = UtilsTime.getCurrentInstant();
|
||||
event.put("timestamp", instant.timestampMs);
|
||||
event.put("hour", instant.hour);
|
||||
event.put("dow", instant.dow);
|
||||
|
||||
if (segmentSize > 0) {
|
||||
event.put("segment", values[1]);
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
package ly.count.android.benchmark;
|
||||
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.view.View;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Switch;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import ly.count.android.sdk.Countly;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
Benchmark benchmark;
|
||||
|
||||
int loop = 10;
|
||||
int segmentSize = 0;
|
||||
int eventSize = 0;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
benchmark = new Benchmark();
|
||||
}
|
||||
|
||||
public void onHardKillPressed(View v) {
|
||||
int id = android.os.Process.myPid();
|
||||
android.os.Process.killProcess(id);
|
||||
}
|
||||
|
||||
public void onSchedulerPressed(View v) {
|
||||
readLoopSegmentEventSize();
|
||||
futureWrapper(() -> {
|
||||
ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
|
||||
// Schedule the task to run every 10 seconds
|
||||
scheduler.scheduleAtFixedRate(() -> {
|
||||
benchmark.fillRequestQueue(1, eventSize, segmentSize);
|
||||
BENCHMARK(1, Countly.sharedInstance().requestQueue()::attemptToSendStoredRequests);
|
||||
}, 0, 10, TimeUnit.SECONDS);
|
||||
});
|
||||
}
|
||||
|
||||
public void onClickFillRequestQueue(View v) {
|
||||
readLoopSegmentEventSize();
|
||||
if (getSwitchValue(R.id.eventQ)) {
|
||||
futureWrapper(() -> benchmark.fillEventQueue(eventSize, segmentSize));
|
||||
} else {
|
||||
futureWrapper(() -> benchmark.fillRequestQueue(loop, eventSize, segmentSize));
|
||||
}
|
||||
if (getSwitchValue(R.id.wait)) {
|
||||
futureWrapper(this::standByForOnTimer);
|
||||
}
|
||||
}
|
||||
|
||||
private void standByForOnTimer() {
|
||||
benchmark.print("[MainActivity] standByForOnTimer, wait is true, waiting for onTimer to be called");
|
||||
//while (Countly.sharedInstance().standBy.get()) ;
|
||||
benchmark.print("[MainActivity] standByForOnTimer, standBy is false, sending requests");
|
||||
BENCHMARK(loop, null);
|
||||
}
|
||||
|
||||
public void onClickBenchmark(View v) {
|
||||
futureWrapper(() -> BENCHMARK(loop, Countly.sharedInstance().requestQueue()::attemptToSendStoredRequests));
|
||||
}
|
||||
|
||||
public void onClearCounters(View v) {
|
||||
benchmark.print("[MainActivity] clear counters");
|
||||
App.appPcc.Clear();
|
||||
}
|
||||
|
||||
public void onPrintCounters(View v) {
|
||||
benchmark.print("[MainActivity] print counters");
|
||||
String res = App.appPcc.ReturnResults();
|
||||
|
||||
benchmark.print(res);
|
||||
}
|
||||
|
||||
public void onClearStorage(View v) {
|
||||
benchmark.print("[MainActivity] Clear Storage");
|
||||
Countly.sharedInstance().requestQueue().flushQueues();
|
||||
}
|
||||
|
||||
public void onGenerateBenchmarkData(View v) {
|
||||
benchmark.print("[MainActivity] Generate benchmark data");
|
||||
|
||||
readLoopSegmentEventSize();
|
||||
|
||||
futureWrapper(() -> benchmark.GenerateBenchmarkDataset(eventSize, segmentSize));
|
||||
|
||||
if (getSwitchValue(R.id.wait)) {
|
||||
futureWrapper(this::standByForOnTimer);
|
||||
}
|
||||
}
|
||||
|
||||
protected void BENCHMARK(int loop, Runnable runnable) {
|
||||
benchmark.print("------------------------------------------------------------");
|
||||
benchmark.print("[MainActivity] BENCHMARK");
|
||||
benchmark.print("------------------------------------------------------------");
|
||||
benchmark.print("[MainActivity] BENCHMARK, rqSize: " + Benchmark.countlyStore.getRequests().length);
|
||||
|
||||
benchmark.print("[MainActivity] BENCHMARK loop: " + loop + ", events size: " + eventSize + ", segment size: " + segmentSize);
|
||||
benchmark.print("[MainActivity] BENCHMARK Triggering sending");
|
||||
long startTime = System.currentTimeMillis();
|
||||
if (runnable != null) {
|
||||
runnable.run();
|
||||
}
|
||||
while (Benchmark.countlyStore.getRequests().length > 0) ; // wait for RQ to finish sending
|
||||
long endTime = System.currentTimeMillis();
|
||||
benchmark.print("[MainActivity] BENCHMARK, SENDING TOOK: " + (endTime - startTime) + "MS");
|
||||
benchmark.print("------------------------------------------------------------");
|
||||
|
||||
String res = App.appPcc.ReturnResults();
|
||||
benchmark.print(res);
|
||||
}
|
||||
|
||||
private void readLoopSegmentEventSize() {
|
||||
loop = Integer.parseInt(((EditText) findViewById(R.id.loop)).getText().toString());
|
||||
segmentSize = Integer.parseInt(((EditText) findViewById(R.id.segmentSize)).getText().toString());
|
||||
eventSize = Integer.parseInt(((EditText) findViewById(R.id.eventSize)).getText().toString());
|
||||
}
|
||||
|
||||
private void futureWrapper(Runnable runnable) {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
|
||||
CompletableFuture.runAsync(() -> {
|
||||
try {
|
||||
runnable.run();
|
||||
} catch (Exception e) {
|
||||
Countly.sharedInstance().L.e("[MainActivity] futureWrapper, Failed to run scheduler", e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private boolean getSwitchValue(int id) {
|
||||
return ((Switch) findViewById(id)).isChecked();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
package ly.count.android.benchmark;
|
||||
|
||||
import java.util.Random;
|
||||
|
||||
public class RandomUtil {
|
||||
private final Random random;
|
||||
|
||||
public RandomUtil() {
|
||||
random = new Random();
|
||||
}
|
||||
|
||||
public String generateRandomString(int size) {
|
||||
int length = random.nextInt(size) + 1; // Random string length between 1 and 20
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < length; i++) {
|
||||
char randomChar = (char) (random.nextInt(26) + 'a'); // Random lowercase letter
|
||||
sb.append(randomChar);
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public int generateRandomInt(int bound) {
|
||||
return random.nextInt(bound);
|
||||
}
|
||||
|
||||
public double generateRandomDouble() {
|
||||
return random.nextDouble();
|
||||
}
|
||||
|
||||
protected Object generateRandomImmutable() {
|
||||
int randomInt = random.nextInt(6);
|
||||
Object value;
|
||||
switch (randomInt) {
|
||||
case 0:
|
||||
value = random.nextInt();
|
||||
break;
|
||||
case 1:
|
||||
value = random.nextBoolean();
|
||||
break;
|
||||
case 2:
|
||||
value = random.nextLong();
|
||||
break;
|
||||
case 3:
|
||||
value = random.nextFloat();
|
||||
break;
|
||||
case 4:
|
||||
value = random.nextDouble();
|
||||
break;
|
||||
case 5:
|
||||
value = generateRandomString(20);
|
||||
break;
|
||||
default:
|
||||
value = "default";
|
||||
break;
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 9.2 KiB |
|
After Width: | Height: | Size: 167 B |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 130 B |
|
After Width: | Height: | Size: 14 KiB |
|
After Width: | Height: | Size: 204 B |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 269 B |
|
After Width: | Height: | Size: 342 B |
|
After Width: | Height: | Size: 167 B |
@@ -0,0 +1,151 @@
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:paddingLeft="@dimen/activity_horizontal_margin"
|
||||
android:paddingRight="@dimen/activity_horizontal_margin"
|
||||
android:paddingTop="@dimen/activity_vertical_margin"
|
||||
android:paddingBottom="@dimen/activity_vertical_margin"
|
||||
tools:context=".MainActivity"
|
||||
>
|
||||
|
||||
<Switch
|
||||
android:id="@+id/eventQ"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_alignBottom="@+id/wait"
|
||||
android:layout_marginBottom="-46dp"
|
||||
android:checked="true"
|
||||
android:minHeight="48dp"
|
||||
android:text="Generate Events in place of requests"
|
||||
/>
|
||||
<Switch
|
||||
android:id="@+id/wait"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:checked="true"
|
||||
android:minHeight="48dp"
|
||||
android:text="Wait"
|
||||
/>
|
||||
<LinearLayout
|
||||
android:orientation="vertical"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_centerHorizontal="true"
|
||||
tools:ignore="UselessParent"
|
||||
>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Segmentation Values Per Event:"
|
||||
/>
|
||||
<EditText
|
||||
android:id="@+id/segmentSize"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autofillHints=""
|
||||
android:ems="10"
|
||||
android:inputType="number"
|
||||
android:minHeight="48dp"
|
||||
android:text="6"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/textView2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Generated Request Count:"
|
||||
/>
|
||||
<EditText
|
||||
android:id="@+id/loop"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:autofillHints=""
|
||||
android:ems="10"
|
||||
android:inputType="number"
|
||||
android:minHeight="48dp"
|
||||
android:text="1"
|
||||
/>
|
||||
<TextView
|
||||
android:id="@+id/textView3"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Event Count:"
|
||||
/>
|
||||
<EditText
|
||||
android:id="@+id/eventSize"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ems="10"
|
||||
android:importantForAutofill="no"
|
||||
android:inputType="number"
|
||||
android:minHeight="48dp"
|
||||
android:text="24000"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/button2"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onGenerateBenchmarkData"
|
||||
android:text="Generate benchmark Data"
|
||||
android:visibility="visible"
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/button9"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClickFillRequestQueue"
|
||||
android:text="@string/fill_rq"
|
||||
android:visibility="visible"
|
||||
tools:visibility="visible"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/tests_button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClickBenchmark"
|
||||
android:text="@string/send_requests"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/button20"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onHardKillPressed"
|
||||
android:text="Exit"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/button23"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onSchedulerPressed"
|
||||
android:text="Schedule"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button24"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClearCounters"
|
||||
android:text="Clear Counter"
|
||||
/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/button25"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onPrintCounters"
|
||||
android:text="Print Counter"
|
||||
/>
|
||||
<Button
|
||||
android:id="@+id/button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:onClick="onClearStorage"
|
||||
android:text="Clear Storage"
|
||||
/>
|
||||
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 29 KiB |
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
|
||||
(such as screen margins) for screens with more than 820dp of available width. This
|
||||
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
|
||||
<dimen name="activity_horizontal_margin">64dp</dimen>
|
||||
</resources>
|
||||
@@ -0,0 +1,6 @@
|
||||
<resources>
|
||||
<dimen name="fab_margin">16dp</dimen>
|
||||
|
||||
<dimen name="activity_horizontal_margin">16dp</dimen>
|
||||
<dimen name="activity_vertical_margin">16dp</dimen>
|
||||
</resources>
|
||||
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Countly Benchmarking App</string>
|
||||
<string name="fill_rq">Fill RQ</string>
|
||||
<string name="send_requests">Send Requests</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,17 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.NoActionBar">
|
||||
<item name="windowActionBar">false</item>
|
||||
<item name="windowNoTitle">true</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar" />
|
||||
|
||||
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light" />
|
||||
|
||||
</resources>
|
||||
1
libraries/countly/app-kotlin/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
47
libraries/countly/app-kotlin/build.gradle
Normal file
@@ -0,0 +1,47 @@
|
||||
plugins {
|
||||
id 'com.android.application'
|
||||
id 'kotlin-android'
|
||||
id 'kotlin-kapt'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.android.compileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId "ly.count.android.demo.kotlin"
|
||||
minSdkVersion rootProject.ext.android.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.android.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
kotlinOptions {
|
||||
jvmTarget = '1.8'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
||||
implementation 'androidx.core:core-ktx:1.5.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
|
||||
implementation 'androidx.navigation:navigation-fragment-ktx:2.1.0'
|
||||
implementation 'androidx.navigation:navigation-ui-ktx:2.1.0'
|
||||
|
||||
implementation project(':libraries:countly:sdk')
|
||||
}
|
||||
21
libraries/countly/app-kotlin/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
25
libraries/countly/app-kotlin/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="ly.count.android.demo.kotlin">
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
|
||||
<application
|
||||
android:name=".App"
|
||||
android:allowBackup="true"
|
||||
android:label="@string/app_name"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/Theme.Kotlin">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
BIN
libraries/countly/app-kotlin/src/main/ic_launcher-playstore.png
Normal file
|
After Width: | Height: | Size: 76 KiB |
@@ -0,0 +1,67 @@
|
||||
package ly.count.android.demo.kotlin
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.navigation.findNavController
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
/**
|
||||
* Adapter for the main list
|
||||
*/
|
||||
class AdapterMainList :
|
||||
RecyclerView.Adapter<AdapterMainList.MainViewHolder>() {
|
||||
|
||||
private val list = listOf("event", "sessions", "view", "remote config")
|
||||
|
||||
/**
|
||||
* View holder for the main list
|
||||
*/
|
||||
class MainViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||
val button: Button = view.findViewById(R.id.item_view)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int {
|
||||
return list.size
|
||||
}
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MainViewHolder {
|
||||
val layout = LayoutInflater
|
||||
.from(parent.context)
|
||||
.inflate(R.layout.item_view, parent, false)
|
||||
|
||||
return MainViewHolder(layout)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: MainViewHolder, position: Int) {
|
||||
val item = list[position]
|
||||
holder.button.text = item
|
||||
|
||||
// 创建Bundle来保存参数
|
||||
val bundle = Bundle()
|
||||
bundle.putString("title", holder.button.text.toString())
|
||||
|
||||
// 创建Fragment实例
|
||||
val fragment = FragmentCustomEvents()
|
||||
|
||||
// 设置参数
|
||||
fragment.arguments = bundle
|
||||
|
||||
// 设置一个标记
|
||||
val tag = "FragmentCustomEvents"
|
||||
|
||||
// 使用FragmentManager来添加或替换Fragment
|
||||
holder.button.setOnClickListener {
|
||||
val fragmentManager = (holder.view.context as? AppCompatActivity)?.supportFragmentManager
|
||||
fragmentManager?.beginTransaction()
|
||||
?.replace(R.id.nav_host_fragment, fragment, tag) // R.id.fragmentContainerId应该是您容器的ID
|
||||
?.addToBackStack(null)
|
||||
?.commit()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package ly.count.android.demo.kotlin
|
||||
|
||||
import android.content.Context
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import android.widget.Button
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
import ly.count.android.sdk.Countly
|
||||
|
||||
/**
|
||||
* Adapter for the second list
|
||||
*/
|
||||
class AdapterSecondList(private val titleId: String, context: Context) :
|
||||
RecyclerView.Adapter<AdapterSecondList.SecondViewHolder>() {
|
||||
|
||||
private val filteredWords: List<String>
|
||||
|
||||
init {
|
||||
val titles = context.resources.getStringArray(R.array.titles).toList()
|
||||
|
||||
filteredWords = titles
|
||||
.filter { it.contains(titleId, ignoreCase = true) }
|
||||
.shuffled()
|
||||
.sorted()
|
||||
}
|
||||
|
||||
/**
|
||||
* View holder for the second list
|
||||
*/
|
||||
class SecondViewHolder(val view: View) : RecyclerView.ViewHolder(view) {
|
||||
val button = view.findViewById<Button>(R.id.item_view)
|
||||
}
|
||||
|
||||
override fun getItemCount(): Int = filteredWords.size
|
||||
|
||||
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): SecondViewHolder {
|
||||
val layout = LayoutInflater
|
||||
.from(parent.context)
|
||||
.inflate(R.layout.item_view, parent, false)
|
||||
|
||||
return SecondViewHolder(layout)
|
||||
}
|
||||
|
||||
override fun onBindViewHolder(holder: SecondViewHolder, position: Int) {
|
||||
val item = filteredWords[position]
|
||||
// Needed to call startActivity
|
||||
val context = holder.view.context
|
||||
// Set the text of the WordViewHolder
|
||||
holder.button.text = item
|
||||
|
||||
holder.view.setOnClickListener {
|
||||
Countly.sharedInstance().events().recordEvent(item)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
package ly.count.android.demo.kotlin
|
||||
|
||||
import android.app.Application
|
||||
import android.util.Log
|
||||
import ly.count.android.sdk.Countly
|
||||
import ly.count.android.sdk.CountlyConfig
|
||||
|
||||
/**
|
||||
* Main Application class
|
||||
*/
|
||||
class App : Application() {
|
||||
private val COUNTLY_SERVER_URL = "https://your.server.ly"
|
||||
private val COUNTLY_APP_KEY = "YOUR_APP_KEY"
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
|
||||
// if (COUNTLY_SERVER_URL == "https://your.server.ly" || COUNTLY_APP_KEY == "YOUR_APP_KEY") {
|
||||
// Log.e("CountlyDemo", "Please provide correct COUNTLY_SERVER_URL and COUNTLY_APP_KEY")
|
||||
// return
|
||||
// }
|
||||
|
||||
val countlyConfig = CountlyConfig(
|
||||
this,
|
||||
COUNTLY_APP_KEY,
|
||||
COUNTLY_SERVER_URL
|
||||
)
|
||||
.setDeviceId(
|
||||
"myDeviceId"
|
||||
)
|
||||
.enableCrashReporting()
|
||||
.setRecordAllThreadsWithCrash()
|
||||
.setLoggingEnabled(true)
|
||||
.setViewTracking(false)
|
||||
|
||||
Countly.sharedInstance().init(countlyConfig)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package ly.count.android.demo.kotlin
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
/**
|
||||
* Fragment for the events list
|
||||
*/
|
||||
class FragmentCustomEvents : Fragment() {
|
||||
|
||||
companion object {
|
||||
val TITLE = "title"
|
||||
}
|
||||
|
||||
private var _binding: View? = null
|
||||
private val binding get() = _binding!!
|
||||
private lateinit var titleId: String
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
arguments?.let {
|
||||
titleId = it.getString(TITLE).toString()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding =
|
||||
LayoutInflater.from(context).inflate(R.layout.fragment_second_list, container, false)
|
||||
return binding
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
val recyclerView = binding.findViewById<RecyclerView>(R.id.recycler_view)
|
||||
recyclerView.layoutManager = LinearLayoutManager(requireContext())
|
||||
recyclerView.adapter = AdapterSecondList(titleId, requireContext())
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package ly.count.android.demo.kotlin
|
||||
|
||||
import android.os.Bundle
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.recyclerview.widget.LinearLayoutManager
|
||||
import androidx.recyclerview.widget.RecyclerView
|
||||
|
||||
/**
|
||||
* Fragment for the main list
|
||||
*/
|
||||
class FragmentMainList : Fragment() {
|
||||
private var _binding: View? = null
|
||||
|
||||
private val binding get() = _binding!!
|
||||
private lateinit var recyclerView: RecyclerView
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
}
|
||||
|
||||
override fun onCreateView(
|
||||
inflater: LayoutInflater,
|
||||
container: ViewGroup?,
|
||||
savedInstanceState: Bundle?
|
||||
): View? {
|
||||
_binding =
|
||||
LayoutInflater.from(context).inflate(R.layout.fragment_main_list, container, false)
|
||||
val view = binding
|
||||
return view
|
||||
}
|
||||
|
||||
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
|
||||
recyclerView = binding.findViewById(R.id.recycler_view)
|
||||
recyclerView.layoutManager = LinearLayoutManager(context)
|
||||
recyclerView.adapter = AdapterMainList()
|
||||
}
|
||||
|
||||
override fun onDestroyView() {
|
||||
super.onDestroyView()
|
||||
_binding = null
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
package ly.count.android.demo.kotlin
|
||||
|
||||
import android.content.res.Configuration
|
||||
import android.os.Bundle
|
||||
import androidx.appcompat.app.AppCompatActivity
|
||||
import androidx.navigation.NavController
|
||||
import androidx.navigation.fragment.NavHostFragment
|
||||
import androidx.navigation.ui.setupActionBarWithNavController
|
||||
import ly.count.android.sdk.Countly
|
||||
|
||||
/**
|
||||
* Main Activity
|
||||
*/
|
||||
class MainActivity : AppCompatActivity() {
|
||||
private lateinit var navController: NavController
|
||||
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
|
||||
setContentView(R.layout.activity_main)
|
||||
|
||||
val navHostFragment = supportFragmentManager
|
||||
.findFragmentById(R.id.nav_host_fragment) as NavHostFragment
|
||||
navController = navHostFragment.navController
|
||||
setupActionBarWithNavController(navController)
|
||||
}
|
||||
|
||||
override fun onSupportNavigateUp(): Boolean {
|
||||
return navController.navigateUp() || super.onSupportNavigateUp()
|
||||
}
|
||||
|
||||
override fun onStart() {
|
||||
super.onStart()
|
||||
Countly.sharedInstance().onStart(this)
|
||||
}
|
||||
|
||||
override fun onStop() {
|
||||
Countly.sharedInstance().onStop()
|
||||
super.onStop()
|
||||
}
|
||||
|
||||
override fun onConfigurationChanged(newConfig: Configuration) {
|
||||
super.onConfigurationChanged(newConfig)
|
||||
Countly.sharedInstance().onConfigurationChanged(newConfig)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="28dp"
|
||||
android:height="28dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M4,11h5L9,5L4,5v6zM4,18h5v-6L4,12v6zM10,18h5v-6h-5v6zM16,18h5v-6h-5v6zM10,11h5L15,5h-5v6zM16,5v6h5L21,5h-5z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108.3dp"
|
||||
android:height="108.3dp"
|
||||
android:viewportWidth="108.3"
|
||||
android:viewportHeight="108.3">
|
||||
<path
|
||||
android:pathData="M26.04,0L82.26,0A26.04,26.04 0,0 1,108.3 26.04L108.3,82.26A26.04,26.04 0,0 1,82.26 108.3L26.04,108.3A26.04,26.04 0,0 1,0 82.26L0,26.04A26.04,26.04 0,0 1,26.04 0z"
|
||||
android:fillColor="#0097a7" />
|
||||
</vector>
|
||||
@@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108"
|
||||
android:name="vector">
|
||||
<group
|
||||
android:scaleX="0.72527474"
|
||||
android:scaleY="0.72527474"
|
||||
android:translateX="22.45055"
|
||||
android:translateY="21">
|
||||
<path
|
||||
android:name="path"
|
||||
android:pathData="M 20.67 45.82 L 0 31.66 L 25.04 32.35 L 16.64 8.75 L 36.49 24.03 L 43.57 0 L 50.65 24.03 L 70.5 8.75 L 62.11 32.35 L 87.15 31.66 L 66.48 45.82 L 87.15 59.98 L 62.11 59.28 L 70.5 82.88 L 50.65 67.6 L 43.57 91.63 L 36.49 67.6 L 16.64 82.88 L 25.04 59.28 L 0 59.98 L 20.67 45.82 Z"
|
||||
android:fillColor="#fcc015" />
|
||||
<path
|
||||
android:name="path_1"
|
||||
android:pathData="M 21.2 22.45 L 40.74 22.45 C 41.095 22.45 41.436 22.591 41.688 22.842 C 41.939 23.094 42.08 23.435 42.08 23.79 L 42.08 42.85 C 42.08 43.205 41.939 43.546 41.688 43.798 C 41.436 44.049 41.095 44.19 40.74 44.19 L 21.2 44.19 C 20.845 44.19 20.504 44.049 20.252 43.798 C 20.001 43.546 19.86 43.205 19.86 42.85 L 19.86 23.79 C 19.86 23.435 20.001 23.094 20.252 22.842 C 20.504 22.591 20.845 22.45 21.2 22.45 Z"
|
||||
android:fillColor="#006064" />
|
||||
<path
|
||||
android:name="path_2"
|
||||
android:pathData="M 30 28.91 L 31.91 28.91 L 35.22 37.72 L 33.4 37.72 L 32.66 35.62 L 29.28 35.62 L 28.55 37.72 L 26.71 37.72 Z M 32.11 34.09 L 31.33 31.87 L 31 30.81 L 30.9 30.81 L 30.58 31.87 L 29.79 34.09 Z"
|
||||
android:fillColor="#fff" />
|
||||
<path
|
||||
android:name="path_3"
|
||||
android:pathData="M 46.41 22.45 L 65.95 22.45 C 66.305 22.45 66.646 22.591 66.898 22.842 C 67.149 23.094 67.29 23.435 67.29 23.79 L 67.29 42.85 C 67.29 43.205 67.149 43.546 66.898 43.798 C 66.646 44.049 66.305 44.19 65.95 44.19 L 46.41 44.19 C 46.055 44.19 45.714 44.049 45.462 43.798 C 45.211 43.546 45.07 43.205 45.07 42.85 L 45.07 23.79 C 45.07 23.435 45.211 23.094 45.462 22.842 C 45.714 22.591 46.055 22.45 46.41 22.45 Z"
|
||||
android:fillColor="#006064" />
|
||||
<path
|
||||
android:name="path_4"
|
||||
android:pathData="M 52.94 28.91 L 56.39 28.91 C 56.861 28.902 57.326 29.005 57.75 29.21 C 58.151 29.398 58.496 29.687 58.75 30.05 C 58.975 30.393 59.094 30.795 59.094 31.205 C 59.094 31.615 58.975 32.017 58.75 32.36 C 58.54 32.682 58.246 32.941 57.9 33.11 L 57.9 33.2 C 58.338 33.351 58.721 33.63 59 34 C 59.28 34.367 59.425 34.819 59.41 35.28 C 59.411 35.739 59.267 36.187 59 36.56 C 58.747 36.928 58.402 37.225 58 37.42 C 57.541 37.624 57.043 37.726 56.54 37.72 L 52.94 37.72 Z M 56.27 32.5 C 56.588 32.515 56.899 32.408 57.14 32.2 C 57.244 32.103 57.327 31.986 57.382 31.855 C 57.437 31.723 57.464 31.582 57.46 31.44 C 57.462 31.302 57.436 31.165 57.382 31.038 C 57.329 30.91 57.25 30.795 57.15 30.7 C 56.924 30.495 56.625 30.387 56.32 30.4 L 54.61 30.4 L 54.61 32.5 Z M 56.45 36.21 C 56.794 36.228 57.133 36.117 57.4 35.9 C 57.509 35.794 57.595 35.666 57.652 35.525 C 57.709 35.384 57.735 35.232 57.73 35.08 C 57.737 34.925 57.71 34.771 57.651 34.628 C 57.592 34.484 57.503 34.355 57.39 34.25 C 57.11 34.02 56.752 33.905 56.39 33.93 L 54.61 33.93 L 54.61 36.21 Z"
|
||||
android:fillColor="#fff" />
|
||||
<path
|
||||
android:name="path_5"
|
||||
android:pathData="M 21.2 47.45 L 40.74 47.45 C 41.095 47.45 41.436 47.591 41.688 47.842 C 41.939 48.094 42.08 48.435 42.08 48.79 L 42.08 67.85 C 42.08 68.205 41.939 68.546 41.688 68.798 C 41.436 69.049 41.095 69.19 40.74 69.19 L 21.2 69.19 C 20.845 69.19 20.504 69.049 20.252 68.798 C 20.001 68.546 19.86 68.205 19.86 67.85 L 19.86 48.79 C 19.86 48.435 20.001 48.094 20.252 47.842 C 20.504 47.591 20.845 47.45 21.2 47.45 Z"
|
||||
android:fillColor="#006064" />
|
||||
<path
|
||||
android:name="path_6"
|
||||
android:pathData="M 29.18 62.32 C 28.24 61.777 27.521 60.92 27.15 59.899 C 26.779 58.879 26.779 57.761 27.15 56.741 C 27.521 55.72 28.24 54.863 29.18 54.32 C 29.893 53.916 30.7 53.705 31.52 53.71 C 32.142 53.695 32.76 53.815 33.33 54.064 C 33.9 54.313 34.408 54.684 34.82 55.15 L 33.65 56.29 C 33.396 55.972 33.074 55.717 32.706 55.544 C 32.339 55.371 31.936 55.284 31.53 55.29 C 31.006 55.28 30.489 55.408 30.03 55.66 C 29.595 55.915 29.239 56.286 29 56.73 C 28.75 57.223 28.62 57.768 28.62 58.32 C 28.62 58.872 28.75 59.417 29 59.91 C 29.227 60.358 29.573 60.736 30 61 C 30.458 61.256 30.975 61.387 31.5 61.38 C 31.952 61.383 32.399 61.28 32.804 61.078 C 33.208 60.877 33.56 60.583 33.83 60.22 L 35 61.31 C 34.587 61.824 34.06 62.235 33.46 62.51 C 32.832 62.794 32.149 62.934 31.46 62.92 C 30.661 62.917 29.876 62.711 29.18 62.32 Z"
|
||||
android:fillColor="#fff" />
|
||||
<path
|
||||
android:name="path_7"
|
||||
android:pathData="M 46.41 47.45 L 65.95 47.45 C 66.305 47.45 66.646 47.591 66.898 47.842 C 67.149 48.094 67.29 48.435 67.29 48.79 L 67.29 67.85 C 67.29 68.205 67.149 68.546 66.898 68.798 C 66.646 69.049 66.305 69.19 65.95 69.19 L 46.41 69.19 C 46.055 69.19 45.714 69.049 45.462 68.798 C 45.211 68.546 45.07 68.205 45.07 67.85 L 45.07 48.79 C 45.07 48.435 45.211 48.094 45.462 47.842 C 45.714 47.591 46.055 47.45 46.41 47.45 Z"
|
||||
android:fillColor="#006064" />
|
||||
<path
|
||||
android:name="path_8"
|
||||
android:pathData="M 52.42 53.91 L 55.42 53.91 C 56.253 53.89 57.078 54.079 57.82 54.46 C 58.477 54.813 59.018 55.348 59.38 56 C 59.742 56.713 59.93 57.501 59.93 58.3 C 59.93 59.099 59.742 59.887 59.38 60.6 C 59.016 61.259 58.466 61.798 57.8 62.15 C 57.059 62.534 56.234 62.727 55.4 62.71 L 52.4 62.71 Z M 55.33 61.15 C 55.726 61.178 56.123 61.125 56.498 60.995 C 56.873 60.864 57.217 60.658 57.51 60.39 C 57.768 60.114 57.968 59.788 58.097 59.432 C 58.226 59.076 58.281 58.698 58.26 58.32 C 58.28 57.941 58.225 57.561 58.096 57.204 C 57.967 56.847 57.768 56.519 57.51 56.24 C 57.214 55.977 56.869 55.776 56.495 55.647 C 56.121 55.519 55.725 55.465 55.33 55.49 L 54.08 55.49 L 54.08 61.15 Z"
|
||||
android:fillColor="#fff" />
|
||||
</group>
|
||||
</vector>
|
||||
@@ -0,0 +1,11 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="28dp"
|
||||
android:height="28dp"
|
||||
android:tint="#FFFFFF"
|
||||
android:viewportWidth="24"
|
||||
android:viewportHeight="24">
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:pathData="M4,14h4v-4L4,10v4zM4,19h4v-4L4,15v4zM4,9h4L8,5L4,5v4zM9,14h12v-4L9,10v4zM9,19h12v-4L9,15v4zM9,5v4h12L21,5L9,5z" />
|
||||
</vector>
|
||||
@@ -0,0 +1,19 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity"
|
||||
>
|
||||
|
||||
<androidx.fragment.app.FragmentContainerView
|
||||
android:id="@+id/nav_host_fragment"
|
||||
android:name="androidx.navigation.fragment.NavHostFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:defaultNavHost="true"
|
||||
app:navGraph="@navigation/nav_graph"
|
||||
/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".FragmentMainList"
|
||||
>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:padding="16dp"
|
||||
/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,18 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".FragmentCustomEvents"
|
||||
>
|
||||
|
||||
<androidx.recyclerview.widget.RecyclerView
|
||||
android:id="@+id/recycler_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clipToPadding="false"
|
||||
android:padding="16dp"
|
||||
tools:listitem="@layout/item_view"
|
||||
/>
|
||||
|
||||
</FrameLayout>
|
||||
@@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Button xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:id="@+id/item_view"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="4dp"
|
||||
android:padding="8dp"
|
||||
/>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 982 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 1.9 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 2.8 KiB |
|
After Width: | Height: | Size: 5.8 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
@@ -0,0 +1,25 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:id="@+id/nav_graph"
|
||||
app:startDestination="@id/fragmentMainList">
|
||||
|
||||
<fragment
|
||||
android:id="@+id/fragmentMainList"
|
||||
android:name="ly.count.android.demo.kotlin.FragmentMainList"
|
||||
android:label="@string/app_name">
|
||||
<action
|
||||
android:id="@+id/action_fragmentMainList_to_fragmentCustomEvents"
|
||||
app:destination="@id/fragmentCustomEvents" />
|
||||
</fragment>
|
||||
<fragment
|
||||
android:id="@+id/fragmentCustomEvents"
|
||||
android:name="ly.count.android.demo.kotlin.FragmentCustomEvents"
|
||||
android:label="@string/new_button_title"
|
||||
tools:layout="@layout/fragment_second_list">
|
||||
<argument
|
||||
android:name="title"
|
||||
app:argType="string" />
|
||||
</fragment>
|
||||
</navigation>
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<style name="Theme.Kotlin" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<item name="colorPrimary">@color/green_700</item>
|
||||
<item name="colorPrimaryVariant">@color/green_900</item>
|
||||
<item name="colorOnPrimary">@color/black</item>
|
||||
<item name="colorSecondary">@color/blue_200</item>
|
||||
<item name="colorSecondaryVariant">@color/blue_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
</style>
|
||||
</resources>
|
||||
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string-array name="titles">
|
||||
<item>event 1</item>
|
||||
<item>event 2</item>
|
||||
<item>session begin</item>
|
||||
<item>sessions end</item>
|
||||
</string-array>
|
||||
</resources>
|
||||
13
libraries/countly/app-kotlin/src/main/res/values/colors.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="green_200">#FF4EC263</color>
|
||||
<color name="green_700">#7EF56E</color>
|
||||
<color name="green_900">#64FAAA</color>
|
||||
|
||||
<color name="blue_200">#62A3FF</color>
|
||||
<color name="blue_700">#1675D1</color>
|
||||
<color name="blue_900">#004A9F</color>
|
||||
|
||||
<color name="black">#FF000000</color>
|
||||
<color name="white">#FFFFFFFF</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<string name="app_name">Countly</string>
|
||||
<string name="new_button_title">{title}</string>
|
||||
</resources>
|
||||
@@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
|
||||
<style name="Widget.Words.TextView" parent="Widget.MaterialComponents.TextView">
|
||||
<item name="android:textAppearance">?attr/textAppearanceHeadline4</item>
|
||||
</style>
|
||||
</resources>
|
||||
13
libraries/countly/app-kotlin/src/main/res/values/themes.xml
Normal file
@@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||
|
||||
<style name="Theme.Kotlin" parent="Theme.MaterialComponents.DayNight.DarkActionBar">
|
||||
<item name="colorPrimary">@color/green_700</item>
|
||||
<item name="colorPrimaryVariant">@color/green_900</item>
|
||||
<item name="colorOnPrimary">@color/white</item>
|
||||
<item name="colorSecondary">@color/blue_200</item>
|
||||
<item name="colorSecondaryVariant">@color/blue_700</item>
|
||||
<item name="colorOnSecondary">@color/black</item>
|
||||
<item name="android:statusBarColor" tools:targetApi="l">?attr/colorPrimaryVariant</item>
|
||||
</style>
|
||||
</resources>
|
||||
1
libraries/countly/app-native/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
62
libraries/countly/app-native/build.gradle
Normal file
@@ -0,0 +1,62 @@
|
||||
apply plugin: 'com.android.application'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.android.compileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
applicationId "ly.count.android.demo.crash"
|
||||
minSdkVersion rootProject.ext.android.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.android.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
externalNativeBuild {
|
||||
cmake {
|
||||
path file('src/main/cpp/CMakeLists.txt')
|
||||
}
|
||||
}
|
||||
// ndkVersion '16.1.4479499'
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
// needed for using sdk-native from countly maven repo
|
||||
mavenCentral()
|
||||
}
|
||||
|
||||
// sdk and sdk-native are pulled from submodules of the project.
|
||||
// If you are running app independently, you may pull their latest version from our maven repo using the commented lines.
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
|
||||
implementation project(':libraries:countly:sdk')
|
||||
//implementation 'ly.count.android:sdk:21.11.0'
|
||||
implementation project(':libraries:countly:sdk-native')
|
||||
//implementation 'ly.count.android:sdk-native:21.11.0'
|
||||
}
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
dependencies {
|
||||
classpath group: 'com.squareup.okhttp3', name: 'okhttp', version: '3.14.1'
|
||||
}
|
||||
}
|
||||
|
||||
21
libraries/countly/app-native/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
22
libraries/countly/app-native/src/main/AndroidManifest.xml
Normal file
@@ -0,0 +1,22 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="ly.count.android.demo.crash">
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
|
||||
<application
|
||||
android:name=".App"
|
||||
android:icon="@mipmap/ic_launcher"
|
||||
android:label="@string/app_name"
|
||||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
<activity android:name=".MainActivity"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
44
libraries/countly/app-native/src/main/cpp/CMakeLists.txt
Normal file
@@ -0,0 +1,44 @@
|
||||
# For more information about using CMake with Android Studio, read the
|
||||
# documentation: https://d.android.com/studio/projects/add-native-code.html
|
||||
|
||||
# Sets the minimum version of CMake required to build the native library.
|
||||
|
||||
cmake_minimum_required(VERSION 3.4.1)
|
||||
|
||||
# Creates and names a library, sets it as either STATIC
|
||||
# or SHARED, and provides the relative paths to its source code.
|
||||
# You can define multiple libraries, and CMake builds them for you.
|
||||
# Gradle automatically packages shared libraries with your APK.
|
||||
|
||||
add_library( # Sets the name of the library.
|
||||
native-lib
|
||||
|
||||
# Sets the library as a shared library.
|
||||
SHARED
|
||||
|
||||
# Provides a relative path to your source file(s).
|
||||
native-lib.cpp)
|
||||
|
||||
# Searches for a specified prebuilt library and stores the path as a
|
||||
# variable. Because CMake includes system libraries in the search path by
|
||||
# default, you only need to specify the name of the public NDK library
|
||||
# you want to add. CMake verifies that the library exists before
|
||||
# completing its build.
|
||||
|
||||
find_library( # Sets the name of the path variable.
|
||||
log-lib
|
||||
|
||||
# Specifies the name of the NDK library that
|
||||
# you want CMake to locate.
|
||||
log)
|
||||
|
||||
# Specifies libraries CMake should link to your target library. You
|
||||
# can link multiple libraries, such as libraries you define in this
|
||||
# build script, prebuilt third-party libraries, or system libraries.
|
||||
|
||||
target_link_libraries( # Specifies the target library.
|
||||
native-lib
|
||||
|
||||
# Links the target library to the log library
|
||||
# included in the NDK.
|
||||
${log-lib})
|
||||
43
libraries/countly/app-native/src/main/cpp/native-lib.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <jni.h>
|
||||
#include <string>
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#ifndef DEBUG
|
||||
#define DEBUG 1
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define TAG_NAME "COUNTLY_DEMO_CRASH_cpp"
|
||||
#define LOGV(...) __android_log_print(2, TAG_NAME, __VA_ARGS__)
|
||||
#define LOGD(...) __android_log_print(3, TAG_NAME, __VA_ARGS__)
|
||||
#define LOGI(...) __android_log_print(4, TAG_NAME, __VA_ARGS__)
|
||||
#define LOGW(...) __android_log_print(5, TAG_NAME, __VA_ARGS__)
|
||||
#define LOGE(...) __android_log_print(6, TAG_NAME, __VA_ARGS__)
|
||||
#else
|
||||
#define LOGV(...) {}
|
||||
#define LOGD(...) {}
|
||||
#define LOGI(...) {}
|
||||
#define LOGW(...) {}
|
||||
#define LOGE(...) {}
|
||||
#endif
|
||||
|
||||
extern "C" {
|
||||
JNIEXPORT jstring JNICALL
|
||||
Java_ly_count_android_demo_crash_MainActivity_stringFromJNI(
|
||||
JNIEnv *env,
|
||||
jobject /* this */) {
|
||||
std::string hello = "Hello from C++";
|
||||
return env->NewStringUTF(hello.c_str());
|
||||
}
|
||||
|
||||
JNIEXPORT jint JNICALL Java_ly_count_android_demo_crash_MainActivity_testCrash(JNIEnv *env,
|
||||
jobject obj) {
|
||||
LOGE("native crash capture begin");
|
||||
char *ptr = NULL;
|
||||
*ptr = 1;
|
||||
LOGE("native crash capture end");
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
package ly.count.android.demo.crash;
|
||||
|
||||
import android.app.Application;
|
||||
import android.util.Log;
|
||||
import ly.count.android.sdk.Countly;
|
||||
import ly.count.android.sdk.CountlyConfig;
|
||||
import ly.count.android.sdknative.CountlyNative;
|
||||
|
||||
public class App extends Application {
|
||||
|
||||
private final static String COUNTLY_SERVER_URL = "https://your.server.ly";
|
||||
private final static String COUNTLY_APP_KEY = "YOUR_APP_KEY";
|
||||
private final static String DEFAULT_URL = "https://your.server.ly";
|
||||
private final static String DEFAULT_APP_KEY = "YOUR_APP_KEY";
|
||||
|
||||
@Override public void onCreate() {
|
||||
super.onCreate();
|
||||
|
||||
// if (DEFAULT_URL.equals(COUNTLY_SERVER_URL) || DEFAULT_APP_KEY.equals(COUNTLY_APP_KEY)) {
|
||||
// Log.e("CountlyCrashDemo", "Please provide correct COUNTLY_SERVER_URL and COUNTLY_APP_KEY");
|
||||
// return;
|
||||
// }
|
||||
|
||||
Countly.applicationOnCreate();
|
||||
|
||||
CountlyConfig config = new CountlyConfig(this, COUNTLY_APP_KEY, COUNTLY_SERVER_URL).setDeviceId("4432")
|
||||
.setLoggingEnabled(true)
|
||||
.enableCrashReporting()
|
||||
.setViewTracking(true)
|
||||
.setRequiresConsent(false);
|
||||
Countly.sharedInstance().init(config);
|
||||
|
||||
CountlyNative.initNative(getApplicationContext());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
package ly.count.android.demo.crash;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import ly.count.android.sdk.Countly;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private static final String TAG = "CountlyDemoNative";
|
||||
|
||||
// Used to load the 'native-lib' library on application startup.
|
||||
static {
|
||||
System.loadLibrary("native-lib");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
// Example of a call to a native method
|
||||
TextView tv = findViewById(R.id.sampleText);
|
||||
tv.setText(stringFromJNI());
|
||||
|
||||
final Button button = findViewById(R.id.crashButton);
|
||||
button.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View v) {
|
||||
Log.d(TAG,"crash button clicked");
|
||||
// CountlyNative.crash();
|
||||
testCrash();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStart()
|
||||
{
|
||||
super.onStart();
|
||||
Countly.sharedInstance().onStart(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop()
|
||||
{
|
||||
Countly.sharedInstance().onStop();
|
||||
super.onStop();
|
||||
}
|
||||
|
||||
// defined in native-lib.cpp
|
||||
public native String stringFromJNI();
|
||||
public native int testCrash();
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="78.5885"
|
||||
android:endY="90.9159"
|
||||
android:startX="48.7653"
|
||||
android:startY="61.0927"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||
android:strokeWidth="1"
|
||||
android:strokeColor="#00000000" />
|
||||
</vector>
|
||||
@@ -0,0 +1,170 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportWidth="108"
|
||||
android:viewportHeight="108">
|
||||
<path
|
||||
android:fillColor="#008577"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeWidth="0.8"
|
||||
android:strokeColor="#33FFFFFF" />
|
||||
</vector>
|
||||
@@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".MainActivity">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/sampleText"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Hello World!"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintLeft_toLeftOf="parent"
|
||||
app:layout_constraintRight_toRightOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<Button
|
||||
android:id="@+id/crashButton"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="161dp"
|
||||
android:layout_marginTop="65dp"
|
||||
android:layout_marginEnd="162dp"
|
||||
android:text="@string/crash"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<background android:drawable="@drawable/ic_launcher_background" />
|
||||
<foreground android:drawable="@drawable/ic_launcher_foreground" />
|
||||
</adaptive-icon>
|
||||
|
After Width: | Height: | Size: 2.9 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
|
After Width: | Height: | Size: 2.0 KiB |
|
After Width: | Height: | Size: 2.7 KiB |
|
After Width: | Height: | Size: 4.4 KiB |
|
After Width: | Height: | Size: 6.7 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 10 KiB |
|
After Width: | Height: | Size: 8.9 KiB |
|
After Width: | Height: | Size: 15 KiB |
@@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<resources>
|
||||
<color name="colorPrimary">#008577</color>
|
||||
<color name="colorPrimaryDark">#00574B</color>
|
||||
<color name="colorAccent">#D81B60</color>
|
||||
</resources>
|
||||
@@ -0,0 +1,4 @@
|
||||
<resources>
|
||||
<string name="app_name">DemoNative</string>
|
||||
<string name="crash">CRASH</string>
|
||||
</resources>
|
||||
11
libraries/countly/app-native/src/main/res/values/styles.xml
Normal file
@@ -0,0 +1,11 @@
|
||||
<resources>
|
||||
|
||||
<!-- Base application theme. -->
|
||||
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
|
||||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/colorPrimary</item>
|
||||
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
|
||||
<item name="colorAccent">@color/colorAccent</item>
|
||||
</style>
|
||||
|
||||
</resources>
|
||||
1
libraries/countly/app/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
27
libraries/countly/app/agconnect-services.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"agcgw":{
|
||||
"backurl":"connect-dre.dbankcloud.cn",
|
||||
"url":"connect-dre.hispace.hicloud.com"
|
||||
},
|
||||
"client":{
|
||||
"cp_id":"5190090000025014013",
|
||||
"product_id":"9105385871708592148",
|
||||
"client_id":"325901171304694848",
|
||||
"client_secret":"31C4D18185700B855D33F575B241288BB0FB884861427DB05A297E54424A601F",
|
||||
"app_id":"101926031",
|
||||
"package_name":"ly.count.android.demo",
|
||||
"api_key":"CV8FgFUqn8qlzRxUglEUhnjcTT7/ca5efyLkxaqzxV8N26kvPX/tnu+XXH4eGCvN2pi1llG6NvRKzmhiAp5QTKpSz6ya"
|
||||
},
|
||||
"service":{
|
||||
"analytics":{
|
||||
"collector_url":"datacollector-dre.dt.hicloud.com,datacollector-dre.dt.dbankcloud.cn",
|
||||
"resource_id":"p1",
|
||||
"channel_id":""
|
||||
},
|
||||
"ml":{
|
||||
"mlservice_url":"ml-api-dre.ai.dbankcloud.com,ml-api-dre.ai.dbankcloud.cn"
|
||||
}
|
||||
},
|
||||
"region":"DE",
|
||||
"configuration_version":"1.0"
|
||||
}
|
||||
68
libraries/countly/app/build.gradle
Normal file
@@ -0,0 +1,68 @@
|
||||
apply plugin: 'com.android.application'
|
||||
apply plugin: 'kotlin-android'
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.android.compileSdkVersion
|
||||
|
||||
signingConfigs {
|
||||
release {
|
||||
storeFile file('keys')
|
||||
keyAlias 'HWDemo'
|
||||
keyPassword 'countly'
|
||||
storePassword 'countly'
|
||||
v1SigningEnabled true
|
||||
v2SigningEnabled true
|
||||
}
|
||||
}
|
||||
|
||||
defaultConfig {
|
||||
applicationId "ly.count.android.demo"
|
||||
minSdkVersion rootProject.ext.android.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.android.targetSdkVersion
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
buildTypes {
|
||||
debug {
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled false
|
||||
shrinkResources false
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
release {
|
||||
signingConfig signingConfigs.release
|
||||
minifyEnabled true
|
||||
shrinkResources true
|
||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation fileTree(dir: 'libs', include: ['*.jar'])
|
||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||
|
||||
implementation project(':libraries:countly:sdk')
|
||||
//implementation 'ly.count.android:sdk:21.11.0'
|
||||
//implementation 'ly.count.android:sdk-plugin:21.11.0'
|
||||
|
||||
|
||||
implementation 'com.google.android.material:material:1.3.0'
|
||||
implementation 'androidx.appcompat:appcompat:1.3.1'
|
||||
implementation 'androidx.constraintlayout:constraintlayout:2.1.0'
|
||||
implementation 'androidx.annotation:annotation:1.2.0'
|
||||
implementation 'androidx.core:core-ktx:1.5.0'
|
||||
|
||||
//required for the install referrer
|
||||
implementation 'com.android.installreferrer:installreferrer:2.2'
|
||||
|
||||
}
|
||||
|
||||
39
libraries/countly/app/google-services.json
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"project_info": {
|
||||
"project_number": "355395217058",
|
||||
"project_id": "countlydemo-7d8d0",
|
||||
"storage_bucket": "countlydemo-7d8d0.appspot.com"
|
||||
},
|
||||
"client": [
|
||||
{
|
||||
"client_info": {
|
||||
"mobilesdk_app_id": "1:355395217058:android:130d09fdf6bebd941c99fb",
|
||||
"android_client_info": {
|
||||
"package_name": "ly.count.android.demo"
|
||||
}
|
||||
},
|
||||
"oauth_client": [
|
||||
{
|
||||
"client_id": "969412419457-07du4kv6e2m9ttjrn40063mcv7erhf0p.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
],
|
||||
"api_key": [
|
||||
{
|
||||
"current_key": "AIzaSyAYxUHbqnotLwParY0UR_fmhaTgx-ahUbc"
|
||||
}
|
||||
],
|
||||
"services": {
|
||||
"appinvite_service": {
|
||||
"other_platform_oauth_client": [
|
||||
{
|
||||
"client_id": "969412419457-07du4kv6e2m9ttjrn40063mcv7erhf0p.apps.googleusercontent.com",
|
||||
"client_type": 3
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"configuration_version": "1"
|
||||
}
|
||||
BIN
libraries/countly/app/keys
Normal file
33
libraries/countly/app/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# By default, the flags in this file are appended to flags specified
|
||||
# in /projects/android-sdk/tools/proguard/proguard-android.txt
|
||||
# You can edit the include path and order by changing the proguardFiles
|
||||
# directive in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# Add any project specific keep options here:
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# This renames the file name on stack traces from "UnknownSource" to "SourceFile"
|
||||
-renamesourcefileattribute SourceFile
|
||||
# This values are kept on stack traces to debug any issue easily
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# Rules recommended for Huawei PushKit
|
||||
-ignorewarnings
|
||||
-keepattributes *Annotation*
|
||||
-keepattributes Exceptions
|
||||
-keepattributes InnerClasses
|
||||
-keepattributes Signature
|
||||
-keepattributes SourceFile,LineNumberTable
|
||||
-keep class com.hianalytics.android.**{*;}
|
||||
-keep class com.huawei.updatesdk.**{*;}
|
||||
-keep class com.huawei.hms.**{*;}
|
||||