Keeping user logged in with SharedPreferences - java

I have a Java SessionManager class which contains many methods for different login actions with sharedPreferences (such as creating a login session, clearing login session, etc.). I also have a dispatch activity which is launched when the app is run. This dispatch activity calls a method from my SessionManager class to check if a user is currently logged in. If he/she is, and intent takes them to my main activity. Otherwise, the login activity is called where they can then login, etc. However, whenever I run my app, I get an error. My code for my main activity is as follows:
public class MainList extends AppCompatActivity {
RecyclerView gradeList;
SwipeRefreshLayout swipeRefreshLayout;
public SessionManager session;
static String tab1 = "studentdata";
static String tab2 = "gradebook";
static String tab3 = "weeklysummary";
static String action = "form";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main_list);
Log.e("MESSAGE: ", "In second class");
session = new SessionManager(getApplicationContext());
setTheme(R.style.AppTheme);
Toolbar toolbar;
toolbar = (Toolbar)findViewById(R.id.tb);
setSupportActionBar(toolbar);
new infoGetter().execute();
gradeList = (RecyclerView)findViewById(R.id.grade_list);
LinearLayoutManager lm = new LinearLayoutManager(getApplicationContext());
lm.setOrientation(lm.VERTICAL);
gradeList.setLayoutManager(lm);
swipeRefreshLayout = (SwipeRefreshLayout)findViewById(R.id.refresh);
swipeRefreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
#Override
public void onRefresh() {
refreshGrades();
}
});
}
private void refreshGrades(){
new infoGetter().execute();
swipeRefreshLayout.setRefreshing(false);
}
#Override
public void onBackPressed() {
}
#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_list, 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) {
return true;
}
return super.onOptionsItemSelected(item);
}
public class Wrapper{
public Elements gradeList;
}
private class infoGetter extends AsyncTask<Void, Void, Wrapper> {
String studentID = session.getID();
String username = session.getUser();
String password = session.getPass();
#Override
protected Wrapper doInBackground(Void... params) {
Wrapper w = new Wrapper();
String loginURL = "https://parents.mtsd.k12.nj.us/genesis/parents/j_security_check";
String userDataUrl = "https://parents.mtsd.k12.nj.us/genesis/parents?tab1=" + tab1 + "&tab2=" + tab2 + "&tab3=" + tab3 + "&studentid=" + studentID + "&action=" + action;
Connection.Response response = new GradeFetcher().getRequest(userDataUrl);
Document loggedInDocument = new GradeFetcher().postRequest(loginURL, username, password, studentID, response);
Elements grades = new GradeFetcher().gradeExtractor(loggedInDocument);
w.gradeList = grades;
Log.e("MESSAGE: ","Going to onPostExecute");
return w;
}
protected void onPostExecute(Wrapper w) {
ArrayList<String>gl = new ArrayList<>();
for (Element e:w.gradeList){
gl.add(e.text());
}
String[]gradeData = gl.toArray(new String[gl.size()]);
gradeList = (RecyclerView)findViewById(R.id.grade_list);
LinearLayoutManager lm = new LinearLayoutManager(getApplicationContext());
lm.setOrientation(lm.VERTICAL);
gradeList.setLayoutManager(lm);
gradeList.setAdapter(new RecyclerAdapter(gradeData));
}
}
}
and my error is as follows:
08-06 21:34:19.970 2010-2010/com.aurum.gradebook E/MESSAGE:﹕ In second class
08-06 21:34:20.018 2010-2010/com.aurum.gradebook E/RecyclerView﹕ No adapter attached; skipping layout
08-06 21:34:20.035 2010-2010/com.aurum.gradebook E/RecyclerView﹕ No adapter attached; skipping layout
08-06 21:34:20.182 2010-2038/com.aurum.gradebook E/GET REQUEST﹕ Making GET request to gradebook page
08-06 21:34:20.183 2010-2038/com.aurum.gradebook E/AndroidRuntime﹕ FATAL EXCEPTION: AsyncTask #1
Process: com.aurum.gradebook, PID: 2010
java.lang.RuntimeException: An error occured while executing doInBackground()
at android.os.AsyncTask$3.done(AsyncTask.java:304)
at java.util.concurrent.FutureTask.finishCompletion(FutureTask.java:355)
at java.util.concurrent.FutureTask.setException(FutureTask.java:222)
at java.util.concurrent.FutureTask.run(FutureTask.java:242)
at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:231)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
at java.lang.Thread.run(Thread.java:818)
Caused by: java.lang.IllegalArgumentException: Data value must not be null
at org.jsoup.helper.Validate.notNull(Validate.java:26)
at org.jsoup.helper.HttpConnection$KeyVal.value(HttpConnection.java:884)
at org.jsoup.helper.HttpConnection$KeyVal.create(HttpConnection.java:864)
at org.jsoup.helper.HttpConnection.data(HttpConnection.java:131)
at com.aurum.gradebook.GradeFetcher.postRequest(GradeFetcher.java:57)
at com.aurum.gradebook.MainList$infoGetter.doInBackground(MainList.java:124)
at com.aurum.gradebook.MainList$infoGetter.doInBackground(MainList.java:109)
at android.os.AsyncTask$2.call(AsyncTask.java:292)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
            
I have checked through my code multiple times but I cannot find my error. I know it is something to do with my AsycTask my I really don't see where. All help is appreciated and will be rewarded with bounty if possible. I can provide my other code if it is necessary.
My post request:
public Document postRequest(String loginURL, String username, String password, String studentID, Response res) {
Document doc = null;
try {
doc = Jsoup.connect(loginURL)
.userAgent("Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.4 Safari/537.36")
.referrer("https://parents.mtsd.k12.nj.us/genesis/parents?gohome=true")
.cookies(res.cookies())
.data("j_username", username)
.data("j_password", password)
.post();
Log.e("POST REQUEST", "Connecting to login page, posting credentials...");
} catch (IOException ioe) {
ioe.printStackTrace();
}
return doc;
}

I think your username or password is null, please check these values
You can download source code of jsoup at jsoup.org then find that in HttpConnection.java the following code
public KeyVal value(String value) {
Validate.notNull(value, "Data value must not be null");
this.value = value;
return this;
}

Related

Problem with loading data with OkHttp request from static method

I have a problem with my Android app for video games. The problem occurs when I make a call from static method to OkHttp to browse the game reviews.
When the OkHttp request was in the activity it worked fine, but when I moved it to another class in order to have cleaner code in the activity, the app is working strange.
Firstly, when I click the button to get reviews i get null data, but when I click again I get the data from previous click. If I open second game I get reviews from the first, if I open third game I get reviews from the second etc.
I have the same problem for all the API requests in the app.
Gif url from the strange behaviour:
https://thumbs.gfycat.com/OilyHardtofindDutchsmoushond-size_restricted.gif
Snippet of the static method in the Request class:
public class ReviewsRequests {
private static ArrayList<Review> reviews = new ArrayList<>();
private static Gson gson = new Gson();
public static ArrayList<Review> getReviews(int gameId){
OkHttpClient client = new OkHttpClient();
String bodyString = "fields *; where game = " + gameId + ";";
MediaType JSON = MediaType.parse("application/json; charset=utf-8");
RequestBody requestBody = RequestBody.create(bodyString, JSON);
Request request = new Request.Builder()
.url("https://api-v3.igdb.com/private/reviews")
.addHeader("user-key", Helper.API_KEY)
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NotNull Call call, #NotNull IOException e) {
}
#Override
public void onResponse(#NotNull Call call, #NotNull Response response) throws IOException {
if (response.isSuccessful()) {
String jsonString = response.body().string();
Type listType = new TypeToken<ArrayList<Review>>(){}.getType();
reviews = gson.fromJson(jsonString, listType);
}
}
});
return reviews;
}
}
And this is the activity when I show the reviews in the recycler view:
public class ReviewsActivity extends AppCompatActivity {
ArrayList<Review> reviews = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reviews);
Toolbar toolbar = findViewById(R.id.toolbar);
RecyclerView recyclerView = findViewById(R.id.reviews_recycler_view);
TextView noReviewsTV = findViewById(R.id.no_reviews_tv);
int gameId = getIntent().getIntExtra("game_id", 1);
String gameName = getIntent().getStringExtra("game_name");
setSupportActionBar(toolbar);
if(getSupportActionBar() != null) {
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setTitle(gameName);
}
recyclerView.setLayoutManager(new LinearLayoutManager(this, RecyclerView.VERTICAL, false));
ReviewsAdapter adapter = new ReviewsAdapter(this);
recyclerView.setAdapter(adapter);
reviews = ReviewsRequests.getReviews(gameId);
if (reviews.size() != 0) {
adapter.setReviews(reviews);
adapter.notifyDataSetChanged();
} else noReviewsTV.setVisibility(View.VISIBLE);
}
}
You are getting a null value because you are storing the value of "reviews" while making the api call. At that time, the function will return null value for reviews as it might have not got the result from the api. Instead, you just have to call a method of Activity when you get results in the onResponse() method to set the value of "reviews".

Android app using SQLite data "Attempt to invoke virtual method '...' on a null object reference"

I am coding an android app and I am having an issue locating my error. I am trying to get data from an SQLite DB. The app runs normally until I call the activity and it crashes.
Here is the code that I have:
error on line mTerm = mDBHelper.getTerm(((Term) i.getSerializableExtra("term")).getTermId())
Error:
Attempt to invoke virtual method 'int com.example...Term.getTermId()' on a null object reference
Activity
public class TermDetailsActivity extends AppCompatActivity {
private Term mTerm;
private DBOpenHelper mDBHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_term_details);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
setTitle("Term Details");
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
mDBHelper = new DBOpenHelper(this);
Intent i = getIntent();
mTerm = mDBHelper.getTerm(((Term) i.getSerializableExtra("term")).getTermId());
setTextViews();
}
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main_menu, menu);
menu.findItem(R.id.edit).setVisible(true);
return true;
}
private void setTextViews() {
TextView Title = findViewById(R.id.term_details_name_value);
TextView Start = findViewById(R.id.term_start_date_value);
TextView End = findViewById(R.id.term_end_date_value);
Title.setText(mTerm.getTermName());
Start.setText(mTerm.getTermStart());
End.setText(mTerm.getTermEnd());
}
}
My DBHelper extends SQLiteOpenHelper and the tables are created fine. I am able to use the following code to pull data on another activity.
DBHelper
public Term getTerm(int termId) {
Term term;
SQLiteDatabase db = this.getReadableDatabase();
Cursor res = db.rawQuery(
"SELECT * FROM " + TABLE_TERMS + " WHERE " + TERM_ID + " = " +
termId, null);
res.moveToFirst();
term = new Term(
res.getInt(0),
res.getString(1),
res.getString(2),
res.getString(3));
res.close();
return term;
}
Term Class
public class Term implements Serializable {
private int termId;
private String termName;
private String termStart;
private String termEnd;
public Term(int termId, String termName, String termStart, String termEnd){
this.termId = termId;
this.termName = termName;
this.termStart = termStart;
this.termEnd = termEnd;
}
public int getTermId(){
return termId;
}
public void setTermId(int termId){
this.termId = termId;
}
Hi try extracting the Term to a variable before using it in DBHelper. I suspect the extra is missing and when the call to getSerializableExtra returns the getTermId is called on null, causing the Exception.
Edit:
This is what I mean by extracting to a variable:
Intent i = getIntent();
Term term = i.getSerializableExtra("term"); // <- this might be null
// Place a breakpoint on the next line to verify
mTerm = mDBHelper.getTerm(term.getTermId());

Unexpected Crash When trying to open the detailactivity

I am facing a strange problem in my material design app . Some thumbnails are opening and loading details activity as expected , but some are not opening instead there is crash happening . in this video u can see the problem I am facing .
I am attaching the link to my project ZIP file link with this ,My Project
this is the main activity ....
public class MainActivity extends AppCompatActivity implements ReaderAdapter.ReaderOnClickItemHandler {
public final static String READER_DATA = "reader";
public final static String POSITION = "position";
private final static String TAG = MainActivity.class.getSimpleName();
private static final String SAVED_ARRAYLIST = "saved_array_list";
private static final String SAVED_LAYOUT_MANAGER = "layout-manager-state";
private ApiInterface mApiInterface;
private List<Reader> mNetworkDataList;
#BindView(R.id.main_recycler_view)
RecyclerView mRecyclerView;
#BindView(R.id.main_linear_layout)
LinearLayout mErrorLinearLayout;
#BindView(R.id.main_progress_bar)
ProgressBar mProgressBar;
#BindView(R.id.toolbar_main)
Toolbar toolbar;
#BindView(R.id.main_reload_button)
Button mButton;
private ReaderAdapter mReaderAdapter;
private Parcelable onSavedInstanceState = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.bind(this);
if (null != toolbar) {
setSupportActionBar(toolbar);
toolbar.setTitle(getResources().getString(R.string.app_name));
}
mApiInterface = ApiClient.getApiClient().create(ApiInterface.class);
mReaderAdapter = new ReaderAdapter(this, this);
LinearLayoutManager linearLayoutManager = new LinearLayoutManager(this,
LinearLayoutManager.VERTICAL, false);
mRecyclerView.setAdapter(mReaderAdapter);
mRecyclerView.setLayoutManager(linearLayoutManager);
// getting the data from api using retrofit interface ApiInterface
if (savedInstanceState != null) {
onSavedInstanceState = savedInstanceState.getParcelable(SAVED_LAYOUT_MANAGER);
mNetworkDataList = savedInstanceState.getParcelableArrayList(SAVED_ARRAYLIST);
}
if (null == mNetworkDataList) {
loadData();
mButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
loadData();
}
});
}else {
loadAdapter();
}
}
public void loadData() {
final Call<List<Reader>> listCall = mApiInterface.getAllReaderData();
// now binding the data in the pojo class
listCall.enqueue(new Callback<List<Reader>>() {
//if data is successfully binded from json to the pojo class onResponse is called
#Override
public void onResponse(Call<List<Reader>> call,
Response<List<Reader>> response) {
Log.d(TAG, "Response : " + response.code());
mNetworkDataList = response.body();
loadAdapter();
}
//if data binding is not successful onFailed called
#Override
public void onFailure(Call<List<Reader>> call, Throwable t) {
//cancelling the GET data request
listCall.cancel();
showError();
}
});
}
private void loadAdapter() {
if (null != mNetworkDataList) {
showReaderList();
mReaderAdapter.ifDataChanged(mNetworkDataList);
if (onSavedInstanceState != null) {
mRecyclerView.getLayoutManager().onRestoreInstanceState(onSavedInstanceState);
}
}
}
/**
* this method is for showing the error textview and making all other views gone
*/
private void showError() {
mRecyclerView.setVisibility(View.GONE);
mProgressBar.setVisibility(View.GONE);
mErrorLinearLayout.setVisibility(View.VISIBLE);
}
/**
* this method is for showing the recyclerview and making all other views gone
*/
private void showReaderList() {
mRecyclerView.setVisibility(View.VISIBLE);
mProgressBar.setVisibility(View.GONE);
mErrorLinearLayout.setVisibility(View.GONE);
}
private int numberOfColumns() {
DisplayMetrics displayMetrics = new DisplayMetrics();
this.getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
// You can change this divider to adjust the size of the poster
int widthDivider = 400;
int width = displayMetrics.widthPixels;
int nColumns = width / widthDivider;
if (nColumns < 2) return 2;
return nColumns;
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putParcelable(SAVED_LAYOUT_MANAGER, mRecyclerView.getLayoutManager()
.onSaveInstanceState());
if (mNetworkDataList != null)
outState.putParcelableArrayList(SAVED_ARRAYLIST, new ArrayList<Parcelable>(mNetworkDataList));
}
#Override
public void onClickItem(int position, Reader reader, ImageView mImage, TextView mTitle) {
// Check if we're running on Android 5.0 or higher
Intent readerIntent = new Intent(this, ReaderDetailsActivity.class);
Bundle mBundle = new Bundle();
mBundle.putParcelable(READER_DATA, reader);
mBundle.putInt(POSITION, position);
readerIntent.putExtras(mBundle);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// Apply activity transition
ActivityOptionsCompat activityOptions = ActivityOptionsCompat.makeSceneTransitionAnimation(
this,
// Now we provide a list of Pair items which contain the view we can transitioning
// from, and the name of the view it is transitioning to, in the launched activity
new Pair<View, String>(mImage,
ReaderDetailsActivity.VIEW_NAME_HEADER_IMAGE),
new Pair<View, String>(mTitle,
ReaderDetailsActivity.VIEW_NAME_HEADER_TITLE));
ActivityCompat.startActivity(this, readerIntent, activityOptions.toBundle());
} else {
// Swap without transition
startActivity(readerIntent);
}
}
}
this is details activity ......
public class ReaderDetailsActivity extends AppCompatActivity {
private static final String TAG = ReaderDetailsActivity.class.getSimpleName();
private static final String SAVED_ARRAYLIST = "saved_array_list";
private static final String SAVED_LAYOUT_MANAGER = "layout-manager-state";
private final static String ARTICLE_SCROLL_POSITION = "article_scroll_position";
// View name of the header image. Used for activity scene transitions
public static final String VIEW_NAME_HEADER_IMAGE = "detail:header:image";
// View name of the header title. Used for activity scene transitions
public static final String VIEW_NAME_HEADER_TITLE = "detail:header:title";
private int position;
private Reader reader;
private int[] scrollPosition = null;
#BindView(R.id.scrollView_details)
ScrollView mScrollView;
#BindView(R.id.details_fragment_title)
TextView mTitle;
#BindView(R.id.imageView_details)
ImageView mImageView;
#BindView(R.id.textView_author_details)
TextView mAuthor;
#BindView(R.id.textView_published_date)
TextView mPublishDate;
#BindView(R.id.textView_description)
TextView mDescription;
#BindView(R.id.floatingActionButton_Up)
FloatingActionButton mFloatingActionButton;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_reader_details);
ButterKnife.bind(this);
Bundle bundle = getIntent().getExtras();
position=0;
mFloatingActionButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mScrollView.scrollTo(0,0);
}
});
ViewCompat.setTransitionName(mImageView, VIEW_NAME_HEADER_IMAGE);
ViewCompat.setTransitionName(mTitle, VIEW_NAME_HEADER_TITLE);
if (null != bundle) {
position = bundle.getInt(MainActivity.POSITION);
reader = bundle.getParcelable(MainActivity.READER_DATA);
if(null != reader) {
mTitle.setText(reader.getTitle());
mPublishDate.setText(reader.getPublishedDate());
mAuthor.setText(reader.getAuthor());
GlideApp.with(this)
.load(reader.getPhoto())
.into(mImageView);
mDescription.setText(reader.getBody());
}
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
scrollPosition = savedInstanceState.getIntArray(ARTICLE_SCROLL_POSITION);
if (scrollPosition != null) {
mScrollView.postDelayed(new Runnable() {
public void run() {
mScrollView.scrollTo(scrollPosition[0], scrollPosition[0]);
}
}, 0);
}
}
}
Json link I am parsing for this project .
Here is a screen recording of my project where u can see the problem I am facing , recording
this is a console log when I am trying to debug ....
when it is working fine the console log is 08/09 20:31:31: Launching app
No apk changes detected since last installation, skipping installation of /home/soumyajit/AndroidStudioProjects/MaterialReader/app/build/outputs/apk/debug/app-debug.apk
$ adb shell am force-stop lordsomen.android.com.materialreader
$ adb shell am start -n "lordsomen.android.com.materialreader/lordsomen.android.com.materialreader.activities.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
Connecting to lordsomen.android.com.materialreader
Connected to the target VM, address: 'localhost:8601', transport: 'socket'
and when it is crashing the console log is
08/09 20:31:31: Launching app
No apk changes detected since last installation, skipping installation of /home/soumyajit/AndroidStudioProjects/MaterialReader/app/build/outputs/apk/debug/app-debug.apk
$ adb shell am force-stop lordsomen.android.com.materialreader
$ adb shell am start -n "lordsomen.android.com.materialreader/lordsomen.android.com.materialreader.activities.MainActivity" -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -D
Connecting to lordsomen.android.com.materialreader
Connected to the target VM, address: 'localhost:8601', transport: 'socket'
Disconnected from the target VM, address: 'localhost:8601', transport: 'socket'
thanks in advance ..
Maximum Parcelable size should not be exceed 1mb. In you app it is 2.1 Mb. Without passing app date to the next activity you can try to pass item id and load data in next activity. Otherwise you can cache the list data and you can load the data from the local database in the details activity. If you cannot see crash log in android studio it because it set as "show only selected activity". In this case app get close and then this type of logs doesnot show in the android studio. switch that to No Filter and you can see the all logs.

Try to change font in list item and get error with getAssets method (bcs class extends from CursorAdapter)

I am using list. Want to change font in it items. Theres a title textview and description. All views are initialized in adapter and they are final. Adapter extened from CursorAdapter thats why i can't use getAssets method.
So what i should do if im extended from CursorAdapter but at the same time i need to use AppCombat methods as getAssets?
Main activity:
public class CatalogActivity extends AppCompatActivity implements
LoaderManager.LoaderCallbacks<Cursor> {
private static final String TAG = "myLogs";
/** Identifier for the pet data loader */
private static final int LIST_LOADER = 0;
/** Adapter for the ListView */
ListCursorAdapter mCursorAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_catalog);
// Changing font
Log.v(TAG, "--- WE ARE IN CATALOG ACTIVITY ---");
// Setup FAB to open EditorActivity
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(CatalogActivity.this, EditorActivity.class);
startActivity(intent);
}
});
// Find the ListView which will be populated with the list data
ListView listListView = (ListView) findViewById(R.id.list);
// Find and set empty view on the ListView, so that it only shows when the list has 0 items.
View emptyView = findViewById(R.id.empty_view);
listListView.setEmptyView(emptyView);
// Setup an Adapter to create a list item for each row of list data in the Cursor.
// There is no items data yet (until the loader finishes) so pass in null for the Cursor.
mCursorAdapter = new ListCursorAdapter(this, null);
listListView.setAdapter(mCursorAdapter);
// Setup the item click listener
listListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
ShoppingListBdHelper helper = new ShoppingListBdHelper(view.getContext());
if (helper.setCompleted(id)) {
mCursorAdapter.setCompleted(view);
}
}
});
// Kick off the loader
getSupportLoaderManager().initLoader(LIST_LOADER, null, this);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu options from the res/menu/menu_catalog.xml file.
// This adds menu items to the app bar.
getMenuInflater().inflate(R.menu.menu_catalog, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// User clicked on a menu option in the app bar overflow menu
switch (item.getItemId()) {
// Respond to a click on the "Insert dummy data" menu option
case R.id.action_share_button:
shareButton(mCursorAdapter.getCursor());
return true;
// Respond to a click on the "Delete all entries" menu option
case R.id.action_delete_all_entries:
deleteAllItems();
return true;
}
return super.onOptionsItemSelected(item);
}
/**
* Share button
*/
private void shareButton(Cursor cursor) {
Log.v(TAG, "--- WE ARE IN SHARE BUTTON METHOD ---");
List<String> test;
test = new ArrayList<String>();
cursor.moveToFirst();
while(!cursor.isAfterLast()) {
Log.d(TAG, "field: " + cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_NAME)));
test.add(cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_NAME)) + " - " + cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_DESCRIPTION))); //add the item
// test.add(cursor.getString(cursor.getColumnIndex(ListContract.ListEntry.COLUMN_ITEM_DESCRIPTION))); //add the item
cursor.moveToNext();
}
cursor.moveToFirst();
cursor.close();
// for (String comma : )
Log.v(TAG, "--- OUR LIST INCLUDES: " + test.toString());
Intent myIntent = new Intent();
myIntent.setAction(Intent.ACTION_SEND);
myIntent.putStringArrayListExtra("test", (ArrayList<String>) test);
myIntent.putExtra(android.content.Intent.EXTRA_TEXT, test.toString());
Log.v(TAG, "--- INTENT EXTRAS ARE: " + myIntent.getExtras());
myIntent.setType("text/plain");
startActivity(Intent.createChooser(myIntent, "Share using"));
}
/**
* Helper method to delete all list in the database.
*/
private void deleteAllItems() {
Log.v(TAG, "Сработал метод удаления всех данных");
long rowsDeleted = getContentResolver().delete(ListContract.ListEntry.CONTENT_URI, null, null);
Log.v("CatalogActivity", rowsDeleted + " rows deleted from list database");
}
#Override
public Loader<Cursor> onCreateLoader(int i, Bundle bundle) {
Log.v(TAG, "Начал работать loader cursor");
// Define a projection that specifies the columns from the table we care about.
String[] projection = {
ListContract.ListEntry._ID,
ListContract.ListEntry.COLUMN_ITEM_NAME,
ListContract.ListEntry.COLUMN_ITEM_DESCRIPTION,
ListContract.ListEntry.COLUMN_ITEM_COMPLETED
};
// This loader will execute the ContentProvider's query method on a background thread
return new CursorLoader(this, // Parent activity context
ListContract.ListEntry.CONTENT_URI, // Provider content URI to query
projection, // Columns to include in the resulting Cursor
null, // No selection clause
null, // No selection arguments
null); // Default sort order
}
#Override
public void onLoadFinished(Loader<Cursor> loader, Cursor data) {
// Update {#link ListCursorAdapter} with this new cursor containing updated pet data
mCursorAdapter.swapCursor(data);
Log.v(TAG, "Cursor adapter загрузился");
}
#Override
public void onLoaderReset(Loader<Cursor> loader) {
// Callback called when the data needs to be deleted
mCursorAdapter.swapCursor(null);
}
}
List adapter
#Override
public void bindView(View view, Context context, final Cursor cursor) {
// Find individual views that we want to modify in the list item layout
final TextView nameTextView = (TextView) view.findViewById(R.id.name);
final TextView summaryTextView = (TextView) view.findViewById(R.id.summary);
Typeface titleTypeface = Typeface.createFromAsset(getAssets(), "Roboto-Regular.ttf");
Typeface descriptionTypeface = Typeface.createFromAsset(getAssets(), "OpenSans-Italic.ttf");
Log.v(TAG, "--- FONT IS ---" + titleTypeface );
nameTextView.setTypeface(titleTypeface);
summaryTextView.setTypeface(descriptionTypeface);
// Find the columns of pet attributes that we're interested in
int nameColumnIndex = cursor.getColumnIndex(ListEntry.COLUMN_ITEM_NAME);
int breedColumnIndex = cursor.getColumnIndex(ListEntry.COLUMN_ITEM_DESCRIPTION);
// Read the pet attributes from the Cursor for the current pet
String petName = cursor.getString(nameColumnIndex);
String petBreed = cursor.getString(breedColumnIndex);
// If the pet breed is empty string or null, then use some default text
// that says "Unknown breed", so the TextView isn't blank.
if (TextUtils.isEmpty(petBreed)) {
petBreed = context.getString(R.string.unknown_description);
}
// Update the TextViews with the attributes for the current pet
nameTextView.setText(petName);
summaryTextView.setText(petBreed);
view.findViewById(R.id.editImageView).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG, "--- WE ARE IN IMAGEVIEW LISTENER ---");
Intent intent = new Intent(v.getContext(), EditorActivity.class);
// Form the content URI that represents the specific pet that was clicked on,
// by appending the "id" (passed as input to this method) onto the
// {#link PetEntry#CONTENT_URI}.
// For example, the URI would be "content://com.example.android.pets/pets/2"
// if the pet with ID 2 was clicked on.
Uri currentPetUri = ContentUris.withAppendedId(
ListContract.ListEntry.CONTENT_URI,
cursor.getInt(cursor.getColumnIndex(ListEntry._ID))
);
Log.v(TAG, "--- CONTENT URI " + cursor.getInt(cursor.getColumnIndex(ListEntry._ID)));
// Set the URI on the data field of the intent
intent.setData(currentPetUri);
// Launch the {#link EditorActivity} to display the data for the current pet.
v.getContext().startActivity(intent);
}
}
);
view.findViewById(R.id.leftSide).setOnClickListener(
new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.v(TAG, "--- WE ARE IN LEFTSIDE LISTENER ---");
//
// Intent intent = new Intent(v.getContext(), EditorActivity.class);
//
// // Form the content URI that represents the specific pet that was clicked on,
// // by appending the "id" (passed as input to this method) onto the
// // {#link PetEntry#CONTENT_URI}.
// // For example, the URI would be "content://com.example.android.pets/pets/2"
// // if the pet with ID 2 was clicked on.
// Uri currentPetUri = ContentUris.withAppendedId(
// ListContract.ListEntry.CONTENT_URI,
// cursor.getInt(cursor.getColumnIndex(ListEntry._ID))
// );
//
// // Set the URI on the data field of the intent
// intent.setData(currentPetUri);
//
// // Launch the {#link EditorActivity} to display the data for the current pet.
// v.getContext().startActivity(intent);
nameTextView.setPaintFlags(nameTextView.getPaintFlags()| Paint.STRIKE_THRU_TEXT_FLAG);
summaryTextView.setPaintFlags(summaryTextView.getPaintFlags()| Paint.STRIKE_THRU_TEXT_FLAG);
}
}
);
Boolean completed = cursor.getInt(cursor.getColumnIndex(ListEntry.COLUMN_ITEM_COMPLETED)) == 1;
if (completed) {
setCompleted(view);
}
}
Error type 2
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.list, PID: 10811
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.android.list/com.example.android.list.CatalogActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setTypeface(android.graphics.Typeface)' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2665)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6119)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void android.widget.TextView.setTypeface(android.graphics.Typeface)' on a null object reference
at com.example.android.list.CatalogActivity.onCreate(CatalogActivity.java:69)
at android.app.Activity.performCreate(Activity.java:6679)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1118)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2618)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2726) 
at android.app.ActivityThread.-wrap12(ActivityThread.java) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1477) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:154) 
at android.app.ActivityThread.main(ActivityThread.java:6119) 
at java.lang.reflect.Method.invoke(Native Method) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:886) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776) 

How to use multiple adapters on Android

I'm trying to create 2 activities, in the first one I'm showing the "nome" and the "tipo_pessoa" in a listview, I want to show the "cargo" in the second activity. As you can see in my parsed Json, I'm using 2 models, my question is, do I need to use 2 adapters in order to do that? here is what I tried so far:
public void parseJson(JSONObject json) throws JSONException {
try {
JSONArray dados = json.getJSONArray("dados");
feedList = new ArrayList<ClientesModel>();
contatoList = new ArrayList<ClientesContatosModel>();
// parsing json object
for (int i = 0; i < dados.length(); i++) {
JSONObject item = dados.getJSONObject(i);
ClientesModel mClientesModel = new ClientesModel();
mClientesModel.setNome(item.optString("nome"));
mClientesModel.setTipo_pessoa(item.optString("tipo_pessoa"));
mClientesModel.setInformacoes_adicionais(item.optString("informacoes_adicionais"));
mClientesModel.setCpf(item.optString("cpf"));
mClientesModel.setCnpj(item.optString("cnpj"));
JSONArray contatos = item.getJSONArray("contatos");
for (int j = 0; j < contatos.length(); j++) {
JSONObject data = contatos.getJSONObject(j);
ClientesContatosModel mClientesContatoModel = new ClientesContatosModel();
contatoList.add(mClientesContatoModel);
mClientesContatoModel.setNomeContato(data.optString("nome"));
mClientesContatoModel.setCargo(data.optString("cargo"));
}
feedList.add(mClientesModel);
System.out.println(contatoList);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
MainActivity:
public void updateList() {
feedListView= (ListView) findViewById(R.id.custom_list);
feedListView.setVisibility(View.VISIBLE);
progressbar.setVisibility(View.GONE);
feedListView.setAdapter(new CustomListAdapter(this, feedList));
feedListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
ntent intent = new Intent(FeedListActivity.this, FeedDetailsActivity.class);
intent.putExtra("data", contatoList);
startActivity(intent);
}
});
}
the second Activity:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_feed_details);
ListView lv = (ListView) findViewById(R.id.listViewContatos);
lv.setAdapter(new ContatosListAdapter(this, contatoList));
feed = (ClientesContatosModel) this.getIntent().getSerializableExtra("data");
TextView title = (TextView) findViewById(R.id.textView);
title.setText(feed.getNomeContato());
}
Now here is my log:
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.javatechig.feedreader/com.javatechig.feedreader.FeedDetailsActivity}: java.lang.NullPointerException
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2198)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257)
at android.app.ActivityThread.access$800(ActivityThread.java:139)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5086)
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:785)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.NullPointerException
at com.javatechig.feedreader.ContatosListAdapter.getCount(ContatosListAdapter.java:33)
at android.widget.ListView.setAdapter(ListView.java:480)
at com.javatechig.feedreader.FeedDetailsActivity.onCreate(FeedDetailsActivity.java:33)
java line 33 is : lv.setAdapter(new ContatosListAdapter(this, contatoList));
The data from your first activity is not completely passed into the second activity. The error is from contatoList being null, which appears to be populated in the MainActivity, but only the feed data is passed using the intent.
You need to find a way to pass the contatoList data to your second activity as well. One way to do this is to pass your JSON string as an Extra in the second activity launch Intent (if it is not too large) just like you are passing "nome" and re-parse is in the second activity.
You could also store the data using Sqlite or even SharedPreferences.
And if you have two different displays, then you will need two different adapters.
I could solve it:
public void updateList() {
feedListView= (ListView) findViewById(R.id.custom_list);
feedListView.setVisibility(View.VISIBLE);
progressbar.setVisibility(View.GONE);
feedListView.setAdapter(new CustomListAdapter(this, feedList));
final ListView V = (ListView) findViewById(R.id.contato_list);
//V.setVisibility(View.VISIBLE);
V.setAdapter(new ContatosListAdapter(this, contatoList));
feedListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int position, long id) {
Object o = V.getItemAtPosition(position);
ClientesContatosModel newsData = (ClientesContatosModel) o;
Intent intent = new Intent(FeedListActivity.this, FeedDetailsActivity.class);
intent.putExtra("feed", newsData);
startActivity(intent);
}
});
}

Categories

Resources