package cn.bidaround.ytcore.util;
import java.io.IOException;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.widget.Toast;
import cn.bidaround.ytcore.YtCore;
import cn.bidaround.ytcore.data.KeyInfo;
import cn.bidaround.ytcore.data.YtPlatform;
import cn.bidaround.ytcore.wxapi.WXEntryActivity;
import cn.bidaround.ytcore.yxapi.YXBaseActivity;
/**
* <h1>集成检测,检测配置文件是否丢失</h1>
* <b>检测内容</b>
* <li>检测资源文件是否丢失(youtui_sdk.xml/res资源)
* <li>检测是否缺少权限(由于某些机型不支持无法检测权限,所以取消权限检测)
* <li>检测AndroidManifest.xml配置
* <li>检测是否配置友推appKey
* <li>如果有配置微信、易信检测是否有创建集成需要的类,是否有在manifest中配置
* <hr>
* <li>检测过程中存在问题将以<b><font color=red>YouTui</font></b>为tag,警告或者错误的方式提示在LogCat,并会有相应的Toast提示
* <hr>
* @author youtui
* @since 2014/11/11
*/
public class CheckConfig {
private final static String TAG = "YouTui";
private Context mContext;
private List<String> mLayoutList;
private List<String> mActivityList;
private List<String> mDrawableList;
private List<String> mAnimList;
/** 缺少res下drawable/string/layout文件*/
private final String MISS_RES = "miss resources in res directory!";
/** 缺少assets/youtui_sdk.xml*/
private final String MISS_ASSESTS = "miss youtui_sdk.xml in assets directory!";
/** 未配置youtui_sdk.xml中友推appkey*/
private final String MISS_YOUTUIKEY = "miss youtui appkey!";
/** AndroidManifest缺少需要注册的Activity*/
private final String MISS_ACTIVITY = "miss activity in AndroidManifest!";
/** 检测微信、易信集成需要添加的类是否有创建*/
private final String MISS_CLASS = "class not found!";
public CheckConfig(Context context){
mContext = context;
}
private void init(){
mLayoutList = new ArrayList<String>();
mActivityList = new ArrayList<String>();
mLayoutList.add("yt_activity_dialog");
mLayoutList.add("yt_activity_screencapedit");
mLayoutList.add("yt_activity_share");
mLayoutList.add("yt_activity_shareedit");
mLayoutList.add("yt_authdialog");
mLayoutList.add("yt_black_grid_item");
mLayoutList.add("yt_dialog_shareedit");
mLayoutList.add("yt_point_webview");
mLayoutList.add("yt_popup_list");
mLayoutList.add("yt_popup_viewpager");
mLayoutList.add("yt_popup_whiteviewpager");
mLayoutList.add("yt_share_pager");
mLayoutList.add("yt_white_grid_item");
mLayoutList.add("yt_white_list_item");
mActivityList.add("cn.bidaround.ytcore.login.AuthActivity");
mActivityList.add("cn.bidaround.point.PointActivity");
mActivityList.add("cn.bidaround.youtui_template.ScreenCapEditActivity");
mDrawableList = new ArrayList<String>();
mDrawableList.add("yt_colorchoose_gray");
mDrawableList.add("yt_button");
mDrawableList.add("yt_btn_style_alert_dialog_cancel_normal");
mDrawableList.add("yt_yixinfriends");
mDrawableList.add("yt_yixin");
mDrawableList.add("yt_sinaweibo");
mDrawableList.add("yt_wechat");
mDrawableList.add("yt_wechatfavorite");
mDrawableList.add("yt_tencentweibo");
mDrawableList.add("yt_side");
mDrawableList.add("yt_sendbutton");
mDrawableList.add("yt_screencap_save");
mDrawableList.add("yt_screencap_rectangle_on");
mDrawableList.add("yt_screencap_rectangle_off");
mDrawableList.add("yt_screencap_pencil_on");
mDrawableList.add("yt_screencap_pencil_off");
mDrawableList.add("yt_screencap_circle_small_on");
mDrawableList.add("yt_screencap_circle_small_off");
mDrawableList.add("yt_screencap_circle_middle_on");
mDrawableList.add("yt_screencap_circle_middle_off");
mDrawableList.add("yt_screencap_cancel");
mDrawableList.add("yt_renren");
mDrawableList.add("yt_reddot");
mDrawableList.add("yt_qq");
mDrawableList.add("yt_wechatmoments");
mDrawableList.add("yt_more");
mDrawableList.add("yt_shortmessage");
mDrawableList.add("yt_email");
mDrawableList.add("yt_loadfail");
mDrawableList.add("yt_list_newmessage");
mDrawableList.add("yt_list_item_unselected_color_border");
mDrawableList.add("yt_copylink");
mDrawableList.add("yt_left_arrow");
mDrawableList.add("yt_kaixin");
mDrawableList.add("yt_guide_dot_white");
mDrawableList.add("yt_guide_dot_black");
mAnimList = new ArrayList<String>();
mAnimList.add("yt_sharepopup_fade_in");
mAnimList.add("yt_sharepopup_fade_out");
}
public void check() {
if(!YtCore.getInstance().isCheckConfig()) return;
if(Util.readCheckConfigTime() >= Constant.MAX_SUC_CHECKCONFIG_TIME){
w("友推集成检测机制已连续运行" + Util.readCheckConfigTime() +"次,未检测出异常,已自动关闭.");
return;
}
w("开始友推集成检测...");
w("如需关闭集成检测机制,请调用YtTemplate.checkConfig(Boolean)");
new Thread(new Runnable() {
public void run() {
init();
if(checkAssets())
if(checkYoutuiKey())
if(checkActivity() && checkOtherActivity())
if(checkClass())
checkRes();
else
showErrorToast(MISS_CLASS);
else
showErrorToast(MISS_ACTIVITY);
else
showErrorToast(MISS_YOUTUIKEY);
else
showErrorToast(MISS_ASSESTS);
}
}).start();
}
@SuppressWarnings("rawtypes")
private void checkRes(){
String packageName = mContext.getPackageName();
Class r = null;
try {
r = Class.forName(packageName + ".R");
Class[] classes = r.getClasses();
boolean success = true;
for (int i = 0; i < classes.length; ++i) {
String name = classes[i].getName().split("\\$")[1];
boolean b = true;
if("layout".equals(name))
if(!checkLayout(classes[i]))
b = false;
if("drawable".equals(name))
if(!checkDrawable(classes[i]))
b = false;
if("string".equals(name))
if(!checkValues(classes[i]))
b = false;
if("anim".equals(name))
if(!checkAnim(classes[i]))
b = false;
if("style".equals(name))
if(!checkStyle(classes[i]))
b = false;
if(!b) {
showErrorToast(MISS_RES);
if(success)
success = false;
}
}
if(success)
Util.addCheckConfigTime();
} catch (Exception e) {
e.printStackTrace();
}
}
private boolean checkAnim(Class<?> desireClass){
Field[] fields = desireClass.getFields();
if(fields != null && fields.length > 0 ){
boolean b = true;
List<String> list = new ArrayList<String>();
for(Field f : fields)
list.add(f.getName());
for(String str : mAnimList){
if(!list.contains(str)){
e("code:1022;>>>Miss "+str + ".xml in res/anim directory");
b = false;
}
}
return b;
}
return false;
}
private boolean checkStyle(Class<?> desireClass){
Field[] fields = desireClass.getFields();
if(fields != null && fields.length > 0 ){
boolean b = true;
List<String> list = new ArrayList<String>();
for(Field f : fields)
list.add(f.getName());
if(!list.contains("YtSharePopupAnim")){
e("code:1023;>>>Miss yt_style.xml in res/values directory");
b = false;
}
return b;
}
return false;
}
private boolean checkAssets(){
try {
mContext.getResources().getAssets().open("youtui_sdk.xml").close();
} catch (IOException e) {
e("code:1001;>>>Miss youtui_sdk.xml in the directory of assets");
return false;
}
return true;
}
/**
* 微信、易信需在包名下创建一个类,判断该类是否有创建
* @return
*/
private boolean checkClass(){
boolean b = true;
// 微信、朋友圈、收藏,判断是否有创建WXEntryActivity类
if("true".equals(YtPlatform.PLATFORM_WECHAT.getEnable()) || "true".equals(YtPlatform.PLATFORM_WECHATFAVORITE.getEnable())
|| "true".equals(YtPlatform.PLATFORM_WECHATMOMENTS.getEnable())){
boolean ad = checkClassExist(mContext.getPackageName()+".wxapi.WXEntryActivity", WXEntryActivity.class.getName());
if(!ad) b = false;
}
// // 判断易信、易信朋友圈
if("true".equals(YtPlatform.PLATFORM_YIXIN.getEnable()) || "true".equals(YtPlatform.PLATFORM_YIXINFRIENDS.getEnable())){
boolean ad = checkClassExist(mContext.getPackageName()+".yxapi.YXEntryActivity", YXBaseActivity.class.getName());
if(!ad) b = false;
}
return b;
}
private boolean checkOtherActivity(){
boolean b = true;
// 微信、朋友圈,判断是否有在menifest.xml中配置
if("true".equals(YtPlatform.PLATFORM_WECHATFAVORITE.getEnable()) || "true".equals(YtPlatform.PLATFORM_WECHAT.getEnable())
|| "true".equals(YtPlatform.PLATFORM_WECHATMOMENTS.getEnable())){
boolean ac = haveActivity(mContext.getPackageName()+".wxapi.WXEntryActivity");
if(!ac) b = false;
}
// 判断易信、易信朋友圈
if("true".equals(YtPlatform.PLATFORM_YIXIN.getEnable()) || "true".equals(YtPlatform.PLATFORM_YIXINFRIENDS.getEnable())){
boolean ac = haveActivity(mContext.getPackageName()+".yxapi.YXEntryActivity");
if(!ac) b = false;
}
// 判断qq、qq空间
if("true".equals(YtPlatform.PLATFORM_QQ.getEnable()) || "true".equals(YtPlatform.PLATFORM_QZONE.getEnable())){
boolean assistActivity = haveActivity("com.tencent.connect.common.AssistActivity");
boolean authActivity = haveActivity("com.tencent.tauth.AuthActivity");
if(!assistActivity || !authActivity) b = false;
}
// 判断人人网
if("true".equals(YtPlatform.PLATFORM_RENREN.getEnable())){
boolean ac = haveActivity("com.renn.rennsdk.oauth.OAuthActivity");
if(!ac) b = false;
}
// 判断新浪微博
if("true".equals(YtPlatform.PLATFORM_SINAWEIBO.getEnable())){
boolean ac = haveActivity("cn.bidaround.ytcore.activity.SinaShareActivity");
if(!ac) b = false;
}
return b;
}
/**
* 指定类路径,判断是否存在,如果没有该类,则会进入异常处理块中
* @param clazz
* @return
*/
private boolean checkClassExist(String clazz, String parentClass){
try {
Class.forName(clazz);
return true;
} catch (Exception e) {
e("code:1002;>>>Class not found "+ clazz +", please create the class extends " + parentClass);
return false;
}
}
private boolean checkYoutuiKey(){
if(TextUtils.isEmpty(KeyInfo.youTui_AppKey)){
e("code:1003;>>>Miss 'YouTui' label in youtui_sdk.xml");
return false;
}
return true;
}
private boolean checkLayout(Class<?> desireClass){
Field[] fields = desireClass.getFields();
if(fields != null && fields.length > 0 ){
boolean b = true;
List<String> list = new ArrayList<String>();
for(Field f : fields)
list.add(f.getName());
for(String str : mLayoutList){
if(!list.contains(str)){
e("code:1004;>>>Miss "+str + ".xml文件");
b = false;
}
}
return b;
}
return false;
}
private boolean checkDrawable(Class<?> desireClass){
Field[] fields = desireClass.getFields();
if(fields != null && fields.length > 0 ){
boolean b = true;
List<String> list = new ArrayList<String>();
for(Field f : fields)
list.add(f.getName());
for(String str : mDrawableList){
if(!list.contains(str)){
e("code:1005;>>>Miss "+str + ".png in drawable directory");
b = false;
}
}
return b;
}
return false;
}
private boolean checkValues(Class<?> desireClass){
Field[] fields = desireClass.getFields();
if(fields != null && fields.length > 0 ){
for(Field f : fields)
if("youtui_appId".equals(f.getName()))
return true;
e("code:1006;>>>Miss yt_strings.xml in values directory");
return false;
}
return false;
}
/**
* 检测必须配置的Activity
* @return
*/
private boolean checkActivity(){
boolean b = true;
for(String act : mActivityList){
if(!haveActivity(act))
b = false;
}
return b;
}
private boolean haveActivity(String name){
try {
// 如果没有配置Activity,怎会抛出异常
mContext.getPackageManager().getActivityInfo(new ComponentName(mContext, name), PackageManager.GET_ACTIVITIES);
return true;
} catch (NameNotFoundException e) {
e("code:1008;>>>In AndoridManifest.xml do not found Activity with name "+name);
return false;
}
}
/** 出现Toast提示,说明检测过程中发现 错误*/
private void showErrorToast(String msg){
// 这种提示说明有检查出错误信息
YtCore.getInstance().setCheckConfigHasError(msg);
Util.clearCheckConfigTime();
Message message = new Message();
message.obj = msg;
handler.sendMessage(message);
}
@SuppressLint("HandlerLeak") private Handler handler = new Handler(){
public void handleMessage(android.os.Message msg) {
Toast.makeText(mContext, msg.obj.toString(), Toast.LENGTH_LONG).show();
};
};
private static void e(String msg){
YtLog.e(TAG, "):>" + msg);
}
private static void w(String msg){
YtLog.w(TAG, "):>" + msg);
}
}