Author Dex_DQT
From now, we will begin to learn how to build the Android version of Digging. In this chapter, we will build the environment and create the function to getting the wallet balance.
Build Project
This article uses koltin for development, and the IDE is Android. Open Android studio and create a new project.

Here we choose Empty Activity

The development language is koltin, and the minimum supported SDK is API 21
After the project is created, the directory is as follows:

Then we introduce the SDK of Platon’s Android version
Open build.gradle in app directory, the content is as follows:
plugins { id 'com.android.application' id 'kotlin-android' } android { compileSdk 31 defaultConfig { applicationId "com.digquant" minSdkVersion 21 targetSdkVersion 31 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } buildFeatures { viewBinding true } dataBinding { //noinspection DataBindingWithoutKapt enabled = true } sourceSets { main { jniLibs.srcDirs = ['libs'] } } android.applicationVariants.all { variant -> variant.outputs.all { //在这里修改apk文件名 outputFileName = "digging.apk" } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } splits { abi { enable true reset() universalApk true } } kotlinOptions { jvmTarget = '1.8' } } dependencies { implementation 'com.google.android.material:material:1.4.0' // 引入platON的jar包 implementation 'com.platon.client:core:0.13.0.2-android' implementation 'com.platon.client:crypto:0.13.0.2-android' }
Then open the outermost settings.gradle file, as shown below:

Add the warehouse address of PlatON, as follows:
dependencyResolutionManagement { repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) repositories { google() maven { url "https://jitpack.io" } maven { url "https://sdk.platon.network/nexus/content/groups/public/" } mavenCentral() jcenter() // Warning: this repository is going to shut down soon } } rootProject.name = "Digging" include ':app'
Next, create the libs directory in the app directory and copy the libscrypt.so to the modified directory, as shown in the following picture:

Set it to support arm64 and x86. Readers can delete unnecessary platforms by themselves.
Finally, add the permission to use the network in the AndroidManifest.xml. The code is as follows:
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.digquant"> <!-- 访问网络,网络定位需要上网--> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:usesCleartextTraffic="true" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/Theme.Digging"> <activity android:name=".activity.MainActivity" android:screenOrientation="fullSensor" android:exported="true"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
So far, the construction of the project has been completed.
编写代码
Creat an api vfolder in the com.digquant, then add PlatonApi, as shown in follow:

As its’ name shows, All interaction interfaces with the Platon node are placed in PlatonApi. Its code is as follows:
class PlatonApi { // companion object { // 测试节点地址 const val url: String = "http://35.247.155.162:6789" //连接超时时间 const val TRANSACTION_SEND_CONNECT_TIMEOUT: Long = 10000 // 读取超时 const val TRANSACTION_SEND_READ_TIMEOUT: Long = 50000 // PlatonApi为单例 val platonApi: PlatonApi = PlatonApi() } // 手续费 private val GasPrice: BigInteger = BigInteger.valueOf(2000000000000L) // 手续费上线 private val GasLimit: BigInteger = BigInteger.valueOf(99999L) // 手续费类 var gasProvider = ContractGasProvider(GasPrice, GasLimit) // 和PlatON通讯的对象 var mWeb3j: Web3j = Web3jFactory.build( HttpService( url, OkHttpClient().newBuilder() .connectTimeout( TRANSACTION_SEND_CONNECT_TIMEOUT, TimeUnit.MILLISECONDS ) .readTimeout( TRANSACTION_SEND_READ_TIMEOUT, TimeUnit.MILLISECONDS ) .build(), false ) ); /** * 获取余额 */ fun GetBalance(walletAddress: String): PlatonGetBalance { return mWeb3j.platonGetBalance( walletAddress, DefaultBlockParameterName.LATEST ).send() } }
It is an soly example to realize the construction of handling fee class through companion method.
The naming rules of functions in this project refer to Golang: the first letter of public functions are uppercase, and others are lowercase. Because the function to obtain the specified wallet balance here is a public function, so it should be GetBalance.
Then write the interface. Open activity_main.xml in res/layout, as shown:

Code as follows:
<?xml version="1.0" encoding="utf-8"?> <LinearLayout 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" android:orientation="vertical" android:padding="10dp" tools:context=".MainActivity"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:text="钱包地址:" /> <EditText android:id="@+id/walletAddress" android:layout_width="match_parent" android:layout_height="wrap_content" android:hint="请输入要查询的钱包地址" /> </LinearLayout> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="10dp"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginRight="10dp" android:text="当前余额:" /> <TextView android:id="@+id/balance" android:layout_width="match_parent" android:layout_height="wrap_content" /> </LinearLayout> <Button android:id="@+id/btn" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="10dp" android:text="获取" /> </LinearLayout>
The interface would be like:

Then add MainActivity into com.digquant.activity.
Code as follows:
class MainActivity : AppCompatActivity() { /** * 使用binding */ lateinit var binding: ActivityMainBinding /** * 创建handler */ lateinit var handler: Handler override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // 构建布局 val inflater = LayoutInflater.from(this) binding = ActivityMainBinding.inflate(inflater, null, false); setContentView(binding.root) handler = Handler(); initEvent(); } /** * 初始化时间 */ private fun initEvent() { binding.btn.setOnClickListener { val walletAddress = binding.walletAddress.text.toString() /** * 因此platonApi调用Http的方式都是同步的 * 而在UI线程不能发起Http调用因此需要在子线程调用 * 把调用任务放在线程池 */ ThreadPoolUtil.AddTask { /** * 获取platonApi对象 */ val platonApi = PlatonApi.platonApi val platonBalance = platonApi.GetBalance(walletAddress) /** * 获取的balance单位为Von,要手动转为LAT */ val lat = Convert.fromVon(BigDecimal(platonBalance.balance), Convert.Unit.LAT).toDouble(); // 通过handler讲balance传回UI线程 handler.post { binding.balance.text = lat.toString() } } } } }
Note that Platon’s Api calls to Http are synchronous, so they cannot be used in the UI thread and need to be placed in a sub-thread. To avoid the need to create a sub-thread for each call, we will build a thread pool here.
Creat com.digquant.util and add ThreadPoolUtilin it, code as follows:
package com.digquant.util import java.util.concurrent.LinkedBlockingDeque import java.util.concurrent.ThreadPoolExecutor import java.util.concurrent.TimeUnit class ThreadPoolUtil { companion object { private val executor = ThreadPoolExecutor( 2, 10, 10 * 60, TimeUnit.SECONDS, LinkedBlockingDeque() ) fun AddTask(runnable: Runnable?) { executor.execute(runnable) } } }
Finally, enter this adress in the app: lat1zrq89dhle45g78mm4j8aq3dq5m2shpu56ggc6e0
Than tou can see the balance, as dhown in the follow:

The browser would found the balance as follows:

Same as we got.
Well, that’s all of this chapter.
The URL of github: https://github.com/DQTechnology/Platon_DevGuideProject
This article is reproduced from https://forum.latticex.foundation/t/topic/5948