最近做消息提醒,使用了系统悬浮窗 windowManager,小米手机关闭了悬浮窗权限,就没法弹出通知了,虽然此方案不完美,但是还是纪录下写法。
public class MessageRemindReceiver extends BroadcastReceiver {
@Override
public void onReceive(final Context context, Intent intent) {
if(intent == null){
return;
}
String icon = intent.getStringExtra(IMExtraName.MSG_ICON);
String title = intent.getStringExtra(IMExtraName.MSG_TITLE);
String msgContent = intent.getStringExtra(IMExtraName.MSG_CONTENT);
final String msgUrl = intent.getStringExtra(IMExtraName.MSG_URL);
if(TextUtils.isEmpty(msgContent)){
return;
}
try {
if(TextUtils.isEmpty(title) || TextUtils.isEmpty(msgContent)){
return;
}
final ImTipLayout guideLayout = new ImTipLayout(context);
guideLayout.sendMessage(context,icon,title,msgContent,msgUrl);
new Handler().postDelayed(new Runnable() {
@Override
public void run() {
guideLayout.hideAnimator();
}
},5000);
}catch (Throwable e){
LogUtils.e("MessageRemindReceiver 异常 ",e);
}
}
}
public class ImTipLayout extends FrameLayout {
private WindowManager wManager;
private WindowManager.LayoutParams wmParams;
private View addView;
private RelativeLayout windowRL;
private TextView mTitleTv;
private TextView mContentTv;
private ImageView mImageView;
private boolean isAddView;
private float downY;
private AnimatorSet mShowAnimatorSet, mHideAnimatorSet;
private Handler mHandler = new Handler() {
public void handleMessage(android.os.Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case 1:
showAnimator();
break;
default:
break;
}
};
};
/**
* @param context
*/
public ImTipLayout(Context context) {
this(context, null);
// TODO Auto-generated constructor stub
}
/**
* @param context
* @param attrs
*/
public ImTipLayout(Context context, AttributeSet attrs) {
this(context, attrs, 0);
// TODO Auto-generated constructor stub
}
/**
* @param context
* @param attrs
* @param defStyle
*/
public ImTipLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
addView = LayoutInflater.from(context).inflate(R.layout.im_tip_layout,
this);
windowRL=(RelativeLayout) addView.findViewById(R.id.windowRL);
mTitleTv = (TextView) addView.findViewById(R.id.tv1);
mContentTv=(TextView) addView.findViewById(R.id.tv2);
mImageView = (ImageView) addView.findViewById(R.id.iv1);
windowRL.setVisibility(GONE);
mTitleTv.setVisibility(View.GONE);
mImageView.setVisibility(View.GONE);
setAnimator();
getWindowManager(context);
}
/**
* @category 实例化WindowManager 初次模拟位置时候使用
* @param context
*/
private void getWindowManager(final Context context) {
wManager = (WindowManager) context.getApplicationContext()
.getSystemService(Context.WINDOW_SERVICE);
wmParams = new WindowManager.LayoutParams();
int type;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
type = WindowManager.LayoutParams.TYPE_TOAST;//适用于高版本
} else {
type = WindowManager.LayoutParams.TYPE_PHONE;//适用于低版本
}
wmParams.type = type;
wmParams.format = PixelFormat.TRANSPARENT;
// wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
// | WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
// | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
wmParams.gravity = Gravity.CENTER | Gravity.TOP;
wmParams.x = 0;
wmParams.y = 0;
wmParams.width = WindowManager.LayoutParams.MATCH_PARENT;
wmParams.height = WindowManager.LayoutParams.WRAP_CONTENT;
}
private void setAnimator() {
mShowAnimatorSet = new AnimatorSet();
Animator[] showAnimator = new Animator[3];
showAnimator[0] = ObjectAnimator.ofFloat(windowRL, "alpha",
new float[] { 0.0F, 1.0F });
showAnimator[0]=ObjectAnimator.ofFloat(windowRL, "translationY", -400, 0);
showAnimator[1] = ObjectAnimator.ofFloat(mTitleTv, "alpha",
new float[] { 0.0F, 1.0F });
showAnimator[2] = ObjectAnimator.ofFloat(mImageView, "alpha",
new float[] { 0.0F, 1.0F });
mShowAnimatorSet.playTogether(showAnimator);
mShowAnimatorSet.setDuration(500l);
mHideAnimatorSet = new AnimatorSet();
Animator[] hideAnimator = new Animator[3];
hideAnimator[0] = ObjectAnimator.ofFloat(windowRL, "alpha",
new float[] { 1.0F, 0.0F });
hideAnimator[0]=ObjectAnimator.ofFloat(windowRL, "translationY", 0, -400);
hideAnimator[1] = ObjectAnimator.ofFloat(mTitleTv, "alpha",
new float[] { 1.0F, 1F });
hideAnimator[2] = ObjectAnimator.ofFloat(mImageView, "alpha",
new float[] { 1.0F, 1F });
mHideAnimatorSet.playTogether(hideAnimator);
mHideAnimatorSet.setDuration(500l);
}
public void showAnimator() {
windowRL.setVisibility(VISIBLE);
mTitleTv.setVisibility(View.VISIBLE);
mImageView.setVisibility(View.VISIBLE);
mShowAnimatorSet.start();
isAddView=true;
}
public void hideAnimator() {
mHideAnimatorSet.start();
mHideAnimatorSet.addListener(new Animator.AnimatorListener() {
@Override
public void onAnimationStart(Animator animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationRepeat(Animator animation) {
// TODO Auto-generated method stub
}
@Override
public void onAnimationEnd(Animator animation) {
// TODO Auto-generated method stub
mTitleTv.setVisibility(View.INVISIBLE);
mImageView.setVisibility(View.INVISIBLE);
windowRL.setVisibility(INVISIBLE);
recycleView();
}
@Override
public void onAnimationCancel(Animator animation) {
// TODO Auto-generated method stub
}
});
}
private void recycleView(){
try {
windowRL.setVisibility(INVISIBLE);
wManager.removeView(this);
mHandler.removeMessages(1);
isAddView=false;
}catch (Throwable e){
}
}
public void sendMessage(final Context context,String icon,String title,String content,final String msgUrl) {
if (isAddView) {
recycleView();
}
mTitleTv.setText(title);
mContentTv.setText(content);
DisplayImageOptions options = new DisplayImageOptions.Builder()
.showImageOnLoading(R.drawable.ic_launcher)// 设置图片在下载期间显示的图片
.showImageForEmptyUri(R.drawable.ic_launcher)// 设置图片Uri为空或是错误的时候显示的图片
.showImageOnFail(R.drawable.ic_launcher)// 设置图片加载/解码过程中错误时候显示的图片
.cacheInMemory(true)// 设置下载的图片是否缓存在内存中
.cacheOnDisk(true)// 设置下载的图片是否缓存在SD卡中
.build();
ImageLoaderUtil.displayImage(icon,mImageView,options);
mHandler.sendEmptyMessage(1);
wManager.addView(this, wmParams);
windowRL.setOnTouchListener(new OnTouchListener() {
@Override
public boolean onTouch(View view, MotionEvent event) {
switch (event.getAction()){
case MotionEvent.ACTION_DOWN:
downY = event.getRawY();
break;
case MotionEvent.ACTION_UP:
float currentY = event.getRawY();
if((downY - currentY) >= 10 || TextUtils.isEmpty(msgUrl) || !msgUrl.startsWith("http")){
if(!mHideAnimatorSet.isRunning()){
hideAnimator();
}
}else {
if(isAddView){
recycleView();
// KidImActivity.startActivity(context,msgUrl);
}
}
break;
}
return true;
}
});
}
}