Nov 27 | 9:55 AM |
Mark M. | has entered the room |
Mark M. | turned on guest access |
John C. | has entered the room |
Gabriele | has entered the room |
Mark M. |
howdy, John!
|
John C. |
it worked!
|
Mark M. |
and howdy, Gabriele!
|
Gabriele |
Hi :)
|
Mark M. |
John: you narrowly got in first, so... do you have a question?
|
John C. |
so, shall I kick off? i've got one question straight away...
|
John C. |
How can I install / remove s/ware from the Android device programmatically?
|
Mark M. |
do you mean from an Android app running on the device?
|
Mark M. |
or do you mean from some software running on a PC attached to the device
|
Mark M. |
?
|
John C. |
could be - i'm an Android newbie... I'm thinking via some google API on the device?
|
Nov 27 | 10:00 AM |
John C. |
NOT on a PC attached, that's not an option for me.
|
Mark M. |
from on the device, you can *initiate* an install or uninstall, but the user has to accept some dialogs to complete the process
|
John C. |
ok, sounds cool. am I allowed to continue asking questions? :-) or is this round robin?
|
Mark M. |
you initiate an install via an ACTION_VIEW or
ACTION_INSTALL Intent with startActivity(), and initiate an uninstall
via ACTION_UNINSTALL_PACKAGE with startActivity()
|
Mark M. |
it is round-robin, to help maintain my sanity
|
Mark M. |
:-)
|
John C. |
in that case.... next please!
|
Mark M. |
and, with that... Gabriele: do you have a question?
|
Gabriele |
I've solved the problem of yesterday, anyway, now I
have a new one: if I select a bookmark from my listView (inside my
BookmarkFragment) and I press a button to delete it, it works, but if I
rotate the screen, wait and then press the delete button, I get:
"java.lang.IllegalStateException: Content view not yet created" on line
"ListView l = getListView();", have you an idea of why this can happen?
|
Mark M. |
hmmm... I just answered a question on that on StackOverflow recently... hold on...
|
Gabriele |
ok, thank you
|
Mark M. | |
Mark M. |
take a look at the UPDATE section of my answer
|
Gabriele |
yes, I will read it, you can continue with John, thank you :P
|
Mark M. |
OK
|
Mark M. |
John: do you have another question?
|
John C. |
ok, via ACTION_INSTALL - can the s/ware be hosted anywhere or must it be on play... and are installations secure? e.g. HTTPS.
|
Mark M. |
ACTION_INSTALL is for APK files already downloaded by you to the device and available via a local file
|
Mark M. |
how you download that APK file is up to you
|
Nov 27 | 10:05 AM |
Mark M. |
though the file will need to be world-readable
long enough to do the install, as the installer runs in a separate
process from yours
|
Mark M. |
you cannot directly trigger an install from the
Play Store, though you can link users over to an app in the Play Store
if you wish
|
John C. |
getting the file to the device is super easy then?
e.g. if I have a URL I can simply read from that and save it on device,
right?
|
John C. |
hmmm change "save it on the device" to "save it within the sandbox" I suppose....
|
Mark M. |
generally yes -- standard Java network I/O works
|
John C. |
ok, semaphore time - switch to Gabriele...
|
Mark M. |
DownloadManager handles edge cases like failover
from WiFi to mobile data, but not via SSL and the resulting APK has to
go onto external storage (not internal storage)
|
Mark M. |
Gabriele: do you have another question?
|
Mark M. |
OK, John -- back to you
|
Gabriele |
no, I'm still reading and checking
|
Mark M. |
(Gabriele: I thought that might be the case...)
|
John C. |
ok
|
John C. |
does Play have an API to search stuff in it's store?
|
Mark M. |
there are no official Play Store APIs
|
John C. |
official...
|
Gabriele |
(eheh :) )
|
John C. |
:-)
|
John C. |
so, no guaranteed API stability over time, or are we talking utter hack here?
|
Mark M. |
if you poke around, you will find people who have cracked the protocol between the Play Store client and server
|
Nov 27 | 10:10 AM |
Mark M. |
I avoid this like the plague, as it (at least used to) violate terms of service
|
John C. |
right, my thinking too.
|
Mark M. |
so I don't know much about the details
|
Mark M. |
I have begged Google repeatedly to open this up
|
Mark M. |
but, no luck to date
|
John C. |
i'll assume that this also answers my next question; there's no way to initiate play transactions via API either...
|
Mark M. |
define a "play transaction"
|
John C. |
buy a piece of s/ware. good point though....
there's usually a difference between accessing free and paid for apps on
these things.
|
Mark M. |
again, you can link the user over to the Play Store app screen for a particular app
|
Mark M. |
if the user clicks on Buy, they'll go through the normal purchase process
|
Mark M. |
but you cannot click Buy for them
|
John C. |
ok - So i cannot "buy"on the play store on behalf of a user… are there coupon codes?
|
John C. |
then, after that - over to G...
|
Mark M. |
no
|
Mark M. |
though they have set up physical gift cards -- it's possible that there is an online analogue that I missed
|
Mark M. |
but you have no way of helping the user use one, anyway
|
Mark M. |
because that is all inside the Play Store app
|
John C. |
ok, sounds like a nightmware
|
John C. |
nightmare even..
|
Mark M. |
(BTW, Gabriele: chime in when you have a question)
|
Mark M. |
it's more that it's a closed box
|
Gabriele |
(I'm there)
|
Mark M. |
OK, Gabriele: your turn!
|
Gabriele |
Hm, you say that this happen because I'm not gone
through onCreateView(), but in my case I'm gone (I've checked it using a
breakpoint), so I can't understand, why this happen? the listview
should be there
|
Nov 27 | 10:15 AM |
Mark M. |
you went through your original onCreateView()
|
Mark M. |
but you rotated the screen
|
Mark M. |
which destroyed the activity and its views
|
Mark M. |
the new activity apparently has not yet called onCreateView() on the (possibly new) fragment
|
Gabriele |
but after the screen rotation, i went again through onCreateView
|
Mark M. |
then your ListView cannot be null
|
Gabriele |
TT
|
Gabriele |
infact I'm also waiting a lot of time, after the rotation, before press the delete button
|
Gabriele |
and I think it should be not null
|
Mark M. |
is the ListFragment on the screen at the time you press this delete button?
|
Gabriele |
yes
|
Mark M. |
well, you clearly have the ListView, then, because you can see it
|
Mark M. |
hence, I do not know why/how you would get that exception, sorry
|
Gabriele |
ok, thank you, I will try to understand it :P
|
Mark M. |
John: do you have another question?
|
John C. |
I've heard that it's possible to control certain
settings on Android via exchange services - what settings can be
controlled and do you know of a good place i can read about this (I
assume it takes far too long to answer here)?
|
Mark M. |
I know nothing about Exchange services
|
Mark M. |
I don't even know where to tell you to look, as there is nothing in the Android SDK about Exchange
|
Mark M. |
that's a question for your device manufacturer, I guess
|
John C. |
ah, wrong word perhaps... ActiveSync?
|
Mark M. |
likewise
|
Nov 27 | 10:20 AM |
John C. |
drat. ok.
|
Nov 27 | 10:20 AM |
John C. |
:-)
|
Mark M. |
Android the OS has stuff for that, but it's not
exposed to us as developers, and hence, if there is documentation, I
don't know where it would live
|
John C. |
OK - Is there an API to obtain the list of installed applications?
|
Mark M. |
there are methods on PackageManager for that
|
Mark M. |
specifically, getInstalledApplications()
|
John C. |
what about getting hold of all the gory hardware
details, e.g. amount of RAM installed, amount used, type of network
connectivity, name of current network, GPS location? API's for that
stuff too?
|
Mark M. |
ConnectivityManager and LocationManager for the latter stuff
|
Mark M. |
RAM is a complex problem
|
John C. |
what do you mean?
|
John C. |
complex?
|
Mark M. |
I would recommend reading the following StackOverflow answer from Dianne Hackborn: http://stackoverflow.com/questions/2298208/how-...
|
John C. |
ok, cheers, I'll squirrel that link away
|
Mark M. |
quoting the first paragraph: "Note that memory
usage on modern operating systems like Linux is an extremely complicated
and difficult to understand area. In fact the chances of you actually
correctly interpreting whatever numbers you get is extremely low."
|
Mark M. |
Gabriele: do you have another question?
|
Gabriele |
not for now, thank you
|
Mark M. |
OK, if you come up with one, chime in
|
Mark M. |
John: feel free to continue if you have other questions
|
John C. |
excellent, will do.
|
John C. |
ok, next Q coming...
|
John C. |
(gotta reform it so I don't give everything away)...
|
Nov 27 | 10:25 AM |
John C. |
there's a permission called BRICK, allowed only
when the apk is signed by the same cert as the firmware - is this still
available on 4.2 and what does the permission provide access to?
|
Mark M. |
yes, BRICK still exists
|
Mark M. |
however, I have never found what it controls
|
Mark M. |
AFAIK, it's an Easter egg
|
Mark M. |
I tried searching the source code for places that use it and came up with nothing
|
John C. |
i was wondering if it allowed me to initiate a remote wipe of the entire device for example.
|
Mark M. |
no, though you can do wipes via the device admin APIs
|
John C. |
omg, I forgot to ask - what device admin API's exist? :-)
|
Mark M. |
you can set minimum requirements for the device PIN/password and force re-entry of a password
|
Mark M. |
you can set the max amount of inactivity before the device re-locks
|
Mark M. |
you can require full-disk encryption and lead the user to go through that
|
Mark M. |
you can disable the camera
|
Mark M. |
on 4.2, you can disable lockscreen widgets and lockscreen camera access
|
Mark M. |
you can immediately lock the device
|
Mark M. |
and you can initiate a wipe
|
Mark M. | |
John C. |
thanks! is there an easy way to detect if the device is rooted / jailbroken?
|
Mark M. |
not really
|
Mark M. |
you can poke around and see if you can find an 'su' binary
|
Mark M. |
but that's not definitive either way
|
John C. |
ok, thought it might be something like that - but give it's sandboxed - how could i poke around?
|
Mark M. |
try running it
|
John C. |
don't I have access only to a "local" filesystem
|
Mark M. |
:-)
|
John C. |
duh
|
Nov 27 | 10:30 AM |
Mark M. |
honestly, I'm not an expert on rooting, so I don't
know the details of how you run apps as superuser, other than a 'su'
binary is involved
|
John C. |
in Android, am I right when I say the API's to
read/write are entirely sandboxed? e.g. if I tested for
/usr/local/sbin/su - I would only hit the local FS of the app?
|
Mark M. |
it won't be in /usr/local/sbin, because there is no /usr/local/sbin
|
Mark M. |
Android's filesystem is... distinctive
|
John C. |
lol
|
Mark M. |
basically, you have full access to your corner of internal storage
|
Mark M. |
on 4.1 and below, that's /data/data/your.app.package.name.here
|
Mark M. |
think of that as your HOME directory from a Linux standpoint
|
Mark M. |
but you're not chroot'd there
|
Mark M. |
you will have limited access to things outside of that location, such as /proc and /dev
|
Mark M. |
stuff that they couldn't really lock down very well
|
Mark M. |
but you cannot get to other apps' /data/data/... directories
|
John C. |
ok, i think - from my side that's a lot of info I can use to generate more questions.
|
Mark M. |
OK
|
John C. |
so for now - that's all I have. nice and easy!
|
Mark M. |
if either of you have any other questions during the remainder of the chat, just ask
|
Nov 27 | 10:35 AM |
John C. |
Mark, are you available for on-site training in Switzerland?
|
Nov 27 | 10:35 AM |
John C. |
i'd have 5 devs to train in Android.
|
John C. |
we can talk about that offline via email if you wish.
|
Mark M. |
yes, let's discuss this via email
|
Mark M. |
in short: probably yes
|
Gabriele |
hm it seems the problem was the casting of getActivity (inside ModeActionHelper) to WikiApp (which is my main activity)
|
Mark M. |
I am surprised that a cast caused the particular exception you received
|
Gabriele |
anyway now I have a new problem, in onCreate I
have oWikiAdapter = new MyPagerAdapter(getSupportFragmentManager(),
this); but after it is null, how is this possible?
|
Gabriele |
:(
|
Gabriele |
which is giving me NullPointerException
|
Mark M. |
what is "it" in the phrase "after it is null"
|
Mark M. |
?
|
Gabriele |
but after, in my method call, it's null
|
Mark M. |
what is "it's" in your preceding sentence?
|
Gabriele |
it = the adapter, oWikiAdapter
|
John C. |
one thing isn't super clear to me... you mentioned
that there's no official Google Play Store API - which makes it hard to
search/list/query the store items. Is that correct?
|
Nov 27 | 10:40 AM |
Mark M. |
then either you are setting it to null, or this is
a new instance of whatever is calling your constructor and it has not
gotten to that line yet
|
John C. |
as in, there's no way to take URLS from the store and present them to the user in another app for example...
|
Mark M. |
John: yes
|
Mark M. |
if you know the developer or app name, you can construct a URL
|
Mark M. | |
Gabriele |
I'm setting it to null only inside onDestroy hm
|
Gabriele |
oh, after commenting oWikiAdapter = null, inside
onDestroy I get again java.lang.IllegalStateException: Content view not
yet created
|
Mark M. |
by the time onDestroy() is called, I suspect that
onDestroyView() of the fragments will have been called, though I am not
completely certain
|
John C. |
Mark, thanks - I'll be in touch via email.
|
John C. |
G; I wish you the best in your coding endevours!
|
Mark M. |
John: I just sent you an email to kick off that discussion
|
Nov 27 | 10:45 AM |
Gabriele |
I've put a breakpoint inside onDestroy(), but it's raised only in the moment I'm changhing orientation
|
Mark M. |
that makes sense, as your old activity is being destroyed as part of the configuration chagne
|
Mark M. |
er, change
|
Nov 27 | 10:50 AM |
Gabriele |
I have: onDestroyView when the orientation changes, then onCreateView, then getListView is null :(
|
Mark M. |
I have no explanation for that behavior, assuming that you are calling through to the superclass onCreateView()
|
Mark M. |
though, check to make sure you are dealing with the right objects
|
Mark M. |
if this fragment is not retained, then
onDestroyView() is called on one instance, and onCreateView() is called
on a different instance
|
Mark M. |
if you are trying to do things with the old instance, it will not have a ListView
|
Gabriele |
how can I be sure to use the correct istances?
|
Mark M. |
in theory, that should be happening automatically
|
Mark M. |
be sure not to pass fragments around in onRetainNonConfigurationInstance()
|
Gabriele |
no, I don't have it
|
Gabriele |
I'm getting the activity inside my fragment using this: private static WikiApp oActivity = null;
|
Nov 27 | 10:55 AM |
Mark M. |
there's your problem
|
Gabriele |
should I use (cast)getActivity?
|
Gabriele |
but before, with the cast I had the same problem :(
|
Mark M. |
you should get rid of that line entirely
|
Mark M. |
never put activities in static data members
|
Mark M. |
in this case, probably you are referencing the old activity, from before the configuration change
|
Mark M. |
and hence the old fragments
|
Gabriele |
ok thank you, I will try to understand these things for the next time :P
|
Gabriele |
see you the next time, thank you very much
|
Mark M. |
OK
|
Mark M. |
the next office hours chat is next Tuesday, once again at 10am Eastern
|
Gabriele |
nice, thanks
|
Gabriele |
have a good day :)
|
Gabriele | has left the room |
John C. |
thanks - i left you an email re: training.
|
Mark M. |
yes, I see it
|
Mark M. |
I'll respond within the next couple of hours
|
Mark M. |
any other questions for the chat?
|
John C. |
nope - kill it. thank you.
|
Mark M. |
OK
|
John C. | has left the room |
Nov 27 | 11:00 AM |
Mark M. | turned off guest access |