I'm new to Android development and I'm trying to send message to LINE notification service by using "Authentication method -> POST https://notify-api.line.me/api/notify" (LINE Notify API Document)
Here are my codes, and I always get
Return status code: -1
. Please help me figure out where is the problem ?
LINENotify.java
package com.example.test3;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import javax.net.ssl.HttpsURLConnection;
public class LINENotify {
private static final String strEndpoint = "https://notify-api.line.me/api/notify";
private static final String tokenKEY = "ldO3dTIAjT5OpjWbeZAQtnXhq23poCXcEAvKoTwJHhn";
public int sendMSG( String message ) {
int statusCode;
statusCode = -1;
try {
URL url = new URL( strEndpoint );
HttpsURLConnection connection = (HttpsURLConnection) url.openConnection();
connection.setRequestMethod( "POST" );
connection.addRequestProperty("Authorization", "Bearer " + tokenKEY);
connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setConnectTimeout(15*1000);
connection.setDoOutput( true );
connection.setUseCaches( false );
connection.connect();
connection.setReadTimeout(15*1000);
connection.setDoInput( true );
OutputStream os = connection.getOutputStream();
BufferedWriter writer = new BufferedWriter( new OutputStreamWriter( os, "UTF-8") );
writer.write( "message=" + message );
writer.flush();
writer.close();
os.close();
statusCode = connection.getResponseCode();
if ( statusCode == 200 ) {
//
} else {
throw new Exception( "Error:(StatusCode)" + statusCode + ", " + connection.getResponseMessage() );
}
connection.disconnect();
} catch (Exception e) {
e.printStackTrace();
}
return statusCode;
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<EditText
android:id="@+id/editText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:inputType="textPersonName"
android:text="Name" />
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button" />
</LinearLayout>
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test3">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
</manifest>
MainActivity.java
package com.example.test3;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
EditText msg;
Button send;
LINENotify lineNotify;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msg = (EditText) findViewById(R.id.editText);
send = (Button) findViewById(R.id.button);
lineNotify = new LINENotify();
send.setOnClickListener(this);
}// onCreate
@Override
public void onClick(View v) {
switch( v.getId() ) {
case R.id.button: {
int statusCode = lineNotify.sendMSG( msg.getText().toString() );
Toast.makeText(this, "Return status code: " + statusCode, Toast.LENGTH_LONG).show();
break;
}
}
}
}
I got the answer !! Thanks google and people who post their experience and notes.
My failure is
Android Developers -> Docs -> Connect to the network
To avoid creating an unresponsive UI, don't perform network operations on the UI thread. By default, Android 3.0 (API level 11) and higher requires you to perform network operations on a thread other than the main UI thread;
Therefore, I try use AsyncTask to solve the problem.
MainActivity.java
package com.example.test3;
import androidx.appcompat.app.AppCompatActivity;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
EditText msg;
Button send;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
msg = (EditText) findViewById(R.id.editText);
send = (Button) findViewById(R.id.button);
send.setOnClickListener(this);
}// onCreate
@Override
public void onClick(View v) {
switch( v.getId() ) {
case R.id.button: {
new LINENotify().execute(msg.getText().toString());
break;
}
}
}
public class LINENotify extends AsyncTask<String, Integer, String> {
private static final String strEndpoint = "https://notify-api.line.me/api/notify";
private static final String tokenKEY = "ldO3dTIAjT5OpjWbeZAQtnXhq23poCXcEAvKoTwJHhn";
String result = "";
@Override
protected void onPreExecute() {
super.onPreExecute();
}
@Override
protected String doInBackground(String... strings) {
String message = strings[0];
try {
URL url = new URL( strEndpoint );
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setRequestMethod( "POST" );
connection.addRequestProperty("Authorization", "Bearer " + tokenKEY);
connection.addRequestProperty("Content-Type", "application/x-www-form-urlencoded");
connection.setConnectTimeout(15*1000);
connection.setDoOutput( true );
connection.setUseCaches( false );
connection.setReadTimeout(15*1000);
connection.setDoInput( true );
OutputStream os = connection.getOutputStream();
OutputStreamWriter writer = new OutputStreamWriter(os, "UTF-8");
writer.write( "message=" + message );
writer.flush();
writer.close();
os.close();
connection.connect();
result = connection.getResponseMessage();
connection.disconnect();
} catch (IOException error) {
// Handles input and output errors
}
return result;
}
@Override
protected void onProgressUpdate(Integer... values) {
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
}
}
}
Some reference links:
How to fix 'android.os.NetworkOnMainThreadException'?
AsyncTask Android example
[Android] AsyncTask - 非同步任務
【Android】AsyncTask - Thread 外的另一選擇