动态修改strings.xml中的值及获取app版本号

本文介绍如何在Android应用中动态更新关于页面的版本号信息。利用Dialog展示版本信息,并通过Java代码动态修改strings.xml中的字符串模板,同时介绍了获取当前应用版本号的方法。

项目中需求在“关于”中添加版本号信息。
故记录代码实现。

关于用dialog实现,dialog的title和message均存在strings.xml中。如果要实现显示版本号信息,就需要动态修改strings.xml的值。

动态修改strings.xml的值

strings.xml

<string name="info">string %1$s, int %2$d, float %3$.2f.</string>

java代码

String message = getResources().getString(R.string.info);
message = String.format(message, "abc", 12, 13.25);

xml文件中%1$s%2$d%3$.2f类似C语言中scanf的占位符。
- 位于%和$中间的数字为参数索引,索引必须跟在%后并以$结尾。
- $后的字母表示数据类型。

先通过strings中的name获取到含有待修改的变量的string,再用format方法动态修改值。
第一个参数为获取到的string,后面的变量对应strings.xml中待修改的占位符。

获取版本号

public class GetVersion {
    public static String getVersion(Context context) {
        try {
            PackageManager manager = context.getPackageManager();//获取包管理
            PackageInfo info = manager.getPackageInfo(context.getPackageName(), 0);//获取包信息
            String version = info.versionName + "(" + info.versionCode + ")";//获取版本号
            return version;
        } catch(Exception e) {
            e.printStackTrace();
        }
        return "";
    }
}

结合动态修改strings.xml中的值。
strings.xml

<string name="version">version - %1$s</string>

java代码

String message = getResources().getString(R.string.version);
message = String.format(message, GetVersion.getVersion(getActivity()));
<think>我们需要创建一个uniplugin_install插件,该插件需要实现一个安装APK的功能,并能够被JS调用。 根据目录结构,插件代码应该放在uniplugin_install/src/main/java目录下。我们将在该目录下创建一个类,比如叫做InstallPlugin。 这个类需要继承uni-app插件规范中的基类(通常是UniModule),并实现一个方法,该方法使用@UniJSMethod注解暴露给JS。 步骤: 1. 创建插件类 2. 在插件类中实现安装APK的方法 3. 处理安装权限(Android 8.0及以上需要处理未知来源安装权限) 4. 在AndroidManifest.xml中声明必要的权限和组件 注意:由于目录结构中有两个AndroidManifest.xml,我们需要在uniplugin_install模块下的AndroidManifest.xml中添加权限和必要的组件声明。 具体步骤: 1. 在uniplugin_install模块的build.gradle中添加依赖(如果需要的话,比如uniapp的sdk) 2. 创建插件类,例如:InstallPlugin.java 3. 在插件类中编写安装方法,并处理权限 4. 在uniplugin_install模块的AndroidManifest.xml中声明权限和FileProvider(用于7.0及以上版本的文件共享) 详细实现: 第一步:添加依赖(在uniplugin_install/build.gradle中) 由于我们可能需要使用uniapp的sdk,所以需要添加依赖。假设项目已经集成了uniapp,我们可以添加如下依赖(如果还没有的话): 注意:请根据实际情况调整版本号 ``` dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) // 添加uniapp依赖 implementation 'com.android.support:appcompat-v7:28.0.0' compileOnly 'com.alibaba:fastjson:1.1.46.android' // 添加uniapp sdk依赖 compileOnly 'com.github.dcloudio:uni-app-sdk:latest.release' } ``` 第二步:创建InstallPlugin类 路径:uniplugin_install/src/main/java/uni/app/UNIF1D0362/InstallPlugin.java 代码示例: ```java package uni.app.UNIF1D0362; import android.content.Intent; import android.net.Uri; import android.os.Build; import androidx.core.content.FileProvider; import com.taobao.weex.annotation.JSMethod; import com.taobao.weex.bridge.JSCallback; import com.taobao.weex.common.WXModule; import java.io.File; import android.Manifest; import android.content.pm.PackageManager; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.app.Activity; public class InstallPlugin extends WXModule { // 定义请求安装权限的请求码 private static final int REQUEST_CODE_INSTALL_PERMISSION = 1001; private String apkPath; // 用于临时存储js传入的apk路径 private JSCallback callback; // 用于存储回调函数 // 暴露给JS的方法,用于安装APK @JSMethod(uiThread = true) public void installApk(String path, JSCallback callback) { // 保存回调 this.callback = callback; this.apkPath = path; // 检查是否有安装未知应用的权限 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { Activity activity = (Activity) mWXSDKInstance.getContext(); if (!activity.getPackageManager().canRequestPackageInstalls()) { // 没有权限,申请权限 ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, REQUEST_CODE_INSTALL_PERMISSION); return; } } // 有权限,直接安装 install(); } // 处理权限申请结果 @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); if (requestCode == REQUEST_CODE_INSTALL_PERMISSION) { if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // 用户同意,安装 install(); } else { // 用户拒绝 if (callback != null) { callback.invoke("Permission denied"); } } } } // 执行安装 private void install() { Activity activity = (Activity) mWXSDKInstance.getContext(); File apkFile = new File(apkPath); if (!apkFile.exists()) { if (callback != null) { callback.invoke("File not exists"); } return; } Intent intent = new Intent(Intent.ACTION_VIEW); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Uri uri; // Android 7.0及以上需要使用FileProvider if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 注意:这里的authority需要和AndroidManifest.xml中配置的FileProvider的authorities一致 String authority = activity.getPackageName() + ".fileprovider"; uri = FileProvider.getUriForFile(activity, authority, apkFile); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { uri = Uri.fromFile(apkFile); } intent.setDataAndType(uri, "application/vnd.android.package-archive"); activity.startActivity(intent); // 安装成功,回调 if (callback != null) { callback.invoke("Install started"); } } } ``` 第三步:配置AndroidManifest.xml(uniplugin_install模块下的) 在uniplugin_install/src/main/目录下有两个AndroidManifest.xml?根据结构,我们使用uniplugin_install/src/main/AndroidManifest.xml(注意结构中是两个,但根据目录树,我们使用main目录下的那个) 需要添加: 1. 安装未知应用的权限(针对8.0及以上) 2. FileProvider的配置(针对7.0及以上) 示例: ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="uni.app.UNIF1D0362"> <!-- 安装未知应用的权限 --> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <!-- 读写存储权限(用于访问apk文件) --> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <application> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application> </manifest> ``` 第四步:创建file_paths.xml文件 在uniplugin_install/src/main/res目录下创建xml文件夹,然后创建file_paths.xml文件。 file_paths.xml内容示例(根据实际需要调整): ```xml <?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 外部存储根目录 --> <external-path name="external_files" path="." /> <!-- 也可以添加其他路径,如: --> <!-- <root-path name="root" path="." /> --> </paths> ``` 第五步:在uniplugin_install模块的build.gradle中配置资源文件(如果res目录下有资源,需要确保被正确引入) 第六步:在simpleDemo模块中引用这个插件模块 在simpleDemo/build.gradle中添加对uniplugin_install模块的依赖: ``` dependencies { implementation project(':uniplugin_install') } ``` 第七步:在simpleDemo模块中注册插件 在simpleDemo/src/main/assets/dcloud_uniplugins.json(如果没有则创建)中添加插件配置: ```json { "plugins": [ { "type": "module", "name": "InstallPlugin", "class": "uni.app.UNIF1D0362.InstallPlugin" } ] } ``` 注意:这里假设simpleDemo模块的assets目录下已经有dcloud_uniplugins.json文件,如果没有需要创建。 第八步:在JS中调用 在uni-app的JS代码中,可以通过如下方式调用: ```javascript const installPlugin = uni.requireNativePlugin('InstallPlugin'); installPlugin.installApk('/sdcard/Download/app.apk', (result) => { console.log(result); }); ``` 注意事项: 1. 确保传递给installApk的路径是设备上存在的apk文件路径。 2. 由于Android版本碎片化,需要测试不同版本的兼容性。 3. 权限申请的处理可能需要更完善(比如在Android 6.0以下不需要动态申请存储权限,但6.0以上需要,上面的代码只处理了安装权限,存储权限需要另外处理)。 由于存储权限的动态申请不在本插件中处理(因为uni-app框架可能已经处理了),所以这里假设调用该方法时已经具有存储权限。如果没有,需要先申请存储权限。 以上是一个基本的实现,根据实际项目可能需要调整。</think>### 详细实现步骤 #### 1. 创建插件类 在 `uniplugin_install/src/main/java/uni/app/UNIF1D0362/` 下创建 `InstallPlugin.java`: ```java package uni.app.UNIF1D0362; import android.content.Intent; import android.net.Uri; import android.os.Build; import androidx.core.content.FileProvider; import io.dcloud.feature.uniapp.annotation.UniJSMethod; import io.dcloud.feature.uniapp.bridge.UniJSCallback; import io.dcloud.feature.uniapp.common.UniModule; import java.io.File; public class InstallPlugin extends UniModule { // 暴露给JS的安装方法 @UniJSMethod(uiThread = true) public void installApk(String apkPath, UniJSCallback callback) { if (apkPath == null || apkPath.isEmpty()) { callback.invoke("路径不能为空"); return; } File apkFile = new File(apkPath); if (!apkFile.exists()) { callback.invoke("文件不存在"); return; } try { Intent intent = new Intent(Intent.ACTION_VIEW); Uri uri; // Android 7.0+ 需使用FileProvider if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { String authority = mUniSDKInstance.getContext().getPackageName() + ".fileprovider"; uri = FileProvider.getUriForFile(mUniSDKInstance.getContext(), authority, apkFile); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); } else { uri = Uri.fromFile(apkFile); } intent.setDataAndType(uri, "application/vnd.android.package-archive"); intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); mUniSDKInstance.getContext().startActivity(intent); callback.invoke("安装已启动"); } catch (Exception e) { callback.invoke("安装失败: " + e.getMessage()); } } } ``` #### 2. 配置 FileProvider 在 `uniplugin_install/src/main/AndroidManifest.xml` 中添加: ```xml <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="uni.app.UNIF1D0362"> <!-- 添加安装权限 --> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <application> <!-- 配置FileProvider --> <provider android:name="androidx.core.content.FileProvider" android:authorities="${applicationId}.fileprovider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider> </application> </manifest> ``` #### 3. 创建文件路径配置 在 `uniplugin_install/src/main/res/xml/` 下新建 `file_paths.xml`: ```xml <?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <!-- 支持访问外部存储 --> <external-path name="external_files" path="." /> </paths> ``` #### 4. 注册插件 在 `simpleDemo/src/main/assets/dcloud_uniplugins.json` 中添加插件声明: ```json { "plugins": [ { "type": "module", "name": "InstallPlugin", "class": "uni.app.UNIF1D0362.InstallPlugin" } ] } ``` #### 5. 添加模块依赖 在 `simpleDemo/build.gradle` 中添加: ```gradle dependencies { implementation project(':uniplugin_install') // 添加插件模块依赖 } ``` #### 6. JS 调用示例 在 UniApp 的 Vue 文件中使用: ```javascript const installPlugin = uni.requireNativePlugin('InstallPlugin') // 调用安装方法 installPlugin.installApk( "/sdcard/Download/app.apk", (result) => { console.log(result) // 接收安装状态 } ) ``` ### 关键注意事项 1. **权限处理**: - Android 8.0+ 需动态申请 `REQUEST_INSTALL_PACKAGES` 权限 - 在 `MainActivity.java` 中添加权限请求逻辑 2. **文件路径**: - 确保 JS 传递的路径是设备可访问的绝对路径 - 测试时建议使用 `Environment.getExternalStorageDirectory() + "/Download/app.apk"` 3. **FileProvider 冲突**: - 如果主模块已有 FileProvider,需合并 `authorities` 配置
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值