使用APK Editor Studio在Smali中实现自定义编解码器Toast
正确实现:将aptX蓝牙连接Toast替换为带图片的自定义布局(Smali代码)
需求背景
已通过APK Editor Studio 1.7.1反编译目标APK,其中嵌套类aptxalsNotify$1的run方法原本在连接aptX/aptX HD蓝牙耳机时显示纯文本Toast,需修改为:
- 连接aptX设备时,显示包含
qti_aptx.png的自定义Toast - 连接aptX HD设备时,显示包含
qti_aptx_hd.png的自定义Toast
已准备资源ID:
- 自定义Toast布局ID:
0x7f0b0037 - ImageView控件ID:
0x7f0800bc - aptX图片资源ID:
0x7f070077 - aptX HD图片资源ID:
0x7f070078
目标Java逻辑(参考)
@Override public void run() { // 原逻辑中获取的编解码器文本 String codecText = getCodecText(); LayoutInflater inflater = LayoutInflater.from(getContext()); View customToastView = inflater.inflate(0x7f0b0037, null); ImageView ivCodec = customToastView.findViewById(0x7f0800bc); if ("aptX".equals(codecText)) { ivCodec.setImageResource(0x7f070077); } else if ("aptX HD".equals(codecText)) { ivCodec.setImageResource(0x7f070078); } Toast toast = new Toast(getContext()); toast.setView(customToastView); toast.setDuration(Toast.LENGTH_SHORT); toast.show(); }
正确Smali实现代码
找到aptxalsNotify$1.smali文件中的.method public run()V方法,替换为以下内容:
.method public run()V .locals 8 # 获取外部类实例(aptxalsNotify) iget-object v0, p0, LaptxalsNotify$1;->this$0:LaptxalsNotify; # 替换为原代码中实际使用的Context获取方式(示例为外部类的mContext字段) iget-object v1, v0, LaptxalsNotify;->mContext:Landroid/content/Context; # 保留原逻辑中获取编解码器文本的代码,示例为从外部类字段获取 iget-object v2, v0, LaptxalsNotify;->mCodecText:Ljava/lang/String; # 获取LayoutInflater实例 invoke-static {v1}, Landroid/view/LayoutInflater;->from(Landroid/content/Context;)Landroid/view/LayoutInflater; move-result-object v3 # 加载自定义Toast布局 const v4, 0x7f0b0037 const v5, 0x0 invoke-virtual {v3, v4, v5}, Landroid/view/LayoutInflater;->inflate(ILandroid/view/ViewGroup;)Landroid/view/View; move-result-object v6 # 获取ImageView控件并强转类型 const v4, 0x7f0800bc invoke-virtual {v6, v4}, Landroid/view/View;->findViewById(I)Landroid/view/View; move-result-object v7 check-cast v7, Landroid/widget/ImageView; # 判断编解码器类型,设置对应图片 const-string v4, "aptX" invoke-virtual {v2, v4}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z move-result v4 if-eqz v4, :check_aptx_hd const v4, 0x7f070077 invoke-virtual {v7, v4}, Landroid/widget/ImageView;->setImageResource(I)V goto :init_toast :check_aptx_hd const-string v4, "aptX HD" invoke-virtual {v2, v4}, Ljava/lang/String;->equals(Ljava/lang/Object;)Z move-result v4 if-eqz v4, :init_toast const v4, 0x7f070078 invoke-virtual {v7, v4}, Landroid/widget/ImageView;->setImageResource(I)V :init_toast # 创建Toast实例并配置 new-instance v4, Landroid/widget/Toast; invoke-direct {v4, v1}, Landroid/widget/Toast;-><init>(Landroid/content/Context;)V invoke-virtual {v4, v6}, Landroid/widget/Toast;->setView(Landroid/view/View;)V # 设置时长:0x0为SHORT,0x1为LONG,可根据原逻辑调整 const v5, 0x0 invoke-virtual {v4, v5}, Landroid/widget/Toast;->setDuration(I)V # 显示Toast invoke-virtual {v4}, Landroid/widget/Toast;->show()V return-void .end method
关键注意事项
- Context获取适配:必须确保
v1的获取逻辑和原代码一致,若原代码使用Activity或Application Context,需替换为对应的字段或方法调用。 - 编解码器文本对齐:保留原代码中获取编解码器文本的逻辑,不要直接照搬示例中的字段,需与反编译后的原代码匹配。
- 寄存器数量调整:
.locals的值需根据实际使用的寄存器数量调整,若编译报错提示寄存器不足,可增大该数值。 - Toast创建逻辑:必须通过
new Toast(context)+setView()的方式使用自定义布局,不能使用Toast.makeText()(该方法绑定默认文本布局),这是此前生成代码失效的核心原因。 - 类型强转:
findViewById返回的View必须通过check-cast转为ImageView,否则会因类型不匹配导致运行报错。
内容的提问来源于stack exchange,提问作者Zeus Silver
相关产品推荐
相关产品推荐

