Mustafiz Rahman
Mustafiz Rahman

Reputation: 11

Data fetching from an API in android

enter image description here

I have tried to fetch data from an API which has a key. But in the output it says "app key not found".

I have tested it on Postman and it works properly.

Here is my code:

public class fetchData extends AsyncTask<Void,Void,Void> {
    String data="";
    @Override
    protected Void doInBackground(Void... voids) {

        try {
            URL url=new URL("https://app.inyek.com/app_api/api_extra/all_order.php?");

            HttpURLConnection con=(HttpURLConnection) url.openConnection();
            con.setRequestMethod("POST");
            con.setRequestProperty("Content-Type", "application/x-www-form-urlencoded/json;charset=UTF-8");
            con.setRequestProperty("app_key","whatever");
            con.setDoOutput(true);


}

Upvotes: 1

Views: 11933

Answers (5)

user21867871
user21867871

Reputation: 1

    package com.example.heptotech;

import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.view.MenuItem;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.lifecycle.ViewModelProvider;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;

import com.example.heptotech.adapter.DetailsViewAdapter;
import com.example.heptotech.bean.CRUDData;
import com.example.heptotech.model.FetchCRUDData;
import com.google.android.material.bottomnavigation.BottomNavigationView;
import com.google.firebase.database.DatabaseReference;
import com.google.firebase.database.FirebaseDatabase;

import java.util.ArrayList;

public class ThirdNavigationActivity extends AppCompatActivity {
    BottomNavigationView bottomNavigationView;
    CRUDData crudData = new CRUDData();
    DatabaseReference crudDatabaseReference;
    long crudMaxId = 0;
    RecyclerView recycler_view;
    ArrayList<CRUDData> crudDataArrayList = new ArrayList<>();
    DetailsViewAdapter detailsViewAdapter;
    FetchCRUDData fetchCRUDData;
    String userId;
    @Override
    protected void onPostResume() {


        fetchCRUDData = new ViewModelProvider(this).get(FetchCRUDData.class);

        fetchCRUDData.crudTableUpdated.observe(this, books -> {
            detailsViewAdapter.notifyDataSetChanged();
        });
        init_Me_Library_Recyclerview();
        super.onPostResume();
    }
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_third_navigation);
        this.setTitle("Dashboard");
        SharedPreferences sharedPreferences = getSharedPreferences("LOGIN", MODE_PRIVATE);
        userId = sharedPreferences.getString("customerId", "");


        crudDatabaseReference = FirebaseDatabase.getInstance().getReference("CrudTable");
        recycler_view = findViewById(R.id.recycler_view);
        recycler_view.setHasFixedSize(true);
        recycler_view.setLayoutManager(new LinearLayoutManager(ThirdNavigationActivity.this));

        fetchCRUDData = new ViewModelProvider(this).get(FetchCRUDData.class);
        fetchCRUDData.crudTableUpdated.observe(this, books -> {
            detailsViewAdapter.notifyDataSetChanged();
        });

        init_Me_Library_Recyclerview();


        bottomNavigationView = findViewById(R.id.drawerLayout);
        bottomNavigationView.setSelectedItemId(R.id.NavThree);
        bottomNavigationView.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
            @Override
            public boolean onNavigationItemSelected(@NonNull MenuItem item) {
                switch (item.getItemId()) {
                    case R.id.NavOne: {

                        Intent intent = new Intent(getApplicationContext(), FirstNavigationActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                        startActivity(intent);
                        return true;
                    }
                    case R.id.NavTwo: {

                        Intent intent = new Intent(getApplicationContext(), SecondNavigationActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                        startActivity(intent);
                        return true;
                    }
                    case R.id.NavThree: {

                        Intent intent = new Intent(getApplicationContext(), ThirdNavigationActivity.class);
                        intent.setFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION);
                        startActivity(intent);
                        return true;
                    }

                }
                return false;
            }
        });

    }

    public void init_Me_Library_Recyclerview() {

        detailsViewAdapter = new DetailsViewAdapter(this, fetchCRUDData.getUpdatedList("1").getValue(), "2");
        recycler_view.setLayoutManager(new LinearLayoutManager(this));
        recycler_view.setAdapter(detailsViewAdapter);
        detailsViewAdapter.notifyDataSetChanged();

    }
}

Upvotes: 0

Mustafiz Rahman
Mustafiz Rahman

Reputation: 11

Thank you guys! finally i got the answer using OkHttpClient. here is the code:

 OkHttpClient client = new OkHttpClient();

            MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
            RequestBody body = RequestBody.create(mediaType, "app_key=whatever");
            Request request = new Request.Builder()
                    .url("https://app.inyek.com/app_api/api_extra/all_order.php")
                    .post(body)
                    .addHeader("Content-Type", "application/x-www-form-urlencoded")
                    .addHeader("key", "whatever")
                    .addHeader("cache-control", "no-cache")
                    .addHeader("Postman-Token", "whatever")
                    .build();

            Response response = client.newCall(request).execute();

Upvotes: 0

Barn on a Hill
Barn on a Hill

Reputation: 387

I strongly suggest you make an Abstract HttpRequestTask which extends AsyncTask. In this abstract ancestor you can make some helper methods for reading your input, something like so:

/**
 * HttpRequestTask is an abstract extension of an AsyncTask for HTTP Requests.
 *
 * @param <P>
 *      Type for parameter(s) to doInBackground (can be Void if none provided)
 * @param <R>
 *      Type for result of request (can be Void if ignored, or using listeners.)
 */
public abstract class HttpRequestTask<P, R> extends AsyncTask<P, Integer, R>
{
    private static final String TAG = "HttpRequestTask";

    // Post form encoded requests, get back JSON response
    private static final RequestMethod DEFAULT_REQUEST_METHOD = RequestMethod.POST;
    private static final String DEFAULT_CONTENT_TYPE = "application/x-www-form-urlencoded;charset=UTF-8;";
    private static final String DEFAULT_ACCEPT = "application/json;";
    private static final int DEFAULT_TIMEOUT = 8000; // 8 seconds
    private static final String CHARSET = "UTF-8";

    protected static final String NULL_CONTEXT = "Context is null.";
    protected static final String INVALID_RESPONSE = "The server did not send back a valid response.";

    // Request methods supported by back-end
    protected enum RequestMethod
    {
        GET("GET"),
        POST("POST");

        private final String method;

        RequestMethod(String method)
        {
            this.method = method;
        }

        @Override
        public String toString()
        {
            return this.method;
        }
    }

    /**
     * ALWAYS use application context here to prevent memory leaks.
     *
     */
    protected HttpRequestTask(@NonNull final Context context)
    {
        this.context = context;
    }

    protected void verifyConnection() throws IOException
    {
        if (!SystemUtil.isInternetAvailable(context))
        {
            throw new IOException("Internet is unavailable.");
        }
    }

    /**
     * Creates and opens a URLConnection for the url parameter, as well as setting request options.
     *
     * @param url
     *      to connect to.
     *
     * @return opened HTTPURLConnection for POSTing data to ctservices.
     */
    protected HttpURLConnection getURLConnection(URL url) throws IOException
    {
        return this.getURLConnection(url, DEFAULT_REQUEST_METHOD, DEFAULT_CONTENT_TYPE,
                DEFAULT_ACCEPT, DEFAULT_TIMEOUT);
    }

    /**
     * Creates and opens a URLConnection for the url parameter, as well as setting request options.
     *
     * @param url
     *      to connect to.
     *
     * @return opened HTTPURLConnection
     */
    protected HttpURLConnection getURLConnection(@NonNull final URL url,
                                                                                             @NonNull final RequestMethod requestMethod,
                                                                                             @NonNull final String contentType,
                                                                                             @Nullable final String accept, final int timeout)
            throws IOException
    {
        verifyConnection();

        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        urlConnection.setRequestMethod(requestMethod.toString());
        urlConnection.setRequestProperty("Content-Type", contentType);

        if (accept != null && !accept.isEmpty())
        {
            urlConnection.setRequestProperty("Accept", accept);
        }

        urlConnection.setReadTimeout(timeout);
        urlConnection.setConnectTimeout(timeout);
        urlConnection.setUseCaches(false);
        urlConnection.setDoInput(true);
        urlConnection.setDoOutput(true);
        return urlConnection;
    }

    /**
     * Creates and opens a URLConnection for the url parameter, but does not set any request options.
     *
     * @param url
     *      to connect to.
     *
     * @return opened HTTPURLConnection without parameters set.
     */
    protected HttpURLConnection getBasicURLConnection(URL url) throws IOException
    {
        if (!SystemUtil.isInternetAvailable(applicationContext.get()))
        {
            throw new IOException("Internet is unavailable.");
        }

        HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
        return urlConnection;
    }

    /**
     * Write a JSONObject of request parameters to the output stream as form-encoded data.
     *
     * @param urlConnection
     *      opened urlConnection with output enabled (done by getURLConnection).
     * @param params
     *      to write to request.
     *
     * @throws IOException
     *      problem writing to output stream
     */
    protected void writeParams(HttpURLConnection urlConnection, JSONObject params) throws IOException
    {
        OutputStream outputStream = urlConnection.getOutputStream();
        BufferedWriter outWriter = new BufferedWriter(new OutputStreamWriter(outputStream,
                StandardCharsets.UTF_8));

        String urlParams = this.encodeJSONObject(params);

        outWriter.write(urlParams);
        outWriter.flush();
        outWriter.close();
        outputStream.close();
    }

    /**
     * Reads the response of a URLConnection from the input stream and puts it in a string.
     *
     * @param urlConnection
     *      opened urlConnection with input enabled (done by getURLConnection).
     *
     * @return response string
     *
     * @throws IOException
     *      problem reading input stream
     */
    protected String readResponse(HttpURLConnection urlConnection) throws IOException
    {
        InputStream inputStream = null;

        try
        {
            /* If we failed to connect will throw a SocketResponseTimeoutException,
             * which is an IOException. */
            int responseCode = urlConnection.getResponseCode();

            if (HttpURLConnection.HTTP_OK != responseCode)
            {
                throw new IOException("Bad response code - " + responseCode);
            }

            inputStream = urlConnection.getInputStream();
            final String response = parseInputStream(inputStream);
            urlConnection.disconnect();
            return response;
        }
        finally
        {
            if (inputStream != null)
            {
                try
                {
                    inputStream.close();
                }
                catch (Exception e) {}
            }
        }
    }

    protected Context getContext()
    {
        return this.context;
    }

    protected String getString(final int resId)
    {
        return getContext().getString(resId);
    }

    /**
     * Encodes a JSONObject as a form-data URL string.
     *
     * @param jo
     *      to encode
     *
     * @return encoded URL string
     */
    private String encodeJSONObject(JSONObject jo)
    {
        StringBuilder sb = new StringBuilder();
        boolean first = true;
        Iterator<String> itr = jo.keys();
        String key;
        Object val;

        try
        {
            while (itr.hasNext())
            {
                key = itr.next();
                val = jo.get(key);

                if (first)
                {
                    first = false;
                }
                else
                {
                    sb.append('&');
                }

                sb.append(URLEncoder.encode(key, CHARSET));
                sb.append('=');
                sb.append(URLEncoder.encode(val.toString(), CHARSET));
            }
        }
        catch (JSONException | UnsupportedEncodingException e) {}

        return sb.toString();
    }

    private String parseInputStream(InputStream is) throws IOException
    {
        BufferedReader br = null;

        try
        {
            br = new BufferedReader(new InputStreamReader(is));
            StringBuilder sb = new StringBuilder();
            String line;

            while ((line = br.readLine()) != null)
            {
                sb.append(line);
            }

            return sb.toString();
        }
        finally
        {
            if (br != null)
            {
                try
                {
                    br.close();
                }
                catch (Exception e) {}
            }
        }
    }

    /**
     * Merges any properties of b into a that don't already have a key match in a.
     *
     * @param a
     *      merging to
     * @param b
     *      merging from
     *
     * @return a with any unique values from b
     */
    protected JSONObject mergeJSONObjects(JSONObject a, JSONObject b)
    {
        if (b == null)
        {
            return a;
        }
        if (a == null)
        {
            return b;
        }

        try
        {
            Iterator<String> bItr = b.keys();
            String key;
            while (bItr.hasNext())
            {
                key = bItr.next();
                if (!a.has(key))
                {
                    a.put(key, b.get(key));
                }
            }

            return a;
        }
        catch (Exception ex)
        {
            Log.e(TAG, ex.getClass().getSimpleName() + " in mergeJSONObjects: " + ex.getMessage() +
                    '\n' + Log.getStackTraceString(ex));
            return a;
        }
    }
}

Then you can extend your HttpRequestTask to easily make network requests:

public class ExampleNetworkTask extends HttpRequestTask<Void, Void>
{
    private static final String TAG = "ExampleNetworkTask";

    private final SimpleListener successListener;
    private final StringListener errorListener;
    private final String servicesUrl;

    public static void start(@NonNull final Context context,
                             @Nullable final SimpleListener successListener,
                             @Nullable final StringListener errorListener)
        throws IllegalArgumentException
    {
        if (context == null)
        {
            throw new IllegalArgumentException(NULL_CONTEXT);
        }

        new ExampleNetworkTask(context, successListener, errorListener).execute();
    }

    private ExampleNetworkTask(@NonNull final Context context,
                               @Nullable final SimpleListener successListener,
                               @Nullable final StringListener errorListener)
    {
        super(context);

        this.servicesUrl = SystemUtil.getServiceUrl(getContext(), R.string.example_service);
        this.successListener = successListener;
        this.errorListener = errorListener;
    }

    @Override
    protected Void doInBackground(Void... voids)
    {
        try
        {
            final HttpURLConnection urlConnection = super.getURLConnection(new URL(servicesUrl));

            final JSONObject params = new JSONObject();

            // Add params
            params.put("app_key", appKey);
            params.put("order_number", orderNumber);
            // ...

            // Send request, read parse response
            super.writeParams(urlConnection, params);
            final String response = super.readResponse(urlConnection);
            final JSONObject responseObj = new JSONObject(response);

            // Handle response
        }
        catch (Exception ex)
        {
            final String msg = ex.getLocalizedMessage();
            Log.e(TAG, ex.getClass().getSimpleName() + ": " + msg  + '\n' +
                    Log.getStackTraceString(ex));

            // Handle network exceptions and other exceptions here.
        }
        return null;
    }
}

Upvotes: 1

Cheri
Cheri

Reputation: 263

Welcome to Stack Exchange! Firstly I'd suggest you don't put your API Key within questions and/or images, as they might be sensitive and can be abused by malicious users. Feel free to edit your question and remove them.

To answer your query, I think you need to write the contents to the http request body in a json format. This can be done as per the guide on the following webpage: https://www.baeldung.com/httpurlconnection-post

In summary, you need to create an output stream and write the contents to it directly.

Upvotes: 1

ybouane
ybouane

Reputation: 36

In PostMan, how did you specify the app key? was it through an HTTP header? (Sorry, I would have added a comment, but I do not have enough reputation)

Or was it specified as a GET parameter? In the latter case, try something like:

URL url=new URL("https://app.inyek.com/app_api/api_extra/all_order.php?app_key=YOUR_KEY");

Upvotes: 0

Related Questions