MTK 듀얼 카드 이동식 데이터 켜기/끄기에 대한 작은 연구

최근 MTK 듀얼 카드 휴대전화, 4.1 시스템을 연구하고 있다.프로그램에서 이동 데이터의 스위치를 제어하려면 어려운 문제에 부딪혔다.이전에 반사적인 방법으로 Connectivity Manager 종류를 호출한 setMobile DataEnabled 방법이 효력을 상실한 것을 발견했기 때문에 알림의 정보를 찾을 수 없었다. 첫 번째 반응은 4.1 시스템에 이런 방법이 없는 건 생각만 해도 불가능하다는 것이다.원본 검색은 과감하게도 원본과 같다.다시 디버깅을 진행하여 Connectivity Manager 클래스의 모든 함수를 찾았습니다. 이 방법도 존재합니다.원인을 조사하는 것은 아마도 개인적인 방법 때문에 호출할 수 없기 때문일 것이다.그러나 코드를 바꾸면 개인적인 방법을 사용할 수 있고 권한을 부여하고 시스템 서명을 한 후에도 그렇습니다. 제 코드에 문제가 있는지 어떤지 여러분이 보시고 웃지 마세요.
private void setGprsEnable(boolean isEnable) {
        int result = 0;
ConnectivityManager mCM = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        try {
            Class clazz = Class.forName(mCM.getClass().getName());
            Constructor[] cons = clazz.getDeclaredConstructors();
            Constructor con = clazz.getConstructor();//getDeclaredConstructors();
            con.setAccessible(true);

            Field iConnectivityManagerField = clazz.getDeclaredField("mService");
            iConnectivityManagerField.setAccessible(true);
            Object iConnectivityManager = iConnectivityManagerField.get(mCM);
            //Class iConnectivityManagerClass = Class.forName(iConnectivityManager.getClass().getName());
            ConnectivityManager cm =  (ConnectivityManager)con.newInstance(iConnectivityManager);
            Class[] argClasses = new Class[1];
            argClasses[0] = Boolean.class;
            Method ms = clazz.getDeclaredMethod("setMobileDataEnabled", argClasses);
            ms.setAccessible(true);
            Object obj = ms.invoke(cm, isEnable);
            result = (Integer) obj;
        } catch (ClassNotFoundException e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        } catch (IllegalArgumentException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InstantiationException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
}

기왕 이 방법이 통하지 않는다면 다른 방법을 찾겠다.먼저 해탁 인터넷 마스터를 뽑았는데 시스템 서명이 있어야 데이터 스위치를 제어할 수 있다는 결과가 나왔다. 리셋 후 앱 모바일 시스템/app에서 과감하게 실현할 수 있었지만 어떤 방법을 썼는지 모르겠다. 원본 코드가 없으면 구글도 자료가 없다.로그캣을 진지하게 관찰할 수밖에 없어요. 발견할 수 있을지 없을지.
하늘은 마음을 품지 않으니, 정보를 찾아라.데이터 연결을 열 때logcat에서 관건적인 정보를 출력합니다
Provider/Settings(506): put string name = gprs_connection_setting , value = 1 userHandle = 0
SettingsProvider(506): insert(content://settings/system) for user 0 by 0
SettingsProvider(506): redundant, old Value: 0 new value: 1
SettingsProvider(506): system <- value=1 name=gprs_connection_setting for user 0

Provider/Settings(506): put string name = gprs_connection_sim_setting , value = 3 userHandle = 0
SettingsProvider(506): insert(content://settings/system) for user 0 by 0
SettingsProvider(506): redundant, old Value: 0 new value: 3
SettingsProvider(506): system <- value=3 name=gprs_connection_sim_setting for user 0

Provider/Settings(506): Global.putString(name=mobile_data, value=1 for 0
Provider/Settings(506): put string name = mobile_data , value = 1 userHandle = 0
SettingsProvider(506): redundant, old Value: 0 new value: 1
SettingsProvider(506): global <- value=1 name=mobile_data for user 0

설마 이 세 개의 값만 바꾸면 되는 건 아니겠지?과감하기 그지없다.
ContentResolver cr = getWindow().getContext().getContentResolver();
Settings.System.putInt(cr, "gprs_connection_setting", 1);
Settings.System.putInt(cr, "gprs_connection_sim_setting", 3);
Settings.Global.putInt(cr, "mobile_data", 1);

게다가 WRITESECURE_SETTINGS 및 WRITESETTINGS 권한, 시스템 서명을 추가하여 다시 시도하십시오.결과는 여전히 열 수 없지만 밑에 있는 메뉴의 단축 버튼이 바뀌었고 데이터 연결은 이미 열렸다. 바로 신호 값에 데이터 연결이 없는 H나 E 아이콘이다.시스템이 왜 설정 정보를 업데이트하지 않았는지 궁금할 때 나는 비행 모드를 켜 보았는데 켜자마자 비행 모드를 껐다. 그 결과 데이터가 연결되었다.비행 모드가 꺼진 후 시스템은 네트워크를 다시 설정하기 시작했고 네트워크 설정을 업데이트했으며 원래 바뀐 값이 효력을 발생하기 시작했다.
네트워크 상태가 바뀐 후에 시스템은 네트워크 설정을 업데이트할 수 있다. 그러면 네트워크가 바뀐 방송을 보내면 우리가 수정한 설정을 즉시 업데이트할 수 있지 않을까?몇 개의 방송을 해 보았지만 아쉽게도 안 돼, 이해가 안 돼.하지만 와이파이를 스위치하면 비행 모드와 마찬가지로 내가 원하는 결과를 얻을 수 있다.so, 시간이 제한되어 있으니 우선 이 방법을 쓰자.와이파이의 스위치에 대해 나는 이렇게 조작한다. 와이파이가 이미 연결되었을 때 사실 데이터 연결이 켜졌는지는 중요하지 않기 때문에 와이파이가 꺼진 후에 시스템은 자동으로 설정을 업데이트할 것이다.
Handler handler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            switch(msg.what){
            case 0:
                //wifi  ,    
                if(wifiManager.isWifiEnabled()&&mActivity.getWifiState()==200){
                    wifiManager.setWifiEnabled(false);
                    sendEmptyMessageDelayed(2, 200);
                }
                else if(wifiManager.isWifiEnabled()){

                }
                else{
                    wifiManager.setWifiEnabled(true);
                    sendEmptyMessageDelayed(1, 200);
                }
                break;
            case 1:
                wifiManager.setWifiEnabled(false);
                break;
            case 2:
                wifiManager.setWifiEnabled(true);
                break;
            }
            super.handleMessage(msg);
        }
    };

이제 문제가 해결되었다.나는 MTK 더블카드 시스템을 사용하기 때문에 여기서는 좀 더 처리해야 한다
int defaultsim = getDefaultSim();
Settings.System.putInt(cr, "gprs_connection_setting", defaultsim);

getDefaultSim () 방법은 MTK의 인터페이스로 반사로 찾을 수 있습니다.여기는 더 이상 붙이지 않겠습니다.참, 권한 추가하는 거 잊지 마세요. CHANGENETWORK_STATE、CHANGE_WIFI_STATE、ACCESS_WIFI_STATE.
이 방법은 비록 완벽하지는 않지만, 늘 쓸 수 있다. OMG, 시간이 있으면 천천히 연구합시다

좋은 웹페이지 즐겨찾기