I am trying to implement in my Exo media player a TextView title at the top, with a marquee animation.
As far as I can tell, I have set all the necessary attributes, and it does work, but as the text scrolls, I get a weird lag/the animation stop/restarts. I suspect it has something to do with focus?
What do you think, and do have any idea how to solve the issue?
This is my code:
Player activity:
public class MediaPlayerActivity extends Activity implements View.OnClickListener,
PlaybackControlView.VisibilityListener,
ExoPlayer.EventListener,
AdEvent.AdEventListener,
AdErrorEvent.AdErrorListener {
public static final String ACTION_VIEW = "cambium.com.il.sport5.action.VIEW";
public static final String EXTENSION_EXTRA = "extension";
public static final String ACTION_VIEW_LIST = "cambium.com.il.sport5.action.VIEW_LIST";
public static final String URI_LIST_EXTRA = "uri_list";
public static final String EXTENSION_LIST_EXTRA = "extension_list";
private static final String LOG_TAG = "MediaPlayer-ImaAds";
/**
* Constants
*/
private static final DefaultBandwidthMeter BANDWIDTH_METER = new DefaultBandwidthMeter();
private static final CookieManager DEFAULT_COOKIE_MANAGER;
static {
DEFAULT_COOKIE_MANAGER = new CookieManager();
DEFAULT_COOKIE_MANAGER.setCookiePolicy(CookiePolicy.ACCEPT_ORIGINAL_SERVER);
}
/**
* General Obj
*/
private GeneralUtils mGeneralUtils;
private SimpleExoPlayerView simpleExoPlayerView;
private Handler mainHandler;
private DataSource.Factory mediaDataSourceFactory;
private SimpleExoPlayer player;
private DefaultTrackSelector trackSelector;
private TrackSelectionHelper trackSelectionHelper;
private Timeline.Window window;
private boolean isTimelineStatic;
private boolean playerNeedsSource;
private long playerPosition;
private int playerWindow;
private boolean shouldAutoPlay;
/**
* UI
*/
private View rootView;
private PlaybackControlView controlsRootView;
private Button retryButton;
private RelativeLayout mediaPlayerLoader;
private LinearLayout mTopBar;
private CustomTextView mVideoTitle;
private ImageButton mVideoBackBtn;
/**
* IMA ads
*/
/* Factory class for creating SDK objects */
private ImaSdkFactory mSdkFactory;
/* The AdsLoader instance exposes the requestAds method */
private AdsLoader mAdsLoader;
/* AdsManager exposes methods to control ad playback and listen to ad events */
private AdsManager mAdsManager;
/* Whether an ad is displayed */
private boolean mIsAdDisplayed;
/**
* =================
* Lifecycle methods
* =================
*/
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
initActivity();
setContentView(R.layout.activity_media_player);
getViews();
setListeners();
createAdsLoader();
}
#Override
public void onNewIntent(Intent intent) {
releasePlayer();
isTimelineStatic = false;
setIntent(intent);
}
#Override
public void onResume() {
if (mAdsManager != null && mIsAdDisplayed) {
mAdsManager.resume();
} else if (player != null && player.getPlaybackState() == ExoPlayer.STATE_READY) {
player.setPlayWhenReady(true);
}
super.onResume();
}
#Override
public void onPause() {
if (mAdsManager != null && mIsAdDisplayed) {
mAdsManager.pause();
}
if (player != null)
player.setPlayWhenReady(false);
super.onPause();
}
#Override
public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
#Override
protected void onStop() {
releasePlayer();
window = null;
mediaDataSourceFactory = null;
mainHandler = null;
mSdkFactory = null;
mAdsLoader = null;
mAdsLoader = null;
isTimelineStatic = false;
finish();
super.onStop();
}
#Override
public void onBackPressed() {
super.onBackPressed();
}
/**
* =================
* Helper methods
* =================
*/
private void initActivity() {
mGeneralUtils = GeneralUtils.getInstance();
mediaDataSourceFactory = buildDataSourceFactory(true);
mainHandler = new Handler();
window = new Timeline.Window();
if (CookieHandler.getDefault() != DEFAULT_COOKIE_MANAGER) {
CookieHandler.setDefault(DEFAULT_COOKIE_MANAGER);
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}
private void getViews() {
rootView = findViewById(R.id.root);
controlsRootView = (PlaybackControlView) findViewById(R.id.controls_root);
retryButton = (Button) findViewById(R.id.retry_button);
simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);
mediaPlayerLoader = (RelativeLayout) findViewById(R.id.mediaPlayerLoader);
mTopBar = (LinearLayout) findViewById(R.id.topBar);
mVideoBackBtn = (ImageButton) findViewById(R.id.videoBackBtn);
mVideoTitle = (CustomTextView) findViewById(R.id.videoPlayerTitle);
mVideoTitle.setSelected(true);
mVideoTitle.setFocusable(true);
mVideoTitle.setFocusableInTouchMode(true);
}
private void setListeners() {
rootView.setOnClickListener(this);
simpleExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.player_view);
simpleExoPlayerView.setControllerVisibilityListener(this);
simpleExoPlayerView.requestFocus();
retryButton.setOnClickListener(this);
mVideoBackBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
onBackPressed();
}
});
}
private void showToast(int messageId) {
showToast(getString(messageId));
}
private void showToast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_LONG).show();
}
/**
* =================
* Exo player
* =================
*/
private void initPlayer() {
Intent intent = getIntent();
String action = intent.getAction();
if (player == null) {
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveVideoTrackSelection.Factory(BANDWIDTH_METER);
trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
trackSelectionHelper = new TrackSelectionHelper(trackSelector, videoTrackSelectionFactory);
player = ExoPlayerFactory.newSimpleInstance(this, trackSelector, new DefaultLoadControl());
player.addListener(this);
simpleExoPlayerView.setPlayer(player);
if (isTimelineStatic) {
if (playerPosition == C.TIME_UNSET) {
player.seekToDefaultPosition(playerWindow);
} else {
player.seekTo(playerWindow, playerPosition);
}
}
player.setPlayWhenReady(shouldAutoPlay);
playerNeedsSource = true;
if (playerNeedsSource) {
Uri[] uris;
String[] extensions;
if (ACTION_VIEW.equals(action)) {
uris = new Uri[]{intent.getData()};
extensions = new String[]{intent.getStringExtra(EXTENSION_EXTRA)};
} else if (ACTION_VIEW_LIST.equals(action)) {
String[] uriStrings = intent.getStringArrayExtra(URI_LIST_EXTRA);
uris = new Uri[uriStrings.length];
for (int i = 0; i < uriStrings.length; i++) {
uris[i] = Uri.parse(uriStrings[i]);
}
extensions = intent.getStringArrayExtra(EXTENSION_LIST_EXTRA);
if (extensions == null) {
extensions = new String[uriStrings.length];
}
} else {
showToast(getString(R.string.unexpected_intent_action, action));
return;
}
MediaSource[] mediaSources = new MediaSource[uris.length];
for (int i = 0; i < uris.length; i++) {
mediaSources[i] = buildMediaSource(uris[i], extensions[i]);
}
MediaSource mediaSource = mediaSources.length == 1 ? mediaSources[0]
: new ConcatenatingMediaSource(mediaSources);
player.prepare(mediaSource, !isTimelineStatic, !isTimelineStatic);
playerNeedsSource = false;
mGeneralUtils.zoomOutAnimation(mediaPlayerLoader);
updateButtonVisibilities();
}
}
}
private void releasePlayer() {
if (player != null) {
playerWindow = player.getCurrentWindowIndex();
playerPosition = C.TIME_UNSET;
Timeline timeline = player.getCurrentTimeline();
if (!timeline.isEmpty() && timeline.getWindow(playerWindow, window).isSeekable) {
playerPosition = player.getCurrentPosition();
}
player.release();
player = null;
trackSelector = null;
trackSelectionHelper = null;
}
}
private void updateButtonVisibilities() {
controlsRootView.removeAllViews();
retryButton.setVisibility(playerNeedsSource ? View.VISIBLE : View.GONE);
controlsRootView.addView(retryButton);
if (player == null) {
return;
}
}
private void showControls() {
controlsRootView.setVisibility(View.VISIBLE);
}
private DataSource.Factory buildDataSourceFactory(boolean useBandwidthMeter) {
return ((Sport5App) getApplication())
.buildDataSourceFactory(useBandwidthMeter ? BANDWIDTH_METER : null);
}
private MediaSource buildMediaSource(Uri uri, String overrideExtension) {
int type = Util.inferContentType(!TextUtils.isEmpty(overrideExtension) ? "." + overrideExtension
: uri.getLastPathSegment());
switch (type) {
case C.TYPE_SS:
return new SsMediaSource(uri, buildDataSourceFactory(false),
new DefaultSsChunkSource.Factory(mediaDataSourceFactory), mainHandler, null);
case C.TYPE_DASH:
return new DashMediaSource(uri, buildDataSourceFactory(false),
new DefaultDashChunkSource.Factory(mediaDataSourceFactory), mainHandler, null);
case C.TYPE_HLS:
return new HlsMediaSource(uri, mediaDataSourceFactory, mainHandler, null);
case C.TYPE_OTHER:
return new ExtractorMediaSource(uri, mediaDataSourceFactory, new DefaultExtractorsFactory(),
mainHandler, null);
default: {
throw new IllegalStateException("Unsupported type: " + type);
}
}
}
/**
* =================
* Listener methods
* =================
*/
#Override /* View.OnClickListener */
public void onClick(View view) {
if (view == retryButton) {
shouldAutoPlay = true;
initPlayer();
} else if (view.getParent() == controlsRootView) {
MappingTrackSelector.MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo != null) {
trackSelectionHelper.showSelectionDialog(this, ((Button) view).getText(),
trackSelector.getCurrentMappedTrackInfo(), (int) view.getTag());
}
}
}
#Override /* PlaybackControlView.VisibilityListener */
public void onVisibilityChange(int visibility) {
controlsRootView.setVisibility(visibility);
mTopBar.setVisibility(visibility);
}
#Override /* ExoPlayer.EventListener */
public void onTimelineChanged(Timeline timeline, Object manifest) {
isTimelineStatic = !timeline.isEmpty()
&& !timeline.getWindow(timeline.getWindowCount() - 1, window).isDynamic;
}
#Override /* ExoPlayer.EventListener */
public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) {
updateButtonVisibilities();
MappingTrackSelector.MappedTrackInfo mappedTrackInfo = trackSelector.getCurrentMappedTrackInfo();
if (mappedTrackInfo != null) {
if (mappedTrackInfo.getTrackTypeRendererSupport(C.TRACK_TYPE_VIDEO)
== MappingTrackSelector.MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
showToast(R.string.error_unsupported_video);
}
if (mappedTrackInfo.getTrackTypeRendererSupport(C.TRACK_TYPE_AUDIO)
== MappingTrackSelector.MappedTrackInfo.RENDERER_SUPPORT_UNSUPPORTED_TRACKS) {
showToast(R.string.error_unsupported_audio);
}
}
}
#Override /* ExoPlayer.EventListener */
public void onLoadingChanged(boolean isLoading) {
}
#Override /* ExoPlayer.EventListener */
public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
if (playbackState == ExoPlayer.STATE_ENDED) {
// Handle completed event for playing post-rolls.
if (mAdsLoader != null) {
mAdsLoader.contentComplete();
}
showControls();
finish();
}
if (playbackState == ExoPlayer.STATE_BUFFERING) {
// Handle completed event for playing post-rolls.
/*Toast.makeText(this, "STATE_BUFFERING", Toast.LENGTH_SHORT).show();*/
}
if (playbackState == ExoPlayer.STATE_IDLE) {
// Handle completed event for playing post-rolls.
/*Toast.makeText(this, "STATE_IDLE", Toast.LENGTH_SHORT).show();*/
}
if (playbackState == ExoPlayer.STATE_READY) {
// Handle completed event for playing post-rolls.
/*Toast.makeText(this, "STATE_READY", Toast.LENGTH_SHORT).show();*/
}
updateButtonVisibilities();
}
#Override /* ExoPlayer.EventListener */
public void onPlayerError(ExoPlaybackException e) {
String errorString = null;
if (e.type == ExoPlaybackException.TYPE_RENDERER) {
Exception cause = e.getRendererException();
if (cause instanceof MediaCodecRenderer.DecoderInitializationException) {
// Special case for decoder initialization failures.
MediaCodecRenderer.DecoderInitializationException decoderInitializationException =
(MediaCodecRenderer.DecoderInitializationException) cause;
if (decoderInitializationException.decoderName == null) {
if (decoderInitializationException.getCause() instanceof MediaCodecUtil.DecoderQueryException) {
errorString = getString(R.string.error_querying_decoders);
} else if (decoderInitializationException.secureDecoderRequired) {
errorString = getString(R.string.error_no_secure_decoder,
decoderInitializationException.mimeType);
} else {
errorString = getString(R.string.error_no_decoder,
decoderInitializationException.mimeType);
}
} else {
errorString = getString(R.string.error_instantiating_decoder,
decoderInitializationException.decoderName);
}
}
}
if (errorString != null) {
showToast(errorString);
}
playerNeedsSource = true;
updateButtonVisibilities();
showControls();
}
#Override /* ExoPlayer.EventListener */
public void onPositionDiscontinuity() {
}
#Override /* AdErrorEvent.AdErrorListener */
public void onAdError(AdErrorEvent adErrorEvent) {
Log.e(LOG_TAG, "Ad Error: " + adErrorEvent.getError().getMessage());
if (player != null)
player.setPlayWhenReady(true);
else {
shouldAutoPlay = true;
initPlayer();
}
}
#Override /* AdEvent.AdEventListener */
public void onAdEvent(AdEvent adEvent) {
Log.i(LOG_TAG, "Event: " + adEvent.getType());
// These are the suggested event types to handle. For full list of all ad event
// types, see the documentation for AdEvent.AdEventType.
switch (adEvent.getType()) {
case LOADED:
// AdEventType.LOADED will be fired when ads are ready to be played.
// AdsManager.start() begins ad playback. This method is ignored for VMAP or
// ad rules playlists, as the SDK will automatically start executing the
// playlist.
mGeneralUtils.zoomOutAnimation(mediaPlayerLoader);
mAdsManager.start();
break;
case CONTENT_PAUSE_REQUESTED:
// AdEventType.CONTENT_PAUSE_REQUESTED is fired immediately before a video
// ad is played.
mIsAdDisplayed = true;
player.setPlayWhenReady(false);
break;
case CONTENT_RESUME_REQUESTED:
// AdEventType.CONTENT_RESUME_REQUESTED is fired when the ad is completed
// and you should start playing your content.
mIsAdDisplayed = false;
if (player != null)
player.setPlayWhenReady(true);
else {
shouldAutoPlay = true;
initPlayer();
}
break;
case ALL_ADS_COMPLETED:
if (mAdsManager != null) {
mAdsManager.destroy();
mAdsManager = null;
}
break;
default:
break;
}
}
/**
* ================
* IMA ADS
* ================
*/
private void createAdsLoader() {
String adUrl = DataUtils.getInstance().getAdsAdmin().getAdInPlayerUrl();
adUrl = null;
// Create an AdsLoader.
mSdkFactory = ImaSdkFactory.getInstance();
mAdsLoader = mSdkFactory.createAdsLoader(this);
// Add listeners for when ads are loaded and for errors.
mAdsLoader.addAdErrorListener(this);
mAdsLoader.addAdsLoadedListener(new AdsLoader.AdsLoadedListener() {
#Override
public void onAdsManagerLoaded(AdsManagerLoadedEvent adsManagerLoadedEvent) {
// Ads were successfully loaded, so get the AdsManager instance. AdsManager has
// events for ad playback and errors.
mAdsManager = adsManagerLoadedEvent.getAdsManager();
// Attach event and error event listeners.
mAdsManager.addAdErrorListener(MediaPlayerActivity.this);
mAdsManager.addAdEventListener(MediaPlayerActivity.this);
mAdsManager.init();
shouldAutoPlay = false;
initPlayer();
}
});
if (adUrl == null || adUrl.equals("")) {
shouldAutoPlay = true;
initPlayer();
} else {
shouldAutoPlay = false;
requestAds(adUrl);
}
// When Play is clicked, request ads and hide the button.
/*mPlayButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mVideoPlayer.setVideoPath(getString(R.string.content_url));
requestAds(getString(R.string.ad_tag_url));
view.setVisibility(View.GONE);
}
});*/
}
private void requestAds(String adTagUrl) {
AdDisplayContainer adDisplayContainer = mSdkFactory.createAdDisplayContainer();
adDisplayContainer.setAdContainer(simpleExoPlayerView);
// Create the ads request.
AdsRequest request = mSdkFactory.createAdsRequest();
request.setAdTagUrl(adTagUrl);
request.setAdDisplayContainer(adDisplayContainer);
request.setContentProgressProvider(new ContentProgressProvider() {
#Override
public VideoProgressUpdate getContentProgress() {
if (mIsAdDisplayed || player == null || player.getDuration() <= 0) {
return VideoProgressUpdate.VIDEO_TIME_NOT_READY;
}
return new VideoProgressUpdate(player.getCurrentPosition(),
player.getDuration());
}
});
// Request the ad. After the ad is loaded, onAdsManagerLoaded() will be called.
mAdsLoader.requestAds(request);
}
}
My Layout xml:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:id="#+id/root"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#android:color/black"
android:keepScreenOn="true"
android:orientation="vertical">
<!-- Player view -->
<com.google.android.exoplayer2.ui.SimpleExoPlayerView
android:id="#+id/player_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
<!-- Loader container -->
<RelativeLayout
android:id="#+id/mediaPlayerLoader"
android:layout_width="124dp"
android:layout_height="124dp"
android:layout_centerInParent="true">
<com.mikhaellopez.circularimageview.CircularImageView
android:layout_width="121dp"
android:layout_height="121dp"
android:layout_centerInParent="true"
android:src="#drawable/ic_sport5_loader"
app:civ_border="true" />
<!-- Loader-->
<fr.castorflex.android.circularprogressbar.CircularProgressBar xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:indeterminate="true"
app:cpb_color="#color/colorPrimary"
app:cpb_max_sweep_angle="300"
app:cpb_min_sweep_angle="10"
app:cpb_stroke_width="4dp" />
</RelativeLayout>
<!-- Top bar -->
<LinearLayout
android:id="#+id/topBar"
android:layout_width="match_parent"
android:layout_height="56dp"
android:background="#88000000"
android:orientation="horizontal" >
<ImageButton
android:id="#+id/videoBackBtn"
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_margin="16dp"
android:layout_gravity="center_vertical"
android:background="#null"
android:src="#drawable/hplib_ic_back" />
<cambium.com.il.sport5.views.CustomTextView
android:id="#+id/videoPlayerTitle"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:gravity="center|right"
android:layout_gravity="center_vertical"
android:text="אתר ערוץ הספורט - חדשות הספורט, תוצאות, תקצירים ושידורים - Sport5.co.il"
android:textColor="#FFF"
android:textStyle="italic"
android:singleLine="true"
android:ellipsize="marquee"
android:marqueeRepeatLimit="marquee_forever"
android:scrollHorizontally="true"
android:focusable="true"
android:focusableInTouchMode="true"/>
<ImageView
android:id="#+id/sport5Ic"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_vertical"
android:padding="16dp"
android:scaleType="centerCrop"
android:src="#drawable/ic_sport5" />
</LinearLayout>
<!-- New player controls -->
<com.google.android.exoplayer2.ui.PlaybackControlView
android:id="#+id/controls_root"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:background="#88000000">
<Button
android:id="#+id/retry_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Retry"
android:visibility="gone"/>
</com.google.android.exoplayer2.ui.PlaybackControlView>
<!-- Old controls -->
<LinearLayout
android:id="#+id/controls"
android:layout_width="match_parent"
android:layout_height="48dp"
android:layout_gravity="bottom"
android:background="#88000000"
android:orientation="horizontal"
android:visibility="gone">
<ImageButton
android:id="#+id/btn_lock"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center_vertical"
android:layout_marginLeft="20dp"
android:layout_weight="0"
android:background="#null"
android:src="#drawable/hplib_ic_lock" />
<View
android:layout_width="0dp"
android:layout_height="1dp"
android:layout_gravity="bottom"
android:layout_weight="1" />
<ImageButton
android:id="#+id/btn_settings"
android:layout_width="32dp"
android:layout_height="32dp"
android:layout_gravity="center_vertical"
android:layout_marginRight="20dp"
android:layout_weight="0"
android:background="#null"
android:src="#drawable/hplib_ic_settings"
android:text="Settings" />
</LinearLayout>
and finally a shared link to a short video displaying the issue:
https://1drv.ms/v/s!AkkKHWeBCU1WhZwAmz3YW1rlhyYTHA
Thank you
The problem turned out to be setting a width of 0dp with a weightSum of 1.
Just wrapped the text view in a RelativeLayout instead of a LinearLayout, and everything is working as expected.
Related
I am using FlexboxLayout for showing chips in android but stuck at UI Where I want to show number of chips count at the end of second line as per below screenshot
As per above design I want to show chips until second line and the chips that not fit in second line should increase chip count at the end of chips
What I have check is
1- FlexboxLayout setMaxLine(2); But in this case UI only two line draw and second line is strech
2- FlexboxLayout getFlexLineInternel() - this API gives wrong result. Count of line is increases after 1 item added in the line then it gives getFlexLineInternel().size() == 2 it means view is already added in third line but I want to restrict only on 2 lines.
3- Try with Material Chip and ChipGroup - It didn't given me number of lines draw in chipGroup
4- Try with Flowlayout similar as ChipGroup. Didn't given me number of lines draw by layout so that I can show count at end of second line
Please give me suggestion what is helpful in my situation
Here is my code
activity_search_label.xml
<com.google.android.flexbox.FlexboxLayout
android:id="#+id/assetLabelsContainer"
android:layout_width="match_parent"
android:layout_marginLeft="#dimen/size_16"
android:layout_marginRight="#dimen/size_16"
android:layout_height="wrap_content"
app:flexWrap="wrap"/>
LabelSearchActivity.java
public class LabelSearchActivity extends SearchActivity {
#BindView(R.id.assetLabelsContainer)
public FlexboxLayout assetLabelsContainer;
private int COUNTER_LABEL_ID = -1;
private ArrayList<LabelModelParcelableItem> selectedLabels;
private ArrayList<LabelModelParcelableItem> visibleSelectedList;
private CompositeDisposable disposables;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
clearLabelList();
showSelectedLabel();
}
public void hideSearchTitleCountView() {
if (null != searchTitle) {
searchTitle.setVisibility(View.GONE);
}
}
private void clearLabelList() {
selectedLabels = new ArrayList<>();
visibleSelectedList = new ArrayList<>();
assetLabelsContainer.getFlexLinesInternal().clear();
assetLabelsContainer.removeAllViews();
}
private void showSelectedLabel() {
if (getIntent() != null) {
Bundle bundle = getIntent().getExtras();
if (bundle.getParcelableArrayList(SELECTED_LABEL_ITEMS) != null) {
ArrayList<LabelModelParcelableItem> selectedLabels = bundle
.getParcelableArrayList(SELECTED_LABEL_ITEMS);
showLabelList(selectedLabels);
}
}
}
public void addViewToFlex(final LabelModelParcelableItem labelModelParcelableItem) {
if (!selectedLabels.contains(labelModelParcelableItem)) {
selectedLabels.add(labelModelParcelableItem);
final View view = getChipView(labelModelParcelableItem);
if (shouldShowCount()) {
View countView = getCounterView();
if (null != countView) {
LabelModelParcelableItem tag = (LabelModelParcelableItem) countView.getTag();
LabelModelParcelableItem updatedTag =
new LabelModelParcelableItem(
tag.getLabelId(), String.valueOf(getInvisibleItemCount()), tag.getAssetCount());
TextView textView = (TextView) countView.findViewById(R.id.labelNameText);
textView.setText(" + " + updatedTag.getLabelName());
countView.setTag(updatedTag);
assetLabelsContainer.requestLayout();
} else {
addCounterView();
}
} else {
visibleSelectedList.add(labelModelParcelableItem);
assetLabelsContainer.addView(view);
}
}
}
public int getInvisibleItemCount() {
ArrayList<LabelModelParcelableItem> itemList = new ArrayList<>(selectedLabels);
itemList.removeAll(visibleSelectedList);
return itemList.size();
}
private void addCounterView() {
final View view =
LayoutInflater.from(LabelSearchActivity.this)
.inflate(R.layout.label, assetLabelsContainer, false);
LabelModelParcelableItem item =
new LabelModelParcelableItem(
COUNTER_LABEL_ID, String.valueOf(getInvisibleItemCount()), COUNTER_LABEL_ID);
view.setTag(item);
TextView textView = (TextView) view.findViewById(R.id.labelNameText);
textView.setText(" + " + item.getLabelName());
view.setOnClickListener(v -> showLabelContainerScreen(getSelectedLabels()));
if (getInvisibleItemCount() > 0) {
assetLabelsContainer.addView(view);
}
}
public View getChipView(final LabelModelParcelableItem item) {
final View view =
LayoutInflater.from(LabelSearchActivity.this)
.inflate(R.layout.label, assetLabelsContainer, false);
TextView textView = (TextView) view.findViewById(R.id.labelNameText);
textView.setText(item.getLabelName());
view.setOnClickListener(v -> removeViewFormFlex(view, item));
return view;
}
private boolean shouldShowCount() {
if (assetLabelsContainer.getFlexLinesInternal().size() > 2) {
return true;
}
return false;
}
private void updatedLabelAfterRemove() {
if (null != getCounterView()) {
if (getInvisibleItemCount() > 0) {
ArrayList<LabelModelParcelableItem> itemList = new ArrayList<>(selectedLabels);
itemList.removeAll(visibleSelectedList);
Collections.sort(itemList, (o1, o2) -> o2.getLabelName().compareTo(o1.getLabelName()));
if (!itemList.isEmpty()) {
addViewAfterRemove(itemList.get(0));
}
} else {
assetLabelsContainer.removeView(getCounterView());
}
}
}
private void addViewAfterRemove(LabelModelParcelableItem item) {
final View labelView = getChipView(item);
View countView = getCounterView();
if (countView != null) {
assetLabelsContainer.removeView(countView);
visibleSelectedList.add(item);
assetLabelsContainer.addView(labelView);
addCounterView();
} else {
visibleSelectedList.add(item);
assetLabelsContainer.addView(labelView);
}
}
private View getCounterView() {
View countView =
assetLabelsContainer.getFlexItemAt(assetLabelsContainer.getFlexItemCount() - 1);
if (null != countView) {
LabelModelParcelableItem item = (LabelModelParcelableItem) countView.getTag();
if (item != null && item.getLabelId() == -1) {
return countView;
}
}
return null;
}
private void showLabelList(ArrayList<LabelModelParcelableItem> selectedLabels) {
for (LabelModelParcelableItem item : selectedLabels) {
addViewToFlex(item);
assetLabelsContainer.post(() -> assetLabelsContainer.requestLayout());
}
}
public void addSelectedLabel(Parcelable label) {
addViewToFlex((LabelModelParcelableItem) label);
}
public ArrayList<LabelModelParcelableItem> getSelectedLabels() {
return selectedLabels;
}
public List<Parcelable> getUpdatedLabelList(List<? extends Parcelable> newParcelableList) {
if (null != newParcelableList && !newParcelableList.isEmpty()) {
newParcelableList.removeAll(getSelectedLabels());
return new ArrayList<>(newParcelableList);
} else {
return new ArrayList<>();
}
}
public void labelUpdateList(List dataList) {
getSearchAdapter().clearAndUpdateList(dataList);
}
#Override
public void onBackButtonPressed() {
setActivityResult(getSelectedLabels());
}
public void setActivityResult(ArrayList<? extends Parcelable> searchableItem) {
setResult(RESULT_OK, new Intent().putParcelableArrayListExtra(SEARCH_RESULT, searchableItem));
super.onBackButtonPressed();
}
public void addDisposable(Disposable disposable) {
if (null == disposables) {
disposables = new CompositeDisposable();
}
disposables.add(disposable);
}
#Override
public void onDestroy() {
if (disposables != null && !disposables.isDisposed()) {
disposables.clear();
}
super.onDestroy();
}
private void showLabelContainerScreen(List<? extends Parcelable> labels) {
Intent intent = new Intent(this, ViewLabelsActivity.class);
Bundle bundle = new Bundle();
bundle.putParcelableArrayList(
LabelSelectionActivity.ARGUMENT_KEY, (ArrayList<? extends Parcelable>) labels);
intent.putExtras(bundle);
startActivityForResult(intent, LabelSelectionActivity.VIEW_ALL_LABEL_CODE);
}
#Override
public void onBackPressed() {
if (!getSelectedLabels().isEmpty()) {
Intent intent = new Intent();
intent.putParcelableArrayListExtra(
SELECTED_LABEL_ITEMS, (ArrayList<? extends Parcelable>) getSelectedLabels());
setResult(Activity.RESULT_OK, intent);
} else {
this.finish();
}
super.onBackPressed();
}
#OnClick(R.id.navBarBack)
public void onBackButton() {
onBackPressed();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != LabelSelectionActivity.VIEW_ALL_LABEL_CODE) {
return;
}
if (data == null) {
return;
}
if (resultCode != RESULT_OK) {
return;
}
if (!data.hasExtra(SELECTED_LABEL_ITEMS)) {
return;
}
clearLabelList();
ArrayList<LabelModelParcelableItem> selectedLabels =
data.getParcelableArrayListExtra(SELECTED_LABEL_ITEMS);
showLabelList(selectedLabels);
updateAfterViewAllLabels(selectedLabels);
}
private void updateAfterViewAllLabels(ArrayList<LabelModelParcelableItem> labelsAfterRemoved) {
ArrayList<LabelModelParcelableItem> listOfRemovedLabels = new ArrayList<>(getSelectedLabels());
listOfRemovedLabels.removeAll(labelsAfterRemoved);
for (LabelModelParcelableItem item : labelsAfterRemoved) {
//removeViewFormFlex(item);
}
}
public void removeViewFormFlex(View view, LabelModelParcelableItem item) {
if (selectedLabels.remove(item)) {
if (selectedLabels.isEmpty()) {
assetLabelsContainer.removeAllViews();
} else {
visibleSelectedList.remove(item);
assetLabelsContainer.removeView(view);
}
updatedLabelAfterRemove();
Comparator<LabelModelParcelableItem> compareByName =
(o1, o2) -> o1.getLabelName().compareTo(o2.getLabelName());
getSearchAdapter().addLabelItemToList(item, compareByName);
}
}
}
As per above code it look like below image
try to measure the height of FlexboxLayout after each flexboxLayout.addView(view) and if the width increased that is mean you are in second line.
I am using floating action button for navigation from one activity to another but when i am clicking then app is crashing, there is no problem in floating action button, problem is in another activity where its been navigated. And its been navigated to uploadPost class.
public class uploadPost extends Fragment implements SelectPhotoDialog.OnPhotoSelectedListener {
private static final String TAG = "uploadPost";
#Override
public void getImagePath(Uri imagePath) {
Log.d(TAG, "getImagePath: setting the image to imageview");
UniversalImageLoader.setImage(imagePath.toString(), mPostImage);
//assign to global variable
mSelectedBitmap = null;
mSelectedUri = imagePath;
}
#Override
public void getImageBitmap(Bitmap bitmap) {
Log.d(TAG, "getImageBitmap: setting the image to imageview");
mPostImage.setImageBitmap(bitmap);
//assign to a global variable
mSelectedUri = null;
mSelectedBitmap = bitmap;
}
//widgets
private ImageView mPostImage;
private EditText mTitle, mDescription, mPrice, mCountry, mStateProvince, mCity, mContactEmail,mCollege;
private Button mPost;
private ProgressBar mProgressBar;
//vars
private Bitmap mSelectedBitmap;
private Uri mSelectedUri;
private byte[] mUploadBytes;
private double mProgress = 0;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_upload_post, container, false);
mPostImage = view.findViewById(R.id.post_image);
mTitle = view.findViewById(R.id.input_title);
mDescription = view.findViewById(R.id.input_description);
mPrice = view.findViewById(R.id.input_price);
mCountry = view.findViewById(R.id.input_country);
mStateProvince = view.findViewById(R.id.input_state_province);
mCity = view.findViewById(R.id.input_city);
mContactEmail = view.findViewById(R.id.input_email);
mCollege = view.findViewById(R.id.input_clg);
mPost = view.findViewById(R.id.btn_post);
mProgressBar = (ProgressBar) view.findViewById(R.id.progressBar);
mCountry.setText("India");
mStateProvince.setText("Maharashtra");
mCity.setText("Pune");
getActivity().getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_PAN);
init();
return view;
}
private void init(){
mPostImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: opening dialog to choose new photo");
SelectPhotoDialog dialog = new SelectPhotoDialog();
dialog.show(getFragmentManager(), getString(R.string.dialog_select_photo));
dialog.setTargetFragment(uploadPost.this, 1);
}
});
mPost.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Log.d(TAG, "onClick: attempting to post...");
if(!isEmpty(mTitle.getText().toString())
&& !isEmpty(mDescription.getText().toString())
&& !isEmpty(mPrice.getText().toString())
&& !isEmpty(mCountry.getText().toString())
&& !isEmpty(mStateProvince.getText().toString())
&& !isEmpty(mCity.getText().toString())
&& !isEmpty(mContactEmail.getText().toString())){
//we have a bitmap and no Uri
if(mSelectedBitmap != null && mSelectedUri == null){
uploadNewPhoto(mSelectedBitmap);
}
//we have no bitmap and a uri
else if(mSelectedBitmap == null && mSelectedUri != null){
uploadNewPhoto(mSelectedUri);
}
}else{
Toast.makeText(getActivity(), "You must fill out all the fields", Toast.LENGTH_SHORT).show();
}
}
});
}
private void uploadNewPhoto(Bitmap bitmap){
Log.d(TAG, "uploadNewPhoto: uploading a new image bitmap to storage");
BackgroundImageResize resize = new BackgroundImageResize(bitmap);
Uri uri = null;
resize.execute(uri);
}
private void uploadNewPhoto(Uri imagePath){
Log.d(TAG, "uploadNewPhoto: uploading a new image uri to storage.");
BackgroundImageResize resize = new BackgroundImageResize(null);
resize.execute(imagePath);
}
public class BackgroundImageResize extends AsyncTask<Uri, Integer, byte[]>{
Bitmap mBitmap;
public BackgroundImageResize(Bitmap bitmap) {
if(bitmap != null){
this.mBitmap = bitmap;
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(getActivity(), "compressing image", Toast.LENGTH_SHORT).show();
showProgressBar();
}
#Override
protected byte[] doInBackground(Uri... params) {
Log.d(TAG, "doInBackground: started.");
if(mBitmap == null){
try{
RotateBitmap rotateBitmap = new RotateBitmap();
mBitmap = rotateBitmap.HandleSamplingAndRotationBitmap(getActivity(), params[0]);
}catch (IOException e){
Log.e(TAG, "doInBackground: IOException: " + e.getMessage());
}
}
byte[] bytes = null;
Log.d(TAG, "doInBackground: megabytes before compression: " + mBitmap.getByteCount() / 1000000 );
bytes = getBytesFromBitmap(mBitmap, 100);
Log.d(TAG, "doInBackground: megabytes before compression: " + bytes.length / 1000000 );
return bytes;
}
#Override
protected void onPostExecute(byte[] bytes) {
super.onPostExecute(bytes);
mUploadBytes = bytes;
hideProgressBar();
//execute the upload task
executeUploadTask();
}
}
private void executeUploadTask(){
Toast.makeText(getActivity(), "uploading image", Toast.LENGTH_SHORT).show();
final String postId = FirebaseDatabase.getInstance().getReference().push().getKey();
final StorageReference storageReference = FirebaseStorage.getInstance().getReference()
.child("posts/users/" + FirebaseAuth.getInstance().getCurrentUser().getUid() +
"/" + postId + "/post_image");
UploadTask uploadTask = storageReference.putBytes(mUploadBytes);
uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(getActivity(), "Post Success", Toast.LENGTH_SHORT).show();
//insert the download url into the firebase database
Uri firebaseUri = taskSnapshot.getDownloadUrl();
Log.d(TAG, "onSuccess: firebase download url: " + firebaseUri.toString());
DatabaseReference reference = FirebaseDatabase.getInstance().getReference();
Post post = new Post();
post.setImage(firebaseUri.toString());
post.setCity(mCity.getText().toString());
post.setContact_email(mContactEmail.getText().toString());
post.setCountry(mCountry.getText().toString());
post.setDescription(mDescription.getText().toString());
post.setPost_id(postId);
post.setPrice(mPrice.getText().toString());
post.setState_province(mStateProvince.getText().toString());
post.setTitle(mTitle.getText().toString());
post.setUser_id(FirebaseAuth.getInstance().getCurrentUser().getUid());
post.setCollege(mCollege.getText().toString());
reference.child(getString(R.string.node_posts))
.child(postId)
.setValue(post);
resetFields();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(getActivity(), "could not upload photo", Toast.LENGTH_SHORT).show();
}
}).addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
#Override
public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
double currentProgress = (100 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
if( currentProgress > (mProgress + 15)){
mProgress = (100 * taskSnapshot.getBytesTransferred()) / taskSnapshot.getTotalByteCount();
Log.d(TAG, "onProgress: upload is " + mProgress + "& done");
Toast.makeText(getActivity(), mProgress + "%", Toast.LENGTH_SHORT).show();
}
}
});
}
public static byte[] getBytesFromBitmap(Bitmap bitmap, int quality){
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, quality,stream);
return stream.toByteArray();
}
private void resetFields(){
UniversalImageLoader.setImage("", mPostImage);
mTitle.setText("");
mDescription.setText("");
mPrice.setText("");
mCountry.setText("India");
mStateProvince.setText("Maharashtra");
mCity.setText("Pune");
mContactEmail.setText("");
mCollege.setText("");
}
private void showProgressBar(){
mProgressBar.setVisibility(View.VISIBLE);
}
private void hideProgressBar(){
if(mProgressBar.getVisibility() == View.VISIBLE){
mProgressBar.setVisibility(View.INVISIBLE);
}
}
/**
* Return true if the #param is null
* #param string
* #return
*/
private boolean isEmpty(String string){
return string.equals("");
}
}
And it is been navigated from SearchActivity class
public class SearchActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener{
private static final String TAG = "SearchActivity";
private static final int REQUEST_CODE = 1;
private FirebaseAuth.AuthStateListener mAuthStateListener;
//widgets
private TabLayout mTabLayout;
public ViewPager mViewPager;
//vars
public SectionsPagerAdapter mPagerAdapter;
//navigation drawer
private DrawerLayout mDrawerLayout;
private ActionBarDrawerToggle mToggle;
//user info
TextView uname,uemail;
String pemail,pname;
ImageView pimage;
CoordinatorLayout navigation;
FloatingActionButton fab;
#RequiresApi(api = Build.VERSION_CODES.LOLLIPOP)
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_search);
mTabLayout = (TabLayout) findViewById(R.id.tabs);
mViewPager = (ViewPager) findViewById(R.id.viewpager_container);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer);
navigation = (CoordinatorLayout) findViewById(R.id.error);
mToggle = new ActionBarDrawerToggle(this,mDrawerLayout,R.string.open,R.string.close)
{
/* Called when a drawer has settled in a completely close state. */
public void onDrawerClosed(View view) {
// fab.setVisibility(View.VISIBLE);
//navigation.setVisibility(View.VISIBLE);
}
/** Called when a drawer has settled in a completely open state. */
public void onDrawerOpened(View drawerView) {
// fab.setVisibility(View.INVISIBLE);
// navigation.setVisibility(View.INVISIBLE);
}
};
mDrawerLayout.addDrawerListener(mToggle);
mToggle.syncState();
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
NavigationView navigationView = (NavigationView) findViewById(R.id.navigation_view);
navigationView.setNavigationItemSelectedListener(this);
fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setBackgroundTintList(ColorStateList.valueOf(ContextCompat.getColor(getApplicationContext(),R.color.red4)));
View header = navigationView.getHeaderView(0);
pimage = (ImageView) header.findViewById(R.id.pimage);
uname = (TextView) header.findViewById(R.id.uname);
uemail = (TextView) header.findViewById(R.id.emailo);
SharedPreferences sharedPref = PreferenceManager.getDefaultSharedPreferences(SearchActivity.this);
pemail = sharedPref.getString("email", "Not Available");
pname = sharedPref.getString("username", "Not Available");
uname.setText(pname);
uemail.setText(pemail);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(SearchActivity.this,uploadPost.class);
startActivity(intent);
}
});
setupFirebaseListener();
verifyPermissions();
}
private void setupFirebaseListener() {
Log.d(TAG, "setupFirebaseListener: setting up the auth state listener.");
mAuthStateListener = new FirebaseAuth.AuthStateListener() {
#Override
public void onAuthStateChanged(#NonNull FirebaseAuth firebaseAuth) {
FirebaseUser user = firebaseAuth.getCurrentUser();
if (user != null) {
Log.d(TAG, "onAuthStateChanged: signed_in: " + user.getUid());
} else {
Log.d(TAG, "onAuthStateChanged: signed_out");
Toast.makeText(SearchActivity.this, "Signed out", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(SearchActivity.this, LoginActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
}
}
};
}
#Override
public void onStart() {
super.onStart();
FirebaseAuth.getInstance().addAuthStateListener(mAuthStateListener);
}
#Override
public void onStop() {
super.onStop();
if (mAuthStateListener != null) {
FirebaseAuth.getInstance().removeAuthStateListener(mAuthStateListener);
}
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
if(mToggle.onOptionsItemSelected(item)){
return true;
}
return super.onOptionsItemSelected(item);
}
private void setupViewPager(){
mPagerAdapter = new SectionsPagerAdapter(getSupportFragmentManager());
mPagerAdapter.addFragment(new SearchFragment());
mPagerAdapter.addFragment(new WatchListFragment());
// mPagerAdapter.addFragment(new PostFragment());
mViewPager.setAdapter(mPagerAdapter);
mTabLayout.setupWithViewPager(mViewPager);
mTabLayout.getTabAt(0).setText(getString(R.string.fragment_search));
mTabLayout.getTabAt(1).setText(getString(R.string.fragment_watch_list));
// mTabLayout.getTabAt(2).setText(getString(R.string.fragment_post));
}
private void verifyPermissions(){
Log.d(TAG, "verifyPermissions: asking user for permissions");
String[] permissions = {Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.CAMERA};
if(ContextCompat.checkSelfPermission(this.getApplicationContext(),
permissions[0]) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this.getApplicationContext(),
permissions[1]) == PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this.getApplicationContext(),
permissions[2]) == PackageManager.PERMISSION_GRANTED){
setupViewPager();
}else{
ActivityCompat.requestPermissions(SearchActivity.this,
permissions,
REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
verifyPermissions();
}
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
int id = item.getItemId();
if(id == R.id.profile){
Intent intent = new Intent(SearchActivity.this,test.class);
startActivity(intent);
Toast.makeText(this,"Profile",Toast.LENGTH_SHORT).show();
}
if(id == R.id.aboutus){
Intent intent = new Intent(SearchActivity.this,Aboutus.class);
startActivity(intent);
Toast.makeText(this,"About Us",Toast.LENGTH_SHORT).show();
}
if(id == R.id.mypost){
Intent intent = new Intent(SearchActivity.this,MyPosts.class);
startActivity(intent);
Toast.makeText(this,"My Post",Toast.LENGTH_SHORT).show();
}
if(id == R.id.logout){
Log.d(TAG, "onClick: attempting to sign out the user.");
FirebaseAuth.getInstance().signOut();
}
return false;
}
}
I am not able to understand the error which i am seeing on my logs
FATAL EXCEPTION: main
Process: codingwithmitch.com.forsale, PID: 13518
java.lang.RuntimeException: Unable to instantiate activity ComponentInfo{codingwithmitch.com.forsale/codingwithmitch.com.forsale.uploadPost}: java.lang.ClassCastException: codingwithmitch.com.forsale.uploadPost cannot be cast to android.app.Activity
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2561)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
Caused by: java.lang.ClassCastException: codingwithmitch.com.forsale.uploadPost cannot be cast to android.app.Activity
at android.app.Instrumentation.newActivity(Instrumentation.java:1100)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2551)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2724)
at android.app.ActivityThread.-wrap12(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1473)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:154)
at android.app.ActivityThread.main(ActivityThread.java:6123)
my SearchActivity xml file:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:fab="http://schemas.android.com/tools"
android:id="#+id/drawer"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/White"
android:fitsSystemWindows="true">
<android.support.design.widget.CoordinatorLayout
android:id="#+id/error"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.design.widget.AppBarLayout
android:id="#+id/app_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/white"
android:elevation="10dp"
android:fitsSystemWindows="true">
<android.support.design.widget.CollapsingToolbarLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
app:layout_scrollFlags="scroll|exitUntilCollapsed">
<android.support.design.widget.TabLayout
android:id="#+id/tabs"
android:layout_width="match_parent"
android:layout_height="50dp"
app:layout_collapseMode="parallax">
</android.support.design.widget.TabLayout>
</android.support.design.widget.CollapsingToolbarLayout>
</android.support.design.widget.AppBarLayout>
<android.support.v4.view.ViewPager
android:id="#+id/viewpager_container"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
</android.support.v4.view.ViewPager>
<com.getbase.floatingactionbutton.FloatingActionButton
android:id="#+id/fab"
android:layout_width="42dp"
android:layout_height="53dp"
android:layout_gravity="bottom|end"
android:layout_margin="#dimen/fab_margin"
android:scaleType="center"
android:src="#drawable/ic_camera_alt_black_24dp"
app:fabSize="normal"
fab:layout_editor_absoluteX="342dp"
fab:layout_editor_absoluteY="458dp">
</com.getbase.floatingactionbutton.FloatingActionButton>
</android.support.design.widget.CoordinatorLayout>
<android.support.design.widget.NavigationView
android:id="#+id/navigation_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="start"
app:headerLayout="#layout/header"
app:menu="#menu/nav_menu"></android.support.design.widget.NavigationView>
</android.support.v4.widget.DrawerLayout>
You are getting the error :
cannot be cast to android.app.Activity
because you are trying to load uploadPost as an Activity but it extends Fragment so you get the "cannot be cast to android.app.Activity" error.
You must decide whether you want to load it as a Fragment or an Activity. If you want to load uploadPost as an Activity you need to extend to an Activity not Fragment
EDIT
If you wish to continue to use it as a Fragment you must use a FragmentTransaction to either add() the Fragment or replace() a Fragment in your activity layout.
You can replace a Fragment like this example:
Fragment fragment = new UploadPost();
if(fragment != null) {
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
//If you want to play around with different transaction animations
//fragmentTransaction.setCustomAnimations(android.R.anim.fade_in, android.R.anim.fade_out);
fragmentTransaction.replace(R.id.content_main, fragment, "0");
fragmentTransaction.commit();
}
Where R.id.content_main is just a RelativeLayout in my MainActivity which is replaced by the uploadPost fragment.
And as 0X0nosugar indicated: It is java naming convention to capitalize class names. Please adopt this convention--otherwise you will make it more difficult to understand your code.
EDIT 2
Often a Fragment will be used to swap views in an container Activity. For example I use them to swap views in combination with a DrawerLayout. In this case I will continue to replace fragments, but never really remove one explicitly.
For example I will have a xml layout file very similar to your "SearchActivity" file. Just below the </android.support.design.widget.AppBarLayout> tag I will introduce a RelativeLayout with the id android:id="#+id/content_main". This RelativeLayout is just a dummy container view and is being replaced with whatever is in my selected Fragment. So you would need to change the onClick code to replace the fragment as I showed above.
With another action you might want to either remove that fragment or replace it with another... that all depends on your app design--which I do not know.
The issue is that there is a delay when I try to change the orientation of the player. There is a lag of some 2 or 3 seconds before the video resumes. Every thing else works just fine except for the orientation change.
public class MainActivity extends AppCompatActivity {
private final String STATE_RESUME_WINDOW = "resumeWindow";
private final String STATE_RESUME_POSITION = "resumePosition";
private final String STATE_PLAYER_FULLSCREEN = "playerFullscreen";
private SimpleExoPlayerView mExoPlayerView;
private MediaSource mVideoSource;
private boolean mExoPlayerFullscreen = false;
private FrameLayout mFullScreenButton;
private ImageView mFullScreenIcon;
private Dialog mFullScreenDialog;
private int mResumeWindow;
private long mResumePosition;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (savedInstanceState != null) {
mResumeWindow = savedInstanceState.getInt(STATE_RESUME_WINDOW);
mResumePosition = savedInstanceState.getLong(STATE_RESUME_POSITION);
mExoPlayerFullscreen = savedInstanceState.getBoolean(STATE_PLAYER_FULLSCREEN);
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
outState.putInt(STATE_RESUME_WINDOW, mResumeWindow);
outState.putLong(STATE_RESUME_POSITION, mResumePosition);
outState.putBoolean(STATE_PLAYER_FULLSCREEN, mExoPlayerFullscreen);
super.onSaveInstanceState(outState);
}
private void initFullscreenDialog() {
mFullScreenDialog = new Dialog(this, android.R.style.Theme_Black_NoTitleBar_Fullscreen) {
public void onBackPressed() {
if (mExoPlayerFullscreen)
closeFullscreenDialog();
super.onBackPressed();
}
};
}
private void openFullscreenDialog() {
((ViewGroup) mExoPlayerView.getParent()).removeView(mExoPlayerView);
mFullScreenDialog.addContentView(mExoPlayerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT));
mFullScreenIcon.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,R.drawable.ic_fullscreen_shrink));
mExoPlayerFullscreen = true;
mFullScreenDialog.show();
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
private void closeFullscreenDialog() {
((ViewGroup) mExoPlayerView.getParent()).removeView(mExoPlayerView);
((FrameLayout) findViewById(R.id.main_media_frame)).addView(mExoPlayerView);
mExoPlayerFullscreen = false;
mFullScreenDialog.dismiss();
mFullScreenIcon.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,R.drawable.ic_fullscreen_expand));
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
}
private void initFullscreenButton() {
PlaybackControlView controlView = mExoPlayerView.findViewById(R.id.exo_controller);
mFullScreenIcon = controlView.findViewById(R.id.exo_fullscreen_icon);
mFullScreenButton = controlView.findViewById(R.id.exo_fullscreen_button);
mFullScreenButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (!mExoPlayerFullscreen)
openFullscreenDialog();
else
closeFullscreenDialog();
}
});
}
private void initExoPlayer() {
BandwidthMeter bandwidthMeter = new DefaultBandwidthMeter();
TrackSelection.Factory videoTrackSelectionFactory = new AdaptiveTrackSelection.Factory(bandwidthMeter);
TrackSelector trackSelector = new DefaultTrackSelector(videoTrackSelectionFactory);
LoadControl loadControl = new DefaultLoadControl();
SimpleExoPlayer player = ExoPlayerFactory.newSimpleInstance(new DefaultRenderersFactory(this),trackSelector, loadControl);
mExoPlayerView.setPlayer(player);
boolean haveResumePosition = mResumeWindow != C.INDEX_UNSET;
if (haveResumePosition) {
mExoPlayerView.getPlayer().seekTo(mResumeWindow, mResumePosition);
}
mExoPlayerView.getPlayer().prepare(mVideoSource);
mExoPlayerView.getPlayer().setPlayWhenReady(true);
}
#Override
protected void onResume() {
super.onResume();
if (mExoPlayerView == null) {
mExoPlayerView = (SimpleExoPlayerView) findViewById(R.id.exoplayer);
initFullscreenDialog();
initFullscreenButton();
String streamUrl = "https://mnmedias.api.telequebec.tv/m3u8/29880.m3u8";
String userAgent = Util.getUserAgent(MainActivity.this, getApplicationContext().getApplicationInfo().packageName);
DefaultHttpDataSourceFactory httpDataSourceFactory = new DefaultHttpDataSourceFactory(userAgent, null,
DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS,
DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, true);
DefaultDataSourceFactory dataSourceFactory = new DefaultDataSourceFactory(MainActivity.this, null,httpDataSourceFactory);
Uri daUri = Uri.parse(streamUrl);
mVideoSource = new HlsMediaSource(daUri, dataSourceFactory, 1, null, null);
}
initExoPlayer();
if (mExoPlayerFullscreen) {
((ViewGroup) mExoPlayerView.getParent()).removeView(mExoPlayerView);
mFullScreenDialog.addContentView(mExoPlayerView, new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT));
mFullScreenIcon.setImageDrawable(ContextCompat.getDrawable(MainActivity.this,
R.drawable.ic_fullscreen_shrink));
mFullScreenDialog.show();
}
}
#Override
protected void onPause() {
super.onPause();
if (mExoPlayerView != null && mExoPlayerView.getPlayer() != null) {
mResumeWindow = mExoPlayerView.getPlayer().getCurrentWindowIndex();
mResumePosition = Math.max(0, mExoPlayerView.getPlayer().getContentPosition());
mExoPlayerView.getPlayer().release();
}
if (mFullScreenDialog != null)
mFullScreenDialog.dismiss();
}
}
You should look into handling configuration changes yourself - as #marcbaechinger mentions above.
The necessary piece is here:
<activity android:name=".MyActivity"
android:configChanges="orientation|screenSize"
android:label="#string/app_name">
The most important part is:
Remember: When you declare your activity to handle a configuration change, you are responsible for resetting any elements for which you provide alternatives. If you declare your activity to handle the orientation change and have images that should change between landscape and portrait, you must re-assign each resource to each element during onConfigurationChanged().
But if you don't have any landscape specific layout files or images, then you'll likely be okay.
We had to write our own full screen logic for rotation, but that's simple enough considering Android gives you the configuration change event.
And to tack on a little extra validity to this approach, it's recommended by Google via the Youtube player documentation (specifically in regards to fullscreen):
To achieve this for an activity that supports portrait, you need to specify that your activity handles some configuration changes on its own in your application's manifest, including orientation, keyboardHidden and screenSize.
I am developing the android application in which using Kaltura native android sdk to play the video. android-native-kaltura-sdk
I am able to play the video. but when i change the orientation of mobile (Portrait to Landscape) player is not resumed.
Issue is player get restart.
VideoDetailActivity Class
public class VideoDetailActivity extends AppCompatActivity implements DraggableListener, OnTaskFinishedListener, KPEventListener {
public boolean isPlaying;
private static final int FULL_SCREEN_FLAG = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION | View.SYSTEM_UI_FLAG_FULLSCREEN;
private PlayerFragment mPlayerFragment;
// TODO: Rename and change types of parameters
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_video_detail);
ButterKnife.bind(this);
if (getFragmentManager().findFragmentByTag(PlayerFragment.class.getName()) == null) {
Log.d(TAG, this + ": Existing fragment not found.");
isPlaying = false;
mPlayerFragment = new PlayerFragment();
FragmentTransaction transaction = getFragmentManager().beginTransaction();//.setCustomAnimations(R.anim.slide_up, R.anim.slide_down);
// transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left);
transaction.add(R.id.fragment_container, mPlayerFragment, PlayerFragment.class.getName());
transaction.addToBackStack(mPlayerFragment.getClass().getName());
transaction.commit();
} else {
if (savedInstanceState != null) {
isPlaying = savedInstanceState.getBoolean("isPlaying");
}
mPlayerFragment = (PlayerFragment) getFragmentManager().findFragmentByTag(PlayerFragment.class.getName());
Log.d(TAG, this + ": Existing fragment found.");
}
}
/**
* Pause the VideoView content.
*/
private void pauseVideo() {
if (player != null) {
player.releaseAndSavePosition();
}
}
/**
* Resume the VideoView content.
*/
private void startVideo() {
if (player != null) {
player.resumePlayer();
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
//player.releaseAndSavePosition();
mPlayerFragment.pausePlayer();
// mPlayerFragment.killPlayer();
outState.putBoolean("isPlaying", isPlaying);
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
//player.resumePlayer();
//isPlaying = savedInstanceState.getBoolean("isPlaying");
/* if (isPlaying) {
mPlayerFragment.resumePlayer();
}*/
}
public void isPlaying(boolean value) {
isPlaying = value;
}
#Override
protected void onDestroy() {
super.onDestroy();
if (mPlayerFragment != null) {
mPlayerFragment.killPlayer();
}
// if (player != null)
//player.resumePlayer();
}
#Override
protected void onPause() {
super.onPause();
if (!isFinishing() && mPlayerFragment != null) {
//mPlayerFragment.killPlayer();
/* mPlayerFragment = null;*/
isPlaying = true;
}
}
#Override
public void onBackPressed() {
if (getFragmentManager().getBackStackEntryCount() > 0) {
mPlayerFragment.pausePlayer();
} else {
super.onBackPressed();
}
}
}
PlayerFragment Class
public class PlayerFragment extends Fragment implements KPEventListener {
private boolean isResumed = false;
private View mFragmentView = null;
private PlayerViewController mPlayerView;
private boolean mFullScreen = true;
private OnFragmentInteractionListener mListener;
public PlayerFragment() {
// Required empty public constructor
}
public static PlayerFragment newInstance(String param1, String param2) {
PlayerFragment fragment = new PlayerFragment();
/* Bundle args = new Bundle();
args.putString(ARG_PARAM1, param1);
args.putString(ARG_PARAM2, param2);
fragment.setArguments(args);*/
return fragment;
}
public void pausePlayer() {
mPlayerView.releaseAndSavePosition();
}
public void killPlayer() {
mPlayerView.removePlayer();
mPlayerView = null;
//getActivity().getFragmentManager().beginTransaction().remove(this).commit();
}
public void resumePlayer() {
mPlayerView.resumePlayer();
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setRetainInstance(true);
/* if (getArguments() != null) {
mParam1 = getArguments().getString(ARG_PARAM1);
mParam2 = getArguments().getString(ARG_PARAM2);
}*/
// getActivity().getActionBar().hide();
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// Inflate the layout for this fragment
mFragmentView = inflater.inflate(R.layout.fragment_player, container, false);
return mFragmentView;
}
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
mPlayerView = (PlayerViewController) mFragmentView.findViewById(R.id.player);
mPlayerView.loadPlayerIntoActivity(getActivity());
if (!((VideoDetailActivity) getActivity()).isPlaying) {
((VideoDetailActivity) getActivity()).isPlaying(true);
KPPlayerConfig config = new KPPlayerConfig("http://cdnapi.kaltura.com", "Player Cofig ID", "Kaltura Partner ID");
config.setEntryId("Video EntryID");
mPlayerView.initWithConfiguration(config);
mPlayerView.addEventListener(this);
} else {
mPlayerView.resumePlayer();
}
}
public void setFullScreen(boolean fullScreen) {
fullScreen = false;
if (mFullScreen) {
Log.v("FullScreen", "-----------Set full screen SCREEN_ORIENTATION_LANDSCAPE------------");
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
DisplayMetrics displaymetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
/* int height = displaymetrics.heightPixels;
int width = displaymetrics.widthPixels;
android.widget.FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) videoSurface.getLayoutParams();
params.width = width;
params.height=height;
params.setMargins(0, 0, 0, 0);*/
//set icon is full screen
mFullScreen = fullScreen;
} else {
Log.v("FullScreen", "-----------Set small screen SCREEN_ORIENTATION_PORTRAIT------------");
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
DisplayMetrics displaymetrics = new DisplayMetrics();
getActivity().getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
/* final FrameLayout mFrame = (FrameLayout) findViewById(R.id.videoSurfaceContainer);
// int height = displaymetrics.heightPixels;
int height = mFrame.getHeight();//get height Frame Container video
int width = displaymetrics.widthPixels;
android.widget.FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) videoSurface.getLayoutParams();
params.width = width;
params.height= height;
params.setMargins(0, 0, 0, 0);*/
//set icon is small screen
mFullScreen = !fullScreen;
}
}
// TODO: Rename method, update argument and hook method into UI event
public void onButtonPressed(Uri uri) {
if (mListener != null) {
mListener.onFragmentInteraction(uri);
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
#Override
public void onKPlayerStateChanged(PlayerViewController playerViewController, KPlayerState state) {
switch (state) {
case READY:
Log.e("KPlayer State Changed", "Player State READY :- " + state.toString() + "###################################################################");
((VideoDetailActivity) getActivity()).isPlaying(true);
break;
case LOADED:
Log.e("KPlayer State Changed", "Player State LOADED :- " + state.toString() + "###################################################################");
break;
case PAUSED:
Log.e("KPlayer State Changed", "Player State PAUSED :- " + state.toString() + "###################################################################");
break;
case SEEKED:
Log.e("KPlayer State Changed", "Player State PAUSED :- " + state.toString() + "###################################################################");
break;
case SEEKING:
Log.e("KPlayer State Changed", "Player State PAUSED :- " + state.toString() + "###################################################################");
break;
}
}
#Override
public void onKPlayerPlayheadUpdate(PlayerViewController playerViewController, float currentTime) {
Log.e("KPlayer State Changed", "Player State PAUSED :- " +currentTime + "###################################################################");
}
#Override
public void onKPlayerFullScreenToggeled(PlayerViewController playerViewController, boolean isFullscreen) {
setFullScreen(isFullscreen);
}
/**
* This interface must be implemented by activities that contain this
* fragment to allow an interaction in this fragment to be communicated
* to the activity and potentially other fragments contained in that
* activity.
* <p>
* See the Android Training lesson <a href=
* "http://developer.android.com/training/basics/fragments/communicating.html"
* >Communicating with Other Fragments</a> for more information.
*/
public interface OnFragmentInteractionListener {
// TODO: Update argument type and name
public void onFragmentInteraction(Uri uri);
}
I am trying to implement the cwac camera library for taking picture and storing them. When i tested the code on htc desire hd there were few complications. This is the screenshot of camera preview.
And when I take picture it shows image preview as.
The codes I have for this are as follows.
This is Activity for implementing camera preview fragment.
public class Camera extends ActionBarActivity implements CameraPreviewFragment.Contract {
private static final String STATE_SINGLE_SHOT="single_shot";
private static final String STATE_LOCK_TO_LANDSCAPE=
"lock_to_landscape";
private static final int CONTENT_REQUEST=1337;
private CameraPreviewFragment std=null;
private CameraPreviewFragment ffc=null;
private CameraPreviewFragment current=null;
private boolean hasTwoCameras=(android.hardware.Camera.getNumberOfCameras() > 1);
private boolean singleShot=false;
private boolean isLockedToLandscape=false;
private Toolbar mToolbar;
private void setToolBar(int toolbarId){
mToolbar = (Toolbar) findViewById(toolbarId);
if (mToolbar != null) {
setSupportActionBar(mToolbar);
getSupportActionBar().setLogo(R.drawable.ic_launcher);
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_camera);
setToolBar(R.id.toolbar);
if (savedInstanceState == null) {
CameraPreviewFragment frag = new CameraPreviewFragment();
frag = CameraPreviewFragment.newInstance(false);
getFragmentManager().beginTransaction()
.add(R.id.container, frag)
.commit();
}
}
#Override
protected void onRestoreInstanceState(Bundle savedInstanceState) {
setSingleShotMode(savedInstanceState.getBoolean(STATE_SINGLE_SHOT));
isLockedToLandscape=
savedInstanceState.getBoolean(STATE_LOCK_TO_LANDSCAPE);
if (current != null) {
current.lockToLandscape(isLockedToLandscape);
}
}
#Override
protected void onSaveInstanceState(Bundle outState) {
outState.putBoolean(STATE_SINGLE_SHOT, isSingleShotMode());
outState.putBoolean(STATE_LOCK_TO_LANDSCAPE, isLockedToLandscape);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_menu_camera, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public boolean isSingleShotMode() {
return true;
}
#Override
public void setSingleShotMode(boolean mode) {
}
}
And here is my camera preview fragment.(to load camera and has button for taking image)
public class CameraPreviewFragment extends CameraFragment implements SeekBar.OnSeekBarChangeListener, View.OnClickListener{
private static final String DEBUG = CameraPreviewFragment.class.getSimpleName();
private static final String KEY_USE_FFC=
"com.commonsware.cwac.camera.demo.USE_FFC";
private MenuItem singleShotItem=null;
private boolean singleShotProcessing=false;
private static final int FLASH_ALWAYS_OFF = 0;
private static final int FLASH_ALWAYS_ON = 1;
private static final int FLASH_AUTO_MODE = 2;
private SeekBar zoom=null;
private View mCameraView;
private ImageButton mTakePicture;
private Button mFlashButton;
private Button mGridButton;
private ImageView mGridLines;
private long lastFaceToast=0L;
private int flashState = 2;
String flashMode=null, autoFlashMode=null, noFlashMode= null;
private DemoCameraHost cameraHost;
static CameraPreviewFragment newInstance(boolean useFFC) {
CameraPreviewFragment f=new CameraPreviewFragment();
Bundle args=new Bundle();
args.putBoolean(KEY_USE_FFC, useFFC);
f.setArguments(args);
return(f);
}
#Override
public void onCreate(Bundle state) {
super.onCreate(state);
setHasOptionsMenu(true);
cameraHost = new DemoCameraHost(getActivity());
SimpleCameraHost.Builder builder=
new SimpleCameraHost.Builder(cameraHost);
setHost(builder.useFullBleedPreview(true).build());
}
#Override
public View onCreateView(LayoutInflater inflater,
ViewGroup container,
Bundle savedInstanceState) {
mCameraView=
super.onCreateView(inflater, container, savedInstanceState);
View results=inflater.inflate(R.layout.fragment_camera, container, false);
mCameraView.setOnClickListener(this);
mGridLines = (ImageView) results.findViewById(R.id.ivGridLines);
mTakePicture = (ImageButton) results.findViewById(R.id.ibCaptureButton);
mTakePicture.setOnClickListener(this);
mFlashButton = (Button) results.findViewById(R.id.bFlash);
mFlashButton.setOnClickListener(this);
mGridButton = (Button) results.findViewById(R.id.bGrid);
mGridButton.setOnClickListener(this);
((ViewGroup) results.findViewById(R.id.camera)).addView(mCameraView);
zoom=(SeekBar)results.findViewById(R.id.sbZoomControl);
zoom.setKeepScreenOn(true);
return(results);
}
#Override
public void onPause() {
super.onPause();
getActivity().invalidateOptionsMenu();
}
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.menu_camera, menu);
singleShotItem=menu.findItem(R.id.single_shot);
singleShotItem.setChecked(getContract().isSingleShotMode());
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.single_shot:
item.setChecked(!item.isChecked());
getContract().setSingleShotMode(item.isChecked());
return(true);
case R.id.show_zoom:
item.setChecked(!item.isChecked());
zoom.setVisibility(item.isChecked() ? View.VISIBLE : View.GONE);
return(true);
}
return(super.onOptionsItemSelected(item));
}
boolean isSingleShotProcessing() {
return(singleShotProcessing);
}
#Override
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
zoom.setEnabled(false);
zoomTo(zoom.getProgress()).onComplete(new Runnable() {
#Override
public void run() {
zoom.setEnabled(true);
}
}).go();
}
}
#Override
public void onStartTrackingTouch(SeekBar seekBar) {
// ignore
}
#Override
public void onStopTrackingTouch(SeekBar seekBar) {
// ignore
}
Contract getContract() {
return((Contract)getActivity());
}
void takeSimplePicture() {
if (singleShotItem!=null && singleShotItem.isChecked()) {
singleShotProcessing=true;
mTakePicture.setEnabled(false);
}
PictureTransaction xact=new PictureTransaction(getHost());
xact.flashMode(getFlashMode());
takePicture(xact);
}
#Override
public void onClick(View v) {
if(v == mTakePicture){
takeSimplePicture();
}
if(v == mFlashButton){
if(flashState == FLASH_ALWAYS_OFF){
//flash to be always on
flashState = FLASH_ALWAYS_ON;
setFlashMode(flashMode);
Toast.makeText(getActivity(), "Flash! on", Toast.LENGTH_SHORT).show();
}else if(flashState == FLASH_ALWAYS_ON){
flashState = FLASH_AUTO_MODE;
setFlashMode(autoFlashMode);
Toast.makeText(getActivity(), "Flash! auto", Toast.LENGTH_SHORT).show();
}else if(flashState == FLASH_AUTO_MODE){
flashState = FLASH_ALWAYS_OFF;
setFlashMode(noFlashMode);
Toast.makeText(getActivity(), "Flash! off", Toast.LENGTH_SHORT).show();
}
}
if(v == mCameraView){
Log.i(DEBUG,"OnClick autofocus");
autoFocus();
}
if(v == mGridButton){
if(mGridLines.getVisibility() == View.VISIBLE){
mGridLines.setVisibility(View.GONE);
}else if(mGridLines.getVisibility() == View.GONE){
mGridLines.setVisibility(View.VISIBLE);
}
}
}
interface Contract {
boolean isSingleShotMode();
void setSingleShotMode(boolean mode);
}
class DemoCameraHost extends SimpleCameraHost implements
android.hardware.Camera.FaceDetectionListener {
boolean supportsFaces=false;
public DemoCameraHost(Context _ctxt) {
super(_ctxt);
}
#Override
protected File getPhotoDirectory() {
return CameraUtility.getOutputDirectory(CameraUtility.DIRECTORY_TYPE_CAMERA);
}
#Override
public boolean useFrontFacingCamera() {
if (getArguments() == null) {
return(false);
}
return(getArguments().getBoolean(KEY_USE_FFC));
}
#Override
public boolean useSingleShotMode() {
if (singleShotItem == null) {
return(false);
}
return(singleShotItem.isChecked());
}
#Override
public Camera.Size getPictureSize(PictureTransaction xact, Camera.Parameters parameters) {
return super.getPictureSize(xact, parameters);
}
#Override
public void saveImage(PictureTransaction xact, byte[] image) {
if (useSingleShotMode()) {
singleShotProcessing=false;
getActivity().runOnUiThread(new Runnable() {
#Override
public void run() {
mTakePicture.setEnabled(true);
}
});
ImagePreviewActivity.imageToShow=image;
startActivity(new Intent(getActivity(), ImagePreviewActivity.class));
}
else {
String path = getPhotoFilename();
super.saveImage(xact, image);
}
}
#Override
public void autoFocusAvailable() {
if (supportsFaces)
startFaceDetection();
}
#Override
public void autoFocusUnavailable() {
stopFaceDetection();
}
#Override
public void onCameraFail(CameraHost.FailureReason reason) {
super.onCameraFail(reason);
Toast.makeText(getActivity(),
"Sorry, but you cannot use the camera now!",
Toast.LENGTH_LONG).show();
}
#Override
public android.hardware.Camera.Parameters adjustPreviewParameters(android.hardware.Camera.Parameters parameters) {
autoFlashMode =
CameraUtils.findBestFlashModeMatch(parameters,
android.hardware.Camera.Parameters.FLASH_MODE_RED_EYE,
android.hardware.Camera.Parameters.FLASH_MODE_AUTO,
android.hardware.Camera.Parameters.FLASH_MODE_ON);
flashMode = CameraUtils.findBestFlashModeMatch(parameters,
android.hardware.Camera.Parameters.FLASH_MODE_ON);
noFlashMode = CameraUtils.findBestFlashModeMatch(parameters,
Camera.Parameters.FLASH_MODE_OFF);
if (doesZoomReallyWork() && parameters.getMaxZoom() > 0) {
zoom.setMax(parameters.getMaxZoom());
zoom.setOnSeekBarChangeListener(CameraPreviewFragment.this);
}
else {
zoom.setEnabled(false);
}
if (parameters.getMaxNumDetectedFaces() > 0) {
supportsFaces=true;
}
else {
Toast.makeText(getActivity(),
"Face detection not available for this camera",
Toast.LENGTH_LONG).show();
}
return(super.adjustPreviewParameters(parameters));
}
#Override
public void onFaceDetection(android.hardware.Camera.Face[] faces, android.hardware.Camera camera) {
if (faces.length > 0) {
long now= SystemClock.elapsedRealtime();
if (now > lastFaceToast + 10000) {
Toast.makeText(getActivity(), "I see your face!",
Toast.LENGTH_LONG).show();
lastFaceToast=now;
}
}
}
#Override
protected File getPhotoPath() {
return super.getPhotoPath();
}
#Override
#TargetApi(16)
public void onAutoFocus(boolean success, android.hardware.Camera camera) {
super.onAutoFocus(success, camera);
mTakePicture.setEnabled(true);
}
}
}
This one is for viewing the image taken. ImagePreviewActivity
public class ImagePreviewActivity extends ActionBarActivity {
static byte[] imageToShow = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (imageToShow == null) {
Toast.makeText(this, R.string.no_image, Toast.LENGTH_LONG).show();
finish();
} else {
ImageView iv = new ImageView(this);
BitmapFactory.Options opts = new BitmapFactory.Options();
opts.inPurgeable = true;
opts.inInputShareable = true;
opts.inMutable = false;
opts.inSampleSize = 2;
iv.setScaleType(ImageView.ScaleType.FIT_CENTER);
iv.setImageBitmap(BitmapFactory.decodeByteArray(imageToShow,
0,
imageToShow.length,
opts));
imageToShow = null;
iv.setScaleType(ImageView.ScaleType.CENTER_INSIDE);
setContentView(iv);
}
}
}
And as for the xml layouts I have:
for CameraPrevirewFragment
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.ballard.CWACCamera.Camera$PlaceholderFragment"
android:orientation="vertical"
android:weightSum="4">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="0dip"
android:layout_weight="3">
<FrameLayout
android:id="#+id/camera"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
<ImageView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="#android:drawable/gallery_thumb"
android:id="#+id/ivGridLines"
android:visibility="gone"/>
</RelativeLayout>
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="0dip"
android:layout_weight="1">
<SeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="#+id/sbZoomControl"
android:layout_alignParentTop="true"
android:background="#null"
android:layout_toLeftOf="#+id/bFlash"
android:layout_alignBottom="#+id/bFlash"
android:layout_toRightOf="#+id/bGrid"
android:layout_toEndOf="#+id/bGrid" />
<ImageButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/ibCaptureButton"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:src="#android:drawable/ic_menu_camera"
android:background="#null"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Flash"
android:id="#+id/bFlash"
android:layout_alignParentTop="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Grid"
android:id="#+id/bGrid"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
</RelativeLayout>
</LinearLayout>
and for the camera activity I have
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="#+id/rlHomeLayout"
android:layout_width="match_parent" android:layout_height="match_parent"
tools:context="com.example.ballard.Login.Home" tools:ignore="MergeRootFrame"
>
<include
android:id="#+id/toolbar"
layout="#layout/toolbar"/>
<FrameLayout`enter code here`
android:id="#+id/container"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="#+id/toolbar">
</FrameLayout>
</RelativeLayout>
I am using v7 toolbar as the actionbar and is as follows(toolbar.xml)
<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="#+id/toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimaryDark"/>
I tried the demo of the library and is working fine on the same mobile set. Also there seems to be no problem while I was testing it on Nexus 5. I am trying this library for the first time and have no clue for solving this