Jey*_*vel 31 android android-emulator
如何在Android应用程序中使用3G连接而不是Wi-Fi?
我想连接3G连接,是否有任何示例代码连接到3G而不是Wi-Fi?
小智 61
/**
* 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;
}
Run Code Online (Sandbox Code Playgroud)
这用于计算主机地址:
/**
* 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;
}
Run Code Online (Sandbox Code Playgroud)
并且必须将以下权限添加到AndroidManifest.xml
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
Run Code Online (Sandbox Code Playgroud)
它仅适用于Android 2.2及更高版本,在Nexus One和LG Optimus上测试,其他手机我不知道,因为ConnectivityMananger的某些方法是特定于供应商的.在15-20秒不活动后,移动网络将自动断开连接.
snc*_*tln 13
T-Mobile"我的帐户"应用程序执行此操作,如果您连接到WiFi连接,它会告诉您他们的程序无法通过WiFi工作,然后询问用户是否要关闭WiFi连接.如果您选择"没有"然后应用程序退出,如果您选择"是",则应用程序将关闭您的WiFi连接,然后继续启动.
我认为这是一个很好的模型,它将确保您的应用程序不通过WiFi运行,并允许用户决定是否要关闭WiFi.这种模式的改进是当用户离开你的应用程序时重新打开wifi.
我没有测试过以下代码,但它看起来应该可以工作(从这里修改)
在清单中使用以下权限
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
Run Code Online (Sandbox Code Playgroud)
这里有一些实际的代码来打开/关闭wifi
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);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您不想沿着这条路走下去,看起来您可能会告诉手机您更愿意使用移动数据网络而不是wifi网络.
Android ConnectivityManager提供了一个功能setNetworkPreference.如果您单击该链接,则无法记录此功能.我会讨论它,因为定义的常量似乎暗示你可以将它设置为TYPE_MOBILE或TYPE_WIFI,并且还有一个DEFAULT_NETWORK_PREFERENCE常量定义为0x00000001,它与TYPE_WIFI相同.因此,请尝试通过调用访问ConnectivityManager
Context.getSystemService(Context.CONNECTIVITY_SERVICE);
Run Code Online (Sandbox Code Playgroud)
然后尝试使用setNetworkPreference()函数.
它似乎不需要清单中的任何权限,但它可能需要CHANGE_NETWORK_STATE权限或沿着这些行.
如果您使用setNetworkPreference函数,最好也将网络首选项设置回其原始值(从getNetworkPreference接收)
我希望这有帮助.
我认为这不可能来自Java.如果连接到无线网络,系统将关闭所有基于移动网络的通信.我认为您不能从您的程序启动3G连接.
这是适用于 API 21+(棒棒糖、棉花糖 ..)的代码。我更喜欢将 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();
}
}
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
69229 次 |
| 最近记录: |