Commit 6633b7e9 by konghaorui

修复线上问题:

1.课程列表4.4崩溃问题
2.课程播放页面Glide加载图片崩溃问题
3.私聊查看图片放大后崩溃问题
4.音频播放器空指针判断问题
5.Android 7.0 Toast兼容问题
parent 9c2db3e3
...@@ -104,14 +104,20 @@ public class DemoAppLifecycles implements IAppLifecycles { ...@@ -104,14 +104,20 @@ public class DemoAppLifecycles implements IAppLifecycles {
//umeng //umeng
String umAppkey = null; String umAppkey = null;
if (packageName.endsWith("yidianling")) { if (BuildConfig.FLAVOR.endsWith("ydl")) {
umAppkey = "56970affe0f55a9cda001e24"; umAppkey = "56970affe0f55a9cda001e24";
channel = "android_" + channel; channel = "android_" + channel;
initUM(umAppkey, channel,application); initUM(umAppkey, channel,application);
PlatformConfig.setWeixin("wx57a9d930270498c7", "17c031f02500ded3457a80e69d8e5e45"); PlatformConfig.setWeixin("wx57a9d930270498c7", "17c031f02500ded3457a80e69d8e5e45");
PlatformConfig.setQQZone("1105070461", "6BvkUnk6wXJekcgR");
}else if (BuildConfig.FLAVOR.endsWith("xlzx")) {
umAppkey = "5859e1656e27a42fa400021f";
channel = "ATK_7_android_" + channel;
initUM(umAppkey, channel,application);
PlatformConfig.setWeixin("wx1c6af5a11b5f531f", "1ddb93abbb2d81e604657d38e94a5720");
PlatformConfig.setQQZone("1107931541", "8dCvxUpi525uPGTJ");
} }
PlatformConfig.setQQZone("1105070461", "6BvkUnk6wXJekcgR");
MobclickAgent.setScenarioType(application, MobclickAgent.EScenarioType.E_DUM_NORMAL); MobclickAgent.setScenarioType(application, MobclickAgent.EScenarioType.E_DUM_NORMAL);
MobclickAgent.setCatchUncaughtExceptions(!BuildConfig.DEBUG); MobclickAgent.setCatchUncaughtExceptions(!BuildConfig.DEBUG);
......
ext { ext {
kotlin_version = "1.3.21" kotlin_version = "1.3.21"
dev_mode = false dev_mode = true
ydl_app = [ ydl_app = [
appName : "心理咨询壹点灵", appName : "心理咨询壹点灵",
...@@ -256,7 +256,7 @@ ext { ...@@ -256,7 +256,7 @@ ext {
"arouter-compiler" : "com.alibaba:arouter-compiler:1.2.2", "arouter-compiler" : "com.alibaba:arouter-compiler:1.2.2",
"exoplayer" : "com.google.android.exoplayer:exoplayer:2.9.0", "exoplayer" : "com.google.android.exoplayer:exoplayer:2.9.0",
"free_reflection" : "me.weishu:free_reflection:2.0.0", "free_reflection" : "me.weishu:free_reflection:2.0.0",
"imagepicker" : "com.ydl:imagepicker:1.0.6", "imagepicker" : "com.ydl:imagepicker:1.0.7",
"protector" : "com.ydl:protector:1.0.1-SNAPSHOT@aar", "protector" : "com.ydl:protector:1.0.1-SNAPSHOT@aar",
"ydl-hnet" : "com.ydl:h-net:0.0.8", "ydl-hnet" : "com.ydl:h-net:0.0.8",
"ydl-user-router" : "com.ydl:router:1.0.0-SNAPSHOT@aar", "ydl-user-router" : "com.ydl:router:1.0.0-SNAPSHOT@aar",
......
...@@ -24,4 +24,10 @@ public class CourseNewListAdapter extends CommonAdapter<Course> { ...@@ -24,4 +24,10 @@ public class CourseNewListAdapter extends CommonAdapter<Course> {
((CourseItemNewView) convertView).setData(mDataList.get(position)); ((CourseItemNewView) convertView).setData(mDataList.get(position));
return convertView; return convertView;
} }
//修复 Android 4.4 Bug :cannot be cast to android.widget.AbsListView$LayoutParams
@Override
public boolean hasStableIds() {
return true;
}
} }
...@@ -2,8 +2,13 @@ package com.yidianling.course.widget ...@@ -2,8 +2,13 @@ package com.yidianling.course.widget
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.os.Build
import android.os.Handler import android.os.Handler
import android.support.annotation.DrawableRes
import android.support.annotation.Nullable
import android.support.annotation.RawRes
import android.view.View import android.view.View
import android.widget.ImageView
import android.widget.RelativeLayout import android.widget.RelativeLayout
import android.widget.SeekBar import android.widget.SeekBar
import com.bumptech.glide.Glide import com.bumptech.glide.Glide
...@@ -13,10 +18,11 @@ import com.ydl.media.audio.enums.PlayModeEnum ...@@ -13,10 +18,11 @@ import com.ydl.media.audio.enums.PlayModeEnum
import com.ydl.media.audio.model.Music import com.ydl.media.audio.model.Music
import com.ydl.media.view.PlayTypeEnum import com.ydl.media.view.PlayTypeEnum
import com.ydl.media.view.PlayerFloatHelper import com.ydl.media.view.PlayerFloatHelper
import com.yidianling.course.R
import com.yidianling.course.listener.HPlayStatusListener import com.yidianling.course.listener.HPlayStatusListener
import kotlinx.android.synthetic.main.course_play_music_view.view.* import kotlinx.android.synthetic.main.course_play_music_view.view.*
/** /**
* Created by hgw on 2018/4/28. * Created by hgw on 2018/4/28.
*/ */
...@@ -37,7 +43,7 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -37,7 +43,7 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
fun init() { fun init() {
if (mContext == null) return if (mContext == null) return
View.inflate(context, R.layout.course_play_music_view, this) View.inflate(context, com.yidianling.course.R.layout.course_play_music_view, this)
AudioPlayer.get().addOnPlayEventListener(this) AudioPlayer.get().addOnPlayEventListener(this)
course_audio_play_icon.setOnClickListener { course_audio_play_icon.setOnClickListener {
...@@ -116,8 +122,10 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -116,8 +122,10 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
} }
fun setImageBackground(url: String?) { fun setImageBackground(url: String?) {
if (!isDestroy()){
Glide.with(mContext).load(url).into(img_bg) Glide.with(mContext).load(url).into(img_bg)
} }
}
/** /**
* 设置自动播放下一曲 * 设置自动播放下一曲
...@@ -134,9 +142,9 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -134,9 +142,9 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
@SuppressLint("SetTextI18n") @SuppressLint("SetTextI18n")
override fun onChange(music: Music) { override fun onChange(music: Music) {
if (mContext != null) { if (mContext != null) {
Glide.with(mContext).asGif().load(R.drawable.course_loading5).into(img_gif) displayImage(com.yidianling.course.R.drawable.course_loading5,img_gif,true)
} }
course_audio_play_icon.setImageResource(R.drawable.course_ico_course_play) course_audio_play_icon.setImageResource(com.yidianling.course.R.drawable.course_ico_course_play)
pro_progress.progress = 0 pro_progress.progress = 0
text_start_time.text = "00:00" text_start_time.text = "00:00"
...@@ -190,15 +198,15 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -190,15 +198,15 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
if (show) { if (show) {
if (!AudioPlayer.get().isPlaying) { if (!AudioPlayer.get().isPlaying) {
if (mContext != null) { if (mContext != null) {
Glide.with(mContext).asGif().load(R.drawable.course_loading5).into(img_gif) displayImage(com.yidianling.course.R.drawable.course_loading5,img_gif,true)
} }
course_audio_play_icon.setImageResource(R.drawable.course_ico_course_play) course_audio_play_icon.setImageResource(com.yidianling.course.R.drawable.course_ico_course_play)
} }
} else { } else {
if (mContext != null) { if (mContext != null) {
Glide.with(mContext).asGif().load(R.drawable.course_audio_play).into(img_gif) displayImage(com.yidianling.course.R.drawable.course_audio_play,img_gif,true)
} }
course_audio_play_icon.setImageResource(R.drawable.course_ico_course_pause) course_audio_play_icon.setImageResource(com.yidianling.course.R.drawable.course_ico_course_pause)
} }
}, 0) }, 0)
} }
...@@ -208,12 +216,11 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -208,12 +216,11 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
if (mContext == null) return if (mContext == null) return
mHandler?.postDelayed({ mHandler?.postDelayed({
if (show) { if (show) {
Glide.with(mContext).asGif().load(R.drawable.course_audio_play).into(img_gif) displayImage(com.yidianling.course.R.drawable.course_audio_play,img_gif,true)
course_audio_play_icon.setImageResource(R.drawable.course_ico_course_pause) course_audio_play_icon.setImageResource(com.yidianling.course.R.drawable.course_ico_course_pause)
} else { } else {
Glide.with(mContext).asBitmap().load(R.drawable.course_ico_course_bg_pause) displayImage(com.yidianling.course.R.drawable.course_ico_course_bg_pause,img_gif)
.into(img_gif) course_audio_play_icon.setImageResource(com.yidianling.course.R.drawable.course_ico_course_play)
course_audio_play_icon.setImageResource(R.drawable.course_ico_course_play)
} }
}, 0) }, 0)
} }
...@@ -250,4 +257,27 @@ class HPlayView : RelativeLayout, OnPlayerEventListener { ...@@ -250,4 +257,27 @@ class HPlayView : RelativeLayout, OnPlayerEventListener {
mContext = null mContext = null
mHandler = null mHandler = null
} }
/**
* 加载Image
*/
private fun displayImage(@RawRes @DrawableRes @Nullable resourceId: Int, imageView: ImageView , isGif:Boolean = false) {
//判断当前页面是否销毁
if (!isDestroy()) {
if(isGif){
Glide.with(mContext).asGif().load(resourceId).into(imageView)
}else {
Glide.with(mContext).asBitmap().load(resourceId).into(imageView)
}
}
}
/**
* 判断Activity是否Destroy
* @param activity
* @return
*/
fun isDestroy(): Boolean {
return mContext == null || mContext!!.isFinishing || Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1 && mContext!!.isDestroyed
}
} }
\ No newline at end of file
...@@ -10,7 +10,6 @@ import android.os.Handler; ...@@ -10,7 +10,6 @@ import android.os.Handler;
import android.provider.MediaStore; import android.provider.MediaStore;
import android.support.v4.view.PagerAdapter; import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewCompat; import android.support.v4.view.ViewCompat;
import android.support.v4.view.ViewPager;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import android.view.LayoutInflater; import android.view.LayoutInflater;
...@@ -31,6 +30,7 @@ import com.netease.nimlib.sdk.msg.constant.AttachStatusEnum; ...@@ -31,6 +30,7 @@ import com.netease.nimlib.sdk.msg.constant.AttachStatusEnum;
import com.netease.nimlib.sdk.msg.constant.MsgDirectionEnum; import com.netease.nimlib.sdk.msg.constant.MsgDirectionEnum;
import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum; import com.netease.nimlib.sdk.msg.constant.MsgTypeEnum;
import com.netease.nimlib.sdk.msg.model.IMMessage; import com.netease.nimlib.sdk.msg.model.IMMessage;
import com.yidianling.im.R;
import com.yidianling.nimbase.common.ToastHelper; import com.yidianling.nimbase.common.ToastHelper;
import com.yidianling.nimbase.common.activity.ToolBarOptions; import com.yidianling.nimbase.common.activity.ToolBarOptions;
import com.yidianling.nimbase.common.activity.UI; import com.yidianling.nimbase.common.activity.UI;
...@@ -41,7 +41,7 @@ import com.yidianling.nimbase.common.util.file.AttachmentStore; ...@@ -41,7 +41,7 @@ import com.yidianling.nimbase.common.util.file.AttachmentStore;
import com.yidianling.nimbase.common.util.media.BitmapDecoder; import com.yidianling.nimbase.common.util.media.BitmapDecoder;
import com.yidianling.nimbase.common.util.media.ImageUtil; import com.yidianling.nimbase.common.util.media.ImageUtil;
import com.yidianling.nimbase.common.util.storage.StorageUtil; import com.yidianling.nimbase.common.util.storage.StorageUtil;
import com.yidianling.im.R; import com.yidianling.uikit.business.session.view.ImageOriginPager;
import java.io.File; import java.io.File;
import java.util.ArrayList; import java.util.ArrayList;
...@@ -76,7 +76,7 @@ public class WatchMessagePictureActivity extends UI { ...@@ -76,7 +76,7 @@ public class WatchMessagePictureActivity extends UI {
private ImageView simpleImageView; private ImageView simpleImageView;
private int mode; private int mode;
protected CustomAlertDialog alertDialog; protected CustomAlertDialog alertDialog;
private ViewPager imageViewPager; private ImageOriginPager imageImageOriginPager;
private PagerAdapter adapter; private PagerAdapter adapter;
private AbortableFuture downloadFuture; private AbortableFuture downloadFuture;
...@@ -123,7 +123,7 @@ public class WatchMessagePictureActivity extends UI { ...@@ -123,7 +123,7 @@ public class WatchMessagePictureActivity extends UI {
@Override @Override
protected void onDestroy() { protected void onDestroy() {
registerObservers(false); registerObservers(false);
imageViewPager.setAdapter(null); imageImageOriginPager.setAdapter(null);
if (downloadFuture != null) { if (downloadFuture != null) {
downloadFuture.abort(); downloadFuture.abort();
downloadFuture = null; downloadFuture = null;
...@@ -135,7 +135,7 @@ public class WatchMessagePictureActivity extends UI { ...@@ -135,7 +135,7 @@ public class WatchMessagePictureActivity extends UI {
alertDialog = new CustomAlertDialog(this); alertDialog = new CustomAlertDialog(this);
loadingLayout = findViewById(R.id.loading_layout); loadingLayout = findViewById(R.id.loading_layout);
imageViewPager = (ViewPager) findViewById(R.id.view_pager_image); imageImageOriginPager = (ImageOriginPager) findViewById(R.id.view_pager_image);
simpleImageView = (ImageView) findViewById(R.id.simple_image_view); simpleImageView = (ImageView) findViewById(R.id.simple_image_view);
if (mode == MODE_GIF) { if (mode == MODE_GIF) {
...@@ -150,10 +150,10 @@ public class WatchMessagePictureActivity extends UI { ...@@ -150,10 +150,10 @@ public class WatchMessagePictureActivity extends UI {
} }
}); });
imageViewPager.setVisibility(View.GONE); imageImageOriginPager.setVisibility(View.GONE);
} else if (mode == MODE_NOMARL) { } else if (mode == MODE_NOMARL) {
simpleImageView.setVisibility(View.GONE); simpleImageView.setVisibility(View.GONE);
imageViewPager.setVisibility(View.VISIBLE); imageImageOriginPager.setVisibility(View.VISIBLE);
} }
} }
...@@ -184,7 +184,7 @@ public class WatchMessagePictureActivity extends UI { ...@@ -184,7 +184,7 @@ public class WatchMessagePictureActivity extends UI {
} }
// 查询并显示图片,带viewPager // 查询并显示图片,带ImageOriginPager
private void queryImageMessages() { private void queryImageMessages() {
IMMessage anchor = MessageBuilder.createEmptyMessage(message.getSessionId(), message.getSessionType(), 0); IMMessage anchor = MessageBuilder.createEmptyMessage(message.getSessionId(), message.getSessionType(), 0);
NIMClient.getService(MsgService.class).queryMessageListByType(MsgTypeEnum.image, anchor, Integer.MAX_VALUE).setCallback(new RequestCallback<List<IMMessage>>() { NIMClient.getService(MsgService.class).queryMessageListByType(MsgTypeEnum.image, anchor, Integer.MAX_VALUE).setCallback(new RequestCallback<List<IMMessage>>() {
...@@ -198,7 +198,7 @@ public class WatchMessagePictureActivity extends UI { ...@@ -198,7 +198,7 @@ public class WatchMessagePictureActivity extends UI {
// imageMsgList.addAll(param); // imageMsgList.addAll(param);
Collections.reverse(imageMsgList); Collections.reverse(imageMsgList);
setDisplayIndex(); setDisplayIndex();
setViewPagerAdapter(); setImageOriginPagerAdapter();
} }
@Override @Override
...@@ -228,7 +228,7 @@ public class WatchMessagePictureActivity extends UI { ...@@ -228,7 +228,7 @@ public class WatchMessagePictureActivity extends UI {
return (t1.getUuid().equals(t2.getUuid())); return (t1.getUuid().equals(t2.getUuid()));
} }
private void setViewPagerAdapter() { private void setImageOriginPagerAdapter() {
adapter = new PagerAdapter() { adapter = new PagerAdapter() {
@Override @Override
public int getCount() { public int getCount() {
...@@ -263,7 +263,7 @@ public class WatchMessagePictureActivity extends UI { ...@@ -263,7 +263,7 @@ public class WatchMessagePictureActivity extends UI {
layout.setTag(position); layout.setTag(position);
if (position == firstDisplayImageIndex) { if (position == firstDisplayImageIndex) {
onViewPagerSelected(position); onImageOriginPagerSelected(position);
} }
return layout; return layout;
...@@ -275,15 +275,15 @@ public class WatchMessagePictureActivity extends UI { ...@@ -275,15 +275,15 @@ public class WatchMessagePictureActivity extends UI {
} }
}; };
imageViewPager.setAdapter(adapter); imageImageOriginPager.setAdapter(adapter);
imageViewPager.setOffscreenPageLimit(2); imageImageOriginPager.setOffscreenPageLimit(2);
imageViewPager.setCurrentItem(firstDisplayImageIndex); imageImageOriginPager.setCurrentItem(firstDisplayImageIndex);
imageViewPager.setOnPageChangeListener(new ViewPager.OnPageChangeListener() { imageImageOriginPager.setOnPageChangeListener(new ImageOriginPager.OnPageChangeListener() {
@Override @Override
public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {
if (positionOffset == 0f && newPageSelected) { if (positionOffset == 0f && newPageSelected) {
newPageSelected = false; newPageSelected = false;
onViewPagerSelected(position); onImageOriginPagerSelected(position);
} }
} }
...@@ -299,7 +299,7 @@ public class WatchMessagePictureActivity extends UI { ...@@ -299,7 +299,7 @@ public class WatchMessagePictureActivity extends UI {
}); });
} }
private void onViewPagerSelected(int position) { private void onImageOriginPagerSelected(int position) {
if (downloadFuture != null) { if (downloadFuture != null) {
downloadFuture.abort(); downloadFuture.abort();
downloadFuture = null; downloadFuture = null;
...@@ -310,9 +310,9 @@ public class WatchMessagePictureActivity extends UI { ...@@ -310,9 +310,9 @@ public class WatchMessagePictureActivity extends UI {
// 初始化每个view的image // 初始化每个view的image
protected void updateCurrentImageView(final int position) { protected void updateCurrentImageView(final int position) {
View currentLayout = imageViewPager.findViewWithTag(position); View currentLayout = imageImageOriginPager.findViewWithTag(position);
if (currentLayout == null) { if (currentLayout == null) {
ViewCompat.postOnAnimation(imageViewPager, new Runnable() { ViewCompat.postOnAnimation(imageImageOriginPager, new Runnable() {
@Override @Override
public void run() { public void run() {
......
package com.yidianling.uikit.business.session.view; package com.yidianling.uikit.business.session.view;
import android.content.Context; import android.content.Context;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet; import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent; import android.view.MotionEvent;
/** /**
...@@ -11,37 +9,35 @@ import android.view.MotionEvent; ...@@ -11,37 +9,35 @@ import android.view.MotionEvent;
* Des:修复Android 系统级别bug * Des:修复Android 系统级别bug
* *
* Android 处理图片放大缩小时报错java.lang.IllegalArgumentException: pointerIndex out of range pointerIndex=-1 * Android 处理图片放大缩小时报错java.lang.IllegalArgumentException: pointerIndex out of range pointerIndex=-1
* https://github.com/chrisbanes/PhotoView/issues/31
*/ */
public class ImageOriginPager extends ViewPager { public class ImageOriginPager extends android.support.v4.view.ViewPager {
public ImageOriginPager(Context context) { public ImageOriginPager(Context context) {
super (context); super(context);
} }
public ImageOriginPager(Context context, AttributeSet attrs) { public ImageOriginPager(Context context, AttributeSet attrs) {
super (context, attrs); super(context, attrs);
} }
@Override @Override
public boolean onTouchEvent(MotionEvent event) { public boolean onTouchEvent(MotionEvent ev) {
try { try {
super.onTouchEvent(event); return super.onTouchEvent(ev);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException ex) {
Log.e( "ImageOriginPager-error" , "IllegalArgumentException 错误被活捉了!"); ex.printStackTrace();
e.printStackTrace();
} }
return false; return false;
} }
@Override @Override
public boolean onInterceptTouchEvent(MotionEvent event) { public boolean onInterceptTouchEvent(MotionEvent ev) {
try { try {
super.onInterceptTouchEvent(event); return super.onInterceptTouchEvent(ev);
} catch (IllegalArgumentException e) { } catch (IllegalArgumentException ex) {
Log.e( "ImageOriginPager-error" , "IllegalArgumentException 错误被活捉了!"); ex.printStackTrace();
e.printStackTrace();
} }
return false ; return false;
} }
} }
...@@ -11,7 +11,7 @@ ...@@ -11,7 +11,7 @@
<!-- <include layout="@layout/watch_picture_show_more_action_layout" /> --> <!-- <include layout="@layout/watch_picture_show_more_action_layout" /> -->
<android.support.v4.view.ViewPager <com.yidianling.uikit.business.session.view.ImageOriginPager
android:id="@+id/view_pager_image" android:id="@+id/view_pager_image"
android:layout_width="match_parent" android:layout_width="match_parent"
android:layout_height="match_parent"/> android:layout_height="match_parent"/>
......
...@@ -61,7 +61,7 @@ class AudioPlayer private constructor() { ...@@ -61,7 +61,7 @@ class AudioPlayer private constructor() {
} }
val audioSessionId: Int val audioSessionId: Int
get() = mediaPlayer!!.audioSessionId get() = if (mediaPlayer != null)mediaPlayer!!.audioSessionId else 0
val audioPosition: Long val audioPosition: Long
get() = if (isPlaying || isPausing) { get() = if (isPlaying || isPausing) {
......
...@@ -3,14 +3,16 @@ package com.ydl.ydlcommon.utils; ...@@ -3,14 +3,16 @@ package com.ydl.ydlcommon.utils;
import android.app.Application; import android.app.Application;
import android.util.Base64; import android.util.Base64;
import android.util.Log; import android.util.Log;
import com.ydl.ydlcommon.base.BaseApp; import com.ydl.ydlcommon.base.BaseApp;
import com.ydl.ydlcommon.utils.remind.ToastHelper; import com.ydl.ydlcommon.utils.remind.ToastHelper;
import com.yidianling.protector.AppProtectorLib; import com.yidianling.protector.AppProtectorLib;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
/** /**
* Created by haorui on 2019/7/10. * Created by haorui on 2019/7/10.
* Des:应用防护措施 * Des:应用防护措施
...@@ -36,7 +38,7 @@ public class YDLAppProtector { ...@@ -36,7 +38,7 @@ public class YDLAppProtector {
Application app = BaseApp.Companion.getApp(); Application app = BaseApp.Companion.getApp();
//检查应用多开 //检查应用多开
handleDetect(AppProtectorLib.checkIsRunningInVirtualApk(app.getPackageName(),null),true,getHint(hint_1)); //handleDetect(AppProtectorLib.checkIsRunningInVirtualApk(app.getPackageName(),null),true,getHint(hint_1));
//模拟器检测 //模拟器检测
handleDetect(AppProtectorLib.checkIsRunningInEmulator(app,null),true,getHint(hint_2)); handleDetect(AppProtectorLib.checkIsRunningInEmulator(app,null),true,getHint(hint_2));
......
...@@ -12,6 +12,8 @@ import android.widget.LinearLayout; ...@@ -12,6 +12,8 @@ import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.yidianling.common.tools.support.toast.ToastCompat;
/** /**
* 显示Toast工具类 * 显示Toast工具类
* Created by Dog on 2015/4/4. * Created by Dog on 2015/4/4.
...@@ -44,7 +46,7 @@ public class ToastUtil { ...@@ -44,7 +46,7 @@ public class ToastUtil {
private static void showShortToast(Context mContext, String msg) { private static void showShortToast(Context mContext, String msg) {
if (toast == null) { if (toast == null) {
toast = Toast.makeText(mContext.getApplicationContext(), msg, Toast.LENGTH_SHORT); toast = ToastCompat.makeText(mContext.getApplicationContext(), msg, Toast.LENGTH_SHORT);
centerText(toast.getView()); centerText(toast.getView());
toast.show(); toast.show();
oneTime = System.currentTimeMillis(); oneTime = System.currentTimeMillis();
...@@ -68,7 +70,7 @@ public class ToastUtil { ...@@ -68,7 +70,7 @@ public class ToastUtil {
public static void toastShort(Context context, String message) { public static void toastShort(Context context, String message) {
if (context != null && !TextUtils.isEmpty(message)) { if (context != null && !TextUtils.isEmpty(message)) {
showShortToast(context, message); showShortToast(context, message);
// Toast toast = Toast.makeText(context, message, Toast.LENGTH_SHORT); // Toast toast = ToastCompat.makeText(context, message, Toast.LENGTH_SHORT);
// toast.setGravity(Gravity.CENTER, 0, 0); // toast.setGravity(Gravity.CENTER, 0, 0);
// //toast.setView(getView(context,toast,message)); // //toast.setView(getView(context,toast,message));
// centerText(toast.getView()); // centerText(toast.getView());
...@@ -94,7 +96,7 @@ public class ToastUtil { ...@@ -94,7 +96,7 @@ public class ToastUtil {
public static void toastShortBottom(Context context, String message) { public static void toastShortBottom(Context context, String message) {
if (context != null) { if (context != null) {
Toast toast = Toast.makeText(context, message, Toast.LENGTH_SHORT); Toast toast = ToastCompat.makeText(context, message, Toast.LENGTH_SHORT);
centerText(toast.getView()); centerText(toast.getView());
toast.show(); toast.show();
} }
...@@ -102,7 +104,7 @@ public class ToastUtil { ...@@ -102,7 +104,7 @@ public class ToastUtil {
public static void toastLong(Context context, String message) { public static void toastLong(Context context, String message) {
if (context != null) { if (context != null) {
Toast toast = Toast.makeText(context, message, Toast.LENGTH_LONG); Toast toast = ToastCompat.makeText(context, message, Toast.LENGTH_LONG);
toast.setGravity(Gravity.CENTER, 0, 0); toast.setGravity(Gravity.CENTER, 0, 0);
centerText(toast.getView()); centerText(toast.getView());
toast.show(); toast.show();
...@@ -112,7 +114,7 @@ public class ToastUtil { ...@@ -112,7 +114,7 @@ public class ToastUtil {
public static void toastImg(Context context, int ImageResourceId) { public static void toastImg(Context context, int ImageResourceId) {
//创建一个Toast提示消息 //创建一个Toast提示消息
Toast toast = Toast.makeText(context, "", Toast.LENGTH_SHORT); Toast toast = ToastCompat.makeText(context, "", Toast.LENGTH_SHORT);
//设置Toast提示消息在屏幕上的位置 //设置Toast提示消息在屏幕上的位置
toast.setGravity(Gravity.CENTER, 0, 0); toast.setGravity(Gravity.CENTER, 0, 0);
//获取Toast提示消息里原有的View //获取Toast提示消息里原有的View
......
package com.yidianling.common.tools.support.toast;
import android.support.annotation.NonNull;
import android.widget.Toast;
/**
* @author drakeet
*/
public interface BadTokenListener {
void onBadTokenCaught(@NonNull Toast toast);
}
package com.yidianling.common.tools.support.toast;
import android.content.Context;
import android.content.ContextWrapper;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.Toast;
/**
* @author drakeet
*/
final class SafeToastContext extends ContextWrapper {
private @NonNull Toast toast;
private @Nullable BadTokenListener badTokenListener;
SafeToastContext(@NonNull Context base, @NonNull Toast toast) {
super(base);
this.toast = toast;
}
@Override
public Context getApplicationContext() {
return new ApplicationContextWrapper(getBaseContext().getApplicationContext());
}
public void setBadTokenListener(@NonNull BadTokenListener badTokenListener) {
this.badTokenListener = badTokenListener;
}
private final class ApplicationContextWrapper extends ContextWrapper {
private ApplicationContextWrapper(@NonNull Context base) {
super(base);
}
@Override
public Object getSystemService(@NonNull String name) {
if (Context.WINDOW_SERVICE.equals(name)) {
// noinspection ConstantConditions
return new WindowManagerWrapper((WindowManager) getBaseContext().getSystemService(name));
}
return super.getSystemService(name);
}
}
private final class WindowManagerWrapper implements WindowManager {
private static final String TAG = "WindowManagerWrapper";
private final @NonNull WindowManager base;
private WindowManagerWrapper(@NonNull WindowManager base) {
this.base = base;
}
@Override
public Display getDefaultDisplay() {
return base.getDefaultDisplay();
}
@Override
public void removeViewImmediate(View view) {
base.removeViewImmediate(view);
}
@Override
public void addView(View view, ViewGroup.LayoutParams params) {
try {
Log.d(TAG, "WindowManager's addView(view, params) has been hooked.");
base.addView(view, params);
} catch (BadTokenException e) {
Log.i(TAG, e.getMessage());
if (badTokenListener != null) {
badTokenListener.onBadTokenCaught(toast);
}
} catch (Throwable throwable) {
Log.e(TAG, "[addView]", throwable);
}
}
@Override
public void updateViewLayout(View view, ViewGroup.LayoutParams params) {
base.updateViewLayout(view, params);
}
@Override
public void removeView(View view) {
base.removeView(view);
}
}
}
package com.yidianling.common.tools.support.toast;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.StringRes;
import android.view.View;
import android.widget.Toast;
import java.lang.reflect.Field;
/**
* @author drakeet
* Des: 解决 Android 7.1.1 由 Toast 引起的 BadTokenException Crash
*/
public final class ToastCompat extends Toast {
private final @NonNull Toast toast;
/**
* Construct an empty Toast object. You must call {@link #setView} before you
* can call {@link #show}.
*
* @param context The context to use. Usually your {@link Application}
* or {@link Activity} object.
* @param base The base toast
*/
private ToastCompat(Context context, @NonNull Toast base) {
super(context);
this.toast = base;
}
/**
* Make a standard toast that just contains a text view.
*
* @param context The context to use. Usually your {@link Application}
* or {@link Activity} object.
* @param text The text to show. Can be formatted text.
* @param duration How long to display the message. Either {@link #LENGTH_SHORT} or
* {@link #LENGTH_LONG}
*/
public static ToastCompat makeText(Context context, CharSequence text, int duration) {
// We cannot pass the SafeToastContext to Toast.makeText() because
// the View will unwrap the base context and we are in vain.
@SuppressLint("ShowToast")
Toast toast = Toast.makeText(context, text, duration);
setContextCompat(toast.getView(), new SafeToastContext(context, toast));
return new ToastCompat(context, toast);
}
/**
* Make a standard toast that just contains a text view with the text from a resource.
*
* @param context The context to use. Usually your {@link Application}
* or {@link Activity} object.
* @param resId The resource id of the string resource to use. Can be formatted text.
* @param duration How long to display the message. Either {@link #LENGTH_SHORT} or
* {@link #LENGTH_LONG}
* @throws Resources.NotFoundException if the resource can't be found.
*/
public static Toast makeText(Context context, @StringRes int resId, int duration)
throws Resources.NotFoundException {
return makeText(context, context.getResources().getText(resId), duration);
}
public @NonNull ToastCompat setBadTokenListener(@NonNull BadTokenListener listener) {
final Context context = getView().getContext();
if (context instanceof SafeToastContext) {
((SafeToastContext) context).setBadTokenListener(listener);
}
return this;
}
@Override
public void show() {
toast.show();
}
@Override
public void setDuration(int duration) {
toast.setDuration(duration);
}
@Override
public void setGravity(int gravity, int xOffset, int yOffset) {
toast.setGravity(gravity, xOffset, yOffset);
}
@Override
public void setMargin(float horizontalMargin, float verticalMargin) {
toast.setMargin(horizontalMargin, verticalMargin);
}
@Override
public void setText(int resId) {
toast.setText(resId);
}
@Override
public void setText(CharSequence s) {
toast.setText(s);
}
@Override
public void setView(View view) {
toast.setView(view);
setContextCompat(view, new SafeToastContext(view.getContext(), this));
}
@Override
public float getHorizontalMargin() {
return toast.getHorizontalMargin();
}
@Override
public float getVerticalMargin() {
return toast.getVerticalMargin();
}
@Override
public int getDuration() {
return toast.getDuration();
}
@Override
public int getGravity() {
return toast.getGravity();
}
@Override
public int getXOffset() {
return toast.getXOffset();
}
@Override
public int getYOffset() {
return toast.getYOffset();
}
@Override
public View getView() {
return toast.getView();
}
public @NonNull Toast getBaseToast() {
return toast;
}
private static void setContextCompat(@NonNull View view, @NonNull Context context) {
if (Build.VERSION.SDK_INT == 25) {
try {
Field field = View.class.getDeclaredField("mContext");
field.setAccessible(true);
field.set(view, context);
} catch (Throwable throwable) {
throwable.printStackTrace();
}
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment