I am trying to make an app which uses last.fm's web API, sends a query for similar artists and returns all the names of the similar artists. It seems as though I manage to connect and get the xml response properly. However, I cannot extract the value of the name-attribute. I am using artistName = xmlData.getAttributeValue(null, "name"); but all it gives me is null.
import android.app.Activity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.Toast;
import java.util.*;
#SuppressWarnings("FieldCanBeLocal")
public class MainActivity extends Activity implements Observer {
private final String INPUTERROR = "Invalid/missing artist name.";
private NetworkCommunication nc;
private ArrayList<String> list;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
nc = new NetworkCommunication();
nc.register(this);
list = new ArrayList<>();
ListView lv = (ListView)findViewById(R.id.ListView_similarArtistsList);
ArrayAdapter adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, list);
lv.setAdapter(adapter);
}
public void searchButton_Clicked(View v){
EditText inputField = (EditText)findViewById(R.id.editText_artistName);
String searchString = inputField.getText().toString();
searchString = cleanSearchString(searchString);
if(validateSearchString(searchString)){
nc.setSearchString(searchString);
nc.execute();
}
else{
Toast.makeText(MainActivity.this, INPUTERROR, Toast.LENGTH_SHORT).show();
}
}
private String cleanSearchString(String oldSearchString){
String newString = oldSearchString.trim();
newString = newString.replace(" ", "");
return newString;
}
private boolean validateSearchString(String searchString){
boolean rValue = true;
if(TextUtils.isEmpty(searchString)){
rValue = false;
}
return rValue;
}
#Override
public void update(String artistName) {
list.add(artistName);
}
}
Here is my Network Communications class:
import android.os.AsyncTask;
import android.util.Log;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
#SuppressWarnings("FieldCanBeLocal")
class NetworkCommunication extends AsyncTask<Object, String, Integer> implements Subject {
private final String MYAPIKEY = "--------------------------";
private final String ROOT = "http://ws.audioscrobbler.com/2.0/";
private final String METHOD = "?method=artist.getsimilar";
private ArrayList<Observer> observers;
private int amountOfArtists = 0;
private String foundArtistName;
private String searchString;
NetworkCommunication(){
observers = new ArrayList<>();
}
void setSearchString(String newSearchString){
searchString = newSearchString;
}
private XmlPullParser sendRequest(){
try{
URL url = new URL(ROOT + METHOD + "&artist=" + searchString + "&api_key=" + MYAPIKEY);
XmlPullParser receivedData = XmlPullParserFactory.newInstance().newPullParser();
receivedData.setInput(url.openStream(), null);
return receivedData;
}
catch (IOException | XmlPullParserException e){
Log.e("ERROR", e.getMessage(), e);
}
return null;
}
private int tryProcessData(XmlPullParser xmlData){
int artistsFound = 0;
String artistName;
int eventType;
try{
while ((eventType = xmlData.next()) != XmlPullParser.END_DOCUMENT) {
if (eventType == XmlPullParser.START_TAG) {
if(xmlData.getName().equals("name")){
artistName = xmlData.getAttributeValue(null, "name");
publishProgress(artistName);
artistsFound++;
}
}
}
}
catch (IOException | XmlPullParserException e){
Log.e("ERROR", e.getMessage(), e);
}
if (artistsFound == 0) {
publishProgress();
}
return artistsFound;
}
#Override
protected Integer doInBackground(Object... params) {
XmlPullParser data = sendRequest();
if(data != null){
return tryProcessData(data);
}
else{
return null;
}
}
#Override
protected void onProgressUpdate(String... values){
/*
if (values.length == 0) {
//No data found...
}
*/
if (values.length == 1) {
setFoundArtistName(values[0]);
notifyObserver();
}
super.onProgressUpdate(values);
}
private void setFoundArtistName(String newArtistName){
foundArtistName = newArtistName;
}
#Override
public void register(Observer newObserver) {
observers.add(newObserver);
}
#Override
public void unregister(Observer deleteObserver) {
observers.remove(deleteObserver);
}
#Override
public void notifyObserver() {
for (Observer o : observers) {
Log.i("my tag.... ", "name = " + foundArtistName);
o.update(foundArtistName);
}
}
}
Here's a screenshot of the xml response in Google Chrome:
The only thing I am interested in extracting at this moment is the the value of the Name-Element.
I am logging the value of foundArtistName (in the method notifyObserver) it gives me A LOT of "my tag.... name = null my tag.... name = null my tag.... name = null etc.."
EDIT: I tried using getText() instead of getAttributeValue(), but it also gives me null.
I found the solution. I was using: artistName = xmlData.getAttributeValue(null, "name");, when I really should've used: artistName = xmlData.nextText();
Related
Whenever in my Popular Movies Udacity project, I click on a movie poster in the favorites movie collection, which is maintained as a database offline, the URL list gets updated correctly but the JSONArray made in the AsyncTask does not update immediately.
package com.example.android.popularmovies;
import android.database.Cursor;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import com.example.android.popularmovies.Database.Contract;
import com.example.android.popularmovies.utilities.NetworkUtils;
import com.facebook.stetho.Stetho;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private final static String BASE_POSTER_URL = "http://image.tmdb.org/t/p/w500/";
private static String OPTION = "OPTION";
TextView mNoFavorites;
// = new JSONArray();
JSONArray favoriteJsonArray;
int optionChosen;
private ProgressBar mProgessBar;
private TextView mErrorMessage;
private Button mRetry;
private RecyclerView mRecyclerView;
private RecyclerView.Adapter mAdapter;
private URL url;
private ArrayList<String> posterList;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (savedInstanceState != null)
optionChosen = savedInstanceState.getInt(OPTION);
Stetho.initializeWithDefaults(this);
setContentView(R.layout.activity_main);
mRecyclerView = findViewById(R.id.my_recycler_view);
mRecyclerView.setHasFixedSize(true);
RecyclerView.LayoutManager mLayoutManager = new GridLayoutManager(this, 2);
mRecyclerView.setLayoutManager(mLayoutManager);
//mAdapter = new MainActivityAdapter(this, posterList, null);
//mRecyclerView.setAdapter(mAdapter);
mProgessBar = findViewById(R.id.progess_bar);
mErrorMessage = findViewById(R.id.error_message);
mRetry = findViewById(R.id.retry);
mNoFavorites = findViewById(R.id.no_favorites_yet);
favoriteJsonArray = new JSONArray();
tryToConnect(new View(this));
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.preferences, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
try {
if (item.getItemId() == R.id.top_rated) {
mRecyclerView.setVisibility(View.VISIBLE);
mNoFavorites.setVisibility(View.INVISIBLE);
url = NetworkUtils.buildUrl("top_rated");
if (url != null) {
mErrorMessage.setVisibility(View.INVISIBLE);
mRetry.setVisibility(View.INVISIBLE);
new FetchMovies().execute(url, null, null);
}
optionChosen = 1;
}
if (item.getItemId() == R.id.most_popular) {
mRecyclerView.setVisibility(View.VISIBLE);
mNoFavorites.setVisibility(View.INVISIBLE);
url = NetworkUtils.buildUrl("most_popular");
if (url != null) {
mErrorMessage.setVisibility(View.INVISIBLE);
mRetry.setVisibility(View.INVISIBLE);
new FetchMovies().execute(url, null, null);
}
optionChosen = 2;
}
if (item.getItemId() == R.id.favorites) {
optionFavorites();
optionChosen = 3;
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (java.lang.NullPointerException e) {
e.printStackTrace();
}
return super.onOptionsItemSelected(item);
}
#Override
protected void onResume() {
super.onResume();
if (optionChosen == 3)
optionFavorites();
}
#Override
public void onSaveInstanceState(Bundle savedInstanceState) {
// Save the user's current game state
savedInstanceState.putInt(OPTION, optionChosen);
// Always call the superclass so it can save the view hierarchy state
super.onSaveInstanceState(savedInstanceState);
}
/* public void onRestoreInstanceState(Bundle savedInstanceState) {
// Always call the superclass so it can restore the view hierarchy
super.onRestoreInstanceState(savedInstanceState);
// Restore state members from saved instance
optionChosen = savedInstanceState.getInt(OPTION);
}
*/
private void optionFavorites() {
try {
String[] projection = {"movie_id", "favorite_poster_path"};
Cursor cursor = getContentResolver().query(
Contract.FavoriteMovieDatabase.CONTENT_URI,
projection,
null,
null,
null
);
ArrayList<String> posterPathArrayList = new ArrayList<>();
ArrayList<URL> urlArrayList = new ArrayList<>();
if (cursor != null && cursor.moveToFirst()) {
do {
String posterPath = cursor.getString(cursor.getColumnIndex(Contract.FavoriteMovieDatabase.FAVORITE_POSTER_PATH));
posterPathArrayList.add(BASE_POSTER_URL + posterPath);
int movieId = cursor.getInt(cursor.getColumnIndex("movie_id"));
URL favoriteURL = NetworkUtils.buildUrl("favorites", movieId);
urlArrayList.add(favoriteURL);
} while (cursor.moveToNext());
Log.d("urllist", "" + urlArrayList.toString());
new FetchFavorites().execute(urlArrayList, null, null);
mAdapter = new MainActivityAdapter(MainActivity.this, posterPathArrayList, favoriteJsonArray);
mRecyclerView.setAdapter(mAdapter);
} else {
mRecyclerView.setVisibility(View.INVISIBLE);
mNoFavorites.setVisibility(View.VISIBLE);
}
} catch (java.lang.NullPointerException e) {
e.printStackTrace();
} catch (MalformedURLException e) {
e.printStackTrace();
}
}
private void noConnection() {
mErrorMessage.setText(R.string.no_connection);
mErrorMessage.setVisibility(View.VISIBLE);
mRetry.setText(R.string.retry);
mRetry.setVisibility(View.VISIBLE);
}
public void tryToConnect(View v) {
try {
url = NetworkUtils.buildUrl("most_popular");
} catch (MalformedURLException e) {
e.printStackTrace();
}
if (url != null) {
mErrorMessage.setVisibility(View.INVISIBLE);
mRetry.setVisibility(View.INVISIBLE);
new FetchMovies().execute(url, null, null);
}
}
private class FetchMovies extends AsyncTask<URL, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
mProgessBar.setVisibility(View.VISIBLE);
}
#Override
protected String doInBackground(URL... params) {
URL searchUrl = params[0];
String searchResults = null;
try {
searchResults = NetworkUtils.getResponseFromHttpUrl(searchUrl);
} catch (IOException e) {
e.printStackTrace();
}
return searchResults;
}
#Override
protected void onPostExecute(String searchResults) {
mProgessBar.setVisibility(View.INVISIBLE);
try {
posterList = new ArrayList<>();
if (searchResults != null && !searchResults.equals("")) {
JSONObject jsonObject = new JSONObject(searchResults);
JSONArray pageOne = jsonObject.getJSONArray("results");
int length = pageOne.length();
for (int i = 0; i < length; i++) {
JSONObject result = pageOne.getJSONObject(i);
String posterPath = BASE_POSTER_URL + result.getString("poster_path");
posterList.add(posterPath);
}
mAdapter = new MainActivityAdapter(MainActivity.this, posterList, pageOne);
mRecyclerView.setAdapter(mAdapter);
} else noConnection();
} catch (Exception e) {
e.printStackTrace();
}
}
}
private class FetchFavorites extends AsyncTask<ArrayList<URL>, Void, ArrayList<String>> {
#Override
protected ArrayList<String> doInBackground(ArrayList<URL>... params) {
ArrayList<URL> urlArrayList = params[0];
ArrayList<String> stringArrayList = new ArrayList<>();
String searchResults;
URL searchUrl;
favoriteJsonArray = new JSONArray();
for (int i = 0; i < urlArrayList.size(); i++)
try {
searchUrl = urlArrayList.get(i);
searchResults = NetworkUtils.getResponseFromHttpUrl(searchUrl);
stringArrayList.add(searchResults);
} catch (IOException e) {
e.printStackTrace();
}
return stringArrayList;
}
#Override
protected void onPostExecute(ArrayList<String> stringArrayList) {
for (int i = 0; i < stringArrayList.size(); i++)
try {
favoriteJsonArray.put(new JSONObject(stringArrayList.get(i)));
} catch (JSONException e) {
e.printStackTrace();
}
}
}
}
urlArrayList gets updated correctly when database changes occur, but favoriteJsonArray, which is updated inside AsyncTask, does not. Why?
There are two problems in you code:
in FetchFavorites.doInBackground(), you assign a new JSONArray() to favoriteJsonArray, but your mAdapter is still hold the old reference, which is an empty JSONArray.
you didn't call mAdapter.notifyDataSetChanged() after update the favoriteJsonArray.
You can solve the problems in to ways:
do not new JSONArray() in FetchFavorites.doInBackground(), and call mAdapter.notifyDataSetChanged() after update the favoriteJsonArray, but there is still a problem, you should clear the favoriteJsonArray every time you fetch the new data, and clear a JSONArray is kind of boring (there is no clear() method).
new JSONArray(), but edit your MainActivityAdapter, add a method like setFavorites(JSONArray array), and set the new created favoriteJsonArray to it then call mAdapter.notifyDataSetChanged().
please am working on a class project which i will submit soon and i need your help.am trying to get image saved in varbinary format in my sql server 2016 into my android Image view.i have been stock at this level for a while and i need help to cross it.i have also check google and youtube but the answers i found did not help me out.other values in my database table gets retrieved except the image when i look at the log file it tels me no adapter attached skipping layout.as you will see in the code my adapter is attached.help please help. below is my codes
for connecting to the database using jtds
package com.example.abun.shoprite1;
import java.lang.String;
import java.io.File;
import android.annotation.SuppressLint;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import static java.nio.file.Files.size;
import java.sql.*;
import java.util.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.os.StrictMode;
import android.util.Log;
public class ConnectionClass {
String url;
String serverName;
String instanceName;
String databaseName;
String userName;
String password;
String port;
String sql;
ConnectionClass() {
serverName = "192.168.80.1";
port ="1433";
//instanceName = "";
databaseName = "shoprite";
userName = "abun2";
password = "shoprite";
}
private String getConnectionUrl() {
// Constructing the connection string
return url + serverName +" ;DatabaseName = " +databaseName +";user="+userName + ";password="+password +";";
}
//private String getConnectionUrl() {
// Constructing the connection string
//return url + serverName +" ;DatabaseName = " +databaseName+"; integratedSecurity=true";
//}
#SuppressLint("NewApi")
public Connection getConnection() throws SQLException, ClassNotFoundException {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
String ConnUrl;
//String conny= "jdbc:jtds:sqlserver://"+ serverName+ ":" +port+ ";"+ " ;DatabaseName = " +databaseName+"; integratedSecurity=true";
ConnUrl="jdbc:jtds:sqlserver://" + serverName+ ":" +port+ ";"+ "databaseName=" + databaseName + ";user=" + userName + ";password=" + password + ";";
Connection con =null;
try {
Class.forName("net.sourceforge.jtds.jdbc.Driver").newInstance();
con = DriverManager.getConnection(ConnUrl);
//con = DriverManager.getConnection(conny);
//""+"jdbc:jtds:sqlserver://127.0.0.1/shoprite; integrated security=true"
// Establishing the connection
//con = DriverManager.getConnection(getConnectionUrl());
//con = DriverManager.getConnection(ConnUrl);
if(con != null){
System.out.println("Connection Successful!");
}
else{
System.out.println(" no Connection ");
}
}catch(SQLException se){
Log.e("ERROR--",se.getMessage());
Log.e("ERROR--",se.getSQLState());
Log.e("ERROR--",se.getLocalizedMessage());
Log.e("ERROR--",se.getCause().toString());
Log.e("ERROR--",se.getStackTrace().toString());
}catch(ClassNotFoundException se){
Log.e("ERROR--",se.getMessage());
Log.e("ERROR--",se.getLocalizedMessage());
}catch(Exception se){
Log.e("ERROR--",se.getMessage());
Log.e("ERROR--",se.getLocalizedMessage());
}
return con;
}
public boolean verifyCustomer(String username,String password)throws SQLException{
Connection con1;
ResultSet resultSet = null;
String query = "select * from Customer_Details where Customer_Name =? and Password=?";
try {
con1 = getConnection();
PreparedStatement stmt = con1.prepareStatement(query,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
stmt.setString(1, username);
stmt.setString(2, password);
resultSet = stmt.executeQuery();
if(resultSet.next()){
return true;
}else{
return false;
}
}catch(Exception e){
return false;
} finally {
if(resultSet != null)
resultSet.close();
}
}
public boolean verifyEmployee(String username,String password)throws SQLException{
Connection con1;
ResultSet resultSet = null;
String query = "select * from Employee_Details where Employee_Name =? and Designation=?";
try {
con1 = getConnection();
PreparedStatement stmt = con1.prepareStatement(query,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
stmt.setString(1, username);
stmt.setString(2, password);
resultSet = stmt.executeQuery();
if(resultSet.next()){
return true;
}else{
return false;
}
}catch(Exception e){
return false;
} finally {
if(resultSet != null)
resultSet.close();
}
}
public boolean insertDataCustomer(String name, String gender,String address,int phone,
String DOB,String password,String email,int creditcard,String creditCardType){
Connection con1;
String query = "insert into Customer_Details(Customer_Name,Gender,Address,Phone,DOB,Password,CreditCardNo,CreditCardType) values( ?, ?, ?, ?,?,?,?,?)";
try {
con1 = getConnection();
PreparedStatement stmt = con1.prepareStatement(query);
stmt.setString(1, name);
stmt.setString(2, gender);
stmt.setString(3, address);
stmt.setInt(4, phone);
stmt.setString(5, DOB);
stmt.setString(6, password);
//stmt.setString(7, email);
stmt.setInt(7, creditcard);
stmt.setString(8, creditCardType);
long ent= stmt.executeUpdate();
if(ent == -1)
return false;
else
return true;
}catch(Exception e){
// System.out.println(e.getMessage());
Log.e( "error here: ",e.getMessage());
Log.e( "error here: ",e.getLocalizedMessage());
Log.e( "error here: ",e.getCause().toString());
return false;
}
}
public boolean insertDataEmployee(String ID, String name, String gender,
String DOB,String Designation,String address,String email,String phone){
Connection con1;
String query = "insert into Employee_Details(ID,name,gender,DOB,Designation,address,email,phone) values(?, ?, ?, ?, ?,?,?,?)";
try {
con1 = getConnection();
PreparedStatement stmt = con1.prepareStatement(query);
stmt.setString(1, name);
stmt.setString(2, gender);
stmt.setString(3, DOB);
stmt.setString(4, Designation);
stmt.setString(5, address);
stmt.setString(6, email);
stmt.setString(7, phone);
long ent= stmt.executeUpdate();
if(ent == -1)
return false;
else
return true;
}catch(Exception e){
// System.out.println(e.getMessage());
Log.e( "error here: ",e.getMessage());
return false;
}
}
public void veiwOrders()throws SQLException{
Connection con1;
ResultSet resultSet = null;
String query = "select * from Order_Details";
try {
con1 = getConnection();
PreparedStatement stmt = con1.prepareStatement(query,ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_READ_ONLY);
resultSet = stmt.executeQuery();
if(resultSet.next()){
while(resultSet.next()){
}
}
}catch(Exception e){
//return false;
} finally {
if(resultSet != null)
resultSet.close();
}
}
}
below is my activity class
package com.example.abun.shoprite1;
/**
* Created by Abun on 5/12/2018.
*/
import android.app.Activity;
import android.app.ProgressDialog;
import android.support.annotation.RequiresPermission.Write;
import android.os.Bundle;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.util.Log;
import android.view.MenuItem;
import android.os.AsyncTask;
import android.support.design.widget.NavigationView;
import android.content.Intent;
//import android.app.ActionBar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.view.View;
import android.support.v7.app.ActionBar;
import android.widget.Toast;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
public class productPage extends AppCompatActivity {
private RecyclerView mRecycler;
private RecyclerView.LayoutManager mLayoutManager;
private RecyclerView.Adapter mAdapter;
private DrawerLayout mDrawerLayout;
private ArrayList<String> mData;
private ArrayList<ProductPageRetrive> data;
ConnectionClass db;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.productpage1);
db = new ConnectionClass();
data = new ArrayList<ProductPageRetrive>();
mData = new ArrayList<>();
for (int i = 0;i<30;i++){
mData.add("new title"+i);
}
SyncData orderData = new SyncData();
orderData.execute("");
mRecycler = (RecyclerView) findViewById(R.id.recycler_view);
mRecycler.setHasFixedSize(true);
mLayoutManager = new LinearLayoutManager(productPage.this,LinearLayoutManager.HORIZONTAL,false);
mRecycler.setLayoutManager(mLayoutManager);
mAdapter = new MainAdapter(data,productPage.this);
mRecycler.setAdapter(mAdapter);
Toolbar toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
ActionBar actionbar = getSupportActionBar();
actionbar.setDisplayHomeAsUpEnabled(true);
actionbar.setHomeAsUpIndicator(R.mipmap.ic_launcher);
mDrawerLayout = findViewById(R.id.drawer_layout);
mDrawerLayout.addDrawerListener(
new DrawerLayout.DrawerListener() {
#Override
public void onDrawerSlide(View drawerView, float slideOffset) {
// Respond when the drawer's position changes
}
#Override
public void onDrawerOpened(View drawerView) {
// Respond when the drawer is opened
}
#Override
public void onDrawerClosed(View drawerView) {
// Respond when the drawer is closed
}
#Override
public void onDrawerStateChanged(int newState) {
// Respond when the drawer motion state changes
}
}
);
NavigationView navigationView = findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(
new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(MenuItem menuItem) {
// set item as selected to persist highlight
menuItem.setChecked(true);
// close drawer when item is tapped
mDrawerLayout.closeDrawers();
// Add code here to update the UI based on the item selected
// For example, swap UI fragments here
return true;
}
});
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
mDrawerLayout.openDrawer(GravityCompat.START);
return true;
}
return super.onOptionsItemSelected(item);
}
private class SyncData extends AsyncTask<String ,String,String>{
String msg="Internet/DB_Credentials/Windows_FireWall_TurnOn Error, see android monitor in the buttom for details";
ProgressDialog progress;
boolean success = false;
#Override
protected void onPreExecute(){
progress = ProgressDialog.show(productPage.this,"Synchronising","RecyclerView loading! please wait...",true);
}
#Override
protected String doInBackground(String...strings){
try {
Connection con = db.getConnection();
ResultSet resultSet = null;
if (con == null) {
msg="No Data found";
success = false;
}else{
String query = "SELECT * FROM Product_Details";
PreparedStatement stmt = con.prepareStatement(query, ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
resultSet = stmt.executeQuery();
while (resultSet.next()) {
try {
data.add(new ProductPageRetrive(resultSet.getBinaryStream("Image"), resultSet.getInt("Price"), resultSet.getInt("Discount")));
}catch(Exception ex){
ex.printStackTrace();
}
}
msg ="found";
success=true;
}
}catch(Exception e){
e.printStackTrace();
//Write write = new StringWriter();
//e.printStackTrace(new PrintWriter(write));
//msg=writer.toString();
success=false;
}
return msg;
}
#Override
protected void onPostExecute(String msg){
progress.dismiss();
Toast.makeText(productPage.this,msg+"",Toast.LENGTH_LONG).show();
if(success == true){
mAdapter.notifyDataSetChanged();
}else{
try{
}catch (Exception e){
}
}
}
}
}
below is the data object for the array data;
package com.example.abun.shoprite1;
import java.io.InputStream;
import java.sql.Blob;
import java.sql.ResultSet;
/**
* Created by Abun on 6/14/2018.
*/
public class ProductPageRetrive {
private int price;
private int rating;
private String img1;
private InputStream ism;
private ResultSet rs;
public ProductPageRetrive(InputStream is, int money, int rate){
this.ism=is;
this.price=money;
this.rating=rate;
}
public int getRating() {
return rating;
}
public void setRating(int rating) {
this.rating = rating;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getImg1() {
return img1;
}
public void setImg1(String img1) {
this.img1 = img1;
}
public InputStream getIsm() {
return ism;
}
public void setIsm(InputStream ism) {
this.ism = ism;
}
}
below is my adapter class
package com.example.abun.shoprite1;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.widget.RecyclerView;
import android.util.Base64;
import java.io.FileOutputStream;
import android.view.LayoutInflater;
import android.view.ViewGroup;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;
import java.io.File;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.SQLException;
import java.util.ArrayList;
import com.squareup.picasso.Picasso;
import android.content.Context;
/**
* Created by Abun on 6/13/2018.
*/
public class MainAdapter extends RecyclerView.Adapter<MainAdapter.ViewHolder> {
private ArrayList<String> mData;
private ArrayList<ProductPageRetrive> Data;
private Context ct1;
public MainAdapter(ArrayList<String> Data1){
this.mData=Data1;
}
public MainAdapter(ArrayList<ProductPageRetrive> Data, Context ct)
{
this.Data=Data;
this.ct1 =ct;
}
#Override
public MainAdapter.ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext())
.inflate(R.layout.contain,parent,false);
// set the view size, margin,padding and layout parameters
ViewHolder vh = new ViewHolder(v);
return vh;
}
#Override
public void onBindViewHolder(MainAdapter.ViewHolder holder, int position) {
int py =Data.get(position).getRating();
String pp = py +"";
holder.mtitle.setText(pp);
try {
InputStream is = Data.get(position).getIsm();
OutputStream os = new FileOutputStream(new File("photo1.jpg"));
byte[] content = new byte[1024];
int size = 0;
while((size=is.read(content))!=-1){
os.write(content,0,size);
}
os.close();
is.close();
//Picasso.get().load("file:photo1.jpg").into(holder.img);
Picasso.get().load("file:photo1.jpg").into(holder.img);
}catch (Exception e){
}
/*byte[] decorde = Base64.decode(Data.get(position).getImg1(),Base64.DEFAULT);
Bitmap mp = BitmapFactory.decodeByteArray(decorde,0,decorde.length);
holder.img.setImageBitmap(mp);*/
}
#Override
public int getItemCount() {
return Data.size();
}
public class ViewHolder extends RecyclerView.ViewHolder{
public TextView mtitle;
public TextView mtitle1;
public ImageView img;
public View layout;
public ViewHolder(View itemView){
super(itemView);
layout = itemView;
mtitle = (TextView) itemView.findViewById(R.id.mtitle);
img = (ImageView) itemView.findViewById(R.id.imaging);
}
}
}
I tried to write a "login" App using MVP model. And I use WAMP to build up my server. I'm sure that my php documents have no problem.
Here is the structure of my App:
enter image description here
And here are the files:
User.java
package com.example.android.login.mvp;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.presenter.UserLoginPresenter;
import com.example.android.login.mvp.view.IUserLoginView;
public class UserLoginActivity extends AppCompatActivity implements IUserLoginView
{
private EditText mEtUsername, mEtPassword;
private Button mBtnLogin, mBtnClear;
private ProgressBar mPbLoading;
private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_login);
initViews();
}
private void initViews()
{
mEtUsername = (EditText) findViewById(R.id.id_et_username);
mEtPassword = (EditText) findViewById(R.id.id_et_password);
mBtnClear = (Button) findViewById(R.id.id_btn_clear);
mBtnLogin = (Button) findViewById(R.id.id_btn_login);
mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading);
mBtnLogin.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.login();
}
});
mBtnClear.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.clear();
}
});
}
#Override
public String getUserName()
{
return mEtUsername.getText().toString();
}
#Override
public String getPassword()
{
return mEtPassword.getText().toString();
}
#Override
public void clearUserName()
{
mEtUsername.setText("");
}
#Override
public void clearPassword()
{
mEtPassword.setText("");
}
#Override
public void showLoading()
{
mPbLoading.setVisibility(View.VISIBLE);
}
#Override
public void hideLoading()
{
mPbLoading.setVisibility(View.GONE);
}
#Override
public void toMainActivity(User user)
{
Toast.makeText(this, user.getUsername() +
" login success , to MainActivity", Toast.LENGTH_SHORT).show();
}
#Override
public void showFailedError()
{
Toast.makeText(this,
"login failed", Toast.LENGTH_SHORT).show();
}
}
IUserBiz.java
package com.example.android.login.mvp.biz;
/**
* Created by zhy on 15/6/19.
*/
public interface IUserBiz
{
public void login(String username, String password, OnLoginListener loginListener);
}
OnLoginListener.java
package com.example.android.login.mvp.biz;
import com.example.android.login.mvp.bean.User;
/**
* Created by zhy on 15/6/19.
*/
public interface OnLoginListener
{
void loginSuccess(User user);
void loginFailed();
}
UserBiz.java
package com.example.android.login.mvp.biz;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.widget.TextView;
import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
/**
* Created by zhy on 15/6/19.
*/
public class UserBiz extends AppCompatActivity implements IUserBiz
{
private User user;
private OnLoginListener loginListener;
#Override
public void login(final String username, final String password, final OnLoginListener mLoginListener)
{
user = new User();
user.setUsername(username);
user.setPassword(password);
user.setStatus(0);
loginListener = mLoginListener;
LoginAsyncTask task = new LoginAsyncTask();
String test1Url = getString(R.string.server_ip)+"/server/login.php";
task.execute(test1Url);
}
/**
* Update the UI with the given earthquake information.
*/
private void updateUi(User mUser) {
if (mUser.getStatus()==1)
{
loginListener.loginSuccess(user);
} else
{
loginListener.loginFailed();
}
}
private class LoginAsyncTask extends AsyncTask<String, Void, User> {
#Override
protected User doInBackground(String... urls) {
if (urls.length < 1 || urls[0] == null) {
return null;
}
// Perform the HTTP request for earthquake data and process the response.
User mUser = Utils.fetchEarthquakeData(urls[0],user);
return mUser;
}
#Override
protected void onPostExecute(User result) {
if(result==null){
return;
}
updateUi(result);
}
}
}
Utils.java
package com.example.android.login.mvp.biz;
import android.text.TextUtils;
import android.util.Log;
import com.example.android.login.mvp.bean.User;
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.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.nio.charset.Charset;
/**
* Utility class with methods to help perform the HTTP request and
* parse the response.
*/
public final class Utils {
/** Tag for the log messages */
public static final String LOG_TAG = Utils.class.getSimpleName();
/**
* Query the USGS dataset and return an {#link User} object to represent a single earthquake.
*/
public static User fetchEarthquakeData(String requestUrl, User user) {
// Create URL object
URL url = createUrl(requestUrl);
// Perform HTTP request to the URL and receive a JSON response back
String jsonResponse = null;
try {
jsonResponse = makeHttpRequest(url, user);
} catch (IOException e) {
Log.e(LOG_TAG, "Error closing input stream", e);
}
// Extract relevant fields from the JSON response and create an {#link User} object
User earthquake = extractFeatureFromJson(jsonResponse);
// Return the {#link User}
return earthquake;
}
/**
* Returns new URL object from the given string URL.
*/
private static URL createUrl(String stringUrl) {
URL url = null;
try {
url = new URL(stringUrl);
} catch (MalformedURLException e) {
Log.e(LOG_TAG, "Error with creating URL ", e);
}
return url;
}
/**
* Make an HTTP request to the given URL and return a String as the response.
*/
private static String makeHttpRequest(URL url, User user) throws IOException {
String jsonResponse = "";
// If the URL is null, then return early.
if (url == null) {
return jsonResponse;
}
HttpURLConnection urlConnection = null;
InputStream inputStream = null;
try {
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setReadTimeout(10000 /* milliseconds */);
urlConnection.setConnectTimeout(15000 /* milliseconds */);
urlConnection.setRequestMethod("POST");
urlConnection.setDoOutput(true);
String params="app_user_name="+user.getUsername()+'&'+"app_password="+user.getPassword();
OutputStream out=urlConnection.getOutputStream();
out.write(params.getBytes());//post提交参数
out.flush();
out.close();
// If the request was successful (response code 200),
// then read the input stream and parse the response.
if (urlConnection.getResponseCode() == 200) {
inputStream = urlConnection.getInputStream();
jsonResponse = readFromStream(inputStream);
} else {
Log.e(LOG_TAG, "Error response code: " + urlConnection.getResponseCode());
}
} catch (IOException e) {
Log.e(LOG_TAG, "Problem retrieving the earthquake JSON results.", e);
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (inputStream != null) {
inputStream.close();
}
}
return jsonResponse;
}
/**
* Convert the {#link InputStream} into a String which contains the
* whole JSON response from the server.
*/
private static String readFromStream(InputStream inputStream) throws IOException {
StringBuilder output = new StringBuilder();
if (inputStream != null) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream, Charset.forName("UTF-8"));
BufferedReader reader = new BufferedReader(inputStreamReader);
String line = reader.readLine();
while (line != null) {
output.append(line);
line = reader.readLine();
}
}
return output.toString();
}
/**
* Return an {#link User} object by parsing out information
* about the first earthquake from the input earthquakeJSON string.
*/
private static User extractFeatureFromJson(String earthquakeJSON) {
// If the JSON string is empty or null, then return early.
if (TextUtils.isEmpty(earthquakeJSON)) {
return null;
}
try {
JSONObject baseJsonResponse = new JSONObject(earthquakeJSON);
// If there are results in the features array
if (baseJsonResponse.length() > 0) {
int status = baseJsonResponse.getInt("status");
// Create a new {#link User} object
User user=new User();
user.setStatus(status);
return user;
}
} catch (JSONException e) {
Log.e(LOG_TAG, "Problem parsing the earthquake JSON results", e);
}
return null;
}
}
UserLoginPresenter.java
package com.example.android.login.mvp.presenter;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.biz.IUserBiz;
import com.example.android.login.mvp.biz.OnLoginListener;
import com.example.android.login.mvp.biz.UserBiz;
import com.example.android.login.mvp.view.IUserLoginView;
/**
* Created by zhy on 15/6/19.
*/
public class UserLoginPresenter {
private IUserBiz userBiz;
private IUserLoginView userLoginView;
public UserLoginPresenter(IUserLoginView userLoginView) {
this.userLoginView = userLoginView;
this.userBiz = new UserBiz();
}
public void login() {
userLoginView.showLoading();
userBiz.login(userLoginView.getUserName(), userLoginView.getPassword(), new OnLoginListener() {
#Override
public void loginSuccess(final User user) {
userLoginView.toMainActivity(user);
userLoginView.hideLoading();
}
#Override
public void loginFailed() {
userLoginView.showFailedError();
userLoginView.hideLoading();
}
});
}
public void clear() {
userLoginView.clearUserName();
userLoginView.clearPassword();
}
}
IUserLoginView.java
package com.example.android.login.mvp.view;
import com.example.android.login.mvp.bean.User;
/**
* Created by zhy on 15/6/19.
*/
public interface IUserLoginView
{
String getUserName();
String getPassword();
void clearUserName();
void clearPassword();
void showLoading();
void hideLoading();
void toMainActivity(User user);
void showFailedError();
}
UserLoginActivity.java
package com.example.android.login.mvp;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ProgressBar;
import android.widget.Toast;
import com.example.android.login.R;
import com.example.android.login.mvp.bean.User;
import com.example.android.login.mvp.presenter.UserLoginPresenter;
import com.example.android.login.mvp.view.IUserLoginView;
public class UserLoginActivity extends AppCompatActivity implements IUserLoginView
{
private EditText mEtUsername, mEtPassword;
private Button mBtnLogin, mBtnClear;
private ProgressBar mPbLoading;
private UserLoginPresenter mUserLoginPresenter = new UserLoginPresenter(this);
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_user_login);
initViews();
}
private void initViews()
{
mEtUsername = (EditText) findViewById(R.id.id_et_username);
mEtPassword = (EditText) findViewById(R.id.id_et_password);
mBtnClear = (Button) findViewById(R.id.id_btn_clear);
mBtnLogin = (Button) findViewById(R.id.id_btn_login);
mPbLoading = (ProgressBar) findViewById(R.id.id_pb_loading);
mBtnLogin.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.login();
}
});
mBtnClear.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View v)
{
mUserLoginPresenter.clear();
}
});
}
#Override
public String getUserName()
{
return mEtUsername.getText().toString();
}
#Override
public String getPassword()
{
return mEtPassword.getText().toString();
}
#Override
public void clearUserName()
{
mEtUsername.setText("");
}
#Override
public void clearPassword()
{
mEtPassword.setText("");
}
#Override
public void showLoading()
{
mPbLoading.setVisibility(View.VISIBLE);
}
#Override
public void hideLoading()
{
mPbLoading.setVisibility(View.GONE);
}
#Override
public void toMainActivity(User user)
{
Toast.makeText(this, user.getUsername() +
" login success , to MainActivity", Toast.LENGTH_SHORT).show();
}
#Override
public void showFailedError()
{
Toast.makeText(this,
"login failed", Toast.LENGTH_SHORT).show();
}
}
But I got something wrong like this:
enter image description here
I have no idea about it. How to solve it?
the issue is here
this.userBiz = new UserBiz();
UserBiz is an activity so activity gets their context when they are being started with Intent (by OS) but creating an object of an activity will not provide any contenxt hence the null exception at
#Override
public void login(final String username, final String password, final OnLoginListener mLoginListener)
{
user = new User();
user.setUsername(username);
user.setPassword(password);
user.setStatus(0);
loginListener = mLoginListener;
LoginAsyncTask task = new LoginAsyncTask();
String test1Url = getString(R.string.server_ip)+"/server/login.php";
// no context here due to new UserBiz
// getString required context
task.execute(test1Url);
}
Solution : you can use enums or static final constants to avoid context and also would be wise to substitute UserBiz as separate class instead of an activity
I am writing an App that connects to the Fitbit API correctly and pulls back the data I need. I have an Inner class that extends AsyncTask that lets me complete this. So for example, my MainActivity.java opens the Fitbit OAuth2 page and the user logs in. The user is then directed back to the UserActivity.java and their info is displayed.
I now want to add another Activity that pulls back the information for the Activities that they carried out. So, my question is, do I need to add another inner class in my ActivitiesActivity.java or is there some other way to get the data. I know people have used an Interface before but I'm not sure how they work with AsyncTask.
package com.jordan.fitbit_connect;
import android.net.Uri;
import android.os.Bundle;
import android.support.customtabs.CustomTabsIntent;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
public class MainActivity extends AppCompatActivity {
String response_type = "token";
String client_id = "22CJH3";
String redirect_uri = "myapplication://login";
String scope = "activity%20nutrition%20heartrate%20location%20nutrition%20profile%20settings%20sleep%20social%20weight";
String url = "https://www.fitbit.com/oauth2/authorize?" + "response_type=" + response_type + "&client_id=" + client_id + "&redirect_uri=" + redirect_uri + "&scope=" + scope;
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//
// CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
// customTabsIntent.launchUrl(this, Uri.parse(url));
connectToFitbit();
}
public void connectToFitbit()
{
Button btn = (Button)findViewById(R.id.btnConnect);
btn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
customTabsIntent.launchUrl(getApplicationContext(), Uri.parse(url));
}
});
}
}
package com.jordan.fitbit_connect;
import android.content.Intent;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
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.URL;
public class TestActivity extends AppCompatActivity
{
//String to hold the data sent back by the Intent
String string;
//String to extract the token from 'string' above
private static String token;
//Strings to get the data from the JSON Object
public static String name, avatar, age, weight, height;
TextView username, txtAge, txtWeight, txtHeight, txtBMI;
float bmi;
ImageView imgViewAvatar;
//-------------------------------------- START onNewIntent()------------------------------------
/*
This method returns the URI from the Intent as an encoded String
*/
#Override
protected void onNewIntent(Intent intent)
{
string = intent.getDataString();
}
//-------------------------------------- END onNewIntent()--------------------------------------
//-------------------------------------- START onCreate()---------------------------------------
/*
Default method when the class is created
*/
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
onNewIntent(getIntent());
token = string.substring(string.indexOf("&access_token")+36,308);
Log.i("TAG", "Access Token: "+ token);
Log.i("TAG", "Data String: " + string);
//new JSONTask().execute("https://api.fitbit.com/1.2/user/-/sleep/date/2017-10-26.json");
//new JSONTask().execute("https://api.fitbit.com/1/user/-/activities/steps/date/today/6m.json");
new JSONTask().execute("https://api.fitbit.com/1/user/-/profile.json");
}
//-------------------------------------- END onCreate()-----------------------------------------
//-------------------------------------- START of inner class JSONTask -------------------------
public class JSONTask extends AsyncTask<String,String,String>
{
#Override
protected void onPreExecute() {
super.onPreExecute();
username = (TextView)findViewById(R.id.txtUser);
imgViewAvatar = (ImageView)findViewById(R.id.imgViewAvatar);
txtAge = (TextView)findViewById(R.id.txtAge);
txtWeight = (TextView) findViewById(R.id.txtWeight);
txtHeight = (TextView) findViewById(R.id.txtHeight);
txtBMI = (TextView) findViewById(R.id.txtBMI);
}
//-------------------------------------- START doInBackground()-----------------------------
/*
This method is what happens on the background thread when the
app is running. It will
*/
#Override
protected String doInBackground(String... params)
{
HttpURLConnection connection = null;
BufferedReader reader = null;
try
{
URL url = new URL(params[0]);
connection = (HttpURLConnection)url.openConnection();
connection.setRequestMethod("GET");
connection.setDoOutput(false);
connection.addRequestProperty("Authorization", "Bearer " + token);
connection.connect();
InputStream stream = (InputStream)connection.getInputStream();
reader = new BufferedReader(new InputStreamReader(stream));
StringBuffer buffer = new StringBuffer();
String line = "";
while((line = reader.readLine()) !=null)
{
buffer.append(line);
}
return buffer.toString();
} catch (MalformedURLException e)
{
e.printStackTrace();
} catch (IOException e)
{
e.toString();
}
return null;
}
//-------------------------------------- END doInBackground()-------------------------------
//-------------------------------------- START onPostExecute()------------------------------
#Override
protected void onPostExecute(String data)
{
super.onPostExecute(data);
Log.i("TAG", data);
try
{
//GET ALL THE JSON DATA
JSONObject allData = new JSONObject(data);
//GET THE USERNAME
JSONObject userObject = allData.getJSONObject("user");
name = userObject.getString("fullName");
username.append(" "+name);
//GET THE USER'S AVATAR
avatar = userObject.getString("avatar640");
Picasso.get().load(avatar).into(imgViewAvatar);
//GET THE USER'S AGE
age = userObject.getString("age");
txtAge.append(" "+age);
weight = userObject.getString("weight");
txtWeight.append(" "+weight);
float weightFloat = Float.parseFloat(weight);
height = userObject.getString("height");
txtHeight.append(" "+height);
float heightFloat= Float.parseFloat(height)/100;
bmi = (float)(weightFloat/(heightFloat * heightFloat));
if(bmi <= 16)
{
txtBMI.setTextColor(Color.YELLOW);
txtBMI.append(" "+ String.valueOf(bmi) + " - You are severely underweight!");
}
else if(bmi <= 18.5)
{
txtBMI.setTextColor(Color.GRAY);
txtBMI.append(" "+ String.valueOf(bmi) + " - You are underweight!");
}
else if(bmi <= 25)
{
txtBMI.setTextColor(Color.GREEN);
txtBMI.append(" "+ String.valueOf(bmi) + " - Your weight is normal");
}
else if(bmi <= 30)
{
txtBMI.setTextColor(Color.parseColor("#FFA500"));
txtBMI.append(" "+ String.valueOf(bmi) + " - You are overweight!");
}
else
{
txtBMI.setTextColor(Color.RED);
txtBMI.append(" " + String.valueOf(bmi) + " - You are obese!");
}
// for(int i =0; i< userObject.length(); i++) {
//3.DECLARE ANOTHER JSONOBJECT THAT EXTRACTS THE OBECT FROM THE SPECIFIED ARRAY
//JSONObject sleep = sleepArray.getJSONObject(i);
//4.Then use a getString to get the data from the object
//name = userObject.getString("firstName");
// Log.i("TAG",name);
}
catch (JSONException e)
{
e.printStackTrace();
}
}
}
//-------------------------------------- END of inner class JSONTask ---------------------------
}
One of the methods using AsynTask in different Activities, creating a callback interface.
Create a callback interface
interface AsyncTaskListener<T> {
public void onComplete(T result);
}
Then in your MainActivity and TestActivity:
public class MainActivity extends AppCompatActivity
implements AsyncTaskListener<String> {
public void onComplete(String result) {
// your staff here
}
}
public class TestActivity extends AppCompatActivity
implements AsyncTaskListener<String> {
public void onComplete(String result) {
// your staff here
}
}
And add to your AsyncTask class:
public class JSONTask extends AsyncTask<String, String, String>
private AsyncTaskListener<String> listener;
public JSONTask (AsyncTaskListener<String> callback) {
this.listener = callback;
}
protected void onPostExecute(String result) {
listener.onComplete(result); // calling onComplate interface
}
I am also getting ArrayListIndexOutofBound when I am pressing list item when the orientation is changed.As far my knowledge of android I have written Parcelable code correctly.But I think my issues are with the recycler view setup.I am confused with two declaration of my adapter.Help me
MainActivity.class
package com.reader.ashishyadav271.hackernewsmaterial;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteStatement;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.support.v4.util.LruCache;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
import com.wang.avi.AVLoadingIndicatorView;
import org.json.JSONArray;
import org.json.JSONObject;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MainActivity extends AppCompatActivity implements MyCustomAdapter.ClickListener {
private static final String STATE_LIST = "state_list";
Map<Integer, String> articleURLs = new HashMap<>();
Map<Integer, String> articleTitles = new HashMap<>();
Map<Integer, String> articleDates =new HashMap<>();
Map<Integer, String> articleAuthors =new HashMap<>();
ArrayList<Integer> articleIds=new ArrayList<>();
SQLiteDatabase articlesDB;
ArrayList<Information> data=new ArrayList<>();
ArrayList<String> titles=new ArrayList<>();
ArrayList<String> urls=new ArrayList<>();
ArrayList<String> authors=new ArrayList<>();
ArrayList<String> dateAndTimes=new ArrayList<>();
MyCustomAdapter adapter;
RecyclerView recyclerView;
AVLoadingIndicatorView av;
List<DownloadTask> tasks;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
av= (AVLoadingIndicatorView) findViewById(R.id.avloadingIndicatorView);
av.setVisibility(View.INVISIBLE);
tasks = new ArrayList<>();
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
recyclerView= (RecyclerView) findViewById(R.id.recyclerView);
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
recyclerView.addItemDecoration(new SimpleDividerItemDecoration(
getApplicationContext()
));
articlesDB = this.openOrCreateDatabase("Articles", MODE_PRIVATE, null);
articlesDB.execSQL("CREATE TABLE IF NOT EXISTS article (id INTEGER PRIMARY KEY," +
" articleId INTEGER," +
" url VARCHAR," +
" title VARCHAR," +
" author VARCHAR," +
" date VARCHAR)");
if(savedInstanceState != null) {
data=savedInstanceState.getParcelableArrayList(STATE_LIST);
adapter=new MyCustomAdapter(getApplicationContext(),data);
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);
}else{
if (isOnline()) {
requestData("https://hacker-news.firebaseio.com/v0/topstories.json?print=pretty");
} else {
updateDisplay();
Toast.makeText(this, "Network isn't available", Toast.LENGTH_LONG).show();
}
}
//adapter=new MyCustomAdapter(getApplicationContext(),getData());
//adapter.setClickListener(this);
//recyclerView.setAdapter(adapter);
}
protected boolean isOnline() {
ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
} else {
return false;
}
}
private void requestData(String uri) {
DownloadTask task = new DownloadTask();
task.execute(uri);
}
#Override
public void itemClicked(View view, int position) {
Intent i = new Intent(getApplicationContext(), Main2Activity.class);
i.putExtra("articleUrl", urls.get(position));
startActivity(i);
}
protected void updateDisplay() {
adapter=new MyCustomAdapter(getApplicationContext(),getData());
adapter.setClickListener(this);
recyclerView.setAdapter(adapter);;
}
#Override
protected void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelableArrayList(STATE_LIST, data);
}
public class DownloadTask extends AsyncTask<String, Void, String> {
#Override
protected void onPreExecute() {
super.onPreExecute();
if (tasks.size() == 0) {
av.setVisibility(View.VISIBLE);
}
tasks.add(this);
}
#Override
protected String doInBackground(String... urls) {
String result = "";
URL url;
HttpURLConnection urlConnection;
try {
url = new URL(urls[0]);
urlConnection = (HttpURLConnection) url.openConnection();
InputStream in = urlConnection.getInputStream();
InputStreamReader reader = new InputStreamReader(in);
int data = reader.read();
while (data != -1) {
char current = (char) data;
result += current;
data = reader.read();
}
JSONArray jsonArray = new JSONArray(result);
articlesDB.execSQL("DELETE FROM article");
for (int i = 0; i < 15; i++) {
String articleId = jsonArray.getString(i);
url = new URL("https://hacker-news.firebaseio.com/v0/item/" + articleId + ".json?print=pretty");
urlConnection = (HttpURLConnection) url.openConnection();
in = urlConnection.getInputStream();
reader = new InputStreamReader(in);
data = reader.read();
String articleInfo = "";
while (data != -1 ) {
char current = (char) data;
articleInfo += current;
data = reader.read();
}
JSONObject jsonObject = new JSONObject(articleInfo);
String articleTitle = jsonObject.getString("title");
String articleURL = jsonObject.getString("url");
String articleDate=jsonObject.getString("time");
String articleAuthor=jsonObject.getString("by");
long unixSeconds = Long.valueOf(articleDate);
Date date = new Date(unixSeconds*1000L); // *1000 is to convert seconds to milliseconds
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss"); // the format of your date
String formattedarticleDate = sdf.format(date);
articleIds.add(Integer.valueOf(articleId));
articleTitles.put(Integer.valueOf(articleId), articleTitle);
articleURLs.put(Integer.valueOf(articleId), articleURL);
articleDates.put(Integer.valueOf(articleId), formattedarticleDate);
articleAuthors.put(Integer.valueOf(articleId), articleAuthor);
String sql = "INSERT INTO article (articleId, url, title, author, date) VALUES (? , ? , ? , ?, ?)";
SQLiteStatement statement = articlesDB.compileStatement(sql);
statement.bindString(1, articleId);
statement.bindString(2, articleURL);
statement.bindString(3, articleTitle);
statement.bindString(4, articleAuthor);
statement.bindString(5, formattedarticleDate);
statement.execute();
}
}catch (Exception e) {
e.printStackTrace();
}
return result;
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
tasks.remove(this);
if (tasks.size() == 0) {
av.setVisibility(View.INVISIBLE);
}
updateDisplay();
}
}
private List<Information> getData() {
/*List<Information> data=new ArrayList<>();
for(int i=0;i<20;i++){
titles.add(i,"Wikileaks Asssange wins UN ruling on arbitrary detention");
url.add(i,"https://www.google.co.in/search?q=best+custom+list+row");
date.add(i,"3 hrs");
author.add(i,"aburan28");
}
for(int i=0;i<20;i++){
Information current=new Information();
current.title=titles.get(i);
current.url=url.get(i);
current.author=author.get(i);
current.date=date.get(i);
data.add(current);
}
return data;*/
Cursor c = articlesDB.rawQuery("SELECT * FROM article", null);
try {
int urlIndex = c.getColumnIndex("url");
int titleIndex = c.getColumnIndex("title");
int authorIndex = c.getColumnIndex("author");
int dateIndex = c.getColumnIndex("date");
c.moveToFirst();
titles.clear();
//urls.clear();
authors.clear();
dateAndTimes.clear();
int i=0;
while (c != null) {
titles.add(c.getString(titleIndex));
urls.add(c.getString(urlIndex));
authors.add(c.getString(authorIndex));
dateAndTimes.add(c.getString(dateIndex));
Information current=new Information();
current.title=titles.get(i);
current.url=urls.get(i);
current.author=authors.get(i);
current.date = dateAndTimes.get(i);
data.add(current);
i++;
c.moveToNext();
}
}catch (Exception e) {
e.printStackTrace();
}finally {
c.close();
}
return data;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
startActivity(new Intent(getApplicationContext(),SettingsActivity.class));
return true;
}
if (id == R.id.action_about) {
startActivity(new Intent(getApplicationContext(),About.class));
return true;
}
return super.onOptionsItemSelected(item);
}
}
Information.class
package com.reader.ashishyadav271.hackernewsmaterial;
import android.os.Parcel;
import android.os.Parcelable;
public class Information implements Parcelable {
public String title;
public String author;
public String date;
public String url;
public Information(){
}
protected Information(Parcel in) {
title = in.readString();
author = in.readString();
date = in.readString();
url = in.readString();
}
public static final Creator<Information> CREATOR = new Creator<Information>() {
#Override
public Information createFromParcel(Parcel in) {
return new Information(in);
}
#Override
public Information[] newArray(int size) {
return new Information[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(title);
dest.writeString(author);
dest.writeString(date);
dest.writeString(url);
}
}
Log Cat Error
02-06 14:52:58.106 8369-8369/com.reader.ashishyadav271.hackernewsmaterial E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.reader.ashishyadav271.hackernewsmaterial, PID: 8369
java.lang.IndexOutOfBoundsException: Invalid index 0, size is 0
at java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
at java.util.ArrayList.get(ArrayList.java:308)
at com.reader.ashishyadav271.hackernewsmaterial.MainActivity.itemClicked(MainActivity.java:137)
at com.reader.ashishyadav271.hackernewsmaterial.MyCustomAdapter$MyViewHolder.onClick(MyCustomAdapter.java:77)
at android.view.View.performClick(View.java:4471)
at android.view.View$PerformClick.run(View.java:18778)
at android.os.Handler.handleCallback(Handler.java:808)
at android.os.Handler.dispatchMessage(Handler.java:103)
at android.os.Looper.loop(Looper.java:193)
at android.app.ActivityThread.main(ActivityThread.java:5345)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:828)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:644)
at dalvik.system.NativeStart.main(Native Method)
Now I get it after years.I would have simply used.
FLAG_ACTIVITY_CLEAR_TOP - If set, and the activity being launched is already running in the current task, then instead of launching a new instance of that activity, all of the other activities on top of it will be closed and this Intent will be delivered to the (now on top) old activity as a new Intent.