javaandroidhttp-posthttpurlconnectionhttpsurlconnection

Failed send message to LINE Notify (using HttpsURLConnection POST)


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;
            }
        }
    }
}

Solution

  • 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 外的另一選擇