Android 는 네트워크 외부 네트워크 연결 상황 에 따라 서버 액세스 IP 를 설정 합 니 다.

5604 단어
새로운 프로젝트 의 app 은 내부 네트워크 와 외부 네트워크 의 서버 ip 를 통 해 방문 을 요청 할 수 있 지만 고객 은 전문 단말 기 를 제공 합 니 다. 단말 기 는 와 이 파이 상황 에서 외부 네트워크 로 가도 되 지만 와 이 파 이 를 닫 으 면 4G 전문 네트워크 만 걸 을 수 있 습 니 다. 즉, 내부 네트워크 만 걸 을 수 있 습 니 다.
내 작은 사이트 로 가서 볼 수 있 습 니 다: 안 드 로 이 드 는 네트워크 외부 네트워크 연결 상황 에 따라 서버 접근 IP 를 설정 합 니 다.
계획
Android 에 서 는 바 텀 셸 을 직접 호출 하여 해당 명령 을 수행 할 수 있 기 때문에 ping 명령 만 실행 하면 됩 니 다.안 드 로 이 드 는 Process p = Runtime.getRuntime().exec(/system/bin/ping -c 1 -w 1 " + ip) 를 통 해 실행 할 수 있다.그 다음 에 if (p.waitFor() == 0) 을 통 해 ping 통 여 부 를 판단 한다. 여기 있 는 두 개 1 는 매개 변 수 를 나타 내 고 첫 번 째 는 ping 1 회 를 나타 내 며 두 번 째 는 1s 를 초과 하면 실패 라 고 한다.
완전 실현
  • 먼저 권한 을 성명 합 니 다. 이 단 계 는 매우 중요 합 니 다. Android Manifes 파일 에서
  • 
    
    
  • 몇 개의 전역 변 수 를 유지 합 니 다
  •     String outer_ip = "183.230.XXX.XXX"; //      IP
        String inner_ip = "192.168.XXX.XXX"; //      IP
    
        boolean outerIpAvilable = false;  //     
        boolean innerIpAvialable = false; //     
    
  • 두 개의 스 레 드 를 열 어 ping 두 개의 ip 을 제거 하고 Countdown Latch 를 통 해 동기 화 합 니 다.왜냐하면
  • private void initNetworkConfig() {
            try {
                final int totalThread = 2;
                CountDownLatch countDownLatch = new CountDownLatch(totalThread);
                ExecutorService executorService = Executors.newCachedThreadPool();
                executorService.execute(new PingNetwork(outer_ip, countDownLatch, false));
                executorService.execute(new PingNetwork(inner_ip, countDownLatch, true));
                countDownLatch.await(); //         
                Log.d(TAG, "end");
                if (innerIpAvialable && outerIpAvilable)
                    Toast.makeText(this, "      ", Toast.LENGTH_SHORT).show();
                else if (outerIpAvilable)
                    Toast.makeText(this, "     ", Toast.LENGTH_SHORT).show();
                else
                    Toast.makeText(this, "     ", Toast.LENGTH_SHORT).show();
                executorService.shutdown();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    
  • ping 의 비동기 스 레 드 를 실현 합 니 다.
  • class PingNetwork implements Runnable {
    
            String ip; //   ping ip
            CountDownLatch countDownLatch;
            boolean isCheckInner;
            public PingNetwork(String ip, CountDownLatch countDownLatch, boolean isCheckInner) {
                this.ip = ip;
                this.countDownLatch = countDownLatch;
                this.isCheckInner = isCheckInner;
            }
    
            @Override
            public void run() {
                try {
                    Process p = Runtime.getRuntime().exec("/system/bin/ping -c 1 -w 1 " + ip);// ping  3 
                    // ping   
                    final int status = p.waitFor();
                    if (status == 0) {
                        Log.d(TAG, "ping onSuccess");
                        if (isCheckInner){
                            innerIpAvialable = true;
                            outerIpAvilable = false;
                        }
                        else{
                            outerIpAvilable = true;
                            innerIpAvialable = false;
                        }
                    } else {
                        //   ping error  ,    ping    
                        InputStream errorStream = p.getErrorStream();
                        BufferedReader errIn = new BufferedReader(new InputStreamReader(errorStream));
                        StringBuilder sb = new StringBuilder();
                        String err = "";
                        while ((err = errIn.readLine()) != null) {
                            sb.append(err);
                        }
                        Log.d(TAG, "result err : " + sb.toString());
                        Log.d(TAG, "ping onFailure");
                    }
                } catch (Exception e) {
                    Log.d(TAG, "ping onFailure");
                } finally {
                    countDownLatch.countDown();
                }
            }
        }
    

    여기 서 ping 이 실 패 했 을 때 오류 정 보 를 인쇄 하여 볼 수 있 습 니 다. 첫 번 째 단 계 는 성명 권한 입 니 다. 본인 은 두 번 째 권한 을 성명 하지 않 았 습 니 다. 여기 서 오류 정보 ping , ip 를 얻 었 습 니 다. 인터넷 에서 무슨 루트 라 고 하 든 다 있 습 니 다. 사실은 그렇지 않 습 니 다.
    완벽 하 다.
    이상 의 실현 을 통 해 내부 네트워크 연결 상황 을 통 해 서버 에 접근 하 는 ip 를 설정 할 수 있 습 니 다. 그러나 앱 이 시 작 될 때 핸드폰 이 외부 네트워크 에 접근 할 수 있 기 때문에 프로그램 은 외부 네트워크 의 ip (외부 네트워크 의 속도 가 빠 르 기 때문에) 을 설정 할 수 있 습 니 다. 그러나 사용 하 는 과정 에서 외부 네트워크 의 방문 을 닫 았 습 니 다. 예 를 들 어 와 이 파 이 는 이때 전문 네트워크, 즉 내부 네트워크 를 걸 었 습 니 다.서버 에 더 이상 접근 할 수 없습니다.따라서 네트워크 를 전환 할 때 새 설정 에서 ip 에 접근 해 야 합 니 다.따라서 앱 에서 방송 을 통 해 안 드 로 이 드 N (안 드 로 이 드 7) 이전에 Pemission denied 방송 을 통 해 정적 등록 과 동적 등록 을 할 수 있 지만 7 후에 방송 을 바 꾸 는 것 이 잘못 되 었 으 므 로 다음 과 같은 방안 으로 교체 할 수 있 습 니 다.
    ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
            connectivityManager.requestNetwork(new NetworkRequest.Builder().build(),
                    new ConnectivityManager.NetworkCallback() {
                        @Override public void onAvailable(Network network) {
                            super.onAvailable(network);
                            LogUtil.d("      ,    ");
                            NetworkUtils.initNetworkConfig();
                        }
                    });
    
    android.net.conn.CONNECTIVITY_CHANGE 위 에 ping 을 통 해 ip 을 설정 한 패키지 입 니 다.

    좋은 웹페이지 즐겨찾기