Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
7a49160
feat: 添加Windows环境兼容的小程序生成脚本并更新配置
qq547176052 Jan 23, 2026
0a6c7bc
Merge branch 'didi:main' into main
qq547176052 Jan 23, 2026
71a5469
加的小程序
qq547176052 Jan 23, 2026
bde81cb
feat: 添加UDP Socket API支持并创建示例页面
qq547176052 Jan 24, 2026
08a059a
feat: 添加UDP Socket API实现并优化日志中文显示
qq547176052 Jan 26, 2026
ffce6d1
feat: 实现UDP Socket的完整功能并优化消息处理
qq547176052 Jan 27, 2026
539ea6b
feat: 支持UDP发送ArrayBuffer类型数据并优化UDP功能
qq547176052 Jan 27, 2026
6dcb366
feat: 添加蓝牙配网功能和小程序导航API
qq547176052 Jan 28, 2026
f2c88e2
chore: 删除废弃的小程序配置文件及代码
qq547176052 Jan 28, 2026
7c9defb
refactor: 优化小程序打包脚本并更新.gitignore
qq547176052 Jan 28, 2026
fd758cb
feat: 实现微信标准蓝牙适配器 API
qq547176052 Jan 28, 2026
4741379
feat: 添加蓝牙设备发现和通信相关API
qq547176052 Jan 28, 2026
c2e63f8
feat: 实现蓝牙设备扫描功能并添加微信API规范支持
qq547176052 Jan 28, 2026
a7f0ef6
feat: 完善蓝牙权限检查与设备扫描功能
qq547176052 Jan 28, 2026
b3eaf57
feat: 添加小程序自动启动功能并更新蓝牙权限
qq547176052 Jan 29, 2026
881337c
docs: 添加作者注释并更新版本号
qq547176052 Jan 29, 2026
dc75384
fix(compiler): 修复对于不以@开头的npm包,找不到模块问题#148 #134
kevintcl Jan 30, 2026
1933509
Merge pull request #1 from kevintcl/fix/logic-compiler
qq547176052 Jan 30, 2026
d641802
feat: 添加蓝牙功能支持并更新小程序跳转逻辑
qq547176052 Jan 31, 2026
79023ec
feat: 添加蓝牙设备发现事件监听并优化应用打包脚本
qq547176052 Jan 31, 2026
687e7f3
feat: 添加获取状态栏高度功能并更新应用生成脚本
qq547176052 Jan 31, 2026
9011aac
不知道
qq547176052 Feb 2, 2026
f92748a
Merge branch '上电冒烟' of https://github.com/qq547176052/dimina into 上电冒烟
qq547176052 Feb 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
fe/example/**/dd编译/


fe/dd编译/**
20 changes: 20 additions & 0 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"MicroPython.executeButton": [
{
"text": "▶",
"tooltip": "运行",
"alignment": "left",
"command": "extension.executeFile",
"priority": 3.5
}
],
"MicroPython.syncButton": [
{
"text": "$(sync)",
"tooltip": "同步",
"alignment": "left",
"command": "extension.execute",
"priority": 4
}
]
}
80 changes: 70 additions & 10 deletions android/app/src/main/kotlin/com/didi/dimina/demo/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import androidx.compose.material3.Text
import androidx.compose.material3.TextField
import androidx.compose.material3.TextFieldDefaults
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
Expand All @@ -57,6 +58,9 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.view.WindowInsetsControllerCompat
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import com.didi.dimina.Dimina
import com.didi.dimina.bean.MiniProgram
import com.didi.dimina.common.Utils
Expand All @@ -71,6 +75,31 @@ val bgColor = Color(0xFFF5F5F5)
*/
class MainActivity : ComponentActivity() {

private fun openMiniProgram() {
try {
val appid= "wxd58cedf6d1e1c52c"
val jsonString = assets.open("jsapp/$appid/config.json").bufferedReader().use { it.readText() }
val jsonObject = JSONObject(jsonString)
val miniProgram = MiniProgram(
appId = jsonObject.getString("appId"),//"wxd58cedf6d1e1c52c"
name = "小程序",
versionCode = jsonObject.getInt("versionCode"),//1
versionName = jsonObject.getString("versionName"),//1.0.0
path = jsonObject.getString("path"),//"example/index"
)
Log.d("MainActivity", "打开小程序*****************************************")
// 启动小程序
Dimina.getInstance().startMiniProgram(this@MainActivity, miniProgram)

// 关键修改:小程序启动指令发送后,关闭当前 MainActivity
// 此时小程序页面会成为任务栈顶,作为应用首页
finish()

} catch (e: Exception) {
Log.e("MainActivity", "启动失败: ${e.message}")
}
}

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
Expand All @@ -80,8 +109,40 @@ class MainActivity : ComponentActivity() {
window.statusBarColor = bgColor.toArgb() // Convert Compose Color to ARGB int
WindowInsetsControllerCompat(window, window.decorView).isAppearanceLightStatusBars = true

// 启动小程序(启动后会自动关闭当前页面)
// openMiniProgram()

setContent {
DiminaAndroidTheme {
val lifecycleOwner = LocalLifecycleOwner.current
var isHomePageVisible by remember { mutableStateOf(false) }
// 监听生命周期变化(注:若小程序启动成功,当前 Activity 会被销毁,该监听大概率不会触发)
DisposableEffect(lifecycleOwner) {
val observer = LifecycleEventObserver { _, event ->
when (event) {
Lifecycle.Event.ON_START -> {
isHomePageVisible = true
Log.d("MainActivity", "首页变为可见状态")
// 小程序已在 onCreate 中启动,此处无需重复调用
// openMiniProgram();
}

Lifecycle.Event.ON_STOP -> {
isHomePageVisible = false
Log.d("MainActivity", "首页变为不可见状态")
}

else -> {}
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}

// 注:若小程序启动成功,当前 Activity 会被立即销毁,该列表页面不会显示
// 若小程序启动失败,会显示该列表页面作为兜底
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
MiniProgramListScreen(
modifier = Modifier.padding(innerPadding)
Expand All @@ -91,7 +152,6 @@ class MainActivity : ComponentActivity() {
}
}
}

@Composable
fun MiniProgramListScreen(modifier: Modifier = Modifier) {
val context = LocalContext.current
Expand Down Expand Up @@ -133,7 +193,7 @@ fun MiniProgramListScreen(modifier: Modifier = Modifier) {
fontWeight = FontWeight.Bold,
)
}

// Search bar
SearchBar(
query = searchQuery,
Expand All @@ -143,7 +203,7 @@ fun MiniProgramListScreen(modifier: Modifier = Modifier) {
.fillMaxWidth()
.padding(16.dp)
)

// App list title
Text(
text = "应用列表",
Expand All @@ -152,7 +212,7 @@ fun MiniProgramListScreen(modifier: Modifier = Modifier) {
fontSize = 16.sp,
color = Color.Gray
)

// Mini-program list
MiniProgramList(
miniPrograms = filteredMiniPrograms,
Expand All @@ -175,7 +235,7 @@ fun SearchBar(
) {
val keyboardController = LocalSoftwareKeyboardController.current
val focusRequester = remember { FocusRequester() }

Box(
modifier = modifier
.fillMaxWidth()
Expand Down Expand Up @@ -279,9 +339,9 @@ fun MiniProgramItem(
fontWeight = FontWeight.Bold
)
}

Spacer(modifier = Modifier.width(16.dp))

// Mini-program name
Text(
text = miniProgram.name,
Expand All @@ -304,14 +364,14 @@ fun Context.getMiniProgramsList(): List<MiniProgram> {
}?:emptyList()

val miniPrograms = mutableListOf<MiniProgram>()

// Convert to MiniProgram objects with consistent colors based on name
for (jsonObject in configResults) {
if (jsonObject == null) {
continue
}
val name = jsonObject.getString("name")

miniPrograms.add(MiniProgram(
appId = jsonObject.getString("appId"),
name = name,
Expand All @@ -320,7 +380,7 @@ fun Context.getMiniProgramsList(): List<MiniProgram> {
path = jsonObject.getString("path"),
))
}

return miniPrograms
} catch (e: Exception) {
Log.e("MainActivity", "Error reading config.json: ${e.message}")
Expand Down
1 change: 1 addition & 0 deletions android/dimina/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ dependencies {
implementation (libs.okhttp)
implementation(libs.landscapist.coil)
implementation (libs.ui.tooling)
implementation(libs.androidx.bluetooth)
testImplementation(libs.junit)
androidTestImplementation(libs.androidx.junit)
androidTestImplementation(libs.androidx.espresso.core)
Expand Down
33 changes: 33 additions & 0 deletions android/dimina/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,39 @@
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.VIBRATE" />


<!-- AndroidManifest.xml 确保以下权限存在 -->
<!-- 基础蓝牙权限(低版本) -->
<!-- <uses-permission android:name="android.permission.BLUETOOTH" />-->
<!-- <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />-->
<!-- Android 12+ 扫描+连接权限(解耦定位) -->
<uses-permission
android:name="android.permission.BLUETOOTH_SCAN"
android:usesPermissionFlags="neverForLocation"
tools:targetApi="31" />
<!-- <uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />-->
<!-- 低版本扫描/读取名称必需的定位权限 -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 声明BLE支持(确保设备兼容) -->
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!-- Android 12及以上新增蓝牙权限 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />














<application>
<activity
android:name=".ui.container.DiminaActivity"
Expand Down
22 changes: 11 additions & 11 deletions android/dimina/src/main/kotlin/com/didi/dimina/api/ApiHandler.kt
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,18 @@ import org.json.JSONObject


sealed class APIResult
data class SyncResult(val value: JSValue) : APIResult()
data class AsyncResult(val value: JSONObject) : APIResult()
data class NoneResult(val value: Any? = null) : APIResult()
data class SyncResult(val value: JSValue) : APIResult() // 同步结果
data class AsyncResult(val value: JSONObject) : APIResult() // 异步结果
data class NoneResult(val value: Any? = null) : APIResult() // 无结果

/**
* Base interface for all API handlers
* Base interface for all API handlers 所有API处理程序的基本接口
* Author: Doslin
*/
interface ApiHandler {
/**
* Handles an API call
*
* Handles an API call 处理API调用
*
* @param params Parameters for the API call
* @return True if API was successfully handled, false otherwise
*/
Expand All @@ -29,25 +29,25 @@ interface ApiHandler {
params: JSONObject,
responseCallback: (String) -> Unit,
): APIResult

}

/**
* Abstract base class for API handlers
* Abstract base class for API handlers API处理程序的抽象基类
*/
abstract class BaseApiHandler : ApiHandler {

/**
* Set of API names that this handler can process
* Set of API names that this handler can process 此处理程序可以处理的API名称集
*/
protected open val apiNames: Set<String> = emptySet()

override fun handleAction(activity: DiminaActivity, appId: String, apiName: String, params: JSONObject, responseCallback: (String) -> Unit): APIResult {
return ApiUtils.createUnsupportedErrorResponse(apiName)
}

/**
* Registers all API names with the registry
* Registers all API names with the registry 在注册表中注册所有API名称
*/
fun registerWith(registry: ApiRegistry) {
// Register each API name
Expand Down
22 changes: 11 additions & 11 deletions android/dimina/src/main/kotlin/com/didi/dimina/api/ApiRegistry.kt
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,52 @@ import com.didi.dimina.ui.container.DiminaActivity
import org.json.JSONObject

/**
* API Registry to manage all API handlers
* API Registry to manage all API handlers API注册表,用于管理所有API处理程序
* Author: Doslin
*/
class ApiRegistry {
private val tag = "ApiRegistry"
private val apiHandlers = mutableMapOf<String, ApiHandler>()

/**
* Registers an API handler
* Registers an API handler 注册API处理程序
*/
fun register(name: String, handler: ApiHandler) {
apiHandlers[name] = handler
}

/**
* Invokes an API
*
* Invokes an API 调用API
*
* @param apiName The name of the API to invoke
* @param params Parameters for the API call
* @return True if API was successfully invoked, false otherwise
*/
fun invoke(
activity: DiminaActivity,
appId: String,
apiName: String,
apiName: String,
params: JSONObject,
responseCallback: (String) -> Unit,
): APIResult {
val handler = apiHandlers[apiName]
if (handler == null) {
LogUtils.e(tag, "API not found: $apiName")
LogUtils.e(tag, "API not found 找不到api函数: $apiName")
return NoneResult()
}
return handler.handleAction(activity, appId, apiName, params, responseCallback)
}

/**
* Clears all API handlers
*/
fun clear() {
apiHandlers.clear()
}

/**
* Gets a set of all registered API names
*
* Gets a set of all registered API names 获取所有注册的API名称的集合
*
* @return Set of all registered API names
*/
fun getRegisteredApiNames(): Set<String> {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@

// BtFunction.kt
package com.didi.dimina.api.bt



/**
* 蓝牙核心逻辑辅助类(单例)
* 职责:封装蓝牙核心 API、维护核心数据(设备缓存、回调、扫描状态)、处理核心业务逻辑
*/
object BtFunction {

}
Loading