Skip to content

Instantly share code, notes, and snippets.

@junlincao
Last active December 4, 2017 03:47
Show Gist options
  • Save junlincao/1c91e181cde1350ab3db1862561054fc to your computer and use it in GitHub Desktop.
Save junlincao/1c91e181cde1350ab3db1862561054fc to your computer and use it in GitHub Desktop.
ToastCompat, make toast shown when user disabled notification permission
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.graphics.PixelFormat;
import android.support.annotation.StringRes;
import android.support.v4.app.NotificationManagerCompat;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;
/**
* 替代系统Toast,防止用户禁用通知栏权限导致Toast不显示问题.必须在Activity Context下才有效
*
* @author CJL
* @since 2017-11-24
*/
public class ToastCompat {
private Toast mToast;
private FrameLayout mToastView;
private WindowManager.LayoutParams mLayoutParams;
private Runnable mCancelRun;
private boolean useSystemToast = false;
private static ToastCompat mLastToast;
private ToastCompat(Context context, CharSequence text, int duration) {
mToast = Toast.makeText(context.getApplicationContext(), text, duration);
useSystemToast = !(context instanceof Activity) || NotificationManagerCompat.from(context).areNotificationsEnabled();
if (useSystemToast) {
return;
}
mToastView = new FrameLayout(context) {
@Override
protected void onWindowVisibilityChanged(int visibility) {
super.onWindowVisibilityChanged(visibility);
if (visibility != View.VISIBLE) {
cancel();
}
}
};
mToastView.addView(mToast.getView(), ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
mLayoutParams = new WindowManager.LayoutParams();
mLayoutParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
mLayoutParams.width = WindowManager.LayoutParams.WRAP_CONTENT;
mLayoutParams.format = PixelFormat.TRANSLUCENT;
mLayoutParams.windowAnimations = -1;
mLayoutParams.type = WindowManager.LayoutParams.TYPE_APPLICATION_PANEL;
mLayoutParams.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON
| WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
mLayoutParams.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM;
mLayoutParams.y = 200;
mCancelRun = new Runnable() {
@Override
public void run() {
cancel();
}
};
}
public void cancel() {
if (useSystemToast || mCancelRun == null || mToastView == null) {
return;
}
mToastView.removeCallbacks(mCancelRun);
WindowManager windowManager = (WindowManager) mToastView.getContext().getSystemService(Context.WINDOW_SERVICE);
if (windowManager != null && mToastView.getParent() != null) {
try {
windowManager.removeView(mToastView);
} catch (Throwable e) {
Log.e("ToastCompat", "Cancel toast failed!", e);
}
}
mToastView = null;
mCancelRun = null;
mLayoutParams = null;
mLastToast = null;
}
public void show() {
if (useSystemToast) {
mToast.show();
return;
}
if (mLastToast != null) {
mLastToast.cancel();
}
WindowManager windowManager = (WindowManager) mToastView.getContext().getSystemService(Context.WINDOW_SERVICE);
if (windowManager == null) {
return;
}
try {
windowManager.addView(mToastView, mLayoutParams);
int delayTime = mToast.getDuration() == Toast.LENGTH_SHORT ? 2000 : 3000;
mToastView.postDelayed(mCancelRun, delayTime);
mLastToast = this;
} catch (Throwable e) {
Log.e("ToastCompat", "show Toast failed!", e);
}
}
public void setText(CharSequence text) {
mToast.setText(text);
}
public void setText(@StringRes int res) {
setText(mToastView.getContext().getResources().getString(res));
}
public void setGravity(int gravity, int xOffset, int yOffset) {
if (useSystemToast) {
mToast.setGravity(gravity, xOffset, yOffset);
return;
}
mLayoutParams.gravity = gravity;
mLayoutParams.x = xOffset;
mLayoutParams.y = yOffset;
}
public View getView() {
return mToast.getView();
}
public void setDuration(int duration) {
mToast.setDuration(duration);
}
public static ToastCompat makeText(Context context, CharSequence text, int duration) {
return new ToastCompat(context, text, duration);
}
public static ToastCompat makeText(Context context, @StringRes int resId, int duration)
throws Resources.NotFoundException {
return makeText(context, context.getResources().getText(resId), duration);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment