@Override public void onPageSelected(int position) { // Make sure that mRunId is always equal to the run id of the currently viewed // RunFragment as we page through them. Log.i(TAG, "PageChangedListener fetching fragment from position " + position); RunMapFragment fragment = (RunMapFragment) mAdapter.getItem(position); mRunId = fragment.getArguments().getLong(Constants.ARG_RUN_ID, -1); Log.i(TAG, "PageChangeListener fetched Run #" + mRunId + " at position " + position); setSubtitle(); setViewPager((RunDatabaseHelper.RunCursor) mAdapter.getCursor(), mRunId); // Write the RunId to Shared Prefs so that if the user goes back to RunPagerActivity, the // same Run will be displayed there mRunManager.mPrefs.edit().putLong(Constants.ARG_RUN_ID, mRunId).apply(); Log.i(TAG, "Wrote RunId " + mRunId + " to Shared Prefs"); }
@Override public void onReceive(Context context, Intent intent) { String action = intent.getAction(); Log.i(TAG, "Action in RunMapPagerActivity ResultsReceiver is " + action); switch (action) { case Constants.SEND_RESULT_ACTION: Log.i(TAG, "RunMapPagerActivity action is SEND_RESULT_ACTION"); String actionAttempted = intent.getStringExtra(Constants.ACTION_ATTEMPTED); Log.i(TAG, "actionAttempted is " + actionAttempted); if (actionAttempted.equals(Constants.ACTION_INSERT_RUN)) { Run run = intent.getParcelableExtra(Constants.EXTENDED_RESULTS_DATA); if (run.getId() != -1) { // Now that the new Run has been added to the database, we need to open // its RunFragment in the RunPagerActivity mRunManager.mPrefs.edit().putLong(Constants.ARG_RUN_ID, run.getId()).apply(); Log.i(TAG, "Got Run " + run.getId() + " in ResultsReceiver."); Intent runPagerIntent = RunPagerActivity.newIntent( getApplicationContext(), Constants.KEEP_EXISTING_SORT, run.getId()); startActivity(runPagerIntent); // setupAdapterAndLoader(); } else { Toast.makeText(RunMapPagerActivity.this, R.string.insert_run_error, Toast.LENGTH_LONG) .show(); } // Log.i(TAG, "in ResultsReceiver on Insert Run, Runs in adapter: " + // mViewPager.getAdapter().getCount()); // mAdapter.finishUpdate(mViewPager); } // ViewPager isn't interested in any other ACTION_ATTEMPTED, so no "else" clauses // specifying what to do with them needed. break; case Constants.ACTION_DELETE_RUN: Log.i(TAG, "RunMapPagerActivity action is ACTION_DELETE_RUN"); // RunDataBaseHelper's deleteRun() function returns to the IntentService // an int[] with two members,the number of Locations deleted as element 0 // (LOCATION_DELETIONS) and the number of Runs deleted as element 1 (RUN_DELETIONS). // That array is passed along here for display to the user. int[] results = intent.getIntArrayExtra(Constants.EXTENDED_RESULTS_DATA); // The getWritableDatabase().delete() method returns the number of rows affected upon // success and -1 upon error. Check if either result returned is an error. if (results[Constants.RUN_DELETIONS] == -1 || results[Constants.LOCATION_DELETIONS] == -1) { // Tell the user if there was an error deleting a Run entry. if (results[Constants.RUN_DELETIONS] == -1) { Toast.makeText(RunMapPagerActivity.this, R.string.delete_run_error, Toast.LENGTH_LONG) .show(); } // Tell the user if there was an error deleting a Location entry. if (results[Constants.LOCATION_DELETIONS] == -1) { Toast.makeText( RunMapPagerActivity.this, R.string.delete_locations_error, Toast.LENGTH_LONG) .show(); } // Report results to the user upon successful deletions and reset the Adapter, // Subtitle and Loader. } else { // Trying to delete the last Run from this Activity after having deleted other // Runs results in a problem: mRunId remains set to the last previous Run that // was deleted, so we get an error for trying to delete a Run that's already // been deleted. Thus, we need some technique to set a valid RunId for the // new current view after deleting a Run. // We use the position in the ViewPager held by the Run we just deleted to select // what RunId should be after the deletion. If the ViewPager held only one // child view before the deletion, we know we just deleted the last Run so we // can just finish this activity and go back to RunRecyclerView if (mViewPager.getChildCount() == 1) { Log.i( TAG, "Upon entry to ResultsReceiver, ACTION_DELETE_RUN:, getChildCount() is 1, so call finish()"); mAdapter.finishUpdate(mViewPager); finish(); // If there was more than one Run held in the ViewPager, set the ViewPager's // current view item to the view that's in the next higher position in the // ViewPager unless we were already at the highest position, in which case // set the ViewPager's current view item to the view that's in the next lower // position in the ViewPager. } else { int currentPosition = mViewPager.getCurrentItem(); Log.i( TAG, "In ResultsReceiver, currentPosition is " + currentPosition + " and getChildCount() is " + mViewPager.getChildCount()); // Get the fragment associated with the child view we're going to move // to and get its RunId from the arguments that were attached to the // fragment when it was created. Is there a better way to do this? Why // doesn't the onPageChangeListener correctly report the fragment displayed // in the last remaining page of a ViewPager? if (currentPosition < mViewPager.getChildCount() - 1) { int index = currentPosition + 1; mViewPager.setCurrentItem(index); RunMapFragment fragment = (RunMapFragment) mAdapter.getItem(index); mRunId = fragment.getArguments().getLong(Constants.ARG_RUN_ID); Log.i(TAG, "After Run deletion, we moved UP one position and RunId is " + mRunId); } else { int index = currentPosition - 1; mViewPager.setCurrentItem(index); RunMapFragment fragment = (RunMapFragment) mAdapter.getItem(index); mRunId = fragment.getArguments().getLong(Constants.ARG_RUN_ID); Log.i(TAG, "After Run deletion, we moved DOWN one position and RunId is " + mRunId); } } // Now that we've got a "legal" mRunId, we can fetch a new cursor, reconstruct // the adapter, and set the subtitle accordingly. setupAdapterAndLoader(); Resources r = getResources(); Toast.makeText( RunMapPagerActivity.this, r.getQuantityString( R.plurals.runs_deletion_results, results[Constants.RUN_DELETIONS], results[Constants.RUN_DELETIONS], results[Constants.LOCATION_DELETIONS]), Toast.LENGTH_LONG) .show(); } mAdapter.finishUpdate(mViewPager); Log.i( TAG, "In ResultsReceiver ACTION_RUN_DELETE, Runs in adapter: " + mViewPager.getAdapter().getCount()); break; default: // Shouldn't ever get here - intent filter limits us to SEND_RESULT_ACTION // and ACTION_DELETE_RUN Log.i(TAG, "Intent Action wasn't SEND_RESULT_ACTION or ACTION_DELETE_RUN"); } }