Office Hours — Today, January 10

Thursday, January 5

Mark M.
has entered the room
Mark M.
turned on guest access
Jan 10
7:30 PM
nat
has entered the room
Mark M.
hello, nat!
how can I help you today?
nat
Hi mark
question about espresso
with spoon
7:35 PM
nat
I’m using spoon (from square) to run espresso instrumented test on all connected device simultaneously
The issue that I’m facing is when i try to take a screenshot of the app using spoon, I run into permission denied issues on Android 6 & above devices. and the test exits there
View paste
Spoon provides a grantAllPermissions = true in build.gradle, yet this does not work
Another solution was to try to grant the permissions using ADB before the test runs (directly from gradle or by pointing to a bash script)
// This creates two new Gradle tasks in the "permissions" group, one per buildType.
// They depend on the install tasks, so if you run the grantDebugPermissions task
// it will install the app and then grant the permissions.

 android.applicationVariants.all { buildType ->
 def applicationId = buildType.applicationId
 def adb = android.getAdbExe().toString()

 def grantPermissionsTask = tasks.create("grant${buildType.name.capitalize()}Permissions") << {
 "${adb} shell pm grant ${applicationId} android.permission.WRITE_EXTERNAL_STORAGE".execute()
 "${adb} shell pm grant ${applicationId} android.permission.READ_EXTERNAL_STORAGE".execute()
 }
 grantPermissionsTask.description = "Grants permissions for Marshmallow"
 grantPermissionsTask.group = "permissions"
 grantPermissionsTask.dependsOn("install${buildType.name.capitalize()}")
 }
Aritra R.
has entered the room
nat
But I keep getting this
Mark M.
OK, I haven't used Spoon, and I haven't automated screenshots in Espresso tests
nat
ok
Mark M.
(at least not in a serious fashion, in terms of the screenshots)
does everything work if you take Spoon out of the mix, and invoke the tests on a single device?
Rory M.
has entered the room
nat
Will look into that
but what I can tell you if I remove the screenShot activity it works fine in Android 6
Rory M.
Hey
Aritra R.
Hi Mark, I have been facing a serious issue with broadcast receivers not being fired after reboot in some selected devices only. I have given the details of the issue here in the SO question, http://stackoverflow.com/questions/41524459/bro.... Unfortunately no has been able to help me solve it yet. Can you please help me?
Mark M.
hello, Aritra and Rory!
7:40 PM
Aritra R.
It seems to be a very weird kind of an issue. I am unable to figure out what's wrong. I will need your expert help on this.
Test A.
has entered the room
Rory M.
Aritra Roy - Have you maybe considered using <uses-permission android:name="android.permission.WAKE_LOCK" and instead of extending BroadcastReceiver - try extending WakefulBroadcastReceiver...
Test A.
hey, this is Mark
having some technical difficulties on my end
Mark M.
I have missed the past couple of minutes of the chat
nat
still here
Mark M.
and, unfortunately, I can't see the transcript right now
Rory M.
View paste
When you receive the broadcast inside onReceive() method,

BroadcastReceiver : It is not guaranteed that CPU will stay awake if you initiate some long running process. CPU may go immediately back to sleep.
WakefulBroadcastReceiver : is guaranteed that CPU will stay awake until you fire completeWakefulIntent.
Aritra R.
[REPOSTING] Hi Mark, I have been facing a serious issue with broadcast receivers not being fired after reboot in some selected devices only. I have given the details of the issue here in the SO question, http://stackoverflow.com/questions/41524459/bro.... Unfortunately, no has been able to help me solve it yet. Can you please help me?
Mark M.
no, wait, actually, I do have the transcript
Test A.
has left the room
Rory M.
Sorry to butt in -I was having similar trouble recently
Mark M.
nat: I am sorry, but I do not have much advice for you, given that I have not used that stuff much
nat
no worries
I saw your espresso examples
Aritra R.
I am not doing anything long running at all. Am just starting a service.
nat
I hope you'd be able to create one with a way to overcome Android 6 permission
7:45 PM
Rory M.
Ignoring the long running service - it was a copy and paste - but I have read that using WakefulBroadcastReceiver is preferable when starting services on device boot
roberto
has entered the room
Mark M.
Aritra: ACTION_BOOT_COMPLETED will sometimes hiccup, depending on device model, as I understand it
Aritra R.
Should I be using a WakefulBroadcastReceiver then? Am very curious to what is actually wrong in my implementation. It works in some devices perfectly and not in others at all. I have also created a test project just to check this and it works fine on the test project. But it just doesn't work in my app. Some users are facing serious problems because of this.
Rory M.
Yeah - it basically guarantees that the CPU is awake and listening to trigger your device
Mark M.
(BTW, hello roberto -- I will be with you shortly!)
Aritra R.
But what about the PhoneCallReceiver then? It also doesn't work after a reboot.
Rory M.
... not device - your request* on device start
Mark M.
right, and I do not have an explanation for that
roberto
Hi Mark, np.
Mark M.
in the specific case of the Mi 4i, unless I'm mistaken, that does not have the Play Store
which means they do not have to pass the CTS
which means that all bets are off in terms of compatibility
now, if they're sensible, they still aim to pass the CTS, because us app developers expect a degree of compatibility
but, device manufacturers are not always sensible
in terms of why the OnePlus 3 works on one project and not another, that too I cannot explain off the top of my head
Aritra R.
The Mi 4i I have tested on have got a Play Store. Even if I leave the case of Mi 4i, it doesn't work on my OnePlus 3 also and there are some other devices as well. But my test project demonstrating the same thing work in them.
7:50 PM
Mark M.
does anything appear in LogCat from the system when you try responding to NEW_INCOMING_CALL?
(BOOT_COMPLETED is simply a pain to test)
Aritra R.
No nothing appears actually. It just doesn't call the onReceiver() after a reboot. But if I open the app once after a reboot and then make a call, the receivers start working again. So what can happen?
nat
has left the room
Mark M.
again, I can
er, again, I can't explain that
Aritra R.
And it is also happening in some of my friends apps as well, which are in Play Store and some users are facing the exact same issue. I have downloaded and tested their app in my OnePlus 3 and it doesn't work.
Mark M.
I have no answers for you on this, and for that, I apologize
let me take questions from the others, and I will return to you shortly
Rory: sorry for the delays due to my technical hiccup -- do you have a question?
Rory M.
Hey Mark - apologies for me interjecting ... I do yeah. Two actually if you have time
Mark M.
let's tackle the first one
Rory M.
1. Is it possible to have alternative launcher activities depending on a condition - say a shared preference flag
7:55 PM
Mark M.
um
there are two approaches to this
Aritra R.
Okay sure. But if you can later think of the problem once and post a solution on the SO post, it will be very helpful. I have tried almost everything I could, even the SO question I posted didn't help much. If you can take some time later and think about the problem when you are free, it would be great.
Rory M.
So, I have a transparent activity which inflates a dialog alert message if SP flag is true
Otherwise launch MainActivity
Mark M.
right, that's the reliable approach
Rory M.
Oh...and the dialog activity is trigger on boot
Mark M.
the unreliable approach is to enable/disable the activities, using PackageManager and setComponentEnabledSetting()
Rory M.
in a BCR
Mark M.
(Aritra: OK)
Rory: I'd go with the transparent activity that launches the right thing approach
Rory M.
Yeah
Mark M.
so long as it calls finish() when it hands over control, so it is not on the back stack
Rory M.
How would I configure this in the manifest
Mark M.
um, normally? :-)
have an activity, give it the MAIN/LAUNCHER <intent-filter>, and give it the Theme.Translucent.NoTitleBar theme
in onCreate(), read your preference, make your decision about where to go, etc.
Rory M.
As it stands - when the dialog activity is started - it appears for a second and then the main activity (with launcher attribute in manifest) inflates
Am i explains correctly
explaining*
Mark M.
perhaps there's a bug in your implementation
this feels like you're doing something after an if() block instead of in the else {} or something
there's nothing too magical about the transparent activity stuff
Rory M.
I don't think it;s a bug ...May i paste some code -
?
8:00 PM
Rory M.
View paste
 <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
Standard main activity launch
View paste
<activity android:name=".AutoStartReminderActivity"
            android:theme="@android:style/Theme.Translucent.NoTitleBar.Fullscreen"/>
Dialog activity
Mark M.
that does not fit your requirements as originally stated
Rory M.
View paste
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_BOOT_COMPLETED)) {
            if (RoadSafeApplication.getBooleanFromSP("auto-start", "auto-start")) {
                Log.d(TAG, "onReceive: Starting recognition service @ " + SystemClock.elapsedRealtime());
                startWakefulService(context, startRecognitionServiceIntent);
                RoadSafeApplication.createNotification(RoadSafeApplication.APP_NAME, "[AUTO START] Service started");
            }
            else{
                if (!RoadSafeApplication.getBooleanFromSP("auto-start", "auto-start")){
                    Intent i = new Intent(context, AutoStartReminderActivity.class);
                    i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                    context.startActivity(i);
                }
            }

        }
Broadcast receiver on boot
How do you mean?
Mark M.
you asked "Is it possible to have alternative launcher activities depending on a condition - say a shared preference flag"
a boot receiver has little to do with a home screen launcher activity
and launching an activity from a boot-time receiver is evil evil evil
Rory M.
Haha...why?
if flag==true -> launch MainActivity
Mark M.
if you want to take over the UI at boot time, be the home screen
Rory M.
if flag == false --> launch dialog
Yeah - it's intentional - an incentive to purchase the auto start feature ...
But rude maybe...?
*Bit
Mark M.
um, yes, IMHO
beyond that, it'll be unreliable
Rory M.
Ok
Mark M.
you're in a race condition with the home screen
whoever gets in last is what the user sees
and that's going to be very dependent on a lot of environmental factors
moreover, none of this has to do much with "Is it possible to have alternative launcher activities depending on a condition - say a shared preference flag"
which I thought was the question
Rory M.
That comes back to my original question ...
Mark M.
so, let me take questions from the others, and I'll come back to you in a bit, and we can try this all over again
8:05 PM
Rory M.
Ok np
Mark M.
roberto: your turn, and I apologize for the delays -- do you have a question?
roberto
Hello, no problem short question here.
I've an app that has just one activity. The app manipulates some data and refreshes a view. Data goes comes from background thread and I'm using EventBus and AndroidJobPriorityQueue.
I've been doing some memory usage tests
and the total Proportional Set Size (PSS) RAM used by the app increases a 16% over 14hours of continous usage
(i.e. running ui tests without stopping during that time)
Mark M.
I wish more apps behaved that well
roberto
the values are not that high, since that app is very small. The total gives a value of 41543. I guess that is KB.
btw, I'm using meminfo
Right... you got the point.
This is the first time I do this kind of tests and I've no idea if that's are good values or not
Mark M.
in the real world, your process should not live nearly that long
and, hence, a 1% memory growth per hour would seem fairly reasonable
roberto
I just see a graph with a linear curve growing... which, it was discouraging at the beginning. Then I went to yout book and I read that sentence where you say something like, 'you've to keep mem leaks small...'
8:10 PM
roberto
May I ask why 1% is a a fairly reasonable value ?
Mark M.
um, because it's not 50%? :-)
roberto
lol
Mark M.
with memory, you have two main objectives: don't crash with an OutOfMemoryError, and don't piss off the user
(where the former is technically a subset of the latter)
roberto
Ok. May I infere I am leaking memory at that rate ?
Mark M.
possibly
PSS is not purely driven by the Dalvik heap
and so there may be other contributors to that
that's why a lot of the time we focus on the Dalvik heap -- after all, that's where the OutOfMemoryErrors come from
also, PSS is tied into other processes
your app gets "blamed" for a percentage of the zygote's RAM usage
and the percentage will vary based on the # of running processes
hence, so long as PSS is not going through the roof, and you're not using the NDK (where leaks show up in PSS, not the Dalvik heap), I tend not to fixate on it
I'm more worried about using LeakCanary, analyzing the occasional heap dump, and so on
8:15 PM
Test A.
has entered the room
Mark M.
roberto: are you still there?
roberto
Great, you've been very helpful. I'll keep researching. Thank you very much Mark
Mark M.
OK, good -- I thought I was disconnected again...
let me take questions from the others and I'll be back with you later if there is time
Aritra: your turn! do you have another question, one that I might have better luck with? :-)
roberto
Sure, that's all from me
Test A.
has left the room
Mark M.
Aritra: if you have another question, chime in
Aritra R.
No Mark. This is the only problem I am facing because of which many users complaining. If you can give any clues as to what I should look at? What could possibly conflict?
Any ideas from your experience would be great.
Mark M.
well, I have never used the phone receiver
and so I have nothing really to say about it
I mentioned the boot receiver oddities earlier
as to why having an existing process would impact matters... it shouldn't
8:20 PM
Mark M.
that's why I was hoping that the system would be logging something, not necessarily from your app
Aritra R.
The problem is mainly that the broadcast receivers don't register after a reboot. Why can that happen? Any ideas?
Mark M.
your receivers are not receiving the broadcasts after a reboot
that's not strictly the same as "don't register after a reboot"
Aritra R.
If I manually open the app once, then it starts working again.
Mark M.
the behavior would fit "Force Stop" in Settings
Aritra R.
Yes, I mean they are not receiving the broadcasts after a reboot.
Mark M.
and, some device manufacturers do stupid things, like have a task manager that does a "Force Stop" when you terminate a task
Aritra R.
Yes I agree. But if it was a device specific problem, then the test project would also not work right?
Mark M.
agreed
assuming you are doing the same things in your testing
Aritra R.
If you can think of any ideas as what may be conflicting in my project?
Mark M.
so, for example, if with your real app, you are terminating the task from a task manager, but in your test app, you are not, that's a differnce
no
Aritra R.
I am not terminating any of them. I just reboot the device and see that my app doesn't get broadcast but the test app does.
Mark M.
sorry, but I cannot help you further
Rory: back to you!
Rory M.
Hey
8:25 PM
Aritra R.
Okay, thank you for your time Mark. If you can think of something later, please let me know in the SO question.
Mark M.
(Aritra: OK)
Rory: do you have another question?
Rory M.
Yeah - maybe the term launcher activity was misleading. Basically I'd like to launch a dialog enclosed in an activity if a certain condition is false -or else start launcher activity when the use starts app
Or maybe reconsider if this is poor practice
Aritra R.
has left the room
Mark M.
well, let's leave the doing-this-at-boot-time bit aside for the moment
Rory M.
ok..
Mark M.
this gets back to: have a transparent activity that reads the preference and either shows the dialog itself (I assume) or launches the other activity and finishes
the Java code snippet that you pasted in does not exactly do this
it appears to either show a Notification or start an activity
I assume that's your on-boot receiver
Rory M.
Yeah
8:30 PM
Rory M.
if (flag == true){ start Service} else if (false){ start DialogActivity)}
It should read anyways
Mark M.
yes, where you also show the Notification when you start the service
Rory M.
Yeah
Mark M.
but that does not match "I'd like to launch a dialog enclosed in an activity if a certain condition is false -or else start launcher activity when the use starts app"
so I assume that this is something separate
Rory M.
Errr - it does - I didn't mention the notification because it's not relevant here
Mark M.
OK, then I am totally lost
your code references just one activity, not two
"I'd like to launch a dialog enclosed in an activity if a certain condition is false -or else start launcher activity when the use starts app" references two activities
the one that will show the dialog, and the launcher activity
Rory M.
Oh yeah sorry i Was referring to the the manifest launcher
View paste
<activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
This is the crux of my question
Mark M.
but your Java code does not refer to MainActivity
where does MainActivity come into the picture?
Rory M.
Because MainActivity is set as the default launcher activity
Mark M.
is this to be an else for your second if?
8:35 PM
Mark M.
(sorry, third if)
Rory M.
However the code snippet I pasted is for an 'alternative' activity to be launched - so there is a conflict
That is my question - how best to resolve this conflict - ie... how can I prevent both activities being launched
Mark M.
only call startActivity() once
activities do not magically appear
something calls startActivity()
if an activity that you do not expect is appearing, figure out who is starting it
Rory M.
Should I remove this: <category android:name="android.intent.category.LAUNCHER" /> from the activity declaration in the the manifest
Mark M.
I don't know
Rory M.
And just handle startup activities from within the BCR
Mark M.
if you want that activity to appear in the home screen's launcher, then leave LAUNCHER there
if you do not want that activity to appear in the home screen's launcher, remove the <intent-filter> entirely
your BroadcastReceiver, at most, will get control at boot time, and present the user with an activity once
if the answer is that the user has to reboot to get to your activity again... I would expect users to be unhappy
Rory M.
Yeah
Mark M.
so, presumably, you need *something* in the home screen launcher
whether that is MainActivity or another one, I cannot say
8:40 PM
roberto
has left the room
Rory M.
Ok, thanks Mark
Think we got our wires crossed there, thanks for your patience
Mark M.
I am sorry that I wasn't more useful to yuou
er, to you
and that's a belated wrap for today's chat
the transcript should go up on https://commonsware.com/office-hours/ shortly
Rory M.
No - walking through it clear it up in my mind. Many thanks as always Mark
Mark M.
you are very welcome
the next chat is Thursday, at 4pm US Eastern
have a pleasant day!
Rory M.
has left the room
Mark M.
turned off guest access

Thursday, January 5

 

Office Hours

People in this transcript

  • Aritra Roy
  • Mark Murphy
  • nat
  • roberto
  • Rory McGuigan
  • Test Account