8

पर मोबाइल डेटा मैं विकासशील और एप्लिकेशन जो वाईफाई (डिवाइस द्वारा जेनरेट) के माध्यम से हार्डवेयर डिवाइस से कनेक्ट होता है और सॉकेट कनेक्शन के माध्यम से डेटा भेजता हूं। समस्या यह है कि जब मोबाइल डेटा (3 जी/4 जी) सक्रिय होता है तो एंड्रॉइड डिवाइस द्वारा जेनरेट की गई वाईफ़ाई के माध्यम से इसे भेजने के बजाय डेटा भेजने की कोशिश करता है, क्योंकि वाईफ़ाई के पास इंटरनेट कनेक्शन नहीं है। मैं ConnectivityManager#setNetworkPreference() का उपयोग करने का सोच रहा था, लेकिन यह एपीआई में पदावनत किया गया है 21.वाईफाई (कोई इंटरनेट) के माध्यम से डेटा भेजें जब

कैसे मैं इसे सेट मोबाइल डेटा इंटरफेस के बजाय डिवाइस द्वारा उत्पन्न वाईफाई का उपयोग कर डेटा भेजने के लिए कर सकते हैं?

उत्तर

9

बहुत सारे शोध और समय को समझने की कोशिश करने के बाद मुझे यह पता चला कि एंड्रॉइड 5.0 (लॉलीपॉप) के पिछले संस्करणों में यह संभव नहीं है, ओएस केवल एक समय में एक नेटवर्क इंटरफ़ेस रखता है और ऐप्स इस पर नियंत्रण नहीं है। मामले में

  1. अपने सॉकेट कनेक्शन की जांच कर रही है, तो एंड्रॉयड अधिक या बराबर Lollipop में से पहले, यह तुम सिर्फ ऐसा नहीं है:

    तो अधिक से अधिक या लॉलीपॉप के बराबर संस्करणों पर यह करने के लिए मैं निम्नलिखित किया जो भी आपको सामान्य रूप से करना है;

  2. मामले में संस्करण बराबर या अधिक है Lollipop में आप कुछ इस तरह करने की जरूरत है:

    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) { 
        final ConnectivityManager manager = (ConnectivityManager) context 
          .getSystemService(Context.CONNECTIVITY_SERVICE); 
        NetworkRequest.Builder builder; 
        builder = new NetworkRequest.Builder(); 
        //set the transport type do WIFI 
        builder.addTransportType(NetworkCapabilities.TRANSPORT_WIFI); 
        manager.requestNetwork(builder.build(), new ConnectivityManager.NetworkCallback() { 
         @Override 
         public void onAvailable(Network network) { 
          if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
           manager.bindProcessToNetwork(network); 
          } else { 
           //This method was deprecated in API level 23 
           ConnectivityManager.setProcessDefaultNetwork(network); 
          } 
          try { 
           //do a callback or something else to alert your code that it's ok to send the message through socket now 
          } catch (Exception e) { 
           e.printStackTrace(); 
          } 
          manager.unregisterNetworkCallback(this); 
         } 
        }); 
    } 
    
  3. क्या आप इस के साथ प्रक्रिया बाध्यकारी बंद कर देना चाहिए पूरा करने के बाद:

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
        ConnectivityManager manager = (ConnectivityManager) InovePlugApplication.getContext() 
          .getSystemService(Context.CONNECTIVITY_SERVICE); 
        manager.bindProcessToNetwork(null); 
    } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 
        ConnectivityManager.setProcessDefaultNetwork(null); 
    } 
    

इस उत्तर ने मुझे यह सुनिश्चित करने में मदद की कि यह कैसे करें https://stackoverflow.com/a/29837637/2550932

+0

इस काम के लिए आपको अपने मैनिफेस्ट में '<उपयोग-अनुमति एंड्रॉइड: name =" android.permission.CHANGE_NETWORK_STATE "/>' की आवश्यकता होगी। – AppleGrew

+0

@hygorxaraujo मैं आपके कोड का उपयोग कर रहा हूं, लेकिन यह एंड्रॉइड नौगेट के लिए काम नहीं कर रहा है। मैं मार्शमलो और उच्चतर के लिए प्रबंधक.बिंडप्रोसेसनेट नेटवर्क (नेटवर्क) कर रहा हूं। क्या कोई कामकाज है? –

+0

@ satpal002 क्षमा करें, मैंने केवल एंड्रॉइड मार्शमलो तक इस कोड का उपयोग किया है (और मेरे पास परीक्षण करने के लिए नौगेट वाला डिवाइस नहीं है)। मैंने https://developer.android.com/reference/android/net/ConnectivityManager.html पर काम करना बंद करने के लिए एपीआई में कोई भी बदलाव नहीं देखा है। क्या यह सामान्य रूप से पिछले संस्करणों (लॉलीपॉप के ऊपर) में काम कर रहा है? – hygorxaraujo

0

नेटवर्क सेट पर प्रोसेस प्रोसेस डीफॉल्ट नेटवर्क के बाद मोबाइल पर वापस स्विच करेगा, आप इस तरह से बड़े डेटा नहीं भेज सकते हैं, क्योंकि इस तरह से बनाए गए सभी सॉकेट काम करना बंद कर देंगे। मुझे अब एक सही तरीका नहीं मिला है, यहां केवल संदर्भ के लिए है।

1. यदि आप रूट पहुँच प्राप्त कर सकते हैं, ऐसा करने से पहले वाईफाई से कनेक्ट:

Process process = runtime.exec("su"); 
DataOutputStream dataOutputStream = new DataOutputStream(process.getOutputStream()); 
dataOutputStream.writeBytes("settings put global captive_portal_server 127.0.0.1\n"); 
dataOutputStream.writeBytes("exit\n"); 
dataOutputStream.flush(); 
int status = process.waitFor(); 

और इसे हटा आप डेटा भेजने के बाद:

dataOutputStream.writeBytes("settings delete global captive_portal_server\n"); 

2. यदि आप WRITE_SECURE_SETTINGS अनुमति प्राप्त कर सकते हैं :

Settings.Global.putString(getContentResolver(),"captive_portal_server","127.0.0.1"); 

या:

Settings.Global.putInt(getContentResolver(),"captive_portal_detection_enabled",0); 
+0

हाय @MADAO, आपके उत्तर के लिए धन्यवाद, मुझे लगता है कि आप भी सही हैं। मुझे पहले से ही इसका जवाब मिल गया था और यहां सवाल को अपडेट करना भूल गया था। – hygorxaraujo

संबंधित मुद्दे