Office Hours — Today, October 1

Saturday, September 28

Oct 1
8:25 AM
Mark M.
has entered the room
Mark M.
turned on guest access
Ed
has entered the room
Mark M.
hello, Ed!
how can I help you today?
Ed
Good morning Mark
I got the build working with the latest... thanks for the guidance
Mark M.
sure!
Ed
FYI
View paste (3 more lines)
dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation 'androidx.appcompat:appcompat:1.1.0'
    implementation 'com.google.android.material:material:1.1.0-alpha10'
    implementation 'com.jakewharton:butterknife:10.2.0'
    annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.0'
    implementation 'com.squareup.retrofit:retrofit:1.9.0'
    implementation 'io.reactivex:rxandroid:0.25.0'
    implementation 'io.reactivex:rxjava:1.0.14'
    implementation 'com.squareup.picasso:picasso:2.5.2'
    implementation 'com.google.dagger:dagger-android:2.20'
    implementation 'com.google.dagger:dagger-android-support:2.20' // if you use the support libraries
    annotationProcessor 'com.google.dagger:dagger-android-processor:2.20'
    annotationProcessor 'com.google.dagger:dagger-compiler:2.20'
    annotationProcessor 'com.github.frankiesardo:icepick-processor:2.3.6'
...
fixing / updating builds is a lot like polishing a rock
8:30 AM
Mark M.
and when you're done, you still just have a rock :-)
8:30 AM
Ed
I was curious what you thought about this link: https://medium.com/@tauno/android-studio-pro-ti...
lol. --- true dat
I'm not a fan of logging in Android... and it comes from my decades of doing Java...
Mark M.
hmmmm... for some reason, Medium isn't loading for me right now
oh, no, there it goes
Ed
I expanded that article link so I can pass in call stack info as well
I'll flip you the code...
View paste (102 more lines)
import android.util.Log;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * https://medium.com/@tauno/android-studio-pro-tip-go-to-source-from-logcat-output-f13bf46411b5
 * <p>
 * With a few tweaks.
 * <p>
 * Make log files clickable in the debug window so it takes you straight to the source.
 */
public class LogUtil {

    // figure out if Android logging can be used
...
Needs a valid package name
But that TAG stuff just seems down right 'stupid'
that utility allows me to call it like so...
View paste
            } catch (Exception ex) {
                LogUtil.d("Error creating file with name=" + file.getAbsolutePath() + " Exception=" + ex.getLocalizedMessage());
                ex.printStackTrace();
            }
and then I put this String in the logging filter... "<->"
and the log is hot clickable
and if I have a scenario where I have a static method... where I'm trying to figure out who called it....
Mark M.
going back to "what do you think about [this stuff]", if you like it, it seems fine
Ed
I can do something like... "LogUitl.d("Who is this?",2); And I can get the class name and line number of the code that called it
8:35 AM
Ed
I'm just trying to make sure I don't violate the logging design
the TAG text string seems stupid
Mark M.
there's a logging design?
Mark
has entered the room
Ed
Well, there's something there...
Mark M.
TAG was probably there for a filtering mechanism
(BTW, hello, Mark -- I will be with you shortly!)
Mark
has left the room
Ed
I'm good... help Mark...
Mark M.
I tend not to leave logging my code, so my Logcat messages are either very tactical (so I know where the code is) or are crashes (where the stack trace has clickable elements), so this particular trick isn't one that I would use much personally
but, it's a neat trick all the same
Ed
it just saves me time
plus if I'm not in Debug.... it does nothing
so I don't worry about wasted resources on a device
Mark M.
Timber and other libraries offer that as well
the logging API was probably developed in 2006 or thereabouts
Ed
the stack trick is one I got from Cay S. Horstmann's Core Java book on debugging
he had another really good one that would dump the stack trace of ALL running threads in the JVM
that one was really usefully on a deadlock item with a Java Swing app
I've got one last question... and I'll leave you be...
8:40 AM
Mark M.
go ahead!
Ed
this has to do with Android 10 security changes and the Camera
do you know off hand what new permissions are required to grab a photo from the camera media storage area?
Mark M.
if you mean querying the MediaStore, I think READ_EXTERNAL_STORAGE is still required
if you mean ACTION_OPEN_DOCUMENT, no permissions are required
Ed
I have the permissions... and it works on all previous versions... but in API 29 it tells me 'permission denied' when I try to get the URI to the image
Mark M.
how are you trying to get the Uri to the image?
Ed
View paste
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.CAMERA" />

    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Those permissions are not enough
Mark M.
OK, but how are you trying to get the Uri to the image?
Ed
I need to step away for a few... I'll come back with a log trace for you with more details... thanks Mark! Appreciate you...
ndrocchietto _.
has entered the room
Ed
has left the room
Mark M.
hello, Ivano!
ndrocchietto _.
good day mark
Mark M.
how can I help you today?
8:45 AM
ndrocchietto _.
well, I gotta build a notification under the Actionbar, so that user get informed when internet does not work
Mark M.
by "notification", do you really mean a Notification? or do you mean just some sort of pop-up message?
ndrocchietto _.
Yeah you right, a dialog, alert builder, popup and so on not a notification .I did from Application a call to a Broadcast Receiver, and in `onReceive`
and from there is shot an expl intent to an activity that does NOT have any setContentView(r.layout. "
and simply I am building an AlertDialog
but does not work
Mark M.
what specifically is not working?
ndrocchietto _.
I cannot make this alert dialog big as the screen so to fill all the parent, and cannot make is under the ActionBar
Ed
has entered the room
Mark
has entered the room
ndrocchietto _.
I copy pasted half so
Mark M.
well, this activity is independent of whatever activity/fragment is showing your action bar
ndrocchietto _.
without any success
Mark M.
(BTW, hello Ed and Mark -- I will be with you shortly!)
ndrocchietto _.
I even read a blog you wrote about OrderedBroadcasts where you were confessing your passion for the Gladiator movie
\nothing works
8:50 AM
Mark M.
if you want to show something positioned relative to widgets in an activity or fragment, that activity or fragment needs to be the one displaying that "something"
and "make this alert dialog big as the screen so to fill all the parent" seems to conflict with "make is under the ActionBar"
ndrocchietto _.
but I need to shot this popup in every activity or fragment!
when internet is not present
Mark M.
I'm not the one who came up with your requirements -- I am merely the one trying to help you implement the code
I do not even fully understand the requirements -- if the dialog fills the screen, it cannot also be under the action bar
with some well-placed bits of inheritance, you could minimize the coding overhead of teaching each activity or fragment about how to find out when it needs to display this message
you are welcome to try to use your independent-activity approach, but you are going to have to make some guesses as to where the action bar is in the underlying activity, and that may not be reliable
it has been a while since I needed to manually position a dialog, but IIRC it is a matter of margins
your dialog layout would have match_parent for the height and width, plus a top margin that you think will position it approximately below the action bar
8:55 AM
Mark M.
that would give you a dialog as big as you can make it while still having it be vertically low enough so the underlying action bar peeks through
but, at this point, let me take questions from the others, and I will be back with you in a bit
Mark: your turn! how can I help you today?
Ed
Mark is next
Mark M.
Mark: do you have a question?
Mark: if you have a question, chime in and let me know, and I will switch back to you
in the meantime...
Ed: over to you? do you have another question?
Ed
actually I have an answer to your question above...
View paste (35 more lines)
    retrofit.RetrofitError: /storage/emulated/0/DCIM/Camera/IMG_20190919_205439.jpg: open failed: EACCES (Permission denied)
        at retrofit.RestAdapter$RestHandler.invokeRequest(RestAdapter.java:395)
        at retrofit.RestAdapter$RestHandler.access$100(RestAdapter.java:220)
        at retrofit.RestAdapter$RestHandler$1.invoke(RestAdapter.java:265)
        at retrofit.RxSupport$2.run(RxSupport.java:55)
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:462)
        at java.util.concurrent.FutureTask.run(FutureTask.java:266)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
        at retrofit.Platform$Android$2$1.run(Platform.java:142)
        at java.lang.Thread.run(Thread.java:919)
     Caused by: java.io.FileNotFoundException: /storage/emulated/0/DCIM/Camera/IMG_20190919_205439.jpg: open failed: EACCES (Permission denied)
        at libcore.io.IoBridge.open(IoBridge.java:496)
        at java.io.FileInputStream.<init>(FileInputStream.java:159)
        at retrofit.mime.TypedFile.writeTo(TypedFile.java:74)
...
So that stack trace... will ONLY fail on API 29
9:00 AM
Mark M.
correct, because you do not have filesystem access to that location anymore
Ed
I have a QA Pixel phone running Android 10 as well as the simulator
ndrocchietto _.
sorry my laptop switched off, I close my self in a coroutine waiting
Ed
that code works with no issue on API 28
I'll go dig... no worries Mark
Mark M.
I have written quite a bit about the changes in external storage -- here was the ending blog post on the subject: https://commonsware.com/blog/2019/06/07/death-e...
Ed
I'll circle back and let you know how I fixed it
Thanks!
Mark M.
plus, there's a chapter in *Elements of Android Q* on the changes to external storage
Ed
btw I did fix the HTTP issue you mentioned as well...
Mark M.
good to hear!
Ed
View paste
    <application
        android:networkSecurityConfig="@xml/network_security_config"
had to add that
View paste
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" >
    </base-config>
</network-security-config>
Mark
has left the room
Ed
that is WIDE open... but this app is a companion app... for a print server....
we only talk to the local WIFI connection...
Mark M.
yeah, allowing cleartext traffic is not ideal, and I would not be surprised if there are future repercussions from this (e.g., Play Store ranking)
Ed
thanks for the help Mark! I appreciate you and your time
Mark M.
you're welcome!
Ed
Happy Tuesday!
Mark M.
you too!
Ed
has left the room
Mark M.
let me switch back over to Ivano, and I'll return to you in a bit
Ivano: back to you!
ndrocchietto _.
great
well I have to fill the width
the height is a wrap
but I am getting your point about having a specific activity to relate something to
so in broad terms is not allowed from the broadcast receiver trigger a dialog?
9:05 AM
Mark M.
you can trigger a dialog-themed activity, but not an actual Dialog
(and, the dialog-themed activity option will only work on Android 10+ if you have another activity in the foreground)
ndrocchietto _.
dialog themes activity
this is something I want to google
thank you
Mark M.
there are themes with Dialog in their name for the major theme families
ndrocchietto _.
you mean as themes?
in style?
Mark M.
yes
ndrocchietto _.
ah
Mark M.
roughly speaking, these set the overall window to be wrap_content for width and height, rather than match_parent for width and height
ndrocchietto _.
I see
Mark M.
so that way, the size of your content determines the size of the window, and therefore what is visible around it
ndrocchietto _.
without I need to get programmatically layout parameters
but I am afraid a dialog is not made to fill all the screen
has some margin implicit inside
so I am doubting a theme could do the trick
Mark M.
it works for me
ndrocchietto _.
I read something about theme.holo that should work
OK
cool
thank you Mark
I am definitely on my favourite street: best practice way
wish you a nice day thank you
Mark M.
you're welcome!
ndrocchietto _.
have a pleasant day
Mark M.
you too!
9:10 AM
ndrocchietto _.
ops one sec,
I do not know if I have to choice, a Dialog, FragmentDialog, AlertDialog, or whatever of the three
Mark M.
DialogFragment is a wrapper around a Dialog/AlertDialog
ndrocchietto _.
ah
Mark M.
you use it primarily to ensure that the dialog survives configuration changes
ndrocchietto _.
I see
Mark M.
AlertDialog is a subclass of Dialog (IIRC), one that imposes a standard structure (e.g., positive/negative buttons)
ndrocchietto _.
I do not need positive /negative
OK
Mark M.
if you need to handle configuration changes, use DialogFragment and onCreateView() as normal
that will put the contents of your onCreateView() into a Dialog
ndrocchietto _.
a broadcast that fires an activity that fires a fragment ( transparent)
looks too much to me
9:15 AM
ndrocchietto _.
but thanks
Mark M.
sorry -- your questions about Dialog/AlertDialog/DialogFragment are for a regular activity
a dialog-themed activity is an independent thing
ndrocchietto _.
ah
Mark M.
if you are sticking with the broadcast starting an activity, use a suitable theme (e.g., Theme.AppCompat.Dialog) as a starting point for the activity theme
ndrocchietto _.
so I go for a dialog themed asctivity
as parent you mean/
Mark M.
I am not certain what you mean by "parent"
a dialog-themed activity will look like a dialog
you do not need another dialog in addition to the dialog-themed activity
ndrocchietto _.
STYLES.XML has parents
sorry wrong link
View paste
<style name="Theme.AppCompat.Translucent" parent="@style/ProActive.light">
        <item name="android:windowBackground">@android:color/transparent</item>
        <item name="android:windowIsTranslucent">true</item>
        <item name="android:windowAnimationStyle">@android:style/Animation</item>
    </style>
Mark M.
most likely, you would create a custom theme extending from Theme.AppCompat.Dialog
ndrocchietto _.
ah ok
Mark M.
where you set your colors and window background and stuff
ndrocchietto _.
yeah
and there give some command as stay below the action bar and fill parent width
I am going to try
have a nice day
9:20 AM
Mark M.
you too!
9:30 AM
ndrocchietto _.
has left the room
Mark M.
turned off guest access

Saturday, September 28

 

Office Hours

People in this transcript

  • Ed
  • Mark
  • Mark Murphy
  • ndrocchietto _ivano