「Countly」

1、引入countly源码,高度为09d7817a38074cae8a6c34f94c04356b29f6a80f,引入原因是因为gradle、kotlin版本太高了,无法直接使用。需要自己定制化
This commit is contained in:
donghongyu
2024-10-29 19:09:53 +08:00
parent cb397d919a
commit 55500cb376
282 changed files with 29691 additions and 1 deletions

View File

@@ -0,0 +1 @@
/build

View 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"
}

View 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')
}

View 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"
}

Binary file not shown.

View 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.**{*;}

View 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>

View File

@@ -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
*/
}

View File

@@ -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);
}
}

View File

@@ -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;
}
}

View File

@@ -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();
}
}

View File

@@ -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;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 204 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 269 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 342 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 B

View File

@@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -0,0 +1 @@
/build

View 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')
}

View 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

View 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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@@ -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()
}
}
}

View File

@@ -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)
}
}
}

View File

@@ -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)
}
}

View File

@@ -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
}
}

View File

@@ -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
}
}

View File

@@ -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)
}
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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"
/>

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.6 KiB

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -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>

View File

@@ -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>

View 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>

View File

@@ -0,0 +1 @@
/build

View 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'
}
}

View 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

View 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>

View 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})

View 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;
}
}

View File

@@ -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());
}
}

View File

@@ -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();
}

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

View File

@@ -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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@@ -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>

View File

@@ -0,0 +1,4 @@
<resources>
<string name="app_name">DemoNative</string>
<string name="crash">CRASH</string>
</resources>

View 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
View File

@@ -0,0 +1 @@
/build

View 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"
}

View 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'
}

View 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

Binary file not shown.

View 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.**{*;}

Some files were not shown because too many files have changed in this diff Show More