I have an activity (extends WearableActivity) inside which there are multiple fragments.I want only one of the fragment to be in "always on" mode.The default functionality of "closing current app" should happen on ambient timeout for other fragments.How can I achieve this?
You can detect when your app has entered ambient mode by implementing an onEnterAmbient event handler:
#Override
public void onEnterAmbient(Bundle ambientDetails) {
super.onEnterAmbient(ambientDetails);
// your code here
}
From your question, I'm assuming you've already implemented the other pieces required to support ambient mode, as documented at http://developer.android.com/training/wearables/apps/always-on.html.
Within that event handler, you'll just hide all but your "always on" fragment - probably with FragmentTransaction.remove(), but the exact technique will depend on your implementation, and it should be no different than hiding a fragment anywhere else in your apps.
Related
I am using a swipe button from com.ebanx:swipe-button library in my application and I wish to change the state of the swipe button to enable (based on the information recieved via another Bluetooth device) when I open the button's activity. ie: Without any user input I have to change swipe button's state to enable !
You can use toggleState()
SwipeButton mSwipeButton; = findViewById(R.id.my_swipe_button);
mSwipeButton.toggleState();
if you use an older version where toggleState is not available, use collapseButton(); or expandButton(); to collapse or expand the swipe button
There are two issues with the library you're using, first is coding bug, second is wrong documentation, but that's not the case.
to make the button active:
SwipeButton swipe_btn = findViewById(R.id.swipe_btn);
swipe_btn.setEnabled(true);
now by default, the button state is closed and you can change that in the xml file i.e the layout where you created the button, you will see something like below:
<com.ebanx.swipebtn.SwipeButton
app:initial_state="disable" //change to enable will make button open by default
app:has_activate_state="true"
/>
Finally to monitor the state of the button, you will have to listen to the state changes like below:
swipe_btn.setOnStateChangeListener(new OnStateChangeListener() {
#Override
public void onStateChange(boolean active) {
Toast.makeText(MainActivity.this, "IS "+active, Toast.LENGTH_LONG).show();
}
});
if active, the button is open, else it's close.
Note: When I say open, I mean the button is toggledOn, and when I say close, it means the other way round(toggleOff).
The bug here is that when you use swipe_btn.toggleState(); The button will be deactivated, meaning it will not even respond to click event which is not right, so the way around is to use the onStateChangeListener as I use it above so that when the button is open you can do something and when it's close you can still do anything.
Note: library version: 'com.ebanx:swipe-button:0.8.3'
I'm wondering, are there any way to disable analytics auto activity tracking?
I have view hierarchy based on fragments and there are few cases:
Activity that have one fragment always.
Activity that can have different fragments as root.
Activity with root fragment, that contains ViewPager with other fragments.
I use such a code in fragments from Firebase docs to track custom screens:
mFirebaseAnalytics.setCurrentScreen(getActivity(), "some_fragment_1", null);
In first case, I want to track only root fragment.
In second case, I want to track only each fragment that becomes root.
In third case, I want to track only each fragment that becomes visible in ViewPager.
And, the problem is, that I don't want to track Activities at all, but unfortunately, Firebase do it on its own - as a result of that, my statistics looks weird, like:
SomeActivity 50%
some_fragment_1 30%
some_fragment_2 20%
I dont't need activity in this statistics, because, fragment statistics already includes it.
So, is there any way to disable activity tracking?
Now it's possible with new API to manually track screens.
Can disable auto-tracking
On iOS, set FirebaseAutomaticScreenReportingEnabled to NO in your info.plist. On Android, set google_analytics_automatic_screen_reporting_enabled to false in your manifest.
Manual Tracking
iOS
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
// After enough time has passed to make this screen view significant.
Analytics.logEvent(AnalyticsEventScreenView, parameters: [
AnalyticsParameterScreenName: screenName!,
AnalyticsParameterScreenClass: screenClass!,
MyAppAnalyticsParameterFitnessCategory: category!
])
}
Android
#Override
public void onResume() {
super.onResume();
// After enough time has passed to make this screen view significant.
Bundle bundle = new Bundle();
bundle.putString(FirebaseAnalytics.Param.SCREEN_NAME, screenName);
bundle.putString(FirebaseAnalytics.Param.SCREEN_CLASS, screenClass);
bundle.putString(MyAppAnalyticsConstants.Param.TOPIC, topic);
mFirebaseAnalytics.logEvent(FirebaseAnalytics.Event.SCREEN_VIEW, bundle);
}
https://firebase.googleblog.com/2020/08/google-analytics-manual-screen-view.html
I know that this is rather a hack, but seems to be working with latest firebase analytics. The idea is that, Firebase Analytics uses registerActivityLifecycleCallbacks() internally on each activity declared in the manifest, so disabling that way disables auto-activity reporting.
Place that code in each root Activity you are using.
#Override
public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback) {
// com.google.android.gms.measurement.internal.zzfl for firebase-core:17.1.0, play-services-measurement-impl:17.1.0
if (!callback.getClass().getName().startsWith("com.google.android.gms.measurement.")){
super.registerActivityLifecycleCallbacks(callback);
}
}
Credits for finding that goes to #liudongmiao on https://github.com/firebase/quickstart-android/issues/370.
To disable screen auto-tracking in Firebase Analytics 17.5.0, I had to catch callback registrations in my Application class, not in individual activities, and the callback class name has changed again:
#Override
public void registerActivityLifecycleCallbacks(Application.ActivityLifecycleCallbacks callback) {
if (!callback.getClass().getName().startsWith("com.google.android.gms.internal.measurement.")){
super.registerActivityLifecycleCallbacks(callback);
}
}
Unfortunately, contrary to what Google's documentation states (https://firebase.google.com/docs/reference/android/com/google/firebase/analytics/FirebaseAnalytics.Event#SCREEN_VIEW), I wasn't able to manually tag screen views by logging the event FirebaseAnalytics.Event.SCREEN_VIEW. For now I've resorted to logging screen views with a custom event.
If my activity implements a 2D Picker, the ambient mode is not entered at all and the activity just stays active the hole time.
My other activities implementing a WearableListView don't have that problem, so i assume my code is correct. I am calling setAmbientEnabled at onCreate and have implemented onEnterAmbient/onExitAmbient.
Does someone have/had the same experience? Is there a workaround?
#Override
public void onEnterAmbient(Bundle ambientDetails) {
super.onEnterAmbient(ambientDetails);
Log.d("Ambient", "active");
ambientView.setVisibility(View.VISIBLE);
}
#Override
public void onExitAmbient() {
super.onExitAmbient();
Log.d("Ambient", "not active");
ambientView.setVisibility(View.GONE);
}
I presume you are using GridViewPager from the Wearable Support Library. Since I don't have your code, I can't be sure how you are setting things up but I did modify our GridViewPager sample project on GitHub and added Always-on required code and it did work. One thing for you to check is that you do not have android:keepScreenOn="true" in your GridViewPager or somewhere else in your activity layout (the GridViewPager sample has that) and also make sure you are not doing the same (i.e. keeping the screen on) from your Activity.
I have an activity which have multiple piece of UI panel(you can think them as view in android), these panels will be invisible by default.
Now when user trigger action1, PanelA will display, when trigger action2, PanelB will display(at different location of the screen).
Both PanelA and PanelB is visible at the moment, now when user hit the back menu, the PanelB should disappear, and PanelA should disappear when hit the back menu again.
At first, I use View to hold different panels, however I found it is difficult to keep the state consist, for example, the activity will be a little different between PanelA and PanelB.
Then I found the fragment, however after I tried and tested, I found that the addTobackStack() can not apply to my us-case, since the PanelA and PanelB are at different location, android can not save their state by default.
So I wonder if there is any other solution for my requirement?
You need to manually handle this scenario inside onBackPressed() method of an Activity.
For instance -
#Override
public void onBackPressed() {
if (panelB.isOpened()) {
panelB.close()
} else if (panelA.isOpened()) {
panelA.close()
} else {
super.onBackPressed();
}
}
When panelB is opened, it will close only panelB and wont do anything else. Same goes for panelA, if its opened and when both the panel are closed then it will exit the app like normal.
I highly recommend to use DialogFragments here as you can call show() and dismiss() any point of time on that and they can handle custom views pretty well.
Hope it helps.
It seems that Google official documentation on accessing a Chromecast from Android revolves mostly around an ActionBar button that seems to automatically handle the chooser dialog and return the user choice to the Callback.
I have a custom Button (view) with a handleCastButton() method in my activity. Is there an example somewhere of how to bring up the standard chooser when using a custom UI?
Edit: It looks like I should be able to do something with the stock MediaRouteDialogFactory but I can't find any details.
If you are not using the MediaRouteActionProvider to add the cast button to the ActionBar, you should instead use a MediaRouteButton which has the same behavior (bringing up the standard selector dialog, automatically changing state based on whether there are Chromecasts available, etc) but can be placed anywhere a normal Button can be.
Custom styling can be done by copying the default images drawables (and the associated pngs in drawable-hdpi, drawable-mdpi, and drawable-xhdpi) and styling them or just provide overriding resources of the same names.
After analyzing the MediaRouteButton source code, this seems to work:
public void handleCastButton() {
final FragmentManager fm = fragmentActivity.getSupportFragmentManager();
MediaRouteChooserDialogFragment f = MediaRouteDialogFactory.getDefault().onCreateChooserDialogFragment();
f.setRouteSelector(mediaRouteSelector);
f.show(fm, "android.support.v7.mediarouter:MediaRouteChooserDialogFragment");
}
That's it! Make sure your base Activity is a FragmentActivity and all imports are from android.support.v7.*. The dialog fragment will use the Callback you've associated with said selector.
There is also a MediaRouteControllerDialogFragment for when you've already connected and want to adjust the volume or disconnect.
Take a look at this sample project, you should be able to reuse some of it. You basically need to register to listen for routes as they are found and as they are removed and maintain a list of available ones and present that to user whenever user clicks on your button. When user selects a route, you need to handle connection and also set the route to selected one in the media router instance.