后台显示自定义Toast

产品的无脑需求,不按照google规范来搞,要在后台显示自定义Toast。

这可让我发愁呀~

硬着头皮搞需求呗~

联系framework同事,然后在拦截的地方加了白名单

不过他还好心提醒我是否需要限制次数,卧槽,还能这样,我想了下此次的需求不需求就拒绝了。

 W NotificationService: Package com.xxx.xxx.xxx is above allowed toast quota, the following toast was blocked and discarded: CustomToastRecord{e28d3f8 18408:com.xxx.xxx.xxxx/u0a217 isSystemToast=false token=android.os.BinderProxy@d10533b callback=android.app.ITransientNotification$Stub$Proxy@1c800d1 duration=0}

本来以为有了framework同事的魔改万事大吉了,后来发现居然不能再settings里面弹出toast!

没办法,后来才知道,settings限制不安全的弹框出现,只好自己处理了

import android.content.Context;
import android.content.res.Resources;
import android.util.Log;
import android.util.TypedValue;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import android.view.WindowManager;

public class ToastUtil {
    private static Toast toast = new Toast(myApplication.getInstance());
    
    public static void showToast2(Context context, int drawableId) {
        LayoutInflater inflater = (LayoutInflater) context.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.xxxxxx, null);
        ImageView imgContent = view.findViewById(R.id.imgContent);
        imgContent.setImageResource(drawableId);
        setToastParams(toast);
        toast.setView(view);
        toast.show();
    }

    public static void showToast1(Context context) {
        LayoutInflater inflater = (LayoutInflater) context.getApplicationContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        View view = inflater.inflate(R.layout.xxxxxx, null);
        setToastParams(toast);
        toast.setView(view);
        toast.show();
    }
    
    private static void setToastParams(Toast toast) {
        WindowManager.LayoutParams windowParams = getWindowParams(toast);
        Field privateFlags = null;
        Field privateFlagConstField  = null;
        try {
            privateFlagConstField  = WindowManager.LayoutParams.class.getDeclaredField("SYSTEM_FLAG_SHOW_FOR_ALL_USERS");
            privateFlagConstField .setAccessible(true);
            int privateFlagConst = privateFlagConstField.getInt(WindowManager.LayoutParams.class);

            privateFlags = WindowManager.LayoutParams.class.getDeclaredField("privateFlags");
            privateFlags.setAccessible(true);
            int privateFlagsConst = privateFlags.getInt(WindowManager.LayoutParams.class);
            privateFlagsConst |= privateFlagConst;
            privateFlags.setInt(windowParams, privateFlagsConst);

            setTrustedOverlay(windowParams);
        } catch (Exception e) {
            Log.e("xxx", "setToastParams err " + e);
        }
    }
    
    private static WindowManager.LayoutParams getWindowParams(Toast toast){
        try {
            Method getWindowParams = toast.getClass().getMethod("getWindowParams");
            if (getWindowParams == null) {
                return null;
            }
            getWindowParams.setAccessible(true);
            return (WindowManager.LayoutParams) getWindowParams.invoke(toast);
        } catch (Exception e) {
            Log.e("xxxxx", "getWindowParams err " + e);
            return null;
        }
    }
    
    private static void setTrustedOverlay(WindowManager.LayoutParams windowParams) {
        try {
            Method method = windowParams.getClass().getMethod("setTrustedOverlay");
            if (method == null) {
                return;
            }
            method.setAccessible(true);
            method.invoke(windowParams);
        } catch (Exception e) {
            Log.e("xxxxx", "setTrustedOverlay err " + e);
            return;
        }
    }
    
}

服务器编译apk,然后组合命令

adb root

adb remount

adb push xxxx

adb shell sync

adb reboot

重启测试搞定~

太难了~ 做手机除了要懂应用层,framework也要熟悉~

加油,加班狗。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值