Intereting Posts
Макет, как приложение HotStar «Преобразование в формат Dalvik с ошибкой 1» на внешнем JAR Как я могу заставить сайт масштабироваться для исправления для мобильных устройств (Iphone android ..) Android как отправлять и получать изображение и местоположение (используя карту) в групповом чате с помощью xmpp-smack Как добавить текст в видеозапись? Как добавить кнопку в ActionBar (Android)? Тип безопасности: снятый флажок из объекта в список <MyObject> Динамически изменять цвет шрифта TextView в ListView Тестирование инструментальных средств Android – проблемы с интерфейсом пользовательского интерфейса Обнаружение кромок с использованием OpenCV (Canny) Фоновый селектор в элементе RecyclerView В Android CLI build отображается недопустимая ошибка имени каталога ресурса: MY_PROJECT \ res / crunch Обновить индикатор выполнения в панели уведомлений Layout Layers? Z-Axis? Настройка гравитации ImageView в центр в android программно

Как использовать 3G-соединение в приложении Android вместо Wi-Fi?

Как использовать 3G-соединение в приложении Android вместо Wi-Fi?

Я хочу подключить 3G-соединение, есть ли какой-нибудь пример кода для подключения к 3G вместо Wi-Fi?

Solutions Collecting From Web of "Как использовать 3G-соединение в приложении Android вместо Wi-Fi?"

Приложение T-Mobile «Моя учетная запись» делает это, если вы подключены к Wi-Fi-соединению, он сообщает вам, что их программа не будет работать через WiFi, а затем спросит пользователя, хотите ли они отключить WiFi-соединение. Если вы выберете « Нет ", тогда приложение выходит, если вы выберете« Да », приложение отключит ваше WiFi-соединение, а затем продолжит запуск.

Я думаю, что это хорошая модель для подражания, это гарантирует, что ваше приложение не будет работать через WiFi и позволит пользователю решить, хотите ли они отключить WiFi или нет. Улучшение этой модели было бы превратить Wi-Fi обратно, когда пользователь переходит от вашего приложения.

Я не тестировал следующий код, но похоже, что он должен работать (изменен отсюда )

Используйте следующие разрешения в своем манифесте

<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission> <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission> 

И вот какой-то фактический код для включения / отключения Wi-Fi

 private WifiManager wifiManager; @Override public void onCreate(Bundle icicle) { .................... wifiManager = (WifiManager) this.getSystemService(Context.WIFI_SERVICE); if(wifiManager.isWifiEnabled()) { wifiManager.setWifiEnabled(false); } else { wifiManager.setWifiEnabled(true); } } 

Если вы не хотите идти по этому маршруту, похоже, вы могли бы сказать телефону, что предпочитаете использовать мобильную сеть передачи данных, а не сеть Wi-Fi.

Android ConnectivityManager предлагает функцию setNetworkPreference . Эта функция на самом деле не документирована, так как вы можете узнать, нажмите ли вы ссылку. Я бы обдумал это, хотя, поскольку определяемые константы подсказывают, что вы можете установить это либо в TYPE_MOBILE, либо в TYPE_WIFI, и есть константа DEFAULT_NETWORK_PREFERENCE, которая определена как 0x00000001, которая является такой же, как TYPE_WIFI. Поэтому попробуйте получить доступ к ConnectivityManager, позвонив

 Context.getSystemService(Context.CONNECTIVITY_SERVICE); 

А затем попробуйте использовать функцию setNetworkPreference ().

Кажется, что он не требует каких-либо разрешений в манифесте, но для этого может потребоваться разрешение CHANGE_NETWORK_STATE или что-то в этом направлении.

Если вы подали иск в функцию setNetworkPreference, вероятно, было бы лучше также установить сетевое предпочтение на исходные значения (полученные от getNetworkPreference)

Надеюсь, это поможет.

 /** * Enable mobile connection for a specific address * @param context a Context (application or activity) * @param address the address to enable * @return true for success, else false */ private boolean forceMobileConnectionForAddress(Context context, String address) { ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (null == connectivityManager) { Log.debug(TAG_LOG, "ConnectivityManager is null, cannot try to force a mobile connection"); return false; } //check if mobile connection is available and connected State state = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState(); Log.debug(TAG_LOG, "TYPE_MOBILE_HIPRI network state: " + state); if (0 == state.compareTo(State.CONNECTED) || 0 == state.compareTo(State.CONNECTING)) { return true; } //activate mobile connection in addition to other connection already activated int resultInt = connectivityManager.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI"); Log.debug(TAG_LOG, "startUsingNetworkFeature for enableHIPRI result: " + resultInt); //-1 means errors // 0 means already enabled // 1 means enabled // other values can be returned, because this method is vendor specific if (-1 == resultInt) { Log.error(TAG_LOG, "Wrong result of startUsingNetworkFeature, maybe problems"); return false; } if (0 == resultInt) { Log.debug(TAG_LOG, "No need to perform additional network settings"); return true; } //find the host name to route String hostName = StringUtil.extractAddressFromUrl(address); Log.debug(TAG_LOG, "Source address: " + address); Log.debug(TAG_LOG, "Destination host address to route: " + hostName); if (TextUtils.isEmpty(hostName)) hostName = address; //create a route for the specified address int hostAddress = lookupHost(hostName); if (-1 == hostAddress) { Log.error(TAG_LOG, "Wrong host address transformation, result was -1"); return false; } //wait some time needed to connection manager for waking up try { for (int counter=0; counter<30; counter++) { State checkState = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState(); if (0 == checkState.compareTo(State.CONNECTED)) break; Thread.sleep(1000); } } catch (InterruptedException e) { //nothing to do } boolean resultBool = connectivityManager.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress); Log.debug(TAG_LOG, "requestRouteToHost result: " + resultBool); if (!resultBool) Log.error(TAG_LOG, "Wrong requestRouteToHost result: expected true, but was false"); return resultBool; } 

И это для расчета адреса хоста:

 /** * This method extracts from address the hostname * @param url eg. http://some.where.com:8080/sync * @return some.where.com */ public static String extractAddressFromUrl(String url) { String urlToProcess = null; //find protocol int protocolEndIndex = url.indexOf("://"); if(protocolEndIndex>0) { urlToProcess = url.substring(protocolEndIndex + 3); } else { urlToProcess = url; } // If we have port number in the address we strip everything // after the port number int pos = urlToProcess.indexOf(':'); if (pos >= 0) { urlToProcess = urlToProcess.substring(0, pos); } // If we have resource location in the address then we strip // everything after the '/' pos = urlToProcess.indexOf('/'); if (pos >= 0) { urlToProcess = urlToProcess.substring(0, pos); } // If we have ? in the address then we strip // everything after the '?' pos = urlToProcess.indexOf('?'); if (pos >= 0) { urlToProcess = urlToProcess.substring(0, pos); } return urlToProcess; } /** * Transform host name in int value used by {@link ConnectivityManager.requestRouteToHost} * method * * @param hostname * @return -1 if the host doesn't exists, elsewhere its translation * to an integer */ private static int lookupHost(String hostname) { InetAddress inetAddress; try { inetAddress = InetAddress.getByName(hostname); } catch (UnknownHostException e) { return -1; } byte[] addrBytes; int addr; addrBytes = inetAddress.getAddress(); addr = ((addrBytes[3] & 0xff) << 24) | ((addrBytes[2] & 0xff) << 16) | ((addrBytes[1] & 0xff) << 8 ) | (addrBytes[0] & 0xff); return addr; } 

И в AndroidManifest.xml должно быть добавлено следующее разрешение

 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/> <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> 

Он работает только с Android 2.2 и выше, протестирован как на Nexus One, так и на LG Optimus, другие телефоны, которых я не знаю, потому что какой-то метод ConnectivityManager специфичен для вендора. После 15-20 секунд бездействия мобильная сеть автоматически отключается.

Я думаю, что это невозможно из Java. При подключении к беспроводной сети система отключает всю связь на основе мобильной сети. Я думаю, что вам запрещено запускать 3G-соединение из вашей программы.

Используйте диспетчер подключений и настройте сетевое предпочтение как хотите. удачи

Например: dataManager = (ConnectivityManager) getSystemService (CONNECTIVITY_SERVICE); dataManager.setNetworkPreference (ConnectivityManager.TYPE_MOBILE);

Вот код, который работает на API 21+ (Lollipop, Marshmallow ..). Я предпочитаю использовать OkHttp с Network.getSocketFactory () , но Network.openURLConnection () также отлично работает.

 private void doTest() { display("Requesting CELLULAR network connectivity..."); ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE); NetworkRequest request = new NetworkRequest.Builder() .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR) .addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET).build(); connectivityManager.requestNetwork(request, new ConnectivityManager.NetworkCallback() { /** * Called when the framework connects and has declared a new network ready for use. * This callback may be called more than once if the {@link Network} that is * satisfying the request changes. * * This method will be called on non-UI thread, so beware not to use any UI updates directly. * * @param network The {@link Network} of the satisfying network. */ @Override public void onAvailable(final Network network) { display("Got available network: " + network.toString()); try { final InetAddress address = network.getByName("navalclash.com"); display("Resolved host2ip: " + address.getHostName() + " -> " + address.getHostAddress()); } catch (UnknownHostException e) { e.printStackTrace(); } display("Do request test page from remote http server..."); if(okHttpClient == null) { okHttpClient = new OkHttpClient.Builder().socketFactory(network.getSocketFactory()).build(); } Request request = new Request.Builder() .url("http://navalclash.com") .build(); try (Response response = okHttpClient.newCall(request).execute()) { display("RESULT:\n" + response.body().string()); } catch (Exception ex) { ex.printStackTrace(); } } }); } 

Это приложение активирует 3G и Wi-Fi соединение, отдавая предпочтение 3G! Очень полезно http://www.redrails.com.br/2012/02/wireless-analyzer-for-android/

Вдохновленный кодом в этом билете и используя некоторые его части, вот сервис, который устанавливает hipri mobile и поддерживает его.

 import java.net.InetAddress; import java.net.UnknownHostException; import java.util.concurrent.atomic.AtomicBoolean; import android.app.Service; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo.State; import android.os.IBinder; import android.util.Log; public class HipriService extends Service { private AtomicBoolean enabledMobile = new AtomicBoolean(false); public boolean enableMobileConnection() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); if (null == cm) { Log.d(TAG, "ConnectivityManager is null, cannot try to force a mobile connection"); return false; } /* * Don't do anything if we are connecting. On the other hands re-new * connection if we are connected. */ State state = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState(); Log.d(TAG, "TYPE_MOBILE_HIPRI network state: " + state); if (0 == state.compareTo(State.CONNECTING)) return true; /* * Re-activate mobile connection in addition to other connection already * activated */ int resultInt = cm.startUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI"); //Log.d(TAG, "startUsingNetworkFeature for enableHIPRI result: " + resultInt); //-1 means errors // 0 means already enabled // 1 means enabled // other values can be returned, because this method is vendor specific if (-1 == resultInt) { Log.e(TAG, "Wrong result of startUsingNetworkFeature, maybe problems"); return false; } if (0 == resultInt) { Log.d(TAG, "No need to perform additional network settings"); return true; } return requestRouteToHost(this, Uploader.ServerAddress); } private Thread pingerThread = null; private void startMobileConnection() { enabledMobile.set(true); pingerThread = new Thread(new Runnable() { @Override public void run() { while (enabledMobile.get()) { /* * Renew mobile connection. No routing setup is needed. This * should be moved to 3g monitoring service one day. */ enableMobileConnection(); try { Thread.sleep(1000); } catch (InterruptedException e) { // do nothing } } } }); pingerThread.start(); } private void stopMobileConnection() { enabledMobile.set(false); disableMobileConnection(); pingerThread.interrupt(); pingerThread = null; } public void disableMobileConnection() { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); cm.stopUsingNetworkFeature(ConnectivityManager.TYPE_MOBILE, "enableHIPRI"); } public final static int inetAddressToInt(InetAddress inetAddress) { byte[] addrBytes; int addr; addrBytes = inetAddress.getAddress(); addr = ((addrBytes[3] & 0xff) << 24) | ((addrBytes[2] & 0xff) << 16) | ((addrBytes[1] & 0xff) << 8) | (addrBytes[0] & 0xff); return addr; } public final static InetAddress lookupHost(String hostname) { try { return InetAddress.getByName(hostname); } catch (UnknownHostException e) { return null; } } private boolean requestRouteToHost(Context context, String hostname) { ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); if (null == cm) { Log.d(TAG, "ConnectivityManager is null, cannot try to force a mobile connection"); return false; } /* Wait some time needed to connection manager for waking up */ try { for (int counter = 0; enabledMobile.get() && counter < 30; counter++) { State checkState = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState(); Log.i(TAG, "Waiting for mobile data on. State " + checkState); if (0 == checkState.compareTo(State.CONNECTED)) break; Thread.sleep(1000); } } catch (InterruptedException e) { //nothing to do } if (!enabledMobile.get()) { Log.d(TAG, "Mobile data is turned off while waiting for routing."); return false; } State checkState = cm.getNetworkInfo(ConnectivityManager.TYPE_MOBILE_HIPRI).getState(); if (0 != checkState.compareTo(State.CONNECTED)) { Log.e(TAG, "Mobile data is still turned off after 30 sec of waiting."); return false; } Log.i(TAG, "Adding routing for " + hostname); InetAddress inetAddress = lookupHost(hostname); if (inetAddress == null) { Log.e(TAG, "Failed to resolve " + hostname); return false; } int hostAddress = inetAddressToInt(inetAddress); boolean resultBool = cm.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_HIPRI, hostAddress); Log.d(TAG, "requestRouteToHost result: " + resultBool); if (!resultBool) Log.e(TAG, "Wrong requestRouteToHost result: expected true, but was false"); return resultBool; } @Override public void onCreate() { super.onCreate(); startMobileConnection(); } @Override public void onDestroy() { stopMobileConnection(); super.onDestroy(); } @Override public IBinder onBind(Intent intent) { return null; } } 

Вот как я начинаю / останавливаю его, когда это необходимо. Обратите внимание, что он также получает блокировки на процессоре и Wi-Fi, чтобы он мог работать, когда телефон спит (только экран). Wi-Fi необходим, потому что мое приложение является мостом между Wi-Fi и мобильными соединениями. Возможно, вам это не понадобится.

 public void startMobileData() { if (!enabledMobile.get()) { enabledMobile.set(true); WifiManager wm = (WifiManager) getSystemService(Context.WIFI_SERVICE); wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL, "Wifi Wakelock"); wifiLock.acquire(); PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); partialLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "3G Wakelock"); partialLock.acquire(); startService(new Intent(this, HipriService.class)); } } public void stopMobileData() { if (enabledMobile.get()) { enabledMobile.set(false); Log.i(TAG, "Disabled mobile data"); stopService(new Intent(this, HipriService.class)); if (partialLock != null) { partialLock.release(); partialLock = null; } if (wifiLock != null) { wifiLock.release(); wifiLock = null; } } } 

Не забудьте добавить службу в файл манифеста.

@umka

  • Я думаю, приложение может доходить только до тех хостов через HIPRI, которые он запросил, может быть для других хостов (маршруты которых не запрашиваются) использует сеть по умолчанию (MOBILE или WIFI).
  • При вызове stopUsingNetworkFeature () он будет проверять – есть ли другое приложение, использующее эту сеть, если да, то оно будет игнорировать ваш запрос на удаление этой сетевой функции.
  • Одной из главных целей сети HIPRI является то, что если Wi-Fi включен, и приложение хочет использовать мобильную сеть (3G) для доступа к конкретному хосту, она может достигать сети HIPRI.