使用Android Volley调用cross-copy.net API遇PUT请求失败求助
Let's troubleshoot your PUT request failure step by step. Based on the API docs and your code, here are the most likely issues and fixes:
1. Your PUT request is missing the required request body
According to the cross-copy.net API docs, the PUT /api/<secret code> endpoint expects you to send data in the request body. Your current StringRequest doesn't include any body content, which is almost certainly causing the server to reject the request.
To fix this, override the getBody() method in your StringRequest to provide the data you want to send, and set the correct content-type header:
StringRequest stringRequest = new StringRequest(Request.Method.PUT, url, response -> message.setText("Response is: "+ response.substring(0,500)), error -> message.setText("That didn't work!")) { @Override public byte[] getBody() throws AuthFailureError { // Replace with your actual message content String postData = "Hello from my Android app!"; try { return postData.getBytes("utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "text/plain"); // Match your data's content type return headers; } };
2. Missing INTERNET permission
Your app can't make any network requests at all if you haven't declared the internet permission in your AndroidManifest.xml. Add this line outside the <application> tag:
<uses-permission android:name="android.permission.INTERNET" />
3. Cleartext HTTP restriction on Android 9+
If your app targets Android API level 28 or higher, Android blocks plain HTTP requests by default (the cross-copy API uses http:// instead of https://). To allow this, create a network security configuration:
- Make a new file
res/xml/network_security_config.xmlwith this content:
<?xml version="1.0" encoding="utf-8"?> <network-security-config> <domain-config cleartextTrafficPermitted="true"> <domain includeSubdomains="true">cross-copy.net</domain> </domain-config> </network-security-config>
- Reference this config in your
AndroidManifest.xml's<application>tag:
<application ... android:networkSecurityConfig="@xml/network_security_config"> ... </application>
4. Optional: Add device_id parameter (recommended)
While not the direct cause of your failure, adding the device_id parameter as per the API docs will prevent your device from receiving its own sent data. Generate a unique UUID for your device and append it to the URL:
String deviceId = UUID.randomUUID().toString(); String url = "http://www.cross-copy.net/api/nl?device_id=" + deviceId;
Full modified code example
Here's your MainActivity with all fixes applied, plus improved error handling to help debug future issues:
public class MainActivity extends AppCompatActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); final EditText message = findViewById(R.id.editText); // Generate a unique device ID String deviceId = UUID.randomUUID().toString(); String url = "http://www.cross-copy.net/api/nl?device_id=" + deviceId; RequestQueue queue = Volley.newRequestQueue(this); StringRequest stringRequest = new StringRequest(Request.Method.PUT, url, response -> message.setText("Response is: " + response.substring(0, 500)), error -> { // Show detailed error info for debugging String errorMsg = "Error: "; if (error.networkResponse != null) { errorMsg += "Status code: " + error.networkResponse.statusCode; } else { errorMsg += error.getMessage() != null ? error.getMessage() : "Unknown error"; } message.setText(errorMsg); }) { @Override public byte[] getBody() throws AuthFailureError { // Your custom message content here String dataToSend = "Test message from Android app"; try { return dataToSend.getBytes("utf-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } @Override public Map<String, String> getHeaders() throws AuthFailureError { Map<String, String> headers = new HashMap<>(); headers.put("Content-Type", "text/plain"); return headers; } }; queue.add(stringRequest); } }
内容的提问来源于stack exchange,提问作者paniko

