Я хочу отправить JSON с Android на сервер с помощью HTTP (POST).
Но остановитесь на следующей строке:
OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream());
Я использую поток для HTTP и добавил следующий манифест:
<uses-permission android:name = "android.permission.INTERNET" />
Но результаты не изменились.
public class MainActivity extends AppCompatActivity {
private Handler handler = new Handler();
private String PostUrl = "http://localhost:3000";
private String JSON = "{\"test\":\"100\"}";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
callPost();
}
public void callPost() {
handler.post(new Runnable() {
@Override
public void run() {
HttpURLConnection con = null;
try{
URL url = new URL(PostUrl);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setRequestProperty("Content-Type","application/JSON; charset=utf-8");
Log.d("debug", "----- All right here -----");
OutputStreamWriter out = new
OutputStreamWriter(con.getOutputStream());
Log.d("debug", "----- This message is not displayed -----");
out.write(JSON);
out.flush();
con.connect();
} catch (Exception e){
}
}
});
}
}
Ошибки нет, а отображается только "----- All right here -----".
Спасибо за ваш быстрый ответ. Я изменил "локальный: 3000" на IP-адрес сервера, но ситуация не изменилась. И когда я попробовал e.printStackTrace(); , отображалось «android.os.NetworkOnMainThreadException».
Обновленный ответ Убедитесь, что вы реализовали приведенные ниже пункты, а затем используйте код в конце, который будет работать для вас.
1. Используйте IP-адрес:
вы не можете использовать локальный хост в эмуляторе, потому что эмулятор ссылается на локальный хост на себя, а не на ваш ноутбук. Вместо этого используйте IP-адрес вашего ноутбука, например http://100.100.10.1:3000. Подробнее здесь.
2. Проблема с открытым текстом:
вам нужно добавить URL-адрес вашего сервера (IP-адрес в вашем случае) в сетевой конфигурации открытого текста. для этого создайте файл res/xml/network_security_config.xml и добавьте свой IP-адрес вместо Ip.Adress.here.
<?xml version = "1.0" encoding = "utf-8"?>
<network-security-config>
<domain-config cleartextTrafficPermitted = "true">
<domain includeSubdomains = "true">Ip.Adress.here</domain>
</domain-config>
</network-security-config>
Затем добавьте этот файл в манифест тега приложения с помощью android:networkSecurityConfig = "@xml/network_security_config"
Ваш тег приложения в манифесте будет выглядеть так
<application
android:allowBackup = "true"
android:icon = "@mipmap/ic_launcher"
android:label = "@string/app_name"
android:networkSecurityConfig = "@xml/network_security_config"
android:roundIcon = "@mipmap/ic_launcher_round"
android:supportsRtl = "true"
android:theme = "@style/AppTheme">
Подробнее здесь.
3. Сеть в основном потоке
Вы получите Network in main thread issue. Поскольку сетевые вызовы должны быть в фоновом режиме, для этого используйте асинхронную задачу. Ниже код работает нормально для меня, просто замените your.ip.address.here на ваш IP-адрес.
public class MainActivity extends AppCompatActivity {
private String PostUrl = "http://your.ip.address.here:3000";
private String JSON = "{\"test\":\"100\"}";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new PostTask().execute();
}
class PostTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... voids) {
HttpURLConnection con = null;
try {
URL url = new URL(PostUrl);
con = (HttpURLConnection) url.openConnection();
con.setRequestMethod("POST");
con.setDoOutput(true);
con.setDoInput(true);
con.setRequestProperty("Content-Type", "application/JSON; charset=utf-8");
Log.d("debug", "----- All right here -----");
OutputStream os = con.getOutputStream();
Log.d("debug", "----- This message is not displayed -----");
os.write(JSON.getBytes("UTF-8"));
os.close();
BufferedReader br = new BufferedReader(new InputStreamReader(con.getInputStream(), "utf-8"));
StringBuilder response = new StringBuilder();
String responseLine = null;
while ((responseLine = br.readLine()) != null) {
response.append(responseLine.trim());
}
return response.toString();
} catch (Exception e) {
return e.getMessage();
}
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
if (s!=null) {
System.out.println(s);
} else {
System.out.println("Result not found");
}
}
}
}
Удачи. Если проблема не устранена, попробуйте опубликовать результат System.out из logcat.
Большое спасибо за ваши ответы. Но результаты не изменились.
Извините, что опоздал с комментарием, и этот код позволил отправить JSON с Android! Спасибо большое.
Переместите строку con.connect() сразу после строки con.setRequestProperty и закройте OutputStreamWriter после вызова метода flush.
Если вы получаете исключение NetworkOnMainThreadException, это связано с тем, что вы не можете выполнять сетевые вызовы в основном потоке, поэтому вам нужно использовать AsyncTask.
Я смог решить проблему с помощью нескольких советов. Спасибо.
localhost:3000
указывает на текущее устройство, если явно не изменено, чтобы указать на удаленный хост. А для просмотра трассировки стека используйтеe.printStackTrace();