Preface
Because of the need of the project, Toast can still pop up after users forbid notifying permission. After testing three methods on the internet, we found that they did not meet the needs of the company and did not use them. Among them, model adaptation (named millet MIUI8) accounts for a large part of the reasons. And the requirement is that no permission can be added!!!
Look at the picture below.
(Source code at the end of the article)
- The method is very simple, no secondary encapsulation is done.
public void showToast(View view){
if(CustomToast.isNotificationEnabled(this)){
//Notification is available using native Toast
Toast.makeText(getApplicationContext(), "system Toast", Toast.LENGTH_SHORT).show();
}else{
CustomToast.makeText(getApplicationContext(),"custom Toast", CustomToast.LENGTH_SHORT).show();
}
}
First, determine whether the user has forbidden notifications (sometimes the user just wants to block push notifications), if not forbid the direct use of the system's native Toast, otherwise use our custom
The code that judges whether there are permissions is not pasted, which has little to do with this article. It should be noted that the permissions can be judged only when API19 or above, so a judgement can be added.
public static boolean isNotificationEnabled(Context context) {
//Direct use of custom Toast below API 19
if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.KITKAT) {
//Here I use Custom Toast directly below 19
return false;
}
AppOpsManager mAppOps = null;
mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
//N lines of code are omitted here
************;
}
public static CustomToast makeText(Context context, CharSequence text, int duration) {
Toast toast = Toast.makeText(context, text, duration);
CustomToast exToast = new CustomToast(context);
exToast.toast = toast;
exToast.setDuration(duration);
exToast.setText(text);
//Add to the collection and maintain the queue yourself
equeue.add(exToast);
return exToast;
}
makeText returns an instance object and adds it to the equeue collection. In order to imitate the system playing Toast, one display is finished and the second pops up. Let's look at the show method.
public void show() {
//The view being displayed or to be displayed is null
if (isShow || mView == null) {
return;
}
isShow = true;
toast.setView(mView);
//Here we get the TN object of toast by reflection.
initTN();
try {
//Display toast
show.invoke(mTN);
} catch (Exception e) {
e.printStackTrace();
}
//Toast to Time Hiding
handler.postDelayed(hideRunnable, mDuration == LENGTH_SHORT ? LENGTH_SHORT : LENGTH_LONG);
}
hideRunnable just tunes a hide method
private void hide() {
if (!isShow) return;
try {
hide.invoke(mTN);
} catch (Exception e) {
e.printStackTrace();
}
isShow = false;
equeue.remove(0);
//If there are messages in the queue, continue to show
if (equeue.size() > 0) {
equeue.get(0).show();
}
}
This method comes from Breakthrough Millet Suspension Window Authority Control - Suspension Window without Authority
private void initTN() {
try {
Field tnField = toast.getClass().getDeclaredField("mTN");
tnField.setAccessible(true);
mTN = tnField.get(toast);
show = mTN.getClass().getMethod("show");
hide = mTN.getClass().getMethod("hide");
Field tnParamsField = mTN.getClass().getDeclaredField("mParams");
tnParamsField.setAccessible(true);
WindowManager.LayoutParams params = (WindowManager.LayoutParams) tnParamsField.get(mTN);
params.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
/**Make sure to set mNextView before calling tn.show()*/
Field tnNextViewField = mTN.getClass().getDeclaredField("mNextView");
tnNextViewField.setAccessible(true);
tnNextViewField.set(mTN, toast.getView());
} catch (Exception e) {
e.printStackTrace();
}
//Set the toast location here
toast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM, 0, 200);
}
Here's a brief introduction. Welcome to the exchange.
Reference article: http://www.codexiu.cn/android/blog/25708/
Source address: https://github.com/jackyZuo/CustomToastDemo