强制android中的特定网络,即使它没有';我没有互联网连接

强制android中的特定网络,即使它没有';我没有互联网连接,android,android-wifi,android-networking,Android,Android Wifi,Android Networking,我的项目是使用一个旧的USB网络摄像头和一个树莓皮制作一个后视摄像头 我将摄像头插入pi并使用“运动”,当我与pi在同一网络上时,我可以通过浏览器(http://:8081)访问实时视频 为此,我将Pi设置为wifi热点,以便与手机在同一网络中访问视频 但是:在我用Android Studio创建了一个应用程序后,用WebView打开视频链接,当启用移动数据时,我得到了一个错误连接。因为如果未检测到互联网连接,则不会使用Wifi网络 我不希望每次使用时都手动禁用它,我希望应用程序只使用Wi-Fi

我的项目是使用一个旧的USB网络摄像头和一个树莓皮制作一个后视摄像头

我将摄像头插入pi并使用“运动”,当我与pi在同一网络上时,我可以通过浏览器(
http://:8081
)访问实时视频

为此,我将Pi设置为wifi热点,以便与手机在同一网络中访问视频

但是:在我用Android Studio创建了一个应用程序后,用WebView打开视频链接,当启用移动数据时,我得到了一个
错误连接。因为如果未检测到互联网连接,则不会使用Wifi网络

我不希望每次使用时都手动禁用它,我希望应用程序只使用Wi-Fi

我使用以下代码成功地自动连接到pi WiFi:

    WifiNetworkSpecifier specifier = new WifiNetworkSpecifier.Builder()
            .setSsid("Wifi-Fourcon")
            .setWpa2Passphrase("1234567890")
            .build();

    final NetworkRequest request = new NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) // we want WiFi
            .setNetworkSpecifier(specifier) // we want _our_ network
            .build();

    ConnectivityManager connectivityManager = (ConnectivityManager)this.getSystemService(CONNECTIVITY_SERVICE);

    connectivityManager.requestNetwork(request,
我试图补充

.removeTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
但同样的结果

我还试图禁用移动数据与

setMobileDataEnabled()

但是我们不能再使用这种方法了。

谷歌禁用了修改关键Android功能(如启用/禁用移动互联网)的功能。

谷歌禁用了修改关键Android功能(如启用/禁用移动互联网)的功能。

因此我假设这里的问题是Wifi连接实际上没有提供internet,因此android会忽略web请求的连接


编辑:阅读文档后,该方法似乎更适合用例。它将整个过程限制为仅使用该特定网络。我再次没有测试过这一点,但是如果需要反向绑定,可以通过在
onAvailable
中调用正确的方法,并在
onLost
中调用
null
来轻松实现。现有套接字不会被强制,因此最安全的方法是仅在绑定到网络后初始化WebView


可以通过覆盖WebView如何加载其请求并强制其使用网络请求的连接来规避此问题。一个完整的解决方案可能是这样的,尽管我还没有测试过。让我知道这是否有效:

Network networkInstance;

void getNetwork(Context context) {

    final NetworkRequest request = new NetworkRequest.Builder()
            .addTransportType(NetworkCapabilities.TRANSPORT_WIFI) // we want WiFi
            .setNetworkSpecifier("foobar") // we want _our_ network
            .build();


    ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
    connectivityManager.requestNetwork(request, new ConnectivityManager.NetworkCallback() {
        @Override
        public void onAvailable(@NonNull Network network) {
            networkInstance = network;
            loadWebView();
        }

        @Override
        public void onLost(@NonNull Network network) {
            // Notify the user or something ...
            super.onLost(network);
        }
    });

}


public void setupWebView(WebView webView) {


    webView.setWebViewClient(new WebViewClient() {
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

            if (networkInstance != null) {
                try {
                    URL url = new URL(request.getUrl().toString());
                    HttpURLConnection connection = (HttpURLConnection) networkInstance.openConnection(url);
                    connection.setDoOutput(true);
                    connection.setRequestMethod(request.getMethod());

                    for (Map.Entry<String, String> header : request.getRequestHeaders().entrySet()) {
                        connection.setRequestProperty(header.getKey(), header.getValue());
                    }

                    int responseCode = connection.getResponseCode();
                    String responseMessage = connection.getResponseMessage();
                    String contentType = connection.getContentType();
                    String encoding = connection.getContentEncoding();

                    // Transform response headers from Map<String, List<String>> to Map<String, String>
                    HashMap<String, String> headerFields = new HashMap<>();
                    for (Map.Entry<String, List<String>> entry : connection.getHeaderFields().entrySet()) {
                        headerFields.put(entry.getKey(), entry.getValue().get(0));
                    }

                    String[] contentTypeData = contentType.split(";\\s?");
                    contentType = contentTypeData[0];
                    if (contentTypeData.length > 1) {
                        encoding = contentTypeData[1];
                    }

                    if (contentType.contains("text") && encoding == null) {
                        encoding = "UTF-8";
                    }

                    InputStream inputStream;
                    try {
                        inputStream = connection.getInputStream();
                    } catch (Exception e) {
                        inputStream = connection.getErrorStream();
                    }

                    return new WebResourceResponse(
                            contentType,
                            encoding,
                            responseCode,
                            responseMessage,
                            headerFields,
                            inputStream
                    );

                } catch (IOException e) {
                    e.printStackTrace();
                }

            }

            return super.shouldInterceptRequest(view, request);
        }
    });
}
网络实例;
void getNetwork(上下文){
最终NetworkRequest请求=新建NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT\u WIFI)//我们需要WIFI
.setNetworkSpecifier(“foobar”)//我们想要我们的网络
.build();
ConnectivityManager ConnectivityManager=(ConnectivityManager)context.getSystemService(context.CONNECTIVITY_服务);
requestNetwork(请求,新的ConnectionManager.NetworkCallback(){
@凌驾
公共无效onAvailable(@NonNull Network){
网络实例=网络;
loadWebView();
}
@凌驾
public void onLost(@NonNull Network){
//通知用户什么的。。。
super.onLost(网络);
}
});
}
公共无效设置WebView(WebView WebView){
setWebViewClient(新的WebViewClient(){
@凌驾
公共WebResourceResponse应InterceptRequest(WebView视图、WebResourceRequest请求){
if(networkInstance!=null){
试一试{
URL=新URL(request.getUrl().toString());
HttpURLConnection连接=(HttpURLConnection)networkInstance.openConnection(url);
connection.setDoOutput(真);
connection.setRequestMethod(request.getMethod());
for(Map.Entry头:request.getRequestHeaders().entrySet()){
setRequestProperty(header.getKey(),header.getValue());
}
int responseCode=connection.getResponseCode();
字符串responseMessage=connection.getResponseMessage();
String contentType=connection.getContentType();
字符串编码=连接。getContentEncoding();
//将响应头从映射转换为映射
HashMap headerFields=新HashMap();
for(Map.Entry:connection.getHeaderFields().entrySet()){
headerFields.put(entry.getKey(),entry.getValue().get(0));
}
字符串[]contentTypeData=contentType.split(“;\\s?”);
contentType=contentTypeData[0];
如果(contentTypeData.length>1){
编码=contentTypeData[1];
}
if(contentType.contains(“text”)&&encoding==null){
encoding=“UTF-8”;
}
输入流输入流;
试一试{
inputStream=connection.getInputStream();
}捕获(例外e){
inputStream=connection.getErrorStream();
}
返回新的WebResourceResponse(
内容类型,
编码,
响应代码,
响应消息,
校长们,
输入流
);
}捕获(IOE异常){
e、 printStackTrace();
}
}
返回super.shouldInterceptRequest(查看、请求);
}
});
}

应使用WebView实例调用一次
setupWebView
,以设置WebViewClient。(如果您已经在使用WebViewClient,只需复制覆盖的
shouldInterceptRequest
方法即可。)

因此我假设这里的问题是Wifi连接实际上不提供internet,所以