关闭

[Android]反射的使用及如何防止反射

标签: JAVA反射防止反射Reflectionandroid
1117人阅读 评论(0) 收藏 举报

反射的使用


1.使用反射机制获取安卓内部资源


(1) 获取系统Toast的内部资源(layout/view)

Toast的布局文件:com.android.internal.R.layout.transient_notification
Toast的文本视图:com.android.internal.R.id.message
Toast的相关源码:
LayoutInflater inflate = (LayoutInflater)
                context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflate.inflate(com.android.internal.R.layout.transient_notification, null);
TextView tv = (TextView)v.findViewById(com.android.internal.R.id.message);

在安卓的应用程序中无法直接使用这些系统的内部资源,但可以通过反射机制获取并使用,代码如下:
            try{
                Class<?> clazz = Class.forName("com.android.internal.R$layout");
                Field field = clazz.getField("transient_notification");
                field.setAccessible(true);
                int id_layout = field.getInt(null);
                clazz = Class.forName("com.android.internal.R$id");
                field = clazz.getField("message");
                field.setAccessible(true);
                int id_message = field.getInt(null);
                View mImprovedToastView = inflate.inflate(id_layout, null);
                TextView mImprovedToastTextView = (TextView)mImprovedToastView.findViewById(id_message);
            } catch (Exception e){
            }

(2) 获取系统状态栏的高度

        try {
            Class<?> c = Class.forName("com.android.internal.R$dimen");
            Object obj = c.newInstance();
            Field field = c.getField("status_bar_height");
            int x = Integer.parseInt(field.get(obj).toString());
            int sbar = mContext.getResources().getDimensionPixelSize(x);
        } catch (Exception e) {
            e.printStackTrace();
        }

(3) 获取系统字符串

            try {
                Class sysResCls = Class.forName("com.android.internal.R$string");
                Field webUserAgentField = sysResCls.getDeclaredField("web_user_agent");  // 也可以写成 Field field = sysResCls.getField("web_user_agent");
                Integer resId = (Integer) webUserAgentField.get(null);   // 也可以写成  resId = webUserAgentField.getInt(null);
                String webUserAgent = context.getString(resId);
            } catch (Throwable ignored) {
            }


2.使用反射机制调用安卓系统内部类的方法


(1) 获取设备的串号:
        String sn = null;
        try {
            Class<?> c = Class.forName("android.os.SystemProperties");
            Method get = c.getMethod("get", String.class, String.class );
            sn = (String)(get.invoke(c, "ro.serialno", "unknown" ));
            if(sn== null || "".equals(sn)){
                // fail to get the serial number
            }else {
                // succeed to get the serial number
            }
        }
        catch (Exception ignored) {
        }


(2) 判断某个类是否存在的方法:
                    boolean  isClassExisted = false;
                    try {
                        Class.forName("com.xxx.xxx.util.ClassName");
                        isClassExisted = true;
                    } catch (ClassNotFoundException ignored) {
                        //Ignored.
                    }


(3) 获取MTK手机的TeleInfo信息:
        TeleInfo teleInfo = new TeleInfo();
        try {
            Class<?> phone = Class.forName("com.android.internal.telephony.Phone");
            Field fields1 = phone.getField("GEMINI_SIM_1");
            fields1.setAccessible(true);
            int simId_1 = (Integer) fields1.get(null);
            Field fields2 = phone.getField("GEMINI_SIM_2");
            fields2.setAccessible(true);
            int simId_2 = (Integer) fields2.get(null);

            TelephonyManager tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
            Method getSubscriberIdGemini = TelephonyManager.class.getDeclaredMethod("getSubscriberIdGemini", int.class);
            String imsi_1 = (String) getSubscriberIdGemini.invoke(tm, simId_1);
            String imsi_2 = (String) getSubscriberIdGemini.invoke(tm, simId_2);
            teleInfo.imsi_1 = imsi_1;
            teleInfo.imsi_2 = imsi_2;

            Method getDeviceIdGemini = TelephonyManager.class.getDeclaredMethod("getDeviceIdGemini", int.class);
            String imei_1 = (String) getDeviceIdGemini.invoke(tm, simId_1);
            String imei_2 = (String) getDeviceIdGemini.invoke(tm, simId_2);

            teleInfo.imei_1 = imei_1;
            teleInfo.imei_2 = imei_2;

            Method getPhoneTypeGemini = TelephonyManager.class.getDeclaredMethod("getPhoneTypeGemini", int.class);
            int phoneType_1 = (Integer) getPhoneTypeGemini.invoke(tm, simId_1);
            int phoneType_2 = (Integer) getPhoneTypeGemini.invoke(tm, simId_2);
            teleInfo.phoneType_1 = phoneType_1;
            teleInfo.phoneType_2 = phoneType_2;
        } catch (Exception e) {
            e.printStackTrace();
        }


如何防止反射


<待续>

0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:93963次
    • 积分:1157
    • 等级:
    • 排名:千里之外
    • 原创:32篇
    • 转载:11篇
    • 译文:0篇
    • 评论:5条
    文章分类
    最新评论