我这里遇到了一点麻烦
我创建了一个在我的个人计算机上运行的 Flask 服务器,IP 地址为 192.168.1.3:5000,它本身运行得很好。我使用 Insomnia 和网络测试了这些请求,一切都很完美。
但是,当从我的智能手机上的 Expo 应用程序发出请求时,它们不起作用。这就好像应用程序无法访问本地网络请求或类似的东西。
我做了一些研究,在 app.json 文件中找到了有关权限的信息。我按照建议进行了更改,但没有成功。我仍然只能从桌面访问。
还值得一提的是,如果我通过智能手机的网络浏览器访问同一端点,我可以看到我在服务器的“/”路由中插入的“hello world”消息。所以,我不认为这是我机器的 IP 或本地网络内设备之间的通信问题。
这是一些代码:
我的烧瓶服务器:
from flask import Flask, request
from ctypes import windll
from comtypes import CLSCTX_ALL
from pycaw.pycaw import AudioUtilities, IAudioEndpointVolume
from flask_cors import CORS
import requests
app = Flask(__name__)
CORS(app, resources={r"/*": {"origins": "*"}})
VLC_PASSWORD = 'vlcpassword'
VLC_URL = 'http://localhost:8080/requests/status.json'
VK_MEDIA_PLAY_PAUSE = 0xB3
VK_VOLUME_UP = 0xAF
VK_VOLUME_DOWN = 0xAE
def press_key(hexKeyCode):
windll.user32.keybd_event(hexKeyCode, 0, 0, 0)
windll.user32.keybd_event(hexKeyCode, 0, 2, 0)
def set_volume(level):
devices = AudioUtilities.GetSpeakers()
interface = devices.Activate(IAudioEndpointVolume._iid_, CLSCTX_ALL, None)
volume = interface.QueryInterface(IAudioEndpointVolume)
volume.SetMasterVolumeLevelScalar(level, None)
def send_vlc_command(command):
url = f'http://localhost:8080/requests/status.json?command={command}'
response = requests.get(url, auth=('', VLC_PASSWORD))
return response.status_code == 200
@app.route('/play_pause', methods=['POST'])
def play_pause():
data = request.get_json()
is_vlc = data.get('is_vlc', "False")
if is_vlc == "True":
send_vlc_command('pl_pause')
return 'VLC play/pause triggered'
else:
press_key(VK_MEDIA_PLAY_PAUSE)
return 'Play/pause triggered'
@app.route('/volume_up', methods=['POST'])
def volume_up():
data = request.get_json()
is_vlc = data.get('is_vlc', False)
if is_vlc == "True":
send_vlc_command('volume&val=%2B20')
return 'VLC volume up triggered'
else:
press_key(VK_VOLUME_UP)
return 'Volume up triggered'
@app.route('/volume_down', methods=['POST'])
def vlc_volume_down():
data = request.get_json()
is_vlc = data.get('is_vlc', False)
if is_vlc == "True":
send_vlc_command('volume&val=-20')
return 'VLC volume down triggered'
else:
press_key(VK_VOLUME_DOWN)
return 'Volume down triggered'
@app.route('/')
def hello():
return "Hello, World!"
if __name__ == '__main__':
app.run(host='192.168.1.3', port=5000)
我的 expo 应用程序中的 index.tsx:
import React, { useState } from 'react';
import CustomButton from '../../components/CustomButton';
import { StyleSheet, View, Text, Switch } from 'react-native';
import axios from 'axios';
const TabOneScreen = () => {
const [isVLC, setIsVLC] = useState(false);
const [serverIsOnline, setServerIsOnline] = useState(false);
const [log, setLog] = useState<any[]>([]);
const vlcServerURL = 'http://192.168.1.3:5000';
const handlePlayPause = async () => {
try {
const response = await axios.post(vlcServerURL + '/play_pause', {
is_vlc: isVLC ? 'True' : 'False'
});
console.log(response.data);
setLog([...log, response.data]);
setLog([...log, response.status]);
} catch (error) {
console.error('Fail:', error);
}
};
const handleVolumeUp = async () => {
try {
const response = await axios.post(vlcServerURL + '/volume_up', {
is_vlc: isVLC ? 'True' : 'False',
});
console.log(response.data);
} catch (error) {
console.error('Fail:', error);
}
};
const handleVolumeDown = async () => {
try {
const response = await axios.post(vlcServerURL + '/volume_down', {
is_vlc: isVLC ? 'True' : 'False'
});
console.log(response.data);
} catch (error) {
console.error('Fail:', error);
}
};
const testConnection = async () => {
try {
console.log(vlcServerURL)
const response = await axios.get(vlcServerURL + '/');
setLog([...log, response.data]);
if (response.status === 200) {
setServerIsOnline(true);
}
} catch (error) {
console.error('Failure on connection:', error);
}
};
React.useEffect(() => {
testConnection();
}, []);
return (
visual things here ...
);
};
export default TabOneScreen;
我的 app.json android 权限:
"android": {
"adaptiveIcon": {
"foregroundImage": "./assets/images/adaptive-icon.png",
"backgroundColor": "#ffffff"
},
"package": "com.teago.tvpccontrol",
"permissions": ["INTERNET", "ACCESS_NETWORK_STATE"]
},`
我做到了!!!
经过多次尝试,我终于解决了这个问题。根据世博论坛here上的这篇文章,需要将一个插件/属性添加到应用程序中,以便可以完成请求。老实说,我还没有深入研究真正的问题是什么,但对于那些和我有同样问题的人来说,这是解决方案。只需将以下代码片段添加到您的
app.json
:
"plugins": [
[
"expo-build-properties",
{
"android": {
"usesCleartextTraffic": true
}
}
]
]