Android Studio Java中请求Response抛出MalformedURLException求助
解决OAuth请求中的MalformedURLException异常
核心问题定位
你的代码触发MalformedURLException的直接原因是创建OAuthRequest时传入了错误的URL参数:
final OAuthRequest request = new OAuthRequest(Verb.GET, code);
这里的code是OAuth授权码,并非合法的API请求URL,系统无法将其解析为有效地址,因此抛出格式异常。
分步修正代码
1. 替换为合法的Fitbit API URL
根据你的sleep权限需求,使用Fitbit官方提供的API端点,比如获取睡眠数据的接口:
// 示例:获取用户睡眠记录的API地址,可根据需求调整参数 final String fitbitApiUrl = "https://api.fitbit.com/1/user/-/sleep/list.json?afterDate=2024-01-01&sort=asc&limit=10&offset=0"; final OAuthRequest request = new OAuthRequest(Verb.GET, fitbitApiUrl);
2. 修正Authorization的传递方式
Authorization是HTTP请求头,不是请求参数,你当前用addParameter添加的方式错误,应改为:
// Basic与base64编码内容之间必须加空格 request.addHeader("Authorization", "Basic " + base64code);
另外,base64编码的内容应该是clientId:clientSecret的组合,不是单纯的code,修正编码逻辑:
byte[] data = (clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8); String base64code = Base64.encodeToString(data, Base64.NO_WRAP);
3. 移除冗余参数
你已经通过service.getAccessToken(code)获取了访问令牌,service.signRequest(accessToken, request)会自动处理令牌签名,无需重复传递client_id、client_secret、redirect_uri这些参数,直接删除相关addParameter调用。
4. 删除无关配置
request type参数名错误,且该参数是获取令牌阶段使用的,你已完成令牌获取,直接删除。x-li-format是LinkedIn API的请求头,和Fitbit无关,直接删除该行代码。
5. 修复UI更新线程问题
子线程中不能直接操作TextView,需切换到主线程更新UI:
runOnUiThread(() -> fboutputTV.setText(concatRequest));
修正后的核心代码片段
execService.execute(new Runnable() { @Override public void run() { final OAuth2AccessToken oauth2AccessToken; try { oauth2AccessToken = service.getAccessToken(code); } catch (IOException | InterruptedException | ExecutionException e) { throw new RuntimeException(e); } final FitBitOAuth2AccessToken accessToken = (FitBitOAuth2AccessToken) oauth2AccessToken; // 替换为Fitbit合法API地址 final String fitbitApiUrl = "https://api.fitbit.com/1/user/-/sleep/list.json?afterDate=2024-01-01&sort=asc&limit=10&offset=0"; final OAuthRequest request = new OAuthRequest(Verb.GET, fitbitApiUrl); // 正确生成并添加Authorization头 byte[] data = (clientId + ":" + clientSecret).getBytes(StandardCharsets.UTF_8); String base64code = Base64.encodeToString(data, Base64.NO_WRAP); request.addHeader("Authorization", "Basic " + base64code); // 用访问令牌签名请求 service.signRequest(accessToken, request); final TextView fboutputTV = (TextView) findViewById(R.id.fbOutput); Response response; String concatRequest = ""; try { response = service.execute(request); concatRequest = response.getCode() + " " + response.getBody(); } catch (IOException | InterruptedException | ExecutionException e) { throw new RuntimeException(e); } // 切换到主线程更新UI runOnUiThread(() -> fboutputTV.setText(concatRequest)); } });
额外注意事项
- 确保你的Fitbit应用已申请
sleep权限,且用户授权时同意了该权限。 - 使用
Base64.NO_WRAP避免编码后出现换行符,导致Authorization头失效。
内容的提问来源于stack exchange,提问作者Danielle
相关产品推荐
相关产品推荐

