I'm using SQlite database to store my listview data.
I added opportunities to change listview items, delete them by swiping etc. Everything works fine when I run my app using IDE - data can be deleted or changed, but when I'm trying to restart it using my phone, I get this error:
02-04 22:13:03.276 31682-31682/com.example.jeavie.deadlineyesterday E/InputEventReceiver: Exception dispatching input event.
02-04 22:13:03.276 31682-31682/com.example.jeavie.deadlineyesterday E/MessageQueue-JNI: Exception in MessageQueue callback: handleReceiveCallback
02-04 22:13:03.278 31682-31682/com.example.jeavie.deadlineyesterday E/MessageQueue-JNI: android.database.CursorIndexOutOfBoundsException: Index 0 requested, with a size of 0
at android.database.AbstractCursor.checkPosition(AbstractCursor.java:468)
at android.database.AbstractWindowedCursor.checkPosition(AbstractWindowedCursor.java:136)
at android.database.AbstractWindowedCursor.getString(AbstractWindowedCursor.java:50)
at com.example.jeavie.deadlineyesterday.MainActivity$2.onTouch(MainActivity.java:411)
at android.view.View.dispatchTouchEvent(View.java:11772)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2962)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2643)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2968)
at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2657)
at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:448)
at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1829)
at android.app.Activity.dispatchTouchEvent(Activity.java:3307)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:68)
at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:410)
at android.view.View.dispatchPointerEvent(View.java:12015)
at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4795)
at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4609)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4293)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4350)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4200)
at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4166)
at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4174)
at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4147)
at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6661)
at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6635)
at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6596)
at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6764)
at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:325)
at android.os.Looper.loop(Looper.java:142)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.
My MainActivity class:
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener {
public final static int INTENT_REQUEST_CODE = 1;
public final static int INTENT_REQUEST_CODE_TWO = 2;
public static int INTENT_RESULT_CODE = 1;
public static int INTENT_RESULT_CODE_TWO = 2;
public final static int INTENT_EMPTY_CODE = 0;
public static Integer listNumber = 0;
public static Integer dataNumber = 1;
public static Integer editNumber = 1;
//Swiping
private boolean mSwiping = false; // detects if user is swiping on ACTION_UP
private boolean mItemPressed = false; // Detects if user is currently holding down a view
private ListView listView;
DeadlineActivityAdapter deadlineActivityAdapter;
List<DeadlineActivity> list;
String summary, getData, getTime;
DbActivity db;
Cursor fullData;
boolean full;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main_drawer);
db = new DbActivity(this);
fullData = db.getAllData();
if (fullData.getCount() > 0){
if (fullData.moveToFirst()) {
list = new ArrayList<>();
do {
String check = fullData.getString(7);
if (check.startsWith("li")){
summary=fullData.getString(2);
getData=fullData.getString(3);
getTime=fullData.getString(4);
String deadline=fullData.getString(5);
String tags=fullData.getString(6);
list.add(new DeadlineActivity(String.valueOf(dataNumber - 1), summary, getData, getTime, deadline,
tags));
full = true;
listNumber++;
}
} while (fullData.moveToNext());
}
}
if (!full) list = new ArrayList<>();
Toolbar toolbar = findViewById(R.id.toolbar_main);
setSupportActionBar(toolbar);
FloatingActionButton addTask = findViewById(R.id.addTask);
addTask.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(MainActivity.this, AddTaskActivity.class);
startActivityForResult(intent, INTENT_REQUEST_CODE);
}
});
DrawerLayout drawerLayout = findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawerLayout, toolbar, R.string.open, R.string.close);
drawerLayout.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = findViewById(R.id.navigation);
navigationView.setNavigationItemSelectedListener(this);
listView = findViewById(R.id.listDeadlines);
TextView emptyText = findViewById(android.R.id.empty);
listView.setEmptyView(emptyText);
deadlineActivityAdapter = new DeadlineActivityAdapter(this, list, mTouchListener);
listView.setAdapter(deadlineActivityAdapter);
}
#Override
protected void onActivityResult (int requestCode, int resultCode, Intent data) {
if (requestCode == INTENT_RESULT_CODE){
if(resultCode == INTENT_RESULT_CODE) {
Cursor newDeadline = db.getAllData();
newDeadline.moveToLast();
summary=newDeadline.getString(2);
getData=newDeadline.getString(3);
getTime=newDeadline.getString(4);
String deadline=newDeadline.getString(5);
String tags=newDeadline.getString(6);
list.add(new DeadlineActivity(String.valueOf(dataNumber), summary, getData, getTime, deadline,
tags));
dataNumber++;
deadlineActivityAdapter.notifyDataSetChanged();
super.onActivityResult(requestCode, resultCode, data);
}
}
else if (requestCode == INTENT_RESULT_CODE_TWO){
if (resultCode == INTENT_RESULT_CODE_TWO) {
String a = list.get(editNumber).getId();
Cursor newDeadline = db.getData(a);
String id = newDeadline.getString(0);
summary=newDeadline.getString(1);
getData=newDeadline.getString(2);
getTime=newDeadline.getString(3);
String deadline=newDeadline.getString(4);
String tags=newDeadline.getString(5);
list.remove(Integer.valueOf(id) - 1);
list.add(Integer.valueOf(id) - 1, new DeadlineActivity(id, summary, getData, getTime, deadline, tags));
deadlineActivityAdapter.notifyDataSetChanged();
}
}
}
#Override
public void onBackPressed() {
DrawerLayout drawer = findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()){
case R.id.toWeek:
startActivity(new Intent(this, WeekActivity.class));
return true;
case R.id.history:
startActivity(new Intent(this, HistoryActivity.class));
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.tags:
startActivity(new Intent(this, TagsActivity.class));
return true;
case R.id.notifications:
// startActivity(new Intent(this, HistoryActivity.class));
return true;
case R.id.info:
// startActivity(new Intent(this, HistoryActivity.class));
return true;
}
DrawerLayout drawer = findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
private View.OnTouchListener mTouchListener = new View.OnTouchListener()
{
float mDownX;
private int mSwipeSlop = -1;
boolean swiped;
#Override
public boolean onTouch(final View v, MotionEvent event) {
if (mSwipeSlop < 0) {
mSwipeSlop = ViewConfiguration.get(MainActivity.this).getScaledTouchSlop();
}
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mItemPressed) return false; // Doesn't allow swiping two items at same time
mItemPressed = true;
mDownX = event.getX();
swiped = false;
break;
case MotionEvent.ACTION_CANCEL:
v.setTranslationX(0);
mItemPressed = false;
break;
case MotionEvent.ACTION_MOVE:
{
float x = event.getX() + v.getTranslationX();
float deltaX = x - mDownX;
float deltaXAbs = Math.abs(deltaX);
if (!mSwiping) {
if (deltaXAbs > mSwipeSlop) {
mSwiping = true; // tells if user is actually swiping or just touching in sloppy manner
listView.requestDisallowInterceptTouchEvent(true);
}
}
if (mSwiping && !swiped) { // Need to make sure the user is both swiping and has not already completed a swipe action (hence mSwiping and swiped)
v.setTranslationX((x - mDownX)); // moves the view as long as the user is swiping and has not already swiped
if (deltaX > v.getWidth() / 3) { // swipe to right
mDownX = x;
swiped = true;
mSwiping = false;
mItemPressed = false;
v.animate().setDuration(300).translationX(v.getWidth()/3);
int i = listView.getPositionForView(v);
String a = list.get(i).getId();
Cursor newDeadline = db.getData(a);
String id = newDeadline.getString(0);
summary=newDeadline.getString(1);
getData=newDeadline.getString(2);
getTime=newDeadline.getString(3);
String deadline=newDeadline.getString(4);
String tags=newDeadline.getString(5);
boolean isInserted = db.updateData(id, id, summary, getData, getTime, deadline, tags, "history");
if (isInserted)
Toast.makeText(getApplicationContext(), "Deadline completed", Toast.LENGTH_SHORT).show();
list.remove(i);
deadlineActivityAdapter.notifyDataSetChanged();
return true;
}
else if (deltaX < -1 * (v.getWidth() / 3)) { // swipe to left
mDownX = x;
swiped = true;
mSwiping = false;
mItemPressed = false;
v.animate().setDuration(300).translationX(-v.getWidth()/3);
int i = listView.getPositionForView(v);
String a = list.get(i).getId();
Cursor newDeadline = db.getData(a);
String id = newDeadline.getString(0);
summary=newDeadline.getString(1);
getData=newDeadline.getString(2);
getTime=newDeadline.getString(3);
String deadline=newDeadline.getString(4);
String tags=newDeadline.getString(5);
boolean isInserted = db.updateData(id, id, summary, getData, getTime, deadline, tags, "history");
if (isInserted)
Toast.makeText(getApplicationContext(), "Deadline completed", Toast.LENGTH_SHORT).show();
list.remove(i);
deadlineActivityAdapter.notifyDataSetChanged();
return true;
}
}
}
break;
case MotionEvent.ACTION_UP: {
if (mSwiping) { // if the user was swiping, don't go to the and just animate the view back into position
v.animate().setDuration(300).translationX(0).withEndAction(new Runnable() {
#Override
public void run() {
mSwiping = false;
mItemPressed = false;
listView.setEnabled(true);
}
});
}
else { // user was not swiping; registers as a click
//set item click "animation"
ColorDrawable[] color = {
new ColorDrawable(getColor(R.color.grey)),
new ColorDrawable(getColor(R.color.dark_dark_grey))
};
TransitionDrawable trans = new TransitionDrawable(color);
v.setBackground(trans);
trans.startTransition(1000); // duration 2 seconds
// Go back to the default background color of Item
ColorDrawable[] color2 = {
new ColorDrawable(getColor(R.color.dark_dark_grey)),
new ColorDrawable(getColor(R.color.the_darkest_grey))
};
TransitionDrawable trans2 = new TransitionDrawable(color2);
v.setBackground(trans2);
trans2.startTransition(1000); // duration 2 seconds
editNumber = listView.getPositionForView(v);
String a = list.get(editNumber).getId();
Cursor newDeadline = db.getData(a);
String id = newDeadline.getString(0);
Intent intent = new Intent();
intent.putExtra("number", id);
intent.setClass(MainActivity.this, EditTaskActivity.class);
startActivityForResult(intent, INTENT_REQUEST_CODE_TWO);
mItemPressed = false;
listView.setEnabled(true);
return true;
}
}
default:
return false;
}
return true;
}
};
}
I added OnTouch method.
At a guess you may be a little confused with how to handle cursors.
The rule so very often found as broken is that a Cursor, unless specifically set to null, will NEVER be null. Any check for a null Cursor is more than likely unnecessary.
Additionally moveToFirst without then doing something with that first row may well result in handling issues.
As such I'd suggest that you change the getData method to be something like :-
public Cursor getData(String id) {
SQLiteDatabase db = this.getReadableDatabase();
return dq.query(true,
new String[] { DB_NUMBER, DB_SUMMARY,
DB_DATE, DB_TIME, DB_DEADLINE, DB_TAGS},
DB_ID + "=?",
new String[]{id},
null,null,null,null
);
}
i.e. just return the cursor as the null check is useless, moveToFirst is quite likely to result in issues.
In the code that calls the getData method, as it's finding by id and thus only find 1 row then :-
Cursor csr = mydbhlpr.getData();
if(csr.moveToFirst) {
//your code to retrieve and act upon the data from the cursor
} else {
//your code, if needed, to handle no row being found.
}
My guess is that you've assumed done something like :-
Cursor csr = mydbhlpr.getData(); // assuming it is not empty and moved to first row
String mydata = csr.getString(whatever_column_offset);
Note, this is just guessing at what your issue may be (see comment re adding onTouch)
your data base is empty and you are requesting for a row from it
that's what the error says
populate your database before querying it for rows
else include a if statement by checking the cursor size
call the DatabaseHelper insertData function from your MainActivity to populate the database
From your MainActivity you are just querying data from database
I do not see anywhere that you have inserted data to you database
Related
I have two activities that are called DrinksActivity and FoodsActivity. Both have their own RecyclerViews to display items.
They work well, but I have to pass their values to another activity called.. sample_activity.
This is how sample_activity looks like.
public class sample_layout extends AppCompatActivity {
private DrawerLayout dl;
private ActionBarDrawerToggle t;
private NavigationView nv;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.sample_layout);
SetTexts();
Navigation();
TextView textView = findViewById(R.id.txtFoodName);
Intent intent = getIntent();
DrinksModel drinksM = intent.getParcelableExtra("drinks");
FoodModel foodM = intent.getParcelableExtra("foods");
//how can i set the textView from their own getParcelableExtra values
String FoodName = foodM.getFoodName();
textView.setText(FoodName);
//how can i set the textView from their own getParcelableExtra values
String DrinkName = drinksM.getDrinkName();
textView.setText(DrinkName);
}
public String getName(String email) {
String stringList = null;
DatabaseHelperAccounts db = new DatabaseHelperAccounts(this);
SQLiteDatabase dbb = db.getWritableDatabase();
String selectQuery = "SELECT FullName FROM " + db.DATABASE_TABLE + " WHERE email = '" + email + "'";
Cursor c = dbb.rawQuery(selectQuery, null);
if (c != null) {
c.moveToFirst();
while (c.isAfterLast() == false) {
String name2 = (c.getString(c.getColumnIndex("FullName")));
stringList = name2;
c.moveToNext();
}
}
return stringList;
}
public void SetTexts() {
String StringEmail = LoginFragment.EmailString;
NavigationView nav_view = (NavigationView) findViewById(R.id.nv);//this is navigation view from my main xml where i call another xml file
View header = nav_view.getHeaderView(0);//set View header to nav_view first element (i guess)
TextView UserFullNameNav = (TextView) header.findViewById(R.id.UserFullNameNav);//now assign textview imeNaloga to header.id since we made View header.
TextView UserEmailNav = (TextView) header.findViewById(R.id.UserEmailNav);
getName(StringEmail);
UserEmailNav.setText(StringEmail);// And now just set text to that textview
UserFullNameNav.setText(getName(StringEmail));
}
public void Navigation() {
dl = findViewById(R.id.sampleLayout);
t = new ActionBarDrawerToggle(this, dl, R.string.open, R.string.close);
dl.addDrawerListener(t);
t.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
nv = findViewById(R.id.nv);
nv.setNavigationItemSelectedListener(new NavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
switch (id) {
case R.id.itemDrinks:
Intent DrinksIntent = new Intent(getApplicationContext(), DrinksActivity.class);
startActivity(DrinksIntent);
break;
case R.id.itemFoods:
Intent FoodsIntent = new Intent(getApplicationContext(), FoodsActivity.class);
startActivity(FoodsIntent);
break;
case R.id.itmLogout:
Intent LogOut = new Intent(getApplicationContext(), MainActivity.class);
startActivity(LogOut);
finish();
default:
return true;
}
return true;
}
});
}
#Override
public boolean onOptionsItemSelected(#NonNull 'MenuItem' item)
{
if ( t.onOptionsItemSelected(item))
return true;
return super.onOptionsItemSelected(item);
}
}
How can I get the value of the item when it is chosen from the recyclerview of that specific activity?
Try to use this
if (getIntent()!=null ){
if (getIntent.hasExtra("drinks")){
DrinksModel drinksM = intent.getParcelableExtra("drinks");
String DrinkName = drinksM.getDrinkName();
textView.setText(DrinkName);
}else if(getIntent.hasExtra("foods")){
FoodModel foodM = intent.getParcelableExtra("foods");
String FoodName = foodM.getFoodName();
textView.setText(FoodName);
}
}
As I can see you're using database to store data, right? If so, the best (and the most correct) way is to pass some identifier between activity (like "id") and then get value by that id from database where you need. But, if you really want to pass the whole object then you need to use serializable or parcelable (parcelable is better choice since it's from Android SDK). Then in the activity where you're getting the value just parse it.
EDIT:
To get parcelable value call:
Food food = getIntent().getExtras().getParcelable("food");
Then just call:
textView.setText(food.getYourField);
I have a list of threads which I have paginated to use an endless scroll the issue I'm having (well my users) is an OutOfMemoryError: Failed to allocate a [x] byte allocation with [y] free bytes and [z] until OOM. the x, y and z attribute is different per user but the cause of the bug is always in the same place and it's when I refresh the posts. I'm completely out of my depth here as I have no idea how to optimise my code or make it so this doesn't happen. As it's the biggest crash on my app at the moment. I've posted my PostFragment below please see the refreshPosts(ArrayList<Posts> newObjects) method as this is where the crash is happening.
public class PostFragment extends Fragment implements View.OnClickListener {
private View mRootView;
private GridLayoutManager mLayoutManager;
private ThreadItem mThreads;
private PostItem mPost;
private PostAdapter mAdapter;
private PostResponse mData;
private EmoticonResponse mEmoticon;
private PostFeedDataFactory mDataFactory;
private EmoticonFeedDataFactory mEmoticonDataFactory;
private static PostFragment mCurrentFragment;
private int REQUEST_CODE;
//Flip
private boolean isFlipped = false;
private Animation flipAnimation;
#BindView(R.id.postsRecyclerView)
RecyclerView mRecyclerView;
#BindView(R.id.toolbarForPosts)
Toolbar mToolbar;
#BindView(R.id.threadText)
TextView mThreadText;
#BindView(R.id.flipText)
TextView mFlipTextView;
#BindView(R.id.shareText)
TextView mShareTextView;
#BindView(R.id.replyText)
TextView mReplyTextView;
#BindView(R.id.scrimColorView)
View mBackgroundView;
#BindView(R.id.fabMenu)
FloatingActionButton mFabMenu;
#BindView(R.id.flipFab)
FloatingActionButton mFlipFab;
#BindView(R.id.shareFab)
FloatingActionButton mShareFab;
#BindView(R.id.replyFab)
FloatingActionButton mReplyFab;
//Collapsing Toolbar
#BindView(R.id.postParentAppBarLayout)
AppBarLayout postAppBarLayout;
#BindView(R.id.postCollapseToolbar)
CollapsingToolbarLayout postCollapseToolbarLayout;
#BindView(R.id.mainImageContainer)
ViewGroup mainContainer;
//Back to top
#BindView(R.id.backToTopButton)
Button mBackToTop;
public static boolean isFromReply;
//FAB
private boolean mIsFabOpen = false;
private Animation fab_open, fab_close, rotate_forward, rotate_backward;
//Pagination
private int mCurrentPage = 1;
private ArrayList<Posts> postList = new ArrayList<>();
private boolean mIsLoading = false;
private boolean mIsLastPage = false;
public static PostFragment newInstance(#NonNull ThreadItem threadItem) {
Bundle args = new Bundle();
args.putParcelable("ThreadItem", Parcels.wrap(threadItem));
mCurrentFragment = new PostFragment();
mCurrentFragment.setArguments(args);
isFromReply = false;
return mCurrentFragment;
}
public static PostFragment newPostInstance(#NonNull PostItem postItem) {
Bundle args = new Bundle();
args.putParcelable("PostItemFromCompose", Parcels.wrap(postItem));
mCurrentFragment = new PostFragment();
mCurrentFragment.setArguments(args);
isFromReply = true;
return mCurrentFragment;
}
public PostFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mRootView = inflater.inflate(R.layout.fragment_post, container, false);
if (savedInstanceState == null) {
ButterKnife.bind(this, mRootView);
initUI();
}
return mRootView;
}
private void initUI() {
//UI Setup
mLayoutManager = new GridLayoutManager(getActivity(), 1);
mRecyclerView.setLayoutManager(mLayoutManager);
mDataFactory = new PostFeedDataFactory(getActivity());
mEmoticonDataFactory = new EmoticonFeedDataFactory(getActivity());
TextView textThreadTopic = (TextView) mRootView.findViewById(R.id.threadTopic);
TextView textNumPosts = (TextView) mRootView.findViewById(R.id.numPosts);
//FAB onClick Set-Up
mFabMenu.setOnClickListener(this);
mShareFab.setOnClickListener(this);
mReplyFab.setOnClickListener(this);
mFlipFab.setOnClickListener(this);
//FAB Animation Set up
fab_open = AnimationUtils.loadAnimation(getActivity().getApplicationContext(),
R.anim.fab_open);
fab_close = AnimationUtils.loadAnimation(getActivity().getApplicationContext(),
R.anim.fab_close);
rotate_forward = AnimationUtils.loadAnimation(getActivity().getApplicationContext(),
R.anim.rotate_forward);
rotate_backward = AnimationUtils.loadAnimation(getActivity().getApplicationContext(),
R.anim.rotate_backward);
//Toolbar
((AppCompatActivity) getActivity()).setSupportActionBar(mToolbar);
((AppCompatActivity) getActivity()).getSupportActionBar().setDisplayShowTitleEnabled(false);
mToolbar.setNavigationIcon(R.drawable.ic_back_white);
mToolbar.invalidate();
mToolbar.setNavigationOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
getActivity().finish();
}
});
//Load Parcel
Intent intent = getActivity().getIntent();
mThreads = Parcels.unwrap(getArguments().getParcelable("ThreadItem"));
mPost = Parcels.unwrap(getArguments().getParcelable("PostItemFromCompose"));
if (mThreads != null) {
if (mThreads.getName() != null) {
mThreadText.setText(mThreads.getName());
}
if (mThreads.getTopic_name() != null) {
textThreadTopic.setText(mThreads.getTopic_name());
}
if (mThreads.getNum_posts() != null) {
int numPosts = Integer.parseInt(mThreads.getNum_posts());
if (numPosts > 1000) {
textNumPosts.setText("1K");
} else {
textNumPosts.setText(mThreads.getNum_posts());
}
}
}
postAppBarLayout.addOnOffsetChangedListener(new AppBarLayout.OnOffsetChangedListener() {
boolean isShow = false;
int scrollRange = -1;
#Override
public void onOffsetChanged(AppBarLayout appBarLayout, int verticalOffset) {
if (scrollRange == -1) {
scrollRange = appBarLayout.getTotalScrollRange();
}
if (scrollRange + verticalOffset == 0) {
postCollapseToolbarLayout.setTitle("Threads");
mainContainer.setVisibility(View.INVISIBLE);
isShow = true;
} else if (isShow) {
postCollapseToolbarLayout.setTitle("");
isShow = false;
mainContainer.setVisibility(View.VISIBLE);
}
}
});
flipAnimation =
AnimationUtils.loadAnimation(getActivity().getApplicationContext(), R.anim.flip);
loadData(true, 1);
}
private void loadData(final boolean firstLoad, int readDirection) {
if (isFromReply) {
if (mPost.getThread_id() != null) {
mDataFactory.getPostFeed(mPost.getThread_id(), readDirection, mCurrentPage,
new PostFeedDataFactory.PostFeedDataFactoryCallback() {
#Override
public void onPostDataReceived(PostResponse response) {
mData = response;
if (mData.getItems() != null) {
for (int i = 0; i < mData.getItems().size(); i++) {
Posts singlePost = response.getItems().get(i);
postList.add(singlePost);
}
if (firstLoad) {
mIsLoading = false;
mData.getItems().clear();
mData.getItems().addAll(postList);
mEmoticonDataFactory.getEmoticonFeed(
new EmoticonFeedDataFactory.EmoticonFeedDataFactoryCallback() {
#Override
public void onEmoticonDataReceived(EmoticonResponse response) {
mEmoticon = response;
populateUIWithData();
}
#Override
public void onEmoticonDataFailed(Exception exception) {
}
});
} else {
mIsLoading = false;
refreshPosts(postList);
}
if (mData.getItems().size() > 0) {
if (Integer.valueOf(mData.getTotalPosts()) >= response.getItems().size()) {
mCurrentPage++;
} else {
mIsLastPage = true;
}
}
}
}
#Override
public void onPostDataFailed(Exception exception) {
customToast("Error: " + exception.toString());
}
});
}
} else {
if (mThreads.getId() != null)
mDataFactory.getPostFeed(mThreads.getId(), readDirection, mCurrentPage,
new PostFeedDataFactory.PostFeedDataFactoryCallback() {
#Override
public void onPostDataReceived(PostResponse response) {
mData = response;
if (mData.getItems() != null) {
for (int i = 0; i < mData.getItems().size(); i++) {
Posts singlePost = response.getItems().get(i);
postList.add(singlePost);
}
if (firstLoad) {
mIsLoading = false;
mData.getItems().clear();
mData.getItems().addAll(postList);
mEmoticonDataFactory.getEmoticonFeed(
new EmoticonFeedDataFactory.EmoticonFeedDataFactoryCallback() {
#Override
public void onEmoticonDataReceived(EmoticonResponse response) {
mEmoticon = response;
populateUIWithData();
}
#Override
public void onEmoticonDataFailed(Exception exception) {
}
});
} else {
mIsLoading = false;
refreshPosts(postList);
}
if (mData.getItems().size() > 0) {
if (Integer.valueOf(mData.getTotalPosts()) >= response.getItems().size()) {
mCurrentPage++;
} else {
mIsLastPage = true;
}
}
}
}
#Override
public void onPostDataFailed(Exception exception) {
customToast("Error: " + exception.toString());
}
});
}
}
private void populateUIWithData() {
ImageButton moreOptionsButton = (ImageButton) mRootView.findViewById(R.id.moreOptions);
moreOptionsButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
PopupMenu popupMenu = new PopupMenu(v.getContext(), v);
popupMenu.inflate(R.menu.thread_options);
popupMenu.getMenu();
popupMenu.setOnMenuItemClickListener(new PopupMenu.OnMenuItemClickListener() {
#Override
public boolean onMenuItemClick(MenuItem item) {
switch (item.getItemId()) {
case R.id.watch:
WatchedThreadsRequestData watchedThreadsRequestData = new WatchedThreadsRequestData(getActivity());
watchedThreadsRequestData.setWatchedThread(mThreads.getId(), new WatchedThreadsRequestData.WatchedThreadsFeedback() {
#Override
public void onWatchedRequestReceived(ThreadResponse response) {
customToast("Thread watched");
}
#Override
public void onWatchedRequestFailed(Exception exception) {
customToast("Thread wasn't watched: " + exception.toString());
}
});
return true;
case R.id.shareThread:
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.putExtra(Intent.EXTRA_TEXT, mThreads.getName() + " - " + Constants.LIVE_URL +
"talk/" + mThreads.getTopic_url() + '/' + mThreads.getThread_url());
sharingIntent.setType("text/plain");
getActivity().startActivity(Intent.createChooser(sharingIntent, "Share via"));
return true;
case R.id.hideThread:
customToast("Hide: coming soon");
return true;
default:
customToast("Somethings Wrong");
return true;
}
}
});
setForceShowIcon(popupMenu);
popupMenu.show();
}
});
if (mAdapter == null) {
mAdapter = new PostAdapter(getActivity(), mData, mEmoticon);
mRecyclerView.setAdapter(mAdapter);
} else {
mAdapter.setData(mData.getItems());
mAdapter.notifyDataSetChanged();
}
mRecyclerView.addOnScrollListener(paginationListener);
}
public static void setForceShowIcon(PopupMenu popupMenu) {
try {
Field[] fields = popupMenu.getClass().getDeclaredFields();
for (Field field : fields) {
if ("mPopup".equals(field.getName())) {
field.setAccessible(true);
Object menuPopupHelper = field.get(popupMenu);
Class<?> classPopupHelper = Class.forName(menuPopupHelper
.getClass().getName());
Method setForceIcons = classPopupHelper.getMethod(
"setForceShowIcon", boolean.class);
setForceIcons.invoke(menuPopupHelper, true);
break;
}
}
} catch (Throwable e) {
e.printStackTrace();
}
}
private RecyclerView.OnScrollListener paginationListener = new RecyclerView.OnScrollListener() {
#Override
public void onScrollStateChanged(RecyclerView recyclerView, int newState) {
super.onScrollStateChanged(recyclerView, newState);
boolean hasEnded = newState == SCROLL_STATE_IDLE;
if (hasEnded) {
mFabMenu.show();
mFabMenu.setClickable(true);
} else {
if (mIsFabOpen)
closeMenu();
mFabMenu.hide();
mFabMenu.setClickable(false);
}
}
#Override
public void onScrolled(RecyclerView recyclerView, int dx, int dy) {
super.onScrolled(recyclerView, dx, dy);
int visibleItemCount = mLayoutManager.getChildCount();
int totalItemCount = mLayoutManager.getItemCount();
int firstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition();
if (!mIsLoading && !mIsLastPage) {
if ((visibleItemCount + firstVisibleItemPosition) >= totalItemCount) {
loadMoreItems();
}
}
//Back to top
if (mLayoutManager.findLastVisibleItemPosition() == totalItemCount - 1) {
mBackToTop.setVisibility(View.VISIBLE);
mBackToTop.setClickable(true);
mBackToTop.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mLayoutManager.scrollToPositionWithOffset(0,0);
}
});
} else {
mBackToTop.setVisibility(View.GONE);
mBackToTop.setClickable(false);
}
}
};
private void loadMoreItems() {
if (!isFlipped) {
mIsLoading = true;
loadData(false, 1);
} else {
mIsLoading = true;
loadData(false, -1);
}
}
private void refreshPosts(ArrayList<Posts> newObjects) {
postList.addAll(newObjects);
populateUIWithData();
}
#Override
public void onClick(View v) {
int id = v.getId();
switch (id) {
case R.id.fabMenu:
animateFAB();
break;
case R.id.shareFab:
share();
break;
case R.id.replyFab:
reply();
break;
case R.id.flipFab:
flip();
break;
}
}
public void animateFAB() {
if (mIsFabOpen) {
closeMenu();
} else {
mFabMenu.startAnimation(rotate_forward);
mReplyFab.startAnimation(fab_open);
mShareFab.startAnimation(fab_open);
mFlipFab.startAnimation(fab_open);
mReplyFab.setClickable(true);
mShareFab.setClickable(true);
mFlipFab.setClickable(true);
mFlipTextView.setVisibility(View.VISIBLE);
mShareTextView.setVisibility(View.VISIBLE);
mReplyTextView.setVisibility(View.VISIBLE);
mBackgroundView.setVisibility(View.VISIBLE);
mIsFabOpen = true;
}
}
private void closeMenu() {
mFabMenu.startAnimation(rotate_backward);
mReplyFab.startAnimation(fab_close);
mShareFab.startAnimation(fab_close);
mFlipFab.startAnimation(fab_close);
mReplyFab.setClickable(false);
mShareFab.setClickable(false);
mFlipFab.setClickable(false);
mFlipTextView.setVisibility(View.INVISIBLE);
mShareTextView.setVisibility(View.INVISIBLE);
mReplyTextView.setVisibility(View.INVISIBLE);
mBackgroundView.setVisibility(View.INVISIBLE);
mIsFabOpen = false;
}
private void reply() {
PreferenceConnector.writeString(getActivity().getApplicationContext(), "threadID", mThreads.getId());
PreferenceConnector.writeString(getActivity().getApplicationContext(), "threadTitle", mThreads.getName());
if (PreferenceConnector.readString(getActivity(), "authToken") == null ||
PreferenceConnector.readString(getActivity(), "authToken").equalsIgnoreCase("skip")) {
final AlertDialog.Builder loginDialog = new AlertDialog.Builder(getActivity());
loginDialog.setTitle("Please log in");
loginDialog.setMessage("You need to be logged in to reply");
loginDialog.setPositiveButton("Log in", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(getActivity().getApplicationContext(), LoginActivity.class);
startActivity(intent);
}
});
loginDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
}
});
loginDialog.show();
} else {
closeMenu();
Intent intent = new Intent(getActivity().getApplicationContext(), NewPostActivity.class);
intent.putExtra("Threads", Parcels.wrap(mThreads));
getActivity().finish();
startActivityForResult(intent, REQUEST_CODE);
}
}
private void share() {
Intent sharingIntent = new Intent(Intent.ACTION_SEND);
sharingIntent.putExtra(Intent.EXTRA_TEXT, mThreads.getName() + " - " + Constants.LIVE_URL +
"talk/" + mThreads.getTopic_url() + '/' + mThreads.getThread_url());
sharingIntent.setType("text/plain");
startActivity(Intent.createChooser(sharingIntent, "Share via"));
}
private void flip() {
if (!isFlipped) {
mAdapter.clearAll();
isFlipped = true;
mRecyclerView.startAnimation(flipAnimation);
loadData(false, -1);
closeMenu();
} else {
mAdapter.clearAll();
isFlipped = false;
mRecyclerView.startAnimation(flipAnimation);
loadData(true, 1);
closeMenu();
}
}
private void customToast(String toastMessage) {
LayoutInflater inflater = getActivity().getLayoutInflater();
View layout = inflater.inflate(R.layout.custom_toast,
(ViewGroup) getActivity().findViewById(R.id.toastContainer));
TextView customToastText = (TextView) layout.findViewById(R.id.customToastText);
customToastText.setText(toastMessage);
Toast toast = new Toast(getActivity().getApplicationContext());
toast.setGravity(Gravity.BOTTOM, 0, 25);
toast.setDuration(Toast.LENGTH_LONG);
toast.setView(layout);
toast.show();
}
#Override
public void onResume() {
super.onResume();
if (mData != null && mAdapter != null) {
mAdapter.notifyDataSetChanged();
}
getView().setFocusableInTouchMode(true);
getView().requestFocus();
getView().setOnKeyListener(new View.OnKeyListener() {
#Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_UP && keyCode == KeyEvent.KEYCODE_BACK) {
if (mIsFabOpen) {
closeMenu();
} else {
getActivity().finish();
}
return true;
}
return false;
}
});
}
public void updateView() {
mAdapter.notifyDataSetChanged();
}
}
Thanks in advance once again.
Your problem basically boils down to this:
private void refreshPosts(ArrayList<Posts> newObjects) {
postList.addAll(newObjects);
populateUIWithData();
}
The list can only get bigger, never smaller. If the server has lots and lots of posts, then OutOfMemory is pretty much inevitable.
One approach to solving this problem is to use an LRU (Least Recently Used) cache. There is a utility class you can use: android.util.LruCache.
An LRU Cache is essentially a Map. Items are stored with a key, like an ID. With an LRU cache, you put new items in, but once a pre-determined limit is reached, old items start getting pushed out to make room for new items.
This will save memory, but make a lot more management code for you.
Your adapter, instead of having a list of posts, will just have a list of the post IDs. This should be much easier on memory.
As the user scrolls and you collect more posts, you add the post ID to the list, and map the post into the LRU cache using the post ID.
When you bind to the list item view, you look up the post using the post's ID in the LRU cache.
If it's there, great. That's called a cache hit. Bind the post to the
list item view.
If not, then you have a cache miss. You have some work to do.
Start a server request to retrieve the post by ID. I see your current code just retrieves blocks of posts, so you'll need some new server code here.
When the request completes, put the post in the LRU cache and let the adapter know your item has changed using adapter.notifyItemChanged(). Unless the user has scrolled beyond it, the RecyclerView should try to bind with the list item view again. This time, you should get a cache hit.
This is the basic idea. I'd write some code, but I still have a lot of questions since I can't see your model classes, data factories, and adapter class.
Once you have it working, you have to tune the limit on the cache so that it's low enough not to overrun memory, but high enough that your hit/miss ratio isn't close to zero.
BTW, I noticed that you are making the mistake of creating a new adapter and handing it to the RecyclerView each time you get a block of posts. You should create your adapter once, keep a reference to it and update it. Have a method that adds a block of posts then calls notifyDataSetChanged().
Another idea for conserving memory is to use text compression. If the problem is more a result of a large average size of the post rather than a large number of posts, you might explore this idea in addition to the LRU cache.
The concept is that you could take posts over a certain size, write them into a buffer using a ZipOutputStream then save the buffer in memory. When it's time to display the post, you read the buffer with a ZipInputStream to uncompress the text. Here the issue is performance as the compression/decompression is pretty CPU-intensive. But if the problem is really long posts, this approach might be something to consider.
An even better approach: Only save the first part of the post as an "overview" display in the list. When the user clicks on the list item, retrieve the entire post from the server and display that in another page.
I have researched this error on StackOverflow and tried all the suggestions but still have the error. App tries to load and I can see the home screen behind several of the alerts and an error that the app closed.
Things I've tried:
adding to Manifest -
in MainActivity, ensuring I'm using "this" in lieu of other references
adding to AlertDialog -
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
NOTE: I've also commented out out everything from the onCreate() in MainActivity after setContentView(R.layout.activity_main); and still have the error. I suspect the issue is directly related to how I'm using my fragment and the tjerk. ActionSlideExpandableListView menu.
My code:
MainActivity
public class MainActivity extends Activity implements DataPasser {
private final String LOGCAT = "MAINACTIVITY.LOGCAT";
private DrawerLayout mDrawerLayout;
Toolbar toolbar;
private ListView mDrawerList;
private ActionBarDrawerToggle mDrawerToggle;
Fragment fragment = null;
// nav drawer title
private CharSequence mDrawerTitle;
// used to store app title
private CharSequence mTitle;
// slide menu items
private String[] navMenuTitles;
private TypedArray navMenuIcons;
Menu menuMain;
private ArrayList<NavDrawerItem> navDrawerItems;
private NavDrawerListAdapter adapter;
// --------------------------------------------------
private final String PREF_NAME = "band_wit";
String firstLaunch = "firstLaunch", itemPosition = "2";
private TCPdump tcpdump = null;
private TCPdumpHandler tcpDumpHandler = null;
static public String local_Ip_Address;
DBHelper dbHelper;
FragmentManager fragmentManager;
private MyReceiver receiver;
private static final int VPN_REQUEST_CODE = 0x0F;
private boolean waitingForVPNStart;
public static String APP_UID;
public static String NETFLIX_APP_UID;
public static String FACEBOOK_APP_UID;
private BroadcastReceiver vpnStateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (LocalVPNService.BROADCAST_VPN_STATE.equals(intent.getAction())) {
if (intent.getBooleanExtra("running", false))
waitingForVPNStart = false;
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
dbHelper = DBHelper.newInstance(this);
local_Ip_Address = getLocalIpAddress();
// Local VPN
LocalBroadcastManager.getInstance(this).registerReceiver(
vpnStateReceiver,
new IntentFilter(LocalVPNService.BROADCAST_VPN_STATE));
// ====
Intent tcp_Dump_Inent = new Intent(MainActivity.this,TcpDumpService.class);
startService(tcp_Dump_Inent);
/* start service for download manager */
startService(new Intent(this, MyDownloaderMangerService.class));
mTitle = mDrawerTitle = getTitle();
// load slide menu items
navMenuTitles = getResources().getStringArray(R.array.nav_drawer_items);
// nav drawer icons from resources
navMenuIcons = getResources()
.obtainTypedArray(R.array.nav_drawer_icons);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
mDrawerList = (ListView) findViewById(R.id.list_slidermenu);
navDrawerItems = new ArrayList<NavDrawerItem>();
// adding nav drawer items to array
// Home
navDrawerItems.add(new NavDrawerItem(navMenuTitles[0], navMenuIcons
.getResourceId(0, -1)));
// Find People
// Photos
navDrawerItems.add(new NavDrawerItem(navMenuTitles[2], navMenuIcons
.getResourceId(2, -1)));
// Communities, Will add a counter here
navDrawerItems.add(new NavDrawerItem(navMenuTitles[3], navMenuIcons
.getResourceId(3, -1)));
// Pages
// Recycle the typed array
navMenuIcons.recycle();
mDrawerList.setOnItemClickListener(new SlideMenuClickListener());
// ** setting the nav drawer list adapter
adapter = new NavDrawerListAdapter(this,
navDrawerItems);
mDrawerList.setAdapter(adapter);
// enabling action bar app icon and behaving it as toggle button
getActionBar().setDisplayHomeAsUpEnabled(true);
getActionBar().setHomeButtonEnabled(true);
mDrawerToggle = new ActionBarDrawerToggle(this, mDrawerLayout,
toolbar,
//R.drawable.ic_drawer,
R.string.app_name,
R.string.app_name)
{
public void onDrawerClosed(View view) {
getActionBar().setTitle(mTitle);
// calling onPrepareOptionsMenu() to show action bar icons
invalidateOptionsMenu();
}
public void onDrawerOpened(View drawerView) {
getActionBar().setTitle(mDrawerTitle);
// calling onPrepareOptionsMenu() to hide action bar icons
invalidateOptionsMenu();
}
};
mDrawerLayout.setDrawerListener(mDrawerToggle);
if (savedInstanceState == null) {
// on first time display view for first nav item
displayView(0);
}
startService(new Intent(this, MyService.class));
// Run when application first time launched
Const.preferences = getSharedPreferences(PREF_NAME, MODE_PRIVATE);
boolean isFirstTime = Const.preferences.getBoolean(firstLaunch, true);
if (isFirstTime) {
Const.preferences.edit().putBoolean(firstLaunch, false).commit();
addBgData(Const.preferences);
setInitialDataBucket();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.splash_screen, null);
builder.setView(view);
dialog = builder.create();
dialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
dialog.show();
}
APP_UID = myAppUid("com.oda.bandwit");
NETFLIX_APP_UID = myAppUid("com.netflix.mediaclient");
FACEBOOK_APP_UID = myAppUid("com.facebook.katana");
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
try {
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
receiver = new MyReceiver();
registerReceiver(receiver, filter);
} catch (Exception e) {
// TODO: handle exception
}
startVPN();
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
try {
unregisterReceiver(receiver);
} catch (Exception e) {
// TODO: handle exception
}
}
/**
* Slide menu item click listener
* */
private class SlideMenuClickListener implements
ListView.OnItemClickListener {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position,
long id) {
// display view for selected nav drawer item
displayView(position);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// toggle nav drawer on selecting action bar app icon/title
if (mDrawerToggle.onOptionsItemSelected(item)) {
return true;
}
int fragment = 0;
Fragment f = this.getFragmentManager().findFragmentById(
R.id.frame_container);
if (f instanceof HomeFragment) {
fragment = 0;
} else if (f instanceof GeneralSettingsFragment) {
fragment = 1;
} else if (f instanceof ApplicationSettinsFragment) {
fragment = 2;
} else if (f instanceof NetworkSettingsFragment) {
fragment = 3;
} else if (f instanceof GraphAnalysisFragment) {
fragment = 4;
}
// Handle action bar actions click
switch (item.getItemId()) {
case R.id.menuToday:
menuMain.findItem(R.id.menuSelectedItem).setTitle("Today");
itemPosition = "0";
displayView(fragment);
return true;
case R.id.menuThisWeek:
menuMain.findItem(R.id.menuSelectedItem).setTitle("Current Week");
itemPosition = "1";
displayView(fragment);
return true;
case R.id.menuThisMonth:
menuMain.findItem(R.id.menuSelectedItem).setTitle("Current Month");
itemPosition = "2";
displayView(fragment);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
/* *
* Called when invalidateOptionsMenu() is triggered
*/
#Override
public boolean onPrepareOptionsMenu(Menu menu) {
menuMain = menu;
// if nav drawer is opened, hide the action items
boolean drawerOpen = mDrawerLayout.isDrawerOpen(mDrawerList);
menuMain.findItem(R.id.menuToday).setVisible(!drawerOpen);
menuMain.findItem(R.id.menuThisWeek).setVisible(!drawerOpen);
menuMain.findItem(R.id.menuThisMonth).setVisible(!drawerOpen);
menuMain.getItem(Integer.parseInt(itemPosition)).setChecked(true);
return super.onPrepareOptionsMenu(menuMain);
}
/**
* Diplaying fragment view for selected nav drawer list item
* */
private void displayView(int position) {
// update the main content by replacing fragments
switch (position) {
case 0:
try {
fragment = new HomeFragment("" + itemPosition);
callFragment(position);
} catch (Exception e) {
e.getMessage();
}
break;
case 1:
fragment = new ApplicationSettinsFragment();
callFragment(position);
break;
case 2:
startActivity(new Intent(MainActivity.this, GraphicalAnalysis.class));
break;
case 3:
sendMail();
break;
case 4:
dialog = new Dialog(MainActivity.this);
Toast.makeText(MainActivity.this, "Change Limit", Toast.LENGTH_SHORT).show();
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Set Threshold");
ListView list=new ListView(MainActivity.this);
ArrayAdapter<String>adapter = new ArrayAdapter<String>(MainActivity.this, android.R.layout.simple_list_item_1,
new String[]{"5","10","15","20","25","30","35","40","45","50","55","60","65","70","75","80","85","90","95","100","105","110","115","120","125","130","135","140","145","150","155","160","165","170","175","180","185","190","195","200"});
list.setAdapter(adapter);
list.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> arg0, View arg1,
int position, long arg3) {
Toast.makeText(MainActivity.this,
"Now Threshold " + (position + 1) * 5 +" is set",
Toast.LENGTH_SHORT).show();
LocalVPNService.netFlixMaxVal = (position + 1) * 5;
navDrawerItems.get(4).setCount(""+LocalVPNService.netFlixMaxVal);
MainActivity.this.adapter.notifyDataSetChanged();
if (dialog.isShowing()) {
dialog.dismiss();
}
}
});
builder.setView(list);
dialog=builder.create();
dialog.show();
break;
case 5:
fragment = new WhatsHotFragment();
callFragment(position);
break;
default:
break;
}
}
Dialog dialog;
private void callFragment(int position) {
if (fragment != null) {
fragmentManager = getFragmentManager();
fragmentManager.beginTransaction()
.replace(R.id.frame_container, fragment).commit();
// update selected item and title, then close the drawer
mDrawerList.setItemChecked(position, true);
mDrawerList.setSelection(position);
setTitle(navMenuTitles[position]);
mDrawerLayout.closeDrawer(mDrawerList);
} else {
// error in creating fragment
Log.e("MainActivity", "Error in creating fragment");
}
}
#Override
protected void onPostCreate(Bundle savedInstanceState) {
super.onPostCreate(savedInstanceState);
// Sync the toggle state after onRestoreInstanceState has occurred.
mDrawerToggle.syncState();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
// Pass any configuration change to the drawer toggls
mDrawerToggle.onConfigurationChanged(newConfig);
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == VPN_REQUEST_CODE && resultCode == RESULT_OK) {
startService(new Intent(this, LocalVPNService.class));
}
}
}
Home Fragment
public class HomeFragment extends Fragment {
Boolean checked;
DBHelper dbHelper;
String filterFlag = "", networkTypeSelected = "";
CustomAdapter adap = null;
OnClickListener clickListener;
TextView tvNetworkType;
SharedPreferences prefs;
private static String FILENAME = "mlogs.txt";
public HomeFragment() {
// TODO Auto-generated constructor stub
}
public HomeFragment(String dataFilter) {
filterFlag = dataFilter;
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
final View rootView = inflater.inflate(R.layout.fragment_home,
container, false);
prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
try {
dbHelper = DBHelper.newInstance(getActivity());
tvNetworkType = (TextView) rootView
.findViewById(R.id.tvNetworkTypeHome);
clickListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
Editor edit = prefs.edit();
if (v.getId() == R.id.btnCellularHome) {
checked = false;
tvNetworkType.setText("Cellular Data");
edit.putString("network", "0");
} else if (v.getId() == R.id.btnWifiHome) {
checked = true;
tvNetworkType.setText("Wi-fi Data");
edit.putString("network", "1");
}
edit.commit();
setListViewData(rootView);
}
};
rootView.findViewById(R.id.btnCellularHome).setOnClickListener(
clickListener);
rootView.findViewById(R.id.btnWifiHome).setOnClickListener(
clickListener);
if (prefs.getString("network", "0").equalsIgnoreCase("1")) {
checked = true;
tvNetworkType.setText("Wi-fi Data");
} else {
tvNetworkType.setText("Cellular Data");
checked = false;
}
setListViewData(rootView);
} catch (Exception e) {
e.getMessage();
}
TextView ytdata = (TextView) rootView.findViewById(R.id.ytdata);
TcpDumpUtills tcpDumpUtills = new TcpDumpUtills(getActivity());
ytdata.setText(StringUtils.formatToMultiplier(tcpDumpUtills
.getAppsConsumedData("com.google.android.youtube")));
ytdata.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
try {
File file = new File(Environment.getExternalStorageDirectory() + File.separator + "test.txt");
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder log=new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
}
writeDataToFile(log.toString());
} catch (IOException e) {
}
}
});
super.onSaveInstanceState(savedInstanceState);
return rootView;
}
#Override
public void onAttach(Activity activity) {
super.onAttach(activity);
//mContext = activity;
}
public void writeDataToFile(String data){
// write on SD card file data in the text box
try {
File myFile = new File("/sdcard/mysdfile.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile);
OutputStreamWriter myOutWriter =
new OutputStreamWriter(fOut);
myOutWriter.append(data);
myOutWriter.close();
fOut.close();
Toast.makeText(getActivity(),
"Done writing SD 'mysdfile.txt'",
Toast.LENGTH_SHORT).show();
} catch (Exception e) {
Toast.makeText(getActivity(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
private void writeToFile(String data) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(getActivity().openFileOutput(FILENAME, Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Logss", "File write failed: " + e.toString());
}
}
public ListAdapter getData() {
Resources res = getResources();
ArrayList<ListModel> arr = new ArrayList<ListModel>();
ArrayList<ListModel> arrFinal = new ArrayList<ListModel>();
String networkType = "";
if (checked) {
networkType = "1";
} else {
networkType = "0";
}
PackageManager manager = getActivity().getPackageManager();
arr = dbHelper.getAppsDataAccordingToNetworkType(networkType);
if (arr.size() >= 1) {
for (ListModel modelGetter : arr) {
ListModel modelSetter = new ListModel();
String packageName = modelGetter.getAppName();
// Setting App Name
try {
ApplicationInfo appInfo = manager.getApplicationInfo(
modelGetter.getAppName(), 0);
String appName = "" + manager.getApplicationLabel(appInfo);
modelSetter.setAppName(appName);
// Setting Total Data Consumned by the app
long appTotalData = getTotalDataPerApp(modelGetter
.getAppName());
modelSetter.setDataConsumed(appTotalData);
String appTotalDataStr = CommonFunctions
.humanReadableByteCount(appTotalData, false);
modelSetter.setTotalData(appTotalDataStr);
// Setting Total Data as per the network selected
long networkDataPerApp = getDailyNetworkDataPerApp(
modelGetter.getNetworkData(), packageName);
String networkDataStr = CommonFunctions
.humanReadableByteCount(networkDataPerApp, false);
modelSetter.setNetworkData(networkDataStr);
double percd = networkDataPerApp / (double) appTotalData
* 100;
int perc = (int) percd;
modelSetter.setPercenatge(perc);
// Setting App Icon
Drawable draw = manager.getApplicationIcon(modelGetter
.getAppName());
modelSetter.setDrawable(draw);
// Setting Today's Data
long appTodaysData = getUsageData(packageName);
String appTodayDataStr = CommonFunctions
.humanReadableByteCount(appTodaysData, false);
modelSetter.setTodaysData(appTodayDataStr);
Calendar cal = Calendar.getInstance();
long dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
long dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
long time = cal.get(Calendar.HOUR_OF_DAY);
long appConsumptionRate = getConsumptionRate(cal,
appTotalData);
String appConsumptionDataStr = CommonFunctions
.humanReadableByteCount(appConsumptionRate, false);
if (filterFlag.equalsIgnoreCase("0")) {
appConsumptionDataStr = appConsumptionDataStr + " /hr";
} else if (filterFlag.equalsIgnoreCase("1")) {
appConsumptionDataStr = appConsumptionDataStr + " /day";
}else if (filterFlag.equalsIgnoreCase("2")) {
appConsumptionDataStr = appConsumptionDataStr + " /day.";
}
modelSetter.setConsumptionRate(appConsumptionDataStr);
// Setting Forecast Data
long appForecastData = getForecastData(appConsumptionRate,
dayOfMonth, dayOfWeek, time, appTotalData);
String appForecastDataStr = CommonFunctions
.humanReadableByteCount(appForecastData, false);
modelSetter.setForecastData(appForecastDataStr);
arrFinal.add(modelSetter);
} catch (Exception e) {
e.getMessage();
}
}
} else {
ListModel modelSetter = new ListModel();
modelSetter.setAppName("No Data");
modelSetter.setConsumptionRate("0.0 KB");
modelSetter.setForecastData("0.0 KB");
modelSetter.setNetworkData("0.0 KB");
modelSetter.setTodaysData("0.0 KB");
modelSetter.setTotalData("0.0 KB");
arrFinal.add(modelSetter);
}
Collections.sort(arrFinal, new Comparator<ListModel>() {
#Override
public int compare(ListModel lhs, ListModel rhs) {
// TODO Auto-generated method stub
return lhs.getDataConsumed() > rhs.getDataConsumed() ? -1
: lhs.getDataConsumed() < rhs.getDataConsumed() ? 1
: 0;
}
});
adap = new CustomAdapter(getActivity(), arrFinal, res, networkType);
adap.notifyDataSetChanged();
return adap;
}
public void setListViewData(View view) {
try {
ListAdapter adap = getData();
ActionSlideExpandableListView list = (ActionSlideExpandableListView) view
.findViewById(R.id.list);
list.setAdapter(adap);
list.setSmoothScrollbarEnabled(true);
// listen for events in the two buttons for every list item.
// the 'position' var will tell which list item is clicked
} catch (Exception e) {
e.getMessage();
}
}
private long getTotalDataPerApp(String packageName) {
String[] arr = CommonFunctions.getDateAccordingToDuration(filterFlag);
String sDate = arr[0];
String eDate = arr[1];
long data = dbHelper.getDailyTotalDataPerApp(sDate, eDate, packageName);
return data;
}
private long getDailyNetworkDataPerApp(String networkType,
String packageName) {
String[] arr = CommonFunctions.getDateAccordingToDuration(filterFlag);
String sDate = arr[0];
String eDate = arr[1];
long data = dbHelper.getDailyNetworkDataPerApp(sDate, eDate,
networkType, packageName);
return data;
}
private long getUsageData(String packageName) {
String[] arr = CommonFunctions.getDateAccordingToDuration(filterFlag);
String sDate = arr[0];
String eDate = arr[1];
long data = dbHelper.getDailyTotalDataPerApp(sDate, eDate, packageName);
return data;
}
private long getForecastData(long cRate, long dayOfMonth, long dayOfWeek,
long time, long appTotalData) {
long output = 0;
if (filterFlag.equalsIgnoreCase("0")) {
output = (cRate * (24 - time)) + appTotalData;
} else if (filterFlag.equalsIgnoreCase("1")) {
long leftDaysOfWeek = 7 - dayOfWeek;
output = (cRate * leftDaysOfWeek) + appTotalData;
} else if (filterFlag.equalsIgnoreCase("2")) {
long leftDaysOfMonth = 31 - dayOfMonth;
output = (cRate * leftDaysOfMonth) + appTotalData;
}
return output;
}
private long getConsumptionRate(Calendar cal, long totalData) {
long output = 0;
int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
int dayOfMonth = cal.get(Calendar.DAY_OF_MONTH);
int time = cal.get(Calendar.HOUR_OF_DAY);
if (filterFlag.equalsIgnoreCase("0")) {
output = totalData / time;
} else if (filterFlag.equalsIgnoreCase("1")) {
output = totalData / dayOfWeek;
} else if (filterFlag.equalsIgnoreCase("2")) {
output = totalData / dayOfMonth;
}
return output;
}
public ListAdapter buildDummyData() {
final int SIZE = 20;
String[] values = new String[SIZE];
for (int i = 0; i < SIZE; i++) {
values[i] = "Item " + i;
}
return new ArrayAdapter<String>(getActivity(),
R.layout.expandable_list_item, R.id.tvAppName, values);
}
}
Crash Log
11-19 21:33:24.010 12557-12557/com.oda.bandwit E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.oda.bandwit, PID: 12557
android.view.WindowManager$BadTokenException: Unable to add window -- token null is not for an application
at android.view.ViewRootImpl.setView(ViewRootImpl.java:682)
at android.view.WindowManagerGlobal.addView(WindowManagerGlobal.java:342)
at android.view.WindowManagerImpl.addView(WindowManagerImpl.java:93)
at android.app.Dialog.show(Dialog.java:316)
at android.app.AlertDialog$Builder.show(AlertDialog.java:1112)
at com.oda.bandwit.TcpDumpService.startTCPdump(TcpDumpService.java:98)
at com.oda.bandwit.TcpDumpService.access$000(TcpDumpService.java:22)
at com.oda.bandwit.TcpDumpService$1.run(TcpDumpService.java:62)
at android.os.Handler.handleCallback(Handler.java:751)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6077)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:865)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:755)
I am trying to learn the Android onLongclick context menu actions. When clicking an item on list it displays two action image one for calling and another for website url. But I am having null pointer exception. When toasting using the toast method it can display number and url. But this is not what i want to to. Its just for test. I want to dial the number when phone action is clicked and visit website when url action is clicked. I have commented toast for doing so. And tried to create perform call and performUrl() methods. I took idea from the example with toast so i tried to modify it but its simply not working so i commented the performCall() and performUrl() methods for now. Could anyone suggest how to make these things happen?
I have a department class which is a pure java class.
public class DepartmentActivity extends Activity {
//Department dept = new Department();
private ListView listView;
ArrayAdapter<Department> adapter;
//String list_item;
Object mActionMode;
private Department[] myDepartment = {
new Department("CS", "cs#yahoo.edu", "405.111.2222"),
new Department("Biology", "bio#yahoo.edu", "405.222.3333"),
new Department("Business", "business#yahoo.com", "405.333.4444"),
new Department("Music", "music#yahoo.com", "405.444.5555"),
new Department("Engineering", "engg#ucoll.com", "405.555.6666"),
new Department("Nursing", "nursing#yahoo.com", "213.555.6666")
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_department);
listView =(ListView) findViewById(R.id.list);
//adapter = new ArrayAdapter<>(getApplicationContext(), R.layout.deptlist, deptList);
adapter = new ArrayAdapter<>(getApplicationContext(), R.layout.deptlist, myDepartment);
listView.setAdapter(adapter);
//listView.setChoiceMode(ListView.CHOICE_MODE_SINGLE);
//listener = new listView.OnItemLongClickListener(this);
listView.setOnItemLongClickListener(new AdapterView.OnItemLongClickListener() {
#Override
public boolean onItemLongClick(AdapterView<?> parent, View view, int position, long id) {
//list_item = myDepartment.toString();
if (mActionMode != null){
return false;
}
mActionMode = DepartmentActivity.this.startActionMode(mActionModeCallback);
return true;
}
});
}
private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
#Override
public boolean onCreateActionMode(ActionMode mode, Menu menu) {
//mode.setTitle(list_item);
MenuInflater inflater = mode.getMenuInflater();
inflater.inflate(R.menu.context_menu, menu);
return true;
//return false;
}
#Override
public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
return false;
}
#Override
public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
// Respond to clicks on the actions in the CAB
switch (item.getItemId()) {
case R.id.action_phone:
performCall();
mode.finish(); // Action picked, so close the CAB
return true;
case R.id.action_www:
//performUrl();
mode.finish(); // Action picked, so close the CAB
return true;
default:
return false;
}
}
#Override
public void onDestroyActionMode(ActionMode mode) {
mActionMode = null;
}
};
/*
private void performCall() {
SparseBooleanArray selected = listView.getCheckedItemPositions();
String selectedNames ="";
for (int i = 0; i < selected.size(); i++) {
if (selected.valueAt(i)) {
int pos = selected.keyAt(i);
selectedNames += " " + myDepartment[pos].getPhone();
}
}
Intent callIntent = new Intent(Intent.ACTION_DIAL);
callIntent.setData(Uri.parse("tel:"+selectedNames));
startActivity(callIntent);
//Toast.makeText(DepartmentActivity.this, "Call: " + selectedNames,
// Toast.LENGTH_SHORT).show();
}
*/
/*
private void performUrl() {
SparseBooleanArray selected = listView.getCheckedItemPositions();
String selectedNames = "";
for (int i = 0; i < selected.size(); i++) {
if (selected.valueAt(i)) {
int pos = selected.keyAt(i);
selectedNames += " " + myDepartment[pos].getUrl();
}
}
//Toast.makeText(DepartmentActivity.this, "Url: " + selectedNames,
//Toast.LENGTH_SHORT).show();
}
*/
Stack trace
....PID: 3250
java.lang.NullPointerException: Attempt to invoke virtual method 'int android.util.SparseBooleanArray.size()' on a null object reference
at esu.uco.rawal.p4rabina.DepartmentActivity.performCall(DepartmentActivity.java:108)
at esu.uco.rawal.p4rabina.DepartmentActivity.access$100(DepartmentActivity.java:18)
at esu.uco.rawal.p4rabina.DepartmentActivity$2.onActionItemClicked(DepartmentActivity.java:85)
at com.android.internal.policy.PhoneWindow$DecorView$ActionModeCallback2Wrapper.onActionItemClicked(PhoneWindow.java:3540)
at com.android.internal.app.WindowDecorActionBar$ActionModeImpl.onMenuItemSelected(WindowDecorActionBar.java:1093)
at com.android.internal.view.menu.MenuBuilder.dispatchMenuItemSelected(MenuBuilder.java:761)
at com.android.internal.view.menu.MenuItemImpl.invoke(MenuItemImpl.java:152)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:904)
at com.android.internal.view.menu.MenuBuilder.performItemAction(MenuBuilder.java:894)
at android.widget.ActionMenuView.invokeItem(ActionMenuView.java:616)
at com.android.internal.view.menu.ActionMenuItemView.onClick(ActionMenuItemView.java:141)
at android.view.View.performClick(View.java:5198)
at android.view.View$PerformClick.run(View.java:21147)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
Thank You
Very new to android java programming. I created a car payment calculator application for one of my classes and I am trying to create a checkbox that the user can check so that all the values stored in the TextViews and EditViews remain the same when the application is opened again.
Here is my activity:
public class MainActivity extends Activity implements OnClickListener,
OnEditorActionListener, OnItemSelectedListener, OnFocusChangeListener,
OnCheckedChangeListener {
private TextView payment;
private TextView interest;
private EditText principle;
private TextView interestText;
private CheckBox interestBox;
private EditText years;
private TextView apr;
Button plusbutton;
Button minusbutton;
private static String TAG = "CAR";
private Spinner period;
private double aprPercent;
private int t;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.d(TAG, "onCreate");
this.getReferences();
this.setListeners();
}
#Override
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);
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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void getReferences() {
payment = (TextView) findViewById(R.id.paymentLabel);
interest = (TextView) findViewById(R.id.interestLabel);
apr = (TextView) findViewById(R.id.aprLabel);
aprPercent = Double.parseDouble(apr.getText().toString());
interestText = (TextView) findViewById(R.id.interestText);
interestBox = (CheckBox) findViewById(R.id.checkBox1);
interestBox.setChecked(false);
principle = (EditText) findViewById(R.id.principleEditText);
years = (EditText) findViewById(R.id.yearsEditText);
period = (Spinner) findViewById(R.id.spinner1);
minusbutton = (Button) findViewById(R.id.minusbutton);
plusbutton = (Button) findViewById(R.id.plusbutton);
ArrayAdapter<CharSequence> adapter = ArrayAdapter
.createFromResource(this, R.array.split_array,
android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
period.setAdapter(adapter);
// principle.setOnFocusChangeListener(this);
Log.d(TAG, "getReferences principle: " + principle.getText()
+ " years:" + years.getText());
}
public void setListeners() { // where the event being consumed will be
// responding
principle.setOnFocusChangeListener(this);
principle.setOnEditorActionListener(this);
years.setOnFocusChangeListener(this);
years.setOnEditorActionListener(this);
interestBox.setOnCheckedChangeListener(this);
period.setOnItemSelectedListener(this);
Log.d(TAG, "setListeners principle: " + principle.getText() + " years:"
+ years.getText());
}
public void setPeriodValue() {
if (period.getSelectedItem().toString().equalsIgnoreCase("Monthly")) {
t = 12;
} else if (period.getSelectedItem().toString()
.equalsIgnoreCase("Quarterly")) {
t = 4;
} else if (period.getSelectedItem().toString()
.equalsIgnoreCase("Annually")) {
t = 1;
}
}
public void updateResults() {
double dblPrinciple = Double
.parseDouble(principle.getText().toString());
double dblYears = Double.parseDouble(years.getText().toString());
double num, denom, dblPayment;
double r = aprPercent / 100;
NumberFormat nf = NumberFormat.getNumberInstance();
NumberFormat curr = NumberFormat.getCurrencyInstance();
apr.setText(nf.format(aprPercent));
setPeriodValue();
num = (r / t);
denom = (1 - Math.pow((1 + num), (t * -dblYears)));
dblPayment = dblPrinciple * (num / denom);
payment.setText(curr.format(dblPayment));
interest.setText(curr
.format((dblPayment * t * dblYears) - dblPrinciple));
}
public void onFocusChange(View v, boolean hasfocus) {
Log.d(TAG, "Focus Change principle: " + principle.getText() + " years"
+ years.getText());
switch (v.getId()) {
case R.id.principleEditText:
case R.id.yearsEditText:
updateResults();
default:
updateResults();
}
}
#Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(interestBox.isChecked()) {
interest.setVisibility(View.VISIBLE);
interestText.setVisibility(View.VISIBLE);
}
else {
interest.setVisibility(View.INVISIBLE);
interestText.setVisibility(View.INVISIBLE);
}
if (interestBox.isChecked()!=true){
interest.setVisibility(View.INVISIBLE);
interestText.setVisibility(View.INVISIBLE);
}
else {
interest.setVisibility(View.VISIBLE);
interestText.setVisibility(View.VISIBLE);
}
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
updateResults();
}
#Override
public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
updateResults();
return false;
}
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.minusbutton:
if (aprPercent == 1) {
break;
} else {
aprPercent = aprPercent - 1.0;
updateResults();
break;
}
case R.id.plusbutton:
if (aprPercent == 20) {
break;
} else {
aprPercent = aprPercent + 1.0;
updateResults();
break;
}
}
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
updateResults();
}
My guess is that I have to do something with sharedprefs but I'm not exactly sure how to go about it. Any push in the right direction would be great. thank you.
Use getSharedPreferences(...).edit().putString(...).commit() to store values in "onPause()" and again use getSharedPreferences(...).getString(...) to retrieve information in your "onResume()". It's just that easy.
You will have to read how to save your Activity data. In my opinion you should not use checkbox to save this data but save it by default.
To save your data while the screen rotate you will have to check the OnSaveInstanceState and OnRestoreInstanceState like in this post. It will handle the data when rotated too.
To save your data for a longer time (changing of applications, closing application), You will have to use the Android preferences but check how works the lifecycle of an Activity. Basically you will need to save in the OnPause or OnDestroy and reload it in the OnResume or OnCreate.
Concerning the preferences you have a nice tutorial on the Vogella Website
//Get Data
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getActivity());
String url = settings.getString("url", "n/a");
//Save Data
Editor edit = preferences.edit();
edit.putString("username", "new_value_for_user");
edit.apply();