Huawei, Samsung and other models after disabling the notification permission Toast does not pop up
the reason
After a review of source code found Toast, Toast display to be achieved through INotificationManager class, and when the notice is disabled, such calls will return an exception, it does not show cause notice, the source code is as follows:
public void show() {
if (mNextView == null) {
throw new RuntimeException("setView must have been called");
}
INotificationManager service = getService();
String pkg = mContext.getOpPackageName();
TN tn = mTN;
tn.mNextView = mNextView;
try {
service.enqueueToast(pkg, tn, mDuration);
} catch (RemoteException e) {
// 权限禁用后走这里,这里是空方法,所以会发生既不crash又无响应的情况
}
}
This is a google of bug, part of millet phone rewrite Toast code, so you can execute properly, we can be bypassed by way of reflection, and will have the following solutions :
Solution
public class ToastUtils {
private static Object iNotificationManagerObj;
/**
* @param context
* @param message
*/
public static void show(Context context, String message) {
show(context.getApplicationContext(), message, Toast.LENGTH_SHORT);
}
/**
* @param context
* @param message
*/
public static void show(Context context, String message, int duration) {
if (TextUtils.isEmpty(message)) {
return;
}
//后setText 兼容小米默认会显示app名称的问题
Toast toast = Toast.makeText(context, null, duration);
toast.setText(message);
if (isNotificationEnabled(context)) {
toast.show();
} else {
showSystemToast(toast);
}
}
/**
* 显示系统Toast
*/
private static void showSystemToast(Toast toast) {
try {
Method getServiceMethod = Toast.class.getDeclaredMethod("getService");
getServiceMethod.setAccessible(true);
//hook INotificationManager
if (iNotificationManagerObj == null) {
iNotificationManagerObj = getServiceMethod.invoke(null);
Class iNotificationManagerCls = Class.forName("android.app.INotificationManager");
Object iNotificationManagerProxy = Proxy.newProxyInstance(toast.getClass().getClassLoader(), new Class[]{iNotificationManagerCls}, new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//强制使用系统Toast
if ("enqueueToast".equals(method.getName())
|| "enqueueToastEx".equals(method.getName())) { //华为p20 pro上为enqueueToastEx
args[0] = "android";
}
return method.invoke(iNotificationManagerObj, args);
}
});
Field sServiceFiled = Toast.class.getDeclaredField("sService");
sServiceFiled.setAccessible(true);
sServiceFiled.set(null, iNotificationManagerProxy);
}
toast.show();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 消息通知是否开启
*
* @return
*/
private static boolean isNotificationEnabled(Context context) {
NotificationManagerCompat notificationManagerCompat = NotificationManagerCompat.from(context);
boolean areNotificationsEnabled = notificationManagerCompat.areNotificationsEnabled();
return areNotificationsEnabled;
}
}
Toast the same content can not be repeated short-term pop
the reason
When we repeated clicks Toast, Toast will continuously pop up a lot, good visual experience, so the spread of the Internet that these solutions:
Toast mToast;
public void showToast(String text) {
if (mToast == null) {
mToast = Toast.makeText(MainActivity.this, text, Toast.LENGTH_SHORT);
} else {
mToast.setText(text);
mToast.setDuration(Toast.LENGTH_SHORT);
}
mToast.show();
}
This method is no problem in older versions of android, when the new version is displayed for a short time while a Toast, will not be displayed.
Toast the same text and is currently being displayed, the system is considered wrong operation, so that the current display screen Toast request.
This problem is said to be done to prevent rogue app has a pop Toast imitate system interface leading to system collapse.
Solution
This is a limitation of the system, you want to get around this limitation can customize Toast, and here I recommend the god git on a custom version of Toast - XToast
https://github.com/getActivity/XToast
The article is not easy, if you liked this article, or you have a lot of hope that we help, thumbs up , forward , concerned . Articles will be continuously updated. Absolutely dry! ! !