- 这里只是记录,方便自己复制,记得先看官方文档,官方文档更简洁易懂
一、先在官网下载UniMPSDK
- 官网文档 nativesupport.dcloud.net.cn/UniMPDocs/U…
- 创建项目的时候Minimum SDK选API 21 ("Lollipop"; Android 5.0),其他我没试过
- 把demo的
app/libs文件夹复制到你项目的app/libs下面(记住,复制官方demo中的libs,一定不要全复制SDK文件夹里面的libs,因为有些文件会冲突)
- 把官方demo中的
app/proguard.cfg中内容复制到app/proguard-rules.pro文件中
- 在
项目根目录/gradle.properties最后一行加上android.enableJetifier=true
- 将demo中
app/src/main/assets完整复制到项目对应目录下
二、配置app/build.gradle.kts文件(有些省略了)
var mfph = mapOf(
"apk.applicationId" to "com.example.unimpdemo",
)
android {
namespace = "com.airqirke.uni_demo"
compileSdk = 35
buildToolsVersion = "35.0.0"
defaultConfig {
applicationId = "com.airqirke.uni_demo"
minSdk = 21
targetSdk = 34
versionCode = 1
versionName = "1.0"
multiDexEnabled = true
manifestPlaceholders.putAll(mfph)
}
buildTypes {
debug {
isMinifyEnabled = false
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
androidResources {
additionalParameters += listOf("--auto-add-overlay")
ignoreAssetsPattern += listOf("!.svn","!.git",".*","!CVS","!thumbs.db","!picasa.ini","!*.scc","*~")
}
}
dependencies {
implementation(fileTree(mapOf("dir" to "libs", "include" to listOf("*.jar", "*.aar"))))
implementation ("com.android.support:recyclerview-v7:28.0.0")
implementation ("com.android.support:support-v4:28.0.0")
implementation ("com.android.support:appcompat-v7:28.0.0")
implementation ("com.alibaba:fastjson:1.2.83")
implementation ("com.facebook.fresco:fresco:2.5.0")
implementation ("com.facebook.fresco:animated-gif:2.5.0")
implementation ("com.github.bumptech.glide:glide:4.9.0")
implementation ("androidx.webkit:webkit:1.6.1")
implementation("com.tencent.mm.opensdk:wechat-sdk-android:6.8.0")
implementation("androidx.multidex:multidex:2.0.0")
}
三、配置AndroidManifest.xml(不要完整复制,对应的地方改就行了)
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.READ_LOGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<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_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_LOGS"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.RECEIVE_USER_PRESENT" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-feature android:name="android.hardware.camera.autofocus"
tools:ignore="DuplicateUsesFeature" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.SEND_SMS"
tools:ignore="PermissionImpliesUnsupportedChromeOsHardware" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.FLASHLIGHT" />
<uses-feature android:name="android.hardware.camera"
tools:ignore="DuplicateUsesFeature" />
<uses-permission android:name="android.permission.WRITE_OBB"
tools:ignore="ProtectedPermissions" />
<uses-permission android:name="android.permission.READ_SMS"
tools:ignore="PermissionImpliesUnsupportedChromeOsHardware" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<application
android:allowBackup="true"
android:allowClearUserData="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:largeHeap="true"
android:extractNativeLibs="true"
android:theme="@style/Theme.Uni_demo"
tools:targetApi="31"
tools:replace="android:allowBackup,android:allowNativeHeapPointerTagging"
android:allowNativeHeapPointerTagging="false"
android:name=".App"
tools:ignore="AppLinkUrlError">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.Uni_demo"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize"
android:configChanges="orientation|keyboardHidden|screenSize|mcc|mnc|fontScale"
>
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<meta-data
android:name="UMENG_APPKEY"
android:value="xxxxxxx" />
<meta-data
android:name="UMENG_CHANNEL"
android:value="googleplay" />
<provider
android:name="io.dcloud.common.util.DCloud_FileProvider"
android:authorities="${apk.applicationId}.dc.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/dcloud_file_provider" />
</provider>
<meta-data
android:name="com.amap.api.v2.apikey"
android:value="346dc11885001c4fe444bdedc362cd4f" />
<service android:name="com.amap.api.location.APSService"
tools:ignore="MissingClass" />
<meta-data
android:name="QQ_APPID"
android:value="xxxxx" />
<meta-data
android:name="SINA_REDIRECT_URI"
android:value="http://www.dcloud.io/" />
<meta-data
android:name="SINA_SECRET"
android:value="xxxx" />
<meta-data
android:name="SINA_APPKEY"
android:value="xxxxx" />
<meta-data
android:name="WX_SECRET"
android:value="xxxxx" />
<activity
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:label="@string/app_name"
android:launchMode="singleTop">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<data android:scheme="wx0411fa6a39d61297" />
</intent-filter>
</activity>
<activity
android:name=".wxapi.WXPayEntryActivity"
android:exported="true"
android:launchMode="singleTop" />
<meta-data
android:name="WX_APPID"
android:value="xxxxx" />
<meta-data
android:name="com.baidu.speech.APP_ID"
android:value="xxxxx" />
<meta-data
android:name="com.baidu.speech.API_KEY"
android:value="xxxxxxx" />
<meta-data
android:name="com.baidu.speech.SECRET_KEY"
android:value="xxxxxx" />
<service
android:name="com.baidu.speech.VoiceRecognitionService"
android:exported="false" />
<activity
android:name="io.dcloud.PandoraEntryActivity"
android:configChanges="orientation|keyboardHidden|screenSize|mcc|mnc|fontScale|keyboard"
android:hardwareAccelerated="true"
android:launchMode="singleTask"
android:exported="false"
android:permission="com.miui.securitycenter.permission.AppPermissionsEditor"
android:screenOrientation="user"
android:theme="@style/DCloudTheme"
android:windowSoftInputMode="adjustResize"
tools:ignore="Instantiatable">
<intent-filter>
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<action android:name="android.intent.action.VIEW" />
<data android:scheme="h56131bcf" />
</intent-filter>
</activity>
</application>
</manifest>
四、创建App.kt(记得在AndroidManifest.xml的application中引用android:name=".App")
package com.airqirke.uni_demo
import android.app.Application
import android.content.Context
import android.util.Log
import androidx.multidex.MultiDex
import io.dcloud.feature.sdk.DCSDKInitConfig
import io.dcloud.feature.sdk.DCUniMPSDK
import io.dcloud.feature.sdk.MenuActionSheetItem
class App : Application() {
override fun onCreate() {
super.onCreate()
val item = MenuActionSheetItem("关于", "gy")
val item1 = MenuActionSheetItem("获取当前页面url", "hqdqym")
val item2 = MenuActionSheetItem("跳转到宿主原生测试页面", "gotoTestPage")
val sheetItems: MutableList<MenuActionSheetItem> = ArrayList()
sheetItems.add(item)
sheetItems.add(item1)
sheetItems.add(item2)
Log.i("unimp", "onCreate----")
val config: DCSDKInitConfig = DCSDKInitConfig.Builder()
.setCapsule(false)
.setMenuDefFontSize("16px")
.setMenuDefFontColor("#ff00ff")
.setMenuDefFontWeight("normal")
.setMenuActionSheetItems(sheetItems)
.setEnableBackground(true)
.build()
DCUniMPSDK.getInstance().initialize(this, config
) { b -> Log.d("unimpaa", "onInitFinished----$b") }
}
override fun attachBaseContext(base: Context?) {
MultiDex.install(base)
super.attachBaseContext(base)
}
}
五、创建wxapi文件夹(WXEntryActivity.kt和WXPayEntryActivity.kt,如果没有引用可以忽略)
class WXEntryActivity: AbsWXCallbackActivity() {
}
class WXPayEntryActivity: AbsWXPayCallbackActivity() {
}
六、修改MainActivity.kt
package com.airqirke.uni_demo
import android.content.Context
import android.os.Build
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.core.view.WindowCompat
import com.airqirke.uni_demo.ui.theme.Uni_demoTheme
import io.dcloud.feature.sdk.DCUniMPSDK
import io.dcloud.feature.sdk.Interface.IUniMP
class MainActivity : ComponentActivity() {
var mContext: Context? = null
var mHandler: Handler? = null
var mUniMPCaches: HashMap<String, IUniMP> = HashMap()
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mContext = this
mHandler = Handler(Looper.getMainLooper())
if (Build.VERSION.SDK_INT >= 35) {
val windowInsetsController = window.decorView.windowInsetsController
val decorView = window.decorView
val controller = if (windowInsetsController != null
) WindowCompat.getInsetsController(window, decorView)else null
if (controller != null) {
controller.isAppearanceLightStatusBars = true
controller.isAppearanceLightNavigationBars = true
}
}
enableEdgeToEdge()
DCUniMPSDK.getInstance().setCapsuleCloseButtonClickCallBack { appid ->
Toast.makeText(mContext, "点击×号了", Toast.LENGTH_SHORT).show()
if (mUniMPCaches.containsKey(appid)) {
val mIUniMP = mUniMPCaches[appid]
if (mIUniMP != null && mIUniMP.isRuning) {
mIUniMP.closeUniMP()
mUniMPCaches.remove(appid)
}
}
}
setContent {
Uni_demoTheme {
Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding ->
Greeting(
name = "Android",
modifier = Modifier.padding(innerPadding).fillMaxSize(),
onClick = {
try {
val uniMP = DCUniMPSDK.getInstance().openUniMP(mContext, "__UNI__F743940")
mUniMPCaches[uniMP.appid] = uniMP
} catch (e: Exception) {
e.printStackTrace()
}
}
)
}
}
}
}
}
@Composable
fun Greeting(name: String, modifier: Modifier = Modifier,onClick:()->Unit) {
Column (
modifier = modifier,
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
){
Text(
text = "Hello $name!",
)
Button(onClick = {onClick()}) {
Text(text = "Click me")
}
}
}