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.
Related
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.
I've followed the example pattern for handling the android back button in the react-native docs and it works well. I can use the hardware back button to pop my navigation stack.
At the point that there's only 1 view in the stack though I don't pop it (just like the example), and I return false from my hardwareBackPress event listener. At this point it I see the componentWillUnmount method being called in my final view, at which point my app shuts down.
If I return true then nothing happens at all obviously.
What I want to happen is that the app merely gets "backgrounded" instead of exiting completely.
Answered my own question. The trick is to override the default back button behaviour in the MainActiviy:
public class MainActivity extends ReactActivity {
#Override
protected String getMainComponentName() {
return "foo";
}
#Override
public void invokeDefaultOnBackPressed() {
// do not call super. invokeDefaultOnBackPressed() as it will close the app. Instead lets just put it in the background.
moveTaskToBack(true);
}
}
Though I may be very late in giving the answer it may help other facing the issue.
Recently I came across the same requirement where I have to move the app to the background. I tried the solution provided by #pomo. Though it worked I faced problems. Sometimes on multiple clicking of the back button, the app misbehaves in android though it worked perfectly fine in iOS.
And then I came across the following issues in GitHub where it mentions the reason for the misbehaviour.
The following solution works perfectly fine now.
// android/app/.../MainActivity.java
#Override
public void invokeDefaultOnBackPressed() {
moveTaskToBack(true);
}
<!-- AndroidManifest.xml -->
<activity
...
android:launchMode="singleTop">
Link from where I get the solution
I hope I'm able to help guys with the same requirement.
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.
The layout is basic: an EditText at the top followed by a ListView. EditText has a TextWatcher.onTextChanged implemented so that ArrayAdapter.getFilter.filter is called with the entered text. ArrayAdapter's data is refreshed asynchronously on resume (see code snippet below). Easy enough, works just fine too... right up until the screen orientation is changed. Why would filtering suddenly break when the phone is turned sideways?
public class SometActivity extends ListActivity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
...
listAdapter = new ArrayAdapter<MemoryStatistic>(this, R.layout.list_item);
setListAdapter(listAdapter);
searchText = (EditText)findViewById(R.id.searchText);
searchText.addTextChangedListener(new TextWatcher()
{
#Override
public void onTextChanged(CharSequence text, int start, int before, int count)
{
listAdapter.getFilter().filter(text);
}
...
}
...
}
#Override
protected void onResume()
{
asyncRefreshListAdapter();//refresh the data asynchronously when activity is resumed
}
}
I thought I'd make this self-reply post in case other programmers who are new to Android development (like I am) become stumped by this. So, according to android reference onResume will only be called if Activity is
1) created
2) restarted
3) resumed (brought to foreground after resume)
Ok, so what does screen orientation have to do with this?
Well, most devs who read documentation skim through it on the account of the fact that there's a lot to read and they just want to get to implementing something cool. I was no different. If only I had read further, I would've avoided a lot of headache later on:
Unless you specify otherwise, a configuration change (such as a change in screen orientation, language, input devices, etc) will cause your current activity to be destroyed
And now it's obvious why filter wouldn't work correctly. The problem was that (once the activity was destroyed on screen orientation change) listAdapter wasn't fully or at all populated (due to the asynchronous nature of the refresh) before filtering would commence.
I need to handle orientation changes in my Android application. For this purpose I decided to use OrientationEventListener convenience class. But his callback method is given somewhat strange behavior.
My application starts in the portrait mode and then eventually switches to the lanscape one. I have some custom code executing in the callback onOrientationChanged method that provides some additional UI handling logic - it has a few calls to findViewById.
What is strange is that when switching back from landscape to portrait mode onOrientationChanged callback is called twice, and what's even worse - the second call is dealing with bad Context - findViewById method starts returning null. These calls are made right from the MainThread
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
listener = new OrientationListener();
}
#Override
protected void onResume() {
super.onResume();
// enabling listening
listener.enable();
}
#Override
protected void onPause() {
super.onPause();
// disabling listening
listener.disable();
}
I've replicated the same behavior with a dummy Activity without any logic except for one that deals with orientation hadling.
I initiate orientation switch from the Android 2.2 emulator by pressing Ctrl+F11
What could be wrong?
Upd:
Inner class that implements OrientationEventListener
private class OrientationListener extends OrientationEventListener {
public OrientationL() {
super(getBaseContext());
}
#Override
public void onOrientationChanged(int orientation) {
toString();
}
}
}
This is a documented bug in the emulator ONLY. A real device will not exhibit this double-lifecycle-events behavior. I had the same issue a while ago and it disappears on a real device.
I would suggest ignoring the problem if you can by only testing orientation changes in one direction until you get your hands on a physical phone. Otherwise you might be able to "skip" the second set of lifecycle calls by keeping a static boolean around indicating you've already gone through the first set.
See this issue report for more info.
Have you tried using onConfigurationChanged?
#Override
public void onConfigurationChanged(Configuration newConfig) {
if(newConfig.equals(Configuration.ORIENTATION_LANDSCAPE)…
Add android:configChanges="orientation" in manifest file in activity tag like
<activity android:label="#string/app_name"
android:configChanges="orientation"
android:name=".com.androidpeople">