0

I have a problem to show my array list items on screen. googled every possible error but nothing helped. because those answers was for lower API 23. this is my whole code,so pleasse help me,what should i do?

MainActivity 

package com.example.earthquake6;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
//import android.support.v7.app.AppCompatActivity;

import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ListView;
import java.util.ArrayList;
import java.util.List;

//import android.app.LoaderManager;//OK
//import androidx.loader.app.LoaderManager;

import android.content.Loader;//Ok
//import androidx.loader.content.Loader;
import android.app.LoaderManager.LoaderCallbacks;//OK
//import androidx.loader.app.LoaderManager.LoaderCallbacks;

public class MainActivity extends AppCompatActivity implements LoaderCallbacks<List<CustomWord>> {
    // @@@@@@@@@@ States
    //region
    private static final String LOG_TAG = MainActivity.class.getName();
    /**
     * URL for earthquake data from the USGS dataset
     */
    private static final String USGS_REQUEST_URL =
            "http://earthquake.usgs.gov/fdsnws/event/1/query?format=geojson&orderby=time&minmag=6&limit=10";

    /**
     * Constant value for the earthquake loader ID. We can choose any integer.
     * This really only comes into play if you're using multiple loaders.
     */
    private static final int EARTHQUAKE_LOADER_ID = 1;

    /**
     * Adapter for the list of earthquakes
     */
    private CustomArrayAdapter mCustomArrayAdapter;
    //endregion

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.i("*********************", "*********************");
        Log.i(LOG_TAG, "Test: EarthQuacke Activity  onCreate  called");
        setContentView(R.layout.share_activity);

        // Create a new adapter that takes an empty list of earthquakes as input
        mCustomArrayAdapter = new CustomArrayAdapter(MainActivity.this, new ArrayList<CustomWord>());
        // Create list view to set our customArrayAdapter  on it
        ListView listView = (ListView) findViewById(R.id.share_view_id);
        listView.setAdapter(mCustomArrayAdapter);

        // to set OnclickListener on each roe of listviews
        listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                // get rows of each elements in listview
                // each row is a "CustomWord.class", so when get elemnts from
                // a listview by below
                CustomWord customWord1 = mCustomArrayAdapter.getItem(position);
                // now get url elemnt
                // uri use to convert ulr string to a legal encoding format and acceptable to ulr object
                // To make these characters legal they need to be encoded before passing them to the URL constructor.
                Uri uri = Uri.parse(customWord1.getmUrl());
                // define an intent to open related website
                // for send an intent to another app use Intent.ACTION_VIEW
                // for more inf
                // https://developer.android.com/training/basics/intents/sending
                Intent urlIntent = new Intent(Intent.ACTION_VIEW, uri);
                startActivity(urlIntent);
            }
        });

        // Get a reference to the LoaderManager, in order to interact with loaders.
//        LoaderManager loaderManager = getLoaderManager();
        android.app.LoaderManager loaderManager1 = getLoaderManager();
        // Initialize the loader. Pass in the int ID constant defined above and pass in null for
        // the bundle. Pass in this activity for the LoaderCallbacks parameter (which is valid
        // because this activity implements the LoaderCallbacks interface).


        //The third argument(here: this) is what object should receive the LoaderCallbacks (and therefore,
        // the data when the load is complete!) - which will be this activity. This code goes
        // inside the onCreate() method of the EarthquakeActivity, so that the loader
        // can be initialized as soon as the app opens.
        loaderManager1.initLoader(EARTHQUAKE_LOADER_ID, null, this);
        Log.i(LOG_TAG, "Test: EarthQuacke Activity  LoaderManager.initLoader  called");
    }
    @Override
    public  Loader<List<CustomWord>> onCreateLoader(int id, Bundle args) {
        // Create a new loader for the given URL
        Log.i(LOG_TAG,"Test: EarthQuacke Activity  onCreateLoader  called");
        return new EarthQuakeLoader(this,USGS_REQUEST_URL);
    }

    @Override
    public void onLoadFinished(Loader<List<CustomWord>> loader, List<CustomWord> customWordList) {
        // Clear the adapter of previous earthquake data
        Log.i(LOG_TAG,"Test: EarthQuacke Activity  onLoadFinished  called");
        mCustomArrayAdapter.clear();

        // If there is a valid list of {@link Earthquake}s, then add them to the adapter's
        // data set. This will trigger the ListView to update.
        if (customWordList != null && !customWordList.isEmpty()) {
            mCustomArrayAdapter.addAll(customWordList);
        }
    }

    @Override
    public void onLoaderReset(Loader<List<CustomWord>> loader) {
        Log.i(LOG_TAG,"Test: EarthQuacke Activity  onLoaderReset  called");
        // Loader reset, so we can clear out our existing data.
        mCustomArrayAdapter.clear();

    }
}

Then

 In my Loader : EarthQuakeLoader

package com.example.earthquake6;

//import androidx.loader.content.AsyncTaskLoader; -----
//import android.content.AsyncTaskLoader;++++

import android.content.AsyncTaskLoader;//Ok
//import androidx.loader.content.AsyncTaskLoader;//xxxxxxxxxxxxxxxxxx


import android.content.Context;
import androidx.core.content.ContextCompat;
import android.util.Log;

// we should use  import android.content.AsyncTaskLoader;  or import androidx.loader.content.AsyncTaskLoader;
// rather than import androidx.loader.content.AsyncTaskLoader;
// because if we do not use import android.content.AsyncTaskLoader;, we got error  on  MainActivity class
// at the code related to:
//@Override
//public Loader<List<CustomWord>> onCreateLoader(int id, Bundle args) {
//        // Create a new loader for the given URL
//        return new EarthQuakeLoader(this,USGS_REQUEST_URL);
//        }
// this library is This class was deprecated in API level 28. by android developer ref:
// https://developer.android.com/reference/android/content/AsyncTaskLoader
//we could Use the : Support Library AsyncTaskLoader



    import java.util.List;


   

    public class EarthQuakeLoader extends AsyncTaskLoader<List<CustomWord>> {
        // @@@@@@@@@@ States
        //region
        /** Tag for log messages */
        private static final String LOG_TAG = EarthQuakeLoader.class.getName();
    
        /** Query URL */
        private String mUrl;
        //endregion
    
        /**
         * Constructs a new {@link EarthQuakeLoader}.
         *
         * @param context of the activity
         * @param url to load data from
         */
        public EarthQuakeLoader(Context context, String url) {
            super(context);
            mUrl = url;
        }
    
        @Override
        protected void onStartLoading() {
            Log.i(LOG_TAG,"Test: EarthQuakeLoader Class  onStartLoading  called");
            forceLoad();
        }
    
        @Override
        public List<CustomWord> loadInBackground() {
            if(mUrl!=null){
                return null;
            }
            // Perform the network request, parse the response, and extract a list of earthquakes.
            List<CustomWord> customWordList = FetchDataFromInternet.customArrayListFetchDataFromInternet(mUrl);
            Log.i(LOG_TAG,"Test: EarthQuakeLoader Class  loadInBackground  called");
            return customWordList;
        }
    
        @Override
        public void deliverResult(List<CustomWord> data) {
            Log.i(LOG_TAG,"Test: EarthQuakeLoader Class  deliverResult  called");
            super.deliverResult(data);
        }
    }

and in another classes:

CustomWord :

package com.example.earthquake6;

public class CustomWord {
    // States
    private double mMagnitude;
    private String mPlace;
    private long mTime;
    private String mUrl;
    // Constructor
    public CustomWord(double magnitude,String place,long time,String url){
        this.mMagnitude = magnitude;
        this.mPlace = place;
        this.mTime = time;
        this.mUrl = url;
    }

    public double getmMagnitude() {
        return mMagnitude;
    }

    public String getmPlace() {
        return mPlace;
    }

    public long getmTime() {
        return mTime;
    }

    public String getmUrl() {
        return mUrl;
    }
}

and another class:

FetchDataFromInternet  :



package com.example.earthquake6;


import android.text.TextUtils;
import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.Charset;
import java.util.ArrayList;

/**
 * Helper methods related to requesting and receiving earthquake data from USGS.
 */
public final class FetchDataFromInternet  {
    // AsyncTask<Params,Progress,Result >      :
    // if one elemnt do not use, then we use "Void" replace with it
    // in this app we use:  AsyncTask<URL, Void, String>,becuase we dont use progress
    //
    // any element in this < , , >, is an object, even its be a primitive data type like int,long,
    // or else. so long changed to Long, either void change to Void with capital v
    // as there are multiple variable for Params(so saved in array), There are multiple variable
    // for Progress(so saved in array),ans either for Result(so saved in array)
    // Params    :
    // its method to use is :   doInBackground
    // data type in parameters sent to background task, here data type is URL,that means that background
    // in doInBackground(URL... urls)    task will accept the list of URLs
    // Progress :
    // its method to use is :   onProgressUpdate
    // data type used for, measuring progress of the work  being down on the
    // background thread,to do this, we specify Progress as "Integer" data type,as
    // progress parameter,so we can call "publish prgress with integer value in the background,
    // then in method,"onProgressUpdate(Integer progress)", which is called by main thread, we
    // receive that integer progress and update UI
    // Result  :
    // its method to use is :   onPostExecute
    // is data type of return value from "doInBackground" method
    // this is data type of result of background work
    // in this app, return data type from "doInBackground" method is string,so we have String data type in
    //  AsyncTask<URL, Void, String>
    // @@@@@@@@@@         States
    //region
    // use to set up log messages
    public static final String LOG_TAG = FetchDataFromInternet.class.getSimpleName();
    //endregion
    // Constructor
    //region
    /**
     * Create a private constructor because no one should ever create a {@link FetchDataFromInternet} object.
     * This class is only meant to hold static variables and methods, which can be accessed
     * directly from the class name QueryUtils (and an object instance of QueryUtils is not needed).
     */
    private FetchDataFromInternet() {
    }
    //endregion

    public static ArrayList<CustomWord> customArrayListFetchDataFromInternet(String stringURL) {
        //   Step 1: Create Url object from nput string url
        Log.i(LOG_TAG,"Test: FetchDataFromInternet Class  customArrayListFetchDataFromInternet  called");

        // Don't perform the request if there are no URLs, or the first URL is null.
        if (stringURL == null) {
            return null;
        }
        URL urlObject = creatURL(stringURL);
        /*        // Perform HTTP request to the URL and receive a JSON response back
        //  2-   Obtain a URLConnection object from the URL
        //  3-   Configure the URLConnection
        //  4-   Read the header fields  ::::  Not used Here
        //  5-   Get an input stream and read data
        // steps above are in below method*/
        String jasonStringUrlSourceResponse = "";//set to null
        try{
            // if jasonStringUrlSourceResponse url is null then jasonStringUrlSourceResponse is null
            jasonStringUrlSourceResponse = httpConectionReadStreamedData(urlObject);// if  httpConectionReadStreamedData method,
            // has no throw exception,this try/catch got error
        }catch (IOException ioException){
            // handler
            Log.e(LOG_TAG, "Problem making the HTTP request.", ioException);
        }
        // Extract relevant fields from the JSON response and create an {@link Event} object
        ArrayList arrayListQueryFromJAson = QueryFromJAson(jasonStringUrlSourceResponse);

        return arrayListQueryFromJAson;
    }

    ///////////////////////  1-   Create URL object from given String
    private  static URL creatURL(String urlString) {
        URL myURL = null;
        try {
            // prepare url for creating a URL object,because url maybe has special characters example:
            //  http://example.com/hello world/     -------URI----->  http://example.com/hello%20world
            // the space between hello and world occupy by %20 automatically by uri
            // this do by
            URI uri = new URI(urlString);
            // Convert uri to url
            myURL = uri.toURL();
        } catch (MalformedURLException | URISyntaxException exception) {  //MalformedURLException is for URL URISyntaxException exception is for URI
            Log.v("LOG_TAG","Error with creating URL",exception);
            exception.printStackTrace();
            return null;
        }
        return myURL;// URL myURL = null; must be declared for return
    }// End creatURL
    private  static String httpConectionReadStreamedData(URL myURL) throws IOException{// need throws ioexception
        String jsonResponse = "";
        // to make sure that url is not null
        if(myURL==null){
            return jsonResponse;// by return jsonResponse we get out the method httpConectionReadStreamedData
        }
        HttpURLConnection urlConnection = null;
        InputStream inputStream = null;
        try {
            //  2-   Obtain a URLConnection object from the URL
            //       A URLConnection instance is obtained by invoking the openConnection() method on the URL object:
            //       URLConnection urlCon = url.openConnection();
            //       If the protocol is http://, you can cast the returned object to an HttpURLConnection object:
            HttpURLConnection httpURLConnection = (HttpURLConnection) myURL.openConnection();
            //  3-   Configure the URLConnection
            httpURLConnection.setRequestMethod("GET");
            // Timeout for reading InputStream arbitrarily set to 10000 mili second
            httpURLConnection.setReadTimeout(10000 /* milliseconds */);
            // Timeout for connection.connect() arbitrarily set to 15000 ms
            httpURLConnection.setConnectTimeout(15000 /* milliseconds */);
            // Open communications link (network traffic occurs here).
            httpURLConnection.connect();
            //   After the connection has been established, then its need to check the response code by
            // calling below code
            // if the request " httpURLConnection.connect();" is successful (response code is 200)
            // so we could do 4 & 5 steps(read the input stream and then parse the response
            if(httpURLConnection.getResponseCode()==200){
                //  4-   Read the header fields  ::::  Not used Here
                //  5-   Get an input stream and read data
                inputStream = httpURLConnection.getInputStream();
                // The InputStream’s read() is a low-level method that reads data to an array of bytes.
                // So it is more convenient to wrap the InputStream in an InputStreamReader for reading data to characters;
                // Here we use  readFromStream method to read data
                //An InputStream is a readable source of bytes. Once you get an InputStream, it's common
                // to decode or convert it into a target data type. For example, if you were downloading
                // image data, you might decode and display it
                jsonResponse = readFromInputStream(inputStream);// maybe "inputStream", be null becuase "httpURLConnection" method maybe
                // return null string, so need to check handling null string url in the method
            }else{
                Log.e(LOG_TAG,"Error response code: "+urlConnection.getResponseCode());
            }
        } catch (IOException e) {
            Log.e(LOG_TAG,"Problem to making HttpURLConnection httpURLConnection = " +
                    "(HttpURLConnection) myURL.openConnection();",e);
//                e.printStackTrace();
        }finally {
            if (inputStream != null) {//// Close Stream and disconnect HTTPS connection.
                // function must handle java.io.IOException here
                inputStream.close();
            }
            if (urlConnection != null) {
                urlConnection.disconnect();
            }
        }
        return jsonResponse;
    }// End httpConectionReadStreamedData  method
    //  After read data from url(streamming data), its need to form data to readable String data
    // The InputStream’s read() is a low-level method that reads stream data to an array of bytes.
    //An InputStream is a readable source of bytes. Once you get an InputStream, it's common
    // to decode or convert it into a target data type. For example, if you were downloading
    // image data, you might decode and display it
    private static String readFromInputStream(InputStream inputStream) throws IOException {// this exception is due to   bufferedReader.readLine();
        StringBuilder stringBuilder = new StringBuilder();// to concatinate streams of char data
        if(inputStream!=null){
            // for read streams of byte char data from inputstream url
            InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
            // To increase performance. Data to be read will be buffered in to memory for quick access
            // for more info :   http://www.javalearningacademy.com/streams-in-java-concepts-and-usage/
            BufferedReader bufferedReader = new BufferedReader(inputStreamReader);

            String line = bufferedReader.readLine();// read data from buffer
            while(line!=null){  // while there is data, line of data appent to each other
                stringBuilder.append(line);
                line = bufferedReader.readLine();
            }
        }
        return  stringBuilder.toString();
    }
    /**
     * Return an {@link CustomWord} object by parsing out information
     * about the first earthquake from the input earthquakeJSON string.
     */
    private static ArrayList QueryFromJAson(String jasonInputString){
//            final ArrayList<CustomWord> customArrayList = nnull;
        // if we define line below as above   we get error
        final ArrayList<CustomWord> customArrayList = new ArrayList<>();
        // If the JSON string is empty or null, then return early.
        if (TextUtils.isEmpty(jasonInputString)) {
            return null;
        }
        // use try/catch to pass out from class if there is a error
        try {
            JSONObject root = new JSONObject(jasonInputString);
            // Get "features" path to get next path and route to place,time,magnitude,...,etc
            JSONArray root_features = root.getJSONArray("features");
            // Create Custom list array to add "mag,place,time,url

            for (int root_features_Elements_counter=0;root_features_Elements_counter<root_features.length();
                 root_features_Elements_counter++){
                JSONObject root_features_Elements = root_features.getJSONObject(root_features_Elements_counter);
                JSONObject root_features_Elements_properties = root_features_Elements.getJSONObject("properties");
                double magnitude = root_features_Elements_properties.getDouble("mag");
                String place = root_features_Elements_properties.getString("place");
                long time = root_features_Elements_properties.getLong("time");
                String url = root_features_Elements_properties.getString("url");
                // Add "mag,place,time,url to CustomArrayList
                customArrayList.add(new CustomWord(magnitude,place,time,url));
            }//End for

        } catch (JSONException e) {
            e.printStackTrace();
            Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
        }
        return customArrayList;
    }

}// End Class  FetchDataFromInteret

and another:

QueryFromJAson :



package com.example.earthquake6;

import android.util.Log;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;

import static com.example.earthquake6.FetchDataFromInternet.LOG_TAG;

//import static com.example.earthquakerev4_staticclass.MainActivity.LOG_TAG;


public class QueryFromJAson {
    // States
private ArrayList<CustomWord> customArrayList = new ArrayList<>();
    // Constructor
    public QueryFromJAson(String jasonInputString){
 /*       // If the JSON string is empty or null, then return early.
        if (TextUtils.isEmpty(jasonInputString)) {
            return null;
        }*/
        // use try/catch to pass out from class if there is a error
        try {
            JSONObject root = new JSONObject(jasonInputString);
            // Get "features" path to get next path and route to place,time,magnitude,...,etc
            JSONArray root_features = root.getJSONArray("features");
            // Create Custom list array to add "mag,place,time,url

            for (int root_features_Elements_counter=0;root_features_Elements_counter<root_features.length();
                 root_features_Elements_counter++){
                JSONObject root_features_Elements = root_features.getJSONObject(root_features_Elements_counter);
                JSONObject root_features_Elements_properties = root_features_Elements.getJSONObject("properties");
                double magnitude = root_features_Elements_properties.getDouble("mag");
                String place = root_features_Elements_properties.getString("place");
                long time = root_features_Elements_properties.getLong("time");
                String url = root_features_Elements_properties.getString("url");
                // Add "mag,place,time,url to CustomArrayList
                customArrayList.add(new CustomWord(magnitude,place,time,url));
            }//End for

        } catch (JSONException e) {
            e.printStackTrace();
            Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
        }

    }// End Constructor

    public ArrayList<CustomWord> getCustomArrayList() {
        return customArrayList;
    }
} // End Class

i prefer to code with lbrary androidx rather than support library like, import android.support.v4. after run this app, screen nothing shows.

M.J Jalali
  • 102
  • 8

2 Answers2

0

Change my stuff with yours: First, the

MainActivity implements LoaderManager.LoaderCallbacks<ArrayList<Song>>

@Override
    public Loader<ArrayList<Song>> onCreateLoader(int id, Bundle args) {
        return new AsyncSongLoader(getActivity());
    }

    @Override
    public void onLoadFinished(Loader<ArrayList<Song>> loader, ArrayList<Song> data) {
        mAdapter.swapDataSet(data);
    }

    @Override
    public void onLoaderReset(Loader<ArrayList<Song>> loader) {
        mAdapter.swapDataSet(new ArrayList<Song>());
        
    }

    private static class AsyncSongLoader extends SongsAsyncTaskLoader<ArrayList<Song>> {
        public AsyncSongLoader(Context context) {
            super(context);
        }

        @Override
        public ArrayList<Song> loadInBackground() {
// this is where you fetch your data
// SongLoader in your case is FetchDataFromInternet
            return SongLoader.getAllSongs( this );
        }
    }

Inside your adapter add this method:

public void swapDataSet(ArrayList<Song> dataSet) {
        this.dataSet = dataSet;
        notifyDataSetChanged();
    }

Now the SongsAsyncTaskLoader that extends AsyncTaskLoader:

public abstract class SongsAsyncTaskLoader<D> extends AsyncTaskLoader<D> {

    private D mData;

    /**
     * @param context The {@link Context} to use.
     */
    public SongsAsyncTaskLoader(Context context) {
        super(context);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void deliverResult(D data) {
        if (!isReset()) {
            this.mData = data;
            super.deliverResult(data);
        } else {
            // An asynchronous query came in while the loader is stopped
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onStartLoading() {
        super.onStartLoading();
        if (this.mData != null) {
            deliverResult(this.mData);
        } else if (takeContentChanged() || this.mData == null) {
            forceLoad();
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onStopLoading() {
        super.onStopLoading();
        // Attempt to cancel the current load task if possible
        cancelLoad();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    protected void onReset() {
        super.onReset();
        // Ensure the loader is stopped
        onStopLoading();
        this.mData = null;
    }
}
private static
  • 745
  • 8
  • 17
  • 1
    Thank you for your attention,after 3 days work on this, and work on your codes with some corrections at last not get my answer. but i found the answer here ref: https://stackoverflow.com/questions/51408098/what-is-the-appropriate-replacement-of-deprecated-getsupportloadermanager in my code i add these lines : androidx.loader.app.LoaderManager loaderManager = null; and loaderManager.getInstance(this).initLoader(EARTHQUAKE_LOADER_ID,null,this); – M.J Jalali Nov 15 '20 at 13:36
0

After 3 days working and googling i found some tips from website below:

https://stackoverflow.com/questions/51408098/what-is-the-appropriate-replacement-of-deprecated-getsupportloadermanager

so i use codes below in "MainActivity.java" class file:

 androidx.loader.app.LoaderManager loaderManager = null;
 loaderManager.getInstance(this).initLoader(EARTHQUAKE_LOADER_ID,null,this);

nothing need to change anymore. these codes are based on "androidx", library. by the way in "MainActivity.java" its need to use,"LoaderManager.LoaderCallbacks" select from "import androidx.loader.app.LoaderManager;" not from import "import android.app.LoaderManager.LoaderCallbacks;"

public  class MainActivity extends AppCompatActivity implements LoaderManager.LoaderCallbacks<ArrayList<CustomWord>> {
.
codes
.
}
M.J Jalali
  • 102
  • 8