Java tutorial
/* * Copyright (C) 2013 Chris Lacy * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.tweetlanes.android.view; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.HashMap; import com.crittercism.app.Crittercism; import com.tweetlanes.android.App; import com.tweetlanes.android.AppSettings; import com.tweetlanes.android.R; import com.tweetlanes.android.Constant.SystemEvent; import com.tweetlanes.android.model.ComposeTweetDefault; import org.tweetalib.android.TwitterManager; import org.tweetalib.android.model.TwitterStatus; import org.tweetalib.android.model.TwitterStatusesFilter; import org.tweetalib.android.model.TwitterUser; import com.tweetlanes.android.util.Util; import com.tweetlanes.android.view.BaseLaneFragment.InitialDownloadState; import com.tweetlanes.android.view.ComposeBaseFragment.ComposeListener; import com.tweetlanes.android.widget.viewpagerindicator.PageIndicator; import com.tweetlanes.android.widget.viewpagerindicator.TabPageIndicator; import com.tweetlanes.android.widget.viewpagerindicator.TabPageIndicator.TabCallbacks; import com.tweetlanes.android.Constant; import android.app.ActionBar; import android.app.Activity; import android.app.AlertDialog; import android.content.BroadcastReceiver; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.IntentFilter; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.support.v4.app.FragmentActivity; import android.support.v4.app.FragmentStatePagerAdapter; import android.support.v4.app.FragmentTransaction; import android.support.v4.content.LocalBroadcastManager; import android.support.v4.view.PagerAdapter; import android.support.v4.view.ViewPager; import android.support.v4.view.ViewPager.OnPageChangeListener; import android.util.Log; import android.view.ActionMode; import android.view.KeyEvent; import android.view.Menu; import android.view.MenuInflater; import android.view.MenuItem; import android.view.View; import android.view.View.OnClickListener; import android.view.View.OnFocusChangeListener; import android.view.WindowManager; import android.widget.LinearLayout; import android.widget.SearchView; import android.widget.Toast; public class BaseLaneActivity extends FragmentActivity implements SearchView.OnQueryTextListener { private ViewPager mViewPager; PageIndicator mPageIndicator; private ActionMode mCurrentActionMode; private Menu mCurrentMenu; private SearchView mSearchView; private View mLaneMask; private LinearLayout mDummyFocusItem; TwitterStatusesFilter mStatusesFilter = new TwitterStatusesFilter(); private String mShareImagePath; private static final int COMPOSE_TWEET = 0; private static final int COMPOSE_DIRECT_MESSAGE = 1; private ComposeTweetFragment mComposeTweetFragment; private View mComposeTweetView; private ComposeDirectMessageFragment mComposeDirectMessageFragment; private View mComposeDirectMessageView; private ComposeBaseFragment mCurrentComposeFragment; /* * */ public App getApp() { return (App) getApplication(); } /* * (non-Javadoc) * @see android.support.v4.app.FragmentActivity#onCreate(android.os.Bundle) */ @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); if (Constant.ENABLE_CRASH_TRACKING) { Crittercism.init(getApplicationContext(), Constant.CRITTERCISM_APP_ID); } // Key the screen from dimming - http://stackoverflow.com/a/4197370/328679 if (AppSettings.get().isDimScreenEnabled() == false) { getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); } PagerAdapter pagerAdapter = getAdapterForViewPager(); if (pagerAdapter != null) { setTheme(AppSettings.get().getCurrentThemeStyle()); setContentView(R.layout.default_lanes_layout); /* if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) { mPageIndicator = (ListTabPageIndicator)findViewById(R.id.listTabPageIndicator); findViewById(R.id.tabPageIndicator).setVisibility(View.GONE); } else { */ TabPageIndicator tabIndicator = (TabPageIndicator) findViewById(R.id.tabPageIndicator); tabIndicator.setTabCallbacks(new TabCallbacks() { @Override public void onCurrentItemClicked() { onCurrentLaneReselected(); }; }); // If there's only 1 item in the adapter, hide the item. Used for DMs. if (pagerAdapter.getCount() == 1) { tabIndicator.setVisibility(View.GONE); } mPageIndicator = tabIndicator; //findViewById(R.id.listTabLayout).setVisibility(View.GONE); //} int initialLaneIndex = getInitialLaneIndex(); mViewPager = (ViewPager) findViewById(R.id.pager); mViewPager.setAdapter(pagerAdapter); mViewPager.setCurrentItem(initialLaneIndex); mPageIndicator.setViewPager(mViewPager, initialLaneIndex); mPageIndicator.setOnPageChangeListener(mOnPageChangeListener); } mLaneMask = findViewById(R.id.lane_mask); mLaneMask.setOnClickListener(mLaneMaskOnClickListener); mDummyFocusItem = (LinearLayout) findViewById(R.id.dummyFocusItem); FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); mComposeDirectMessageView = findViewById(R.id.composeTweetFragment); mComposeDirectMessageFragment = (ComposeDirectMessageFragment) getSupportFragmentManager() .findFragmentById(R.id.composeDirectMessageFragment); if (mComposeDirectMessageFragment != null) { mComposeDirectMessageFragment.setComposeTweetListener(mComposeDirectMessageListener); mComposeDirectMessageView.setVisibility(View.GONE); //mComposeDirectMessageFragment.setTweetDefaultFromDraft(getApp().getTweetDraftAsString()); //setCurrentComposeFragment(COMPOSE_DIRECT_MESSAGE); ft.hide(mComposeDirectMessageFragment); } mComposeTweetView = findViewById(R.id.composeTweetFragment); mComposeTweetFragment = (ComposeTweetFragment) getSupportFragmentManager() .findFragmentById(R.id.composeTweetFragment); if (mComposeTweetFragment != null) { mComposeTweetFragment.setComposeTweetListener(mComposeTweetListener); mComposeTweetFragment.setTweetDefaultFromDraft(getApp().getTweetDraftAsString()); mComposeTweetView.setVisibility(View.GONE); //setCurrentComposeFragment(COMPOSE_TWEET); ft.hide(mComposeTweetFragment); } ft.commit(); LocalBroadcastManager.getInstance(this).registerReceiver(mForceFragmentPagerAdapterRefreshReceiver, new IntentFilter("" + SystemEvent.FORCE_FRAGMENT_PAGER_ADAPTER_REFRESH)); LocalBroadcastManager.getInstance(this).registerReceiver(mRestartAppReceiver, new IntentFilter("" + SystemEvent.RESTART_APP)); } /* * (non-Javadoc) * @see android.app.Activity#onPostCreate(android.os.Bundle) */ @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); setComposeDefault(); } /* * (non-Javadoc) * @see android.app.Activity#onRestoreInstanceState(android.os.Bundle) */ @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { super.onRestoreInstanceState(savedInstanceState); } /* * (non-Javadoc) * @see android.support.v4.app.FragmentActivity#onDestroy() */ @Override protected void onDestroy() { LocalBroadcastManager.getInstance(this).unregisterReceiver(mForceFragmentPagerAdapterRefreshReceiver); LocalBroadcastManager.getInstance(this).unregisterReceiver(mRestartAppReceiver); super.onDestroy(); } /* * (non-Javadoc) * @see android.support.v4.app.FragmentActivity#onResume() */ @Override protected void onResume() { super.onResume(); if (AppSettings.get().isDirty()) { restartActivity(); } LocalBroadcastManager.getInstance(this).registerReceiver(mDisplayToastReceiver, new IntentFilter("" + SystemEvent.DISPLAY_TOAST)); } /* * (non-Javadoc) * @see android.support.v4.app.FragmentActivity#onPause() */ @Override protected void onPause() { super.onPause(); LocalBroadcastManager.getInstance(this).unregisterReceiver(mDisplayToastReceiver); if (mComposeTweetFragment != null) { mComposeTweetFragment.updateComposeTweetDefault(); getApp().saveTweetDraft(mComposeTweetFragment.getTweetDefaultDraft()); } } /* * */ private BroadcastReceiver mDisplayToastReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { String message = (String) intent.getExtras().get("message"); if (message != null) { Toast.makeText(BaseLaneActivity.this, message, Constant.DEFAULT_TOAST_DISPLAY_TIME).show(); } } }; /* * */ void setCurrentComposeFragment(int type) { if (type == COMPOSE_DIRECT_MESSAGE) { if (mCurrentComposeFragment != mComposeDirectMessageFragment) { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); if (mComposeTweetFragment != null) { ft.hide(mComposeTweetFragment); } ft.show(mComposeDirectMessageFragment); ft.commit(); mCurrentComposeFragment = mComposeDirectMessageFragment; } } else { if (mCurrentComposeFragment != mComposeTweetFragment) { FragmentTransaction ft = getSupportFragmentManager().beginTransaction(); if (mComposeDirectMessageFragment != null) { ft.hide(mComposeDirectMessageFragment); } ft.show(mComposeTweetFragment); ft.commit(); mCurrentComposeFragment = mComposeTweetFragment; } } } /* * */ private HashMap<Integer, BaseLaneFragment> mLaneFragmentHashMap = new HashMap<Integer, BaseLaneFragment>(); private int activeInitialDownloadCount = 0; /* * */ protected BaseLaneFragment getFragmentAtIndex(int index) { if (mLaneFragmentHashMap != null) { return mLaneFragmentHashMap.get(index); } return null; } /* * */ protected void clearFragmentsCache() { if (mLaneFragmentHashMap != null) { for (Integer key : mLaneFragmentHashMap.keySet()) { BaseLaneFragment lane = mLaneFragmentHashMap.get(key); lane.clearLocalCache(); } } } /* * */ String getCachedData(int laneIndex) { return null; } /* * */ protected int getCurrentLaneIndex() { if (mViewPager != null) { return mViewPager.getCurrentItem(); } return 3; } /* * */ private int getLaneCount() { if (mViewPager != null) { return mViewPager.getAdapter().getCount(); } return getApp().getCurrentAccount().getDisplayedLaneDefinitionsSize(); } /* * */ protected void onLaneFragmentInitialDownloadStateChange(BaseLaneFragment fragment) { mLaneFragmentHashMap.put(fragment.getLaneIndex(), fragment); InitialDownloadState state = fragment.getInitialDownloadState(); int currentLane = getCurrentLaneIndex(); BaseLaneFragment currentLaneFragment = mLaneFragmentHashMap.get(currentLane); //HomeLaneAdapter adapter = (HomeLaneAdapter)mViewPager.getAdapter(); //Log.d("tweetlanes url fetch", fragment.getIdentifier() + ": State=" + state.toString()); if (mCurrentComposeFragment == null && currentLaneFragment != null) { int composeType = (currentLaneFragment instanceof DirectMessageFeedFragment) ? COMPOSE_DIRECT_MESSAGE : COMPOSE_TWEET; setCurrentComposeFragment(composeType); } switch (state) { case WAITING: if (fragment.getLaneIndex() == currentLane) { fragment.triggerInitialDownload(); //Log.d("tweetlanes url fetch", "trigger Current lane '" + adapter.getTitle(currentLane) + "' (index = " + currentLane + ")"); } else if (activeInitialDownloadCount == 0) { if (currentLaneFragment != null && currentLaneFragment.getInitialDownloadState() == InitialDownloadState.DOWNLOADED) { fragment.triggerInitialDownload(); //Log.d("tweetlanes url fetch", "trigger neighbour lane '" + adapter.getTitle(fragment.getLaneIndex()) + "' (index = " + fragment.getLaneIndex() + ")"); } } break; case DOWNLOADING: activeInitialDownloadCount++; break; case DOWNLOADED: activeInitialDownloadCount = Math.max(0, activeInitialDownloadCount - 1); triggerNeighbourInitialDownload(currentLane); break; default: break; } } /* * */ protected void onLaneChange(int position, int oldPosition) { invalidateOptionsMenu(); boolean triggeredDownload = false; BaseLaneFragment fragment = mLaneFragmentHashMap.get(position); // fragment will be null if the user scrolls the Tabs to a Fragment not yet created. // In that instance, the download will be triggered in onLaneFragmentDownloadStateChanged(). if (fragment != null) { InitialDownloadState state = fragment.getInitialDownloadState(); if (state == InitialDownloadState.WAITING) { if (fragment.getLaneIndex() == position) { fragment.triggerInitialDownload(); triggeredDownload = true; } } } if (triggeredDownload == false) { triggerNeighbourInitialDownload(position); } setCurrentComposeFragment( (fragment instanceof DirectMessageFeedFragment) ? COMPOSE_DIRECT_MESSAGE : COMPOSE_TWEET); } /* * */ protected void onCurrentLaneReselected() { BaseLaneFragment fragment = mLaneFragmentHashMap.get(getCurrentLaneIndex()); // fragment will be null if the user scrolls the Tabs to a Fragment not yet created. // In that instance, the download will be triggered in onLaneFragmentDownloadStateChanged(). if (fragment != null) { fragment.onJumpToTop(); } } /* * */ protected boolean triggerNeighbourInitialDownload(int currentLane) { //HomeLaneAdapter adapter = (HomeLaneAdapter)mViewPager.getAdapter(); boolean triggeredDownload = false; if (currentLane > 0) { BaseLaneFragment leftFragment = mLaneFragmentHashMap.get(currentLane - 1); if (leftFragment != null && leftFragment.getInitialDownloadState() == InitialDownloadState.WAITING) { //Log.d("tweetlanes url fetch", "trigger Left lane '" + adapter.getTitle(currentLane-1) + "' (index = " + (currentLane-1) + ")"); leftFragment.triggerInitialDownload(); triggeredDownload = true; } } if (triggeredDownload == false) { if (currentLane + 1 < getLaneCount()) { BaseLaneFragment rightFragment = mLaneFragmentHashMap.get(currentLane + 1); if (rightFragment != null && rightFragment.getInitialDownloadState() == InitialDownloadState.WAITING) { //Log.d("tweetlanes url fetch", "trigger Right lane (index = '" + adapter.getTitle(currentLane+1) + "' " + (currentLane+1) + ")"); rightFragment.triggerInitialDownload(); } } } return false; } /* * */ ComposeListener mComposeTweetListener = new ComposeListener() { @Override public void onShowCompose() { mLaneMask.setVisibility(View.VISIBLE); finishCurrentActionMode(); if (mCurrentMenu != null) { mCurrentMenu.close(); mCurrentMenu.clear(); } ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_STANDARD); actionBar.setDisplayShowTitleEnabled(true); actionBar.setTitle(R.string.action_bar_tweet_compose_title); actionBar.setDisplayUseLogoEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayShowCustomEnabled(false); if (mCurrentActionMode != null) { //mCurrentActionMode.invalidate(); //mCurrentActionMode.setCustomView(null); // TODO: Come up with a better solution here mCurrentActionMode.finish(); } invalidateOptionsMenu(); } @Override public void onHideCompose() { mLaneMask.setVisibility(View.GONE); // Give this dummy item focus to stop the cursor blinking on the compose view when the keyboard is no longer on screen mDummyFocusItem.requestFocus(); } @Override public void onBackButtonPressed() { composeReleaseFocus(true); } @Override public void onStatusUpdateRequest() { composeReleaseFocus(true); } @Override public void onStatusUpdateSuccess() { setComposeDefault(); mShareImagePath = null; } @Override public void onMediaAttach() { //MenuItem galleryMenuItem = getMenuItem(R.id.action_gallery); //if (galleryMenuItem != null) { // galleryMenuItem.setIcon(R.drawable.ic_dialog_photo_active_default); //} mShareImagePath = null; } @Override public void onMediaDetach() { //MenuItem galleryMenuItem = getMenuItem(R.id.action_gallery); //if (galleryMenuItem != null) { // galleryMenuItem.setIcon(R.drawable.ic_dialog_photo_default); //} mShareImagePath = null; } @Override public void onStatusHintUpdate() { updateActionModeTitles(); } @Override public void saveDraft(String draftAsJsonString) { getApp().saveTweetDraft(draftAsJsonString); } @Override public String getDraft() { return getApp().getTweetDraftAsString(); } }; /* * */ ComposeListener mComposeDirectMessageListener = new ComposeListener() { @Override public void onShowCompose() { mLaneMask.setVisibility(View.VISIBLE); finishCurrentActionMode(); if (mCurrentMenu != null) { mCurrentMenu.close(); mCurrentMenu.clear(); } ActionBar actionBar = getActionBar(); actionBar.setNavigationMode(android.app.ActionBar.NAVIGATION_MODE_STANDARD); actionBar.setDisplayShowTitleEnabled(true); actionBar.setTitle(R.string.action_bar_direct_message_compose_title); actionBar.setDisplayUseLogoEnabled(true); actionBar.setDisplayHomeAsUpEnabled(true); actionBar.setDisplayShowCustomEnabled(false); if (mCurrentActionMode != null) { //mCurrentActionMode.invalidate(); //mCurrentActionMode.setCustomView(null); // TODO: Come up with a better solution here mCurrentActionMode.finish(); } invalidateOptionsMenu(); } @Override public void onHideCompose() { mLaneMask.setVisibility(View.GONE); // Give this dummy item focus to stop the cursor blinking on the compose view when the keyboard is no longer on screen mDummyFocusItem.requestFocus(); } @Override public void onBackButtonPressed() { composeReleaseFocus(true); } @Override public void onStatusUpdateRequest() { composeReleaseFocus(true); } @Override public void onStatusUpdateSuccess() { setComposeDefault(); } @Override public void onMediaAttach() { } @Override public void onMediaDetach() { } @Override public void onStatusHintUpdate() { updateActionModeTitles(); } @Override public void saveDraft(String draftAsJsonString) { //getApp().saveTweetDraft(draftAsJsonString); } @Override public String getDraft() { //return getApp().getTweetDraftAsString(); return null; } }; /* * */ private void updateActionModeTitles() { if (mCurrentActionMode != null && Util.tagEquals(mCurrentActionMode.getTag(), R.id.tagIdComposeTweetActionBar)) { if (mComposeTweetFragment != null) { if (mComposeTweetFragment.getInReplyToId() == null) { mCurrentActionMode.setTitle(R.string.action_bar_tweet_compose_title); } else { mCurrentActionMode.setTitle(R.string.action_bar_tweet_reply_compose_title); } mCurrentActionMode.setSubtitle(null); } } } /* * */ MenuItem getMenuItem(int resourceId) { if (mCurrentMenu != null) { for (int i = 0; i < mCurrentMenu.size(); i++) { MenuItem menuItem = mCurrentMenu.getItem(i); if (menuItem.getItemId() == resourceId) { return menuItem; } } } return null; } /* * */ OnPageChangeListener mOnPageChangeListener = new OnPageChangeListener() { @Override public void onPageScrollStateChanged(int arg0) { } @Override public void onPageScrolled(int arg0, float arg1, int arg2) { } @Override public void onPageSelected(int position, int oldPosition) { if (mLaneFragmentHashMap != null && mLaneFragmentHashMap.containsKey(position)) { } getApp().getCurrentAccount().setCurrentLaneIndex(position); if (mCurrentActionMode != null) { // TODO: Probably shouldn't clear this in the event the ComposeTweet ActionBar is displaying mCurrentActionMode.finish(); } onLaneChange(position, oldPosition); } }; /* * */ OnClickListener mLaneMaskOnClickListener = new OnClickListener() { @Override public void onClick(View v) { composeReleaseFocus(true); } }; /* * */ void restartApp() { Intent intent = getBaseContext().getPackageManager() .getLaunchIntentForPackage(getBaseContext().getPackageName()); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_NO_ANIMATION); overridePendingTransition(0, 0); startActivity(intent); } /* * */ void restartActivity() { finish(); getIntent().addFlags(Intent.FLAG_ACTIVITY_NO_ANIMATION); overridePendingTransition(0, 0); startActivity(getIntent()); } /* * */ boolean composeReleaseFocus() { boolean result = false; if (mCurrentComposeFragment != null && mCurrentComposeFragment.hasFocus()) { mCurrentComposeFragment.releaseFocus(true); result = true; } return result; } /* * */ boolean composeHasFocus() { if (mCurrentComposeFragment != null) { return mCurrentComposeFragment.hasFocus(); } return false; } /* * */ boolean composeReleaseFocus(boolean forceCleanup) { boolean result = false; if (mCurrentComposeFragment != null && mCurrentComposeFragment.hasFocus()) { mCurrentComposeFragment.releaseFocus(true); forceCleanup = true; result = true; } if (forceCleanup) { ActionBar actionBar = getActionBar(); actionBar.setTitle(null); actionBar.setDisplayShowTitleEnabled(false); invalidateOptionsMenu(); } return result; } /** * Get a temporary file with a fixed (=known in advance) file name * @param context activity context * @return a temp file in the external storage in a package-specific directory */ private File getFixedTempFile(Context context) { File path = new File(Environment.getExternalStorageDirectory(), context.getPackageName()); if (!path.exists()) path.mkdir(); File tempFile; tempFile = new File(path, "image.tmp"); return tempFile; } /** * Get a temporary file with a unique file name * @param context activity context * @return a temp file in the external storage in a package-specific directory */ private File getTempFile(Context context) { File path = new File(Environment.getExternalStorageDirectory(), context.getPackageName()); if (!path.exists()) path.mkdir(); File tempFile; try { tempFile = File.createTempFile("img_", ".jpg", path); } catch (IOException e) { e.printStackTrace(); // TODO: Customise this generated block tempFile = new File(path, "image.tmp"); } Log.d("NewTweetActivity.getTempFile", tempFile.getAbsolutePath()); return tempFile; } /* * (non-Javadoc) * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem) */ /* @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: if (tweetComposeReleaseFocus() == true) { return true; } break; } return super.onOptionsItemSelected(item); }*/ /* * (non-Javadoc) * @see android.widget.SearchView.OnQueryTextListener#onQueryTextChange(java.lang.String) */ @Override public boolean onQueryTextChange(String newText) { // TODO Auto-generated method stub return false; } /* * (non-Javadoc) * @see android.widget.SearchView.OnQueryTextListener#onQueryTextSubmit(java.lang.String) */ @Override public boolean onQueryTextSubmit(String query) { Intent i = new Intent(getApplicationContext(), SearchActivity.class); i.putExtra("query", query); startActivity(i); return false; } /* * */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (event.getAction() == KeyEvent.ACTION_DOWN) { if (keyCode == KeyEvent.KEYCODE_VOLUME_UP) { if (AppSettings.get().isVolScrollEnabled()) { Intent intent = new Intent("" + SystemEvent.VOLUME_UP_KEY_DOWN); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); return true; } } else if (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN) { if (AppSettings.get().isVolScrollEnabled()) { Intent intent = new Intent("" + SystemEvent.VOLUME_DOWN_KEY_DOWN); LocalBroadcastManager.getInstance(this).sendBroadcast(intent); return true; } } } return super.onKeyDown(keyCode, event); } @Override public boolean onKeyUp(int keyCode, KeyEvent event) { // Early exit on these events so that the volume up/down sound doesn't play // TODO: Handle user options for volume scrolling if ((keyCode == KeyEvent.KEYCODE_VOLUME_UP) || (keyCode == KeyEvent.KEYCODE_VOLUME_DOWN)) { return true; } return super.onKeyUp(keyCode, event); } /* * */ protected PagerAdapter getAdapterForViewPager() { throw new RuntimeException("Derived class must implement me"); } /* * */ protected FragmentStatePagerAdapter getFragmentStatePagerAdapter() { throw new RuntimeException("Derived class must implement me"); } /* * */ private BroadcastReceiver mForceFragmentPagerAdapterRefreshReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { FragmentStatePagerAdapter adapter = getFragmentStatePagerAdapter(); if (adapter != null) { adapter.notifyDataSetChanged(); } } }; /* * */ private BroadcastReceiver mRestartAppReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { restartApp(); } }; /* * */ protected int getInitialLaneIndex() { return 0; } /* * */ public String getPath(Uri uri) { String[] projection = { MediaStore.Images.Media.DATA }; Cursor cursor = managedQuery(uri, projection, null, null, null); if (cursor != null) { //HERE YOU WILL GET A NULLPOINTER IF CURSOR IS NULL THIS CAN BE, IF YOU USED OI FILE MANAGER FOR PICKING THE MEDIA int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); } return null; } /* * (non-Javadoc) * @see android.support.v4.app.FragmentActivity#onActivityResult(int, int, android.content.Intent) */ @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); String imagePath = null; if (requestCode == Constant.REQUEST_CODE_IMAGE_PICKER) { if (resultCode == Activity.RESULT_OK) { Uri selectedImageUri = data.getData(); String selectedImagePath = getPath(selectedImageUri); //File mediaFile = null; if (selectedImagePath != null) { //mediaFile = new File(selectedImagePath); imagePath = selectedImagePath; } else { String fileManagerPath = selectedImageUri.getPath(); imagePath = fileManagerPath; if (fileManagerPath != null) { //mediaFile = new File(fileManagerPath); } } //if (mediaFile != null) { // TwitterManager.get().setStatus(new TwitterStatusUpdate("here is a test status", null, mediaFile), null); //} } } else if (requestCode == Constant.REQUEST_CODE_CAMERA) { if (resultCode == Activity.RESULT_OK) { // large size image File file = getFixedTempFile(this); File newPath = getTempFile(this); boolean success = file.renameTo(newPath); if (success) imagePath = newPath.getAbsolutePath(); else imagePath = file.getAbsolutePath(); //Toast.makeText(this,R.string.picture_attached,Toast.LENGTH_SHORT).show(); } } mShareImagePath = imagePath; if (mComposeTweetFragment != null) { mComposeTweetFragment.setMediaFilePath(imagePath); } } /* * (non-Javadoc) * @see android.app.Activity#onActionModeStarted(android.view.ActionMode) */ @Override public void onActionModeStarted(ActionMode mode) { super.onActionModeStarted(mode); mCurrentActionMode = mode; } /* * (non-Javadoc) * @see android.app.Activity#onActionModeFinished(android.view.ActionMode) */ @Override public void onActionModeFinished(ActionMode mode) { super.onActionModeFinished(mode); mCurrentActionMode = null; } /* * (non-Javadoc) * @see android.app.Activity#onCreateOptionsMenu(android.view.Menu) */ @Override public boolean onCreateOptionsMenu(Menu menu) { super.onCreateOptionsMenu(menu); mCurrentMenu = menu; if (mCurrentComposeFragment == null) { return false; } if (mComposeTweetFragment != null && mComposeTweetFragment.hasFocus()) { MenuInflater inflater = getMenuInflater(); inflater.inflate(R.menu.compose_tweet_action_bar, menu); return true; } else if (mComposeDirectMessageFragment != null && mComposeDirectMessageFragment.hasFocus()) { return true; } else { return configureOptionsMenu(menu); } } /* * */ public boolean configureOptionsMenu(Menu menu) { Integer defaultOptionsMenu = getDefaultOptionsMenu(); if (defaultOptionsMenu != null) { MenuInflater inflater = getMenuInflater(); BaseLaneFragment fragment = mLaneFragmentHashMap.get(getCurrentLaneIndex()); if (fragment != null) { if (fragment.configureOptionsMenu(inflater, menu) == false) { inflater.inflate(defaultOptionsMenu.intValue(), menu); } } else { inflater.inflate(defaultOptionsMenu.intValue(), menu); } if (menu != null && App.getActionLauncherInstalled() == true) { MenuItem buyALP = menu.findItem(R.id.action_buy_alp); if (buyALP != null) { buyALP.setVisible(false); } } configureActionBarSearchView(menu); } return true; } /* * */ public Integer getDefaultOptionsMenu() { return R.menu.default_action_bar; } /* * (non-Javadoc) * @see android.app.Activity#onOptionsItemSelected(android.view.MenuItem) */ @Override public boolean onOptionsItemSelected(MenuItem item) { switch (item.getItemId()) { case android.R.id.home: if (composeReleaseFocus(false) == true) { return true; } break; case R.id.action_gallery: { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*"); startActivityForResult(intent, Constant.REQUEST_CODE_IMAGE_PICKER); //startActivityForResult(new Intent(Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.INTERNAL_CONTENT_URI), Constant.REQUEST_CODE_IMAGE_PICKER); return true; } case R.id.action_camera: { if (Util.isIntentAvailable(this, android.provider.MediaStore.ACTION_IMAGE_CAPTURE)) { Uri tmpUri = Uri.fromFile(getFixedTempFile(BaseLaneActivity.this)); Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); intent.putExtra(MediaStore.EXTRA_OUTPUT, tmpUri); startActivityForResult(intent, Constant.REQUEST_CODE_CAMERA); } return true; } /* case R.id.action_locate: Toast.makeText(getApplicationContext(), getString(R.string.functionality_not_implemented), Constant.DEFAULT_TOAST_DISPLAY_TIME).show(); break; */ default: { BaseLaneFragment fragment = mLaneFragmentHashMap.get(getCurrentLaneIndex()); if (fragment != null) { return fragment.onOptionsItemSelected(item); } } } return false; } /* * */ public boolean isComposing() { return mCurrentComposeFragment != null && mCurrentComposeFragment.hasFocus() ? true : false; } /* * */ protected void configureActionBarSearchView(Menu menu) { MenuItem searchItem = menu.findItem(R.id.action_search); mSearchView = (SearchView) searchItem.getActionView(); searchItem.setShowAsActionFlags( MenuItem.SHOW_AS_ACTION_IF_ROOM | MenuItem.SHOW_AS_ACTION_COLLAPSE_ACTION_VIEW); mSearchView.setOnQueryTextListener(this); OnFocusChangeListener onFocusChangeListener = new OnFocusChangeListener() { @Override public void onFocusChange(View v, boolean hasFocus) { mCurrentComposeFragment.setIgnoreFocusChange(true); if (mComposeTweetView != null) { mComposeTweetView.setVisibility(hasFocus ? View.GONE : View.VISIBLE); } if (mComposeDirectMessageView != null) { mComposeDirectMessageView.setVisibility(hasFocus ? View.GONE : View.VISIBLE); } mCurrentComposeFragment.setIgnoreFocusChange(false); } }; mSearchView.setOnQueryTextFocusChangeListener(onFocusChangeListener); mSearchView.setOnFocusChangeListener(onFocusChangeListener); } /* * */ protected void finishCurrentActionMode() { if (mCurrentActionMode != null) { // This is messy, but to prevent a circular loop, clear mCurrentActionMode before calling .finish() ActionMode curr = mCurrentActionMode; mCurrentActionMode = null; curr.finish(); } } /* * */ protected void setDirectMessageOtherUserScreenName(String otherUserScreenName) { if (mComposeDirectMessageFragment != null) { mComposeDirectMessageFragment.setOtherUserScreenName(otherUserScreenName); } } /* * Override if necessary */ protected ComposeTweetDefault getComposeTweetDefault() { if (mShareImagePath != null) { return new ComposeTweetDefault(null, null, null, mShareImagePath); } return null; } /* * */ protected void setComposeTweetDefault(ComposeTweetDefault composeDefault) { if (mComposeTweetFragment != null) { mComposeTweetFragment.setComposeDefault(composeDefault); } } /* * */ protected void setComposeTweetDefault() { setComposeTweetDefault(getComposeTweetDefault()); } /* * */ protected void setComposeDefault() { if (this.mCurrentComposeFragment == mComposeTweetFragment) { setComposeTweetDefault(); } } /* * */ protected void beginShareStatus(String initialStatus) { if (mComposeTweetFragment != null) { mComposeTweetFragment.beginShare(initialStatus); } } protected void beginShareImage(String imagePath) { mShareImagePath = imagePath; if (imagePath != null && mComposeTweetFragment != null) { mComposeTweetFragment.showCompose(); //mComposeTweet.setMediaFilePath(imagePath); } } public void beginCompose() { if (mCurrentComposeFragment != null) { mCurrentComposeFragment.showCompose(); } } public void beginQuote(TwitterStatus statusToQuote) { if (mComposeTweetFragment != null) { mComposeTweetFragment.beginQuote(statusToQuote); } } public void retweetSelected(TwitterStatus status) { if (mComposeTweetFragment != null) { TwitterUser user = TwitterManager.get().getUser(status.mUserId); if (user != null && user.getProtected() == true) { AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this); alertDialogBuilder.setMessage(getString(R.string.alert_retweet_private)); alertDialogBuilder.setPositiveButton(getString(R.string.ok), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int id) { dialog.cancel(); } }); alertDialogBuilder.create().show(); } else if (mComposeTweetFragment != null) { mComposeTweetFragment.retweetSelected(status); } } } /* * */ public void shareSelected(TwitterStatus status) { if (status != null) { final String statusUrl = status.getTwitterComStatusUrl(); final String statusText = status.mStatus; final ArrayList<String> urls = Util.getUrlsInString(status.mStatus); AlertDialog alertDialog = new AlertDialog.Builder(this).create(); alertDialog.setTitle(getString(R.string.alert_share_title)); alertDialog.setMessage(getString(R.string.alert_share_message)); alertDialog.setIcon(AppSettings.get().getCurrentTheme() == AppSettings.Theme.Holo_Dark ? R.drawable.ic_action_share_dark : R.drawable.ic_action_share_light); // TODO: The order these buttons are set looks wrong, but appears correctly. Have to ensure this is consistent on other devices. alertDialog.setButton2(getString(R.string.share_tweet_link), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { shareText(statusUrl); } }); if (urls != null && urls.size() > 0) { alertDialog.setButton3(getString(R.string.share_tweet), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { shareText(statusText); } }); alertDialog.setButton(getString(urls.size() == 1 ? R.string.share_link : R.string.share_first_link), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { shareText(urls.get(0)); } }); } else { alertDialog.setButton(getString(R.string.share_tweet), new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { shareText(statusText); } }); } alertDialog.show(); } } /* * */ private void shareText(String string) { Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND); sharingIntent.setType("text/plain"); sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, string); startActivity(Intent.createChooser(sharingIntent, "Share via")); } }