Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
zeekner
Jul 14, 2007

Karthe posted:

Is there a library that lets you easily load additional information to a listview once you've scrolled to the bottom? The idea being you query only X records at a time and query for X more on-demand. I could've swore I came across something like that but I can't remember where.

Edit: I just remembered it was CWAC's Endless library.

Hey, keep in mind this caveat from that page:

quote:

Note that this has been tested with ArrayAdapter extensively but may not work with other adapter types, particularly SimpleAdapter. It also will only work with a ListView or possibly other one-View-at-a-time AdapterView implementations.

It watches the getView function for a request on the last position, then starts a load.

An alternative would be to implement it yourself using the ListView OnScrollListener interface. You also have the flexibility of starting the load before you hit the end of the page, like starting the next load 5 items before the end.

e: Misread that, it'll work fine with ArrayAdapter, I was mistaking it with one of the issues with CursorAdapter.

zeekner fucked around with this message at 02:29 on May 22, 2013

Adbot
ADBOT LOVES YOU

zeekner
Jul 14, 2007

Karthe posted:

Is there a way to detect when a SQLiteOpenHelper-extended class calls onUpgrade? I want to visually notify the user when a database upgrade is in progress, but I can't figure out how to get that class to speak to the outside world. It just seems to do its thing without any communication back to the main Activity that, hey, work is being done on the database and you probably shouldn't let the user do anything until the upgrade is complete.

Where are you constructing the SQL helper? You could pass in a Messenger instance created by your activity and use that to send messages back. The exact implementation details depend on the location and relationship of your SQL helper. If it's located in a content provider it's a little harder, you might have to put that Messenger in the application context and then pass messages to the final destination via some kind of registration/message passing setup.

Messengers are really useful for this kind of thing, and the messages are thread-safe (as in they execute on whatever thread the destination handler was created on). You just create a Handler and override handleMessage(), then pass that handler into the Messenger constructor. Pass that messenger reference anywhere, any time you want to send a message, just call Message.obtain() with the message details (you can include a bundle too). Messengers can even be attached to Messages themselves (useful as a reply destination).

e: Oh, also, BroadcastReceivers are useful, probably way better for this case too. You can create your own receiver and register it in the activity at runtime and send broadcasts to it from anywhere you can get a Context. Just use the context passed into the constructor of the SQL helper.

zeekner fucked around with this message at 19:11 on Jun 26, 2013

zeekner
Jul 14, 2007

DreadCthulhu posted:

Interesting, thanks for the link. What's the closest I can get to actually being able to very rapidly iterate on an app in Android? There are a couple of not very ToS-friendly ways of achieving this with hundreds of users in iOS, and I was hoping there would be a more supported route in Android.

What are you trying to do? Anything pushed to the market is available within an hour or two. One of the few things the Android market does better than the rest is turnaround time.

zeekner
Jul 14, 2007

DreadCthulhu posted:

Actually, I need to apologize as I didn't quite explain my level of noobishness. We're right now on iOS only and it's been a giant pain to iterate with app update review cycles as long as a week, with some likelihood of being rejected for dumb reasons. I'd seriously consider dumping the platform if it allowed me to have a more web-like development lifecycle experience.

Basically I don't know anything about Android, and would love to find out just how much one can expect to wait for the submission process? I checked the OP, I swear. Does it take a week to get an update reviewed? What kind of control is in place to check the submission? Also, do you have to pay extra for distributing custom binaries to users?

As I mentioned, right now in iOS there's no way to get your poo poo updated the next day, which is a pain if you're in a situation like where we are and you sometimes can have hundreds of users you need to push the change to. We workaround by giving people a link to the binary signed in an in-house profile, which is a $300 license and you're explicitly forbidden from doing that, heh. It's kind of reasonable for us because we're more B2B than consumer (b2b apps still have to go through an approval process in iOS...), so we can directly tell our users to update by re-clicking the link.

There is literally no review process. Upload the apk and hit release and its available as soon as the servers catch up.

Of course, if you are creating a b2b app that you don't want to list on the market, you'll have to distribute directly. You can do this by hosting the apk yourself or going through a service like Hockeyapp. The end user will have to enable the "unknown sources" option, but android users are used to that kind of bullshit.

zeekner
Jul 14, 2007

Glimm posted:

Actually the beta feature should work perfectly for this, right? Though it's not quite what it is intended for.

Within a company that uses Google Apps for Business it's possible to do releases through Play as well, though I haven't done that.

But yeah it's dead easy just to put the apk on a web site and let users download it, even send them a push notification when an update is ready. If you do the update through Google Play it's pretty quick as well. Much simpler than what you might be accustomed to with TestFlight/iOS provisioning.

Yea, I wasn't sure about suggesting using beta for that, since it's a pretty new feature and I don't think Google's clarified if they're fine with using it like that.

I didn't know Google Apps for Business integrated into Play, that sounds like the closest equivalent to Apple's enterprise app distribution system.

zeekner
Jul 14, 2007

Fluue posted:

I'm having a lot of trouble getting a ListView working. I've tried using two different adapters (LazyAdapter and then a custom SimpleAdapter)

My app takes JSON data and then parses it into a listview (simple enough). But I'm also using the ImageLoader library from nostra13 ( https://github.com/nostra13/Android-Universal-Image-Loader ) to take a dynamically generated URL and download an image.

I'm getting NullPointerExceptions, and just now got this when using the custom SimpleAdapter:

code:
07-27 18:56:22.321: ERROR/AndroidRuntime(28133): FATAL EXCEPTION: main
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.dsgunter.randompokemongenerator/
com.dsgunter.randompokemongenerator.Results}: 
java.lang.NullPointerException
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2100)
        at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2132)
        at android.app.ActivityThread.access$600(ActivityThread.java:139)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1231)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loop(Looper.java:137)
        at android.app.ActivityThread.main(ActivityThread.java:5021)
        at java.lang.reflect.Method.invokeNative(Native Method)
        at java.lang.reflect.Method.invoke(Method.java:511)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:789)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:556)
        at dalvik.system.NativeStart.main(Native Method)
        Caused by: java.lang.NullPointerException
        at com.dsgunter.randompokemongenerator.Results.onCreate(Results.java:51)
        at android.app.Activity.performCreate(Activity.java:5058)
        at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1079)
        at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2064)
I'll attach the code that's giving me grief below:
https://gist.github.com/verkaufer/985a7f4e0f145a729e0b (Results.Java)
https://gist.github.com/verkaufer/28ae68336f8b698affec (MyAdapter.java - the new adapter that generated the above error)
https://gist.github.com/verkaufer/63d9764dc80c2fa09d10 (LazyAdapter.java - old adapter that I was using but pokeman on line 72 always remained null)

Should I keep using my LazyAdapter? I tried the other one because I was stumped on why pokeman wasn't populating (even using breakpoints, it stayed null the entire time).

In results.java, you are referencing the listview but you never grab a reference with findViewById();

Specifically, somewhere before:
code:
list.setAdapter(adapter);
You need to add:
code:
list = (ListView) findViewById(R.id.listname);

zeekner
Jul 14, 2007

Karthe posted:

Is there a good or common directory that apps can write files to? I'm planning on implementing a feature that will let users export vocabulary lists from my app. I want them to be able to easily find and copy them off the device afterwards.

External storage typically fills that role, you can create a folder and save your files there. Most devices will offer a method to read from that storage via USB, so they don't even need to pull a card or use a separate app to get to it.

It's up to the device whether that storage will be an SD card or dedicated partition with USB access, so don't explicitly state that it's on the SD card or it might confuse the user.

zeekner
Jul 14, 2007

Tunga posted:

I'm trying to create an action bar which looks something like the one in the AOSP Contacts app. The main bar is blue, the icons and text are white, and the overflow menu is white with dark text.

In my case I'm using purple rather than blue but the principle should be the same.

The problem is that if I use Theme.Holo.Light as my base theme then the overflow icon turns dark grey which looks rubbish on a solid colour, it should be white. If I use Theme.Holo.Light.DarkActionBar then the icon is white (good) but the overflow menu will have a black background (bad).

Which of these things is it easier for me to manually override and how do I go about it? I'm struggling to find any decent API documentation for the Widget.Holo.blabla stuff so I don't even know what it is that I should be overriding.

Here's my code right now:

While we're at it, what is the difference between Solid and Solid.Inverse?

Give this a shot:
http://jgilfelt.github.io/android-actionbarstylegenerator/

It has an option to customize the overflow menu color (but it's flaky in ABS, I've been meaning to try it in ABC). I forget the exact method to customize that color, but you can set a unique color in that utility and look at the results. I think it might have involved a 9-patch image as well, so look at the resources.

zeekner
Jul 14, 2007

JawnV6 posted:

How easy is it to use the USB port on Android?

OTG seems like overkill and puts way too much burden on the phone. Ideally, I'd have an app on the Android device expose a simple interface over USB that the host would poke and prod at, making the app show data. Basically, can I take over the USB port and use it like I would if I'd designed the whole device or is Mass Storage the only way it'll ever show up?

Targeting a single device for what that matters.

Is the host a PC or a microcontroller? There is a USB accessory kit based on AVR8 and ARM32 MCUs, and it exposes a high-speed serial interface. Its compatible with most devices released in the last year or two.

Otherwise, some apps abuse ADB as a bridge to smuggle data. The best example would be PDANet, which uses that method to enable tethering on devices without root access.

zeekner
Jul 14, 2007

JawnV6 posted:

Micro. This is precisely what I need. Thanks!

I've found the AOA documentation on the Android site and it really sounds like they've got a kit, but I'm lost as to where I'd order one. This is enough to get me started though

The easiest one to find is probably the Arduino ADK, which is the simplified version of the official ADK 2011. It's an Atmega2560 in USB host mode, I used one for a personal project a year ago and it worked pretty well. Only downside is that the phone expects to charge from it, so battery powered hosts won't work very well.

There is the ADK 2012, which is the ARM cortex version with audio capability, but I haven't used it yet.

zeekner
Jul 14, 2007

JawnV6 posted:

Running up against this now :/ Is there any way to disable charging? The naive thought to drop the 5v just made it think the cable was gone :v:

Not that I'm aware of, but I'm no EE. For that project I ended up using a Bluetooth serial adapter (like this or a cheap ripoff). The android bluetooth API has good support for the RFCOMM profile so it worked pretty well, but you have all the extra annoyance of managing bluetooth devices.

zeekner
Jul 14, 2007

Besides, Google's pretty much given up on core OS changes, it's all Play services and support library additions from here on out.

Yay, I guess?

zeekner
Jul 14, 2007

TheReverend posted:

So I'm a .NET ~*Compact Framework*~ developer.

I've been that for the past 7 years oh so (holy poo poo :( ).

Anyways as terrible as WindowsMobile is to use, developing for it was so super easy!
I'm having the exact opposite problem with android. Maybe it's just because it's new to me. Maybe I'm a dumb baby.

Anyways, I request advice on the following things:

1)SQL Lite. I've got the basics down. But one thing I'm going to need to do is read the databases from a desktop application over USB. Any ideas how to do that?

2)UI. The eclipse "designer" sucks poo poo(at least for me. I just want something simple). I really miss Visual Studio when it comes to "form designing". I hate the XML editor. What can I do? Suck it up? Is there a good third party form editor?

3)ListView. I can add stuff to my list view from a database. What I would like to do is also keep track of the unique ID in the database for each item in the listview. But I don't want to display it? Any tips?

4)Why is this so terrible? Is this terrible for everyone else? It took me forever to get a "google maps api for android" sample app running. Not to code it, but to setup eclipse. How does everyone feel about android development in general? I LOVE using android devices but so far I'm not that keen on developing for them.

0) Ditch eclipse for the official android studio. Don't worry about the preview label, it's based on the very stable and complete IntelliJ IDE and is way better than eclipse.

1) I don't know of an easy way or officially supported way to do that via USB within android. You may need to fall back to a network based approach.

2) Android studio is better for this, but it's not perfect.

3) Are you using a CursorAdapter? It manages the ID internally. If you are just manually pulling data from your cursor and putting it straight into a separate adapter it's probably worth switching to a CursorAdapter.

4) You'll get the hang of it. There are some things that are well designed, and others that are plain dumb. Coming from a Microsoft platform is probably jarring since they are a bit more consistent and tend to integrate everything together more smoothly.

zeekner
Jul 14, 2007

TheReverend posted:

Thanks for the tips. I'll definitely check all that out. I'm not sure how well the network thing will do because this will be for "remote farm area" stuff but who knows theres got to be Starbucks around somewhere, right?

I didn't want to suggest it, but there are ways to smuggle data via ADB. You can use ADB port forwarding to establish a socket, then pass data over it. That route requires ADB on the PC side (you can bundle the executable with your PC app) and the phone must have USB debugging enabled. Enabling debugging on recent versions of android is hard for normal users, it's a really annoying thing where you have to tap a specific area 7 times just to show the debug options then you have to approve the RSA fingerprint once you connect.

It's hardly ideal, and it's always possible for Google to change something and break it, but it is a way to do local USB communications on a PC.

zeekner
Jul 14, 2007

TheReverend posted:

I have one more question (and I don't mean to hog this thread, honest!):


-I have a popupwindow and I want to click outside of the window to close it. I found out that setting the popupWindow drawable to an empty drawable will make this happen. I also learned that setting it to null will kill all other UI activity except for the popupWindow.
What I don't understand is...why does this happen?

PopupWindow is a little odd, I had to mess around a while to get the functionality you would expect.

You don't need to do anything with the background, you can set the background to whatever you want to use.

For auto-dismiss, you can add:
code:
popup.setOutsideTouchable(true);
This will allow the popup to respond to the touch event happening outside its borders, and the default action for that is to self-dismiss.

You can also add a dismiss listener so you will get a callback when that happens:
code:
popup.setOnDismissListener(new PopupWindow.OnDismissListener() {
                @Override
                public void onDismiss() {
                    //cleanup stuff
                }
            });
e: I'm not sure why setting the background to null would intercept all touch events, maybe that causes it to silently extend the popup background to cover the whole screen? PopupWindow is one of the poorly designed elements that date back to really early Android, and it can be pretty finicky at times.

zeekner fucked around with this message at 05:47 on Sep 12, 2013

zeekner
Jul 14, 2007

Harik posted:

This is not good advice, the preview label is absolutely accurate. Since people have been talking up the new AS, I just spent 12 hours trying to get android studio to simply build an app that's already working under eclipse. It's insanely ridiculously slow, burns 100% CPU on two cores at all times, throws even more obscure build errors than Eclipse and has a "project"/"module" concept so awful it makes Visual Studio 'solutions' look brilliant.

It doesn't even work out of the box, so be prepared to diagnose a huge clusterfuck of halfassed integration. First off, they ship a known-broken version that requires you to update before you do anything. Oh, but they "helpfully" start up in a "wizard" mode that makes you make a project with a known-broken version before opening up the main screen that lets you use help->update. Because it makes perfect sense to not bother updating your download link, you see.

Secondly, if you don't have a working gradle install it provides one - but it builds vs android-18 which the SDK doesn't come with, so you have to drop into the SDK manager and add 18 before you can even get started. Add about a dozen other little gotchas that I had to deal with just to get it going.

Finally, once you do all that you're left with a fairly basic IDE that loses a lot of the polish and features of Eclipse. There's no tool for AndroidManifest, for instance, so it's back to hand-editing XML. All the build property options are gone aside from paths, so you have to hand-edit the build.gradle file. You may have to reload the project for build.gradle changes to take effect, I don't know. I could never get a sense of if it was detecting file changes or not, and there's no file-save to know that your changes hit the disk: what you see is not necessarily what the build-process sees. The layout renderer is basically unchanged from the eclipse plugin (unsurprising) except it looks much more primitive - it's lost the preview images of the widgets that they had in Eclipse. As for actually doing work in it:

code:
  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND    
13192 harik     20   0 2461096 347252  35604 S 173.3  4.2   0:54.35 java       
Typing feels like a terminal session cross-country over a 300 baud modem. Lots of lag and stutters when "idle". Keyboard shortcuts don't register 50-75% of the time, so you have to get off the keyboard, grab the mouse, go to the menus and select the action you want there. It's a real frustration when you're just trying to get work done; I don't have an 8GB quad-core 3ghz machine for text input to be slow!

The project I was attempting to import isn't even complex. It's basically written for 4.1, except using HoloEverywhere prefixes so it runs on older devices. HoloEverywhere themselves have dumped Eclipse support and only target AS preview, so it's surprising that their build doesn't work either.

So yes, it's very much a pre-alpha preview and it's not a very promising preview at that. The only thing it's got going for it is it's entirely self-contained, so it doesn't poo poo up your working Eclipse SDK. I'll give it another shot in a few more releases and try it for all-fresh code and no back-compatibility library to see if it works better then.

For doing development in Eclipse: the last working version of the SDK is 21.1. All SDK development effort in 22.x has gone to the AS preview, so there's a lot of bitrot in the Eclipse integration. I think it still works out-of-the-box for HelloWorld.app but as you add code you suddenly and randomly end up with things like error messages pointing to the middle of comments and NullPointerExceptions thrown in the build process.

http://qdevarena.blogspot.com/2010/05/download-android-sdk-standalone-for.html has instructions on how to grab older versions, just change the build in the URLs from 18.x to 21.1.

I haven't used the gradle integration yet, because I figured gradle was still too new to be stable (and that seems to be the case). IntelliJ/AS has very good legacy Android build support, where it'll manage the project setup and handle the build process just fine (even with proguard). I transitioned in from IntelliJ, and it was so seamless I was able to keep the existing project config files. The project/module/dependency system is far better than 'just throw everything in the same workspace'. AS is built upon an functional, modern IDE. No more having to manually refresh folder contents, or manually triggering a workspace clean because Eclipse can't track state worth a poo poo. It even tracks GIT/SVN/ect without a broken third party plugin.

Losing the AndroidManifest tool wasn't a big deal, the contextual XML autocomplete makes up for it. That tool would often completely screw up the formatting of that XML file and broke way too easily. Not to mention all the cases where the layout tool would desync from the XML file and you would end up in a world of pain until you restarted Eclipse.

I'm not sure what is so special about your setup that you managed to run into every sharp corner, but I have had the exact opposite experience. I found eclipse to be extremely slow, painful, and out of date. Eclipse was my primary IDE for many years I am so glad to be rid of it.

It also sounds like Google shouldn't be pushing gradle in its current state, I'm happy enough with Ant/jenkins for now.

zeekner
Jul 14, 2007

That call to alarmManager.set needs a time including system.currentmilis. Right now you are telling it to start 2 seconds after new years 1970.

zeekner
Jul 14, 2007

NoDamage posted:

So now that there's an ActionBar in the support library is there any reason to use ActionBarSherlock?

Not really, I've converted several ABS projects to ABC and haven't run into any serious issues. It's a little more annoying to work with, like you have to use MenuItemCompat instead of the full-replacement MenuItem ABS has. Really though, both libraries require a few weird changes (Window flags have a duplicate replacement in ABS, *Compat helpers in ABC, ect). Once you get past that it's pretty easy.

zeekner
Jul 14, 2007

Boz0r posted:

Thanks, that did the trick.

Now I'm trying to extend the project to also update a ProgressBar in the main view, and I have some trouble with that too. I don't really know how I'm supposed to bring a reference to the ProgressBar with me through to the service and on to the BroadcastReceiver. I tried making it static, but then I get a nullpointerexception when I try to access it.

Same code as before, the main activity calls a service when a button is called, the service sets an alarm(two now) that's supposed to repeatedly update a ProgressBar until it's full.

code:
class ProgressReceiver extends BroadcastReceiver {
	@Override
	public void onReceive(Context context, Intent intent) {		
		int progress = MainActivity.progressBar.getProgress() + 10;			
		MainActivity.progressBar.setProgress(progress);
	}	
}
Any ideas?

So just to get it straight, are you sending an update broadcast from the service to the activity? If you are trying to keep the receiver outside the activity, you don't really need to.

If you put that ProgressReceiver as an inner class to your Activity or Fragment, you should be able to reference the progressbar directly. You might need to use a Runnable and activity.runOnUiThread(runnable) to make sure you only modify the progressbar on the UI thread or else it might throw an exception.

e: Also, you can use Intent.putExtra() to add a real progress percentage to that broadcast, so you don't have to send exactly 10 updates.

zeekner
Jul 14, 2007

Boz0r posted:

I'm supposed to do the countdown from the service, so I don't think I can have it as an internal class in the Activity.

EDIT: Can I carry a reference to MainActivity through to the service somehow?

EDIT: I've come a little further:

http://pastebin.kde.org/p3zvxowci

I think the only problem left is, that the onReceive doesn't trigger, and I can't see why.

At this line in your service:

code:
Intent progressIntent = new Intent(context, MainActivity.ProgressReceiver.class);
progressIntent.setAction(MainActivity.PROGRESS_ACTION);
Should be:
code:
Intent progressIntent = new Intent(MainActivity.PROGRESS_ACTION);
Since you registered the PROGRESS_ACTION event in your activity you can skip straight to that action. That action string should also include the application package before your action, to prevent any collisions (so "com.yourapp.handin2.progress_action"). Specifying the class is typically only done when you want to launch a new activity, in this case you should use the action string intent constructor with the fully formed ID that you registered in the activity.

When setting up a broadcastreceiver, you should never need direct contact between the receiver and sender.

zeekner fucked around with this message at 18:37 on Nov 24, 2013

zeekner
Jul 14, 2007

I'm not sure why that code isn't working, but I was just able to create a simple broadcast with this:

code:
public class MainActivity extends Activity {
    public static final String ACTION_BROADCAST = "com.salvadordalvik.broadcast.testbroadcast";
    private TestBroadcast broad = new TestBroadcast();

    private class TestBroadcast extends BroadcastReceiver{

        @Override
        public void onReceive(Context context, Intent intent) {
            Toast.makeText(MainActivity.this, "Broadcast received: "+intent.getLongExtra("time", 0), Toast.LENGTH_SHORT).show();
        }
    }

    @Override
    protected void onResume() {
        super.onRestart();
        registerReceiver(broad, new IntentFilter(ACTION_BROADCAST));
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(broad);
    }
}
From a service (or anywhere else) I could call this:
code:
sendBroadcast(new Intent(MainActivity.ACTION_BROADCAST).putExtra("time", System.currentTimeMillis()));
The only real difference is that I register/unregister as part of the resume/pause lifecycle, which you should do so you don't leave any dead references.

zeekner
Jul 14, 2007

TheReverend posted:

I feel like I'm losing my mind.

I had an application I was working on, and when you started it, onstart was called.

When you changed the orientation, onpause and then onresume were called.

All was right with the world.

Now all of a sudden, onstart is being called when the screen oritentation changes.

Any idea what is happening?

Are you handling the configuration change by specifying the manifest entry "configChanges=orientation|screenSize|keyboardHidden"?

Because without that you should be seeing a full application lifecycle on rotation, from onPause to onDestroy and onCreate back to onResume.

One thing that changed is that before 3.x, you only had to specify configChange=orientation|keyboardHidden for that hack to work, but now you have to include screenSize for it to have the same effect.

zeekner fucked around with this message at 23:21 on Dec 6, 2013

zeekner
Jul 14, 2007

TheReverend posted:

Well that fixed it. I had orientation|keyboard before you told me to add in screensize.


That's really the default behavior though? I thought it was pause-resume for screen changes. That seems undesirable. Or is it desirable and I'm not doing stuff right?

Oh well thank you!

It is a bit of a pain, but you should be using onSaveInstanceState so you can handle the other situations where your activity will be killed and need to be recreated.

It's covered in the docs here:
http://developer.android.com/guide/topics/resources/runtime-changes.html

That rotation hack is legitimately useful, but don't rely on it alone.

zeekner
Jul 14, 2007

Infomaniac posted:

I have been using webdings and windings for some assets in my app. Now, I am getting ready to release it. Does anyone know if it is all good or am I setting myself up for a licensing problem or ip infringement case in the future? For example I use the open book webding or wingding for a category icon.
Perhaps I should remake all of the assets idk.

Are you using those fonts to make PNG icons?

You can look at http://fontawesome.io/. It has most of the common symbols you would want, and the license looks pretty much perfect for your needs. I just use it to generate icons in photoshop.

e: Just install the font to your PC and copy/paste from the cheatsheet.

zeekner
Jul 14, 2007

Jarl posted:

Anybody who knows why on earth there only is a horizontal viewpager? There are hacks on the net and selfmade vertical viewpagers, but this is such a fundamental thing that it obviously should be natively supported. Is it possibly a design philosophy by Google?

They don't have a horizontal listview either. :doom:

There are a lot of obvious view elements that should exist but don't, it's pretty frustrating. You might be able to hack jump-by-page functionality into listview, but that doesn't sound fun at all.

zeekner
Jul 14, 2007

mod sassinator posted:

Man, managing jar dependencies is a bit of a nightmare. I'm trying to add the hamcrest library to an android unit test project, but when I do I keep getting this error on build:

Android Dex: [AndroidTests] Unable to execute DX
Android Dex: [AndroidTests] com.android.dex.DexException: Multiple dex files define Lorg/hamcrest/Description;

It seems like this means there are multiple libraries, but as far as I can tell this is the only one. Anyone else run into this?

Also, am I just doing something wrong or is managing jar dependencies a big nightmare? It seems like I have to fight every library I add to make it work. Really feels like I'm doing something wrong.

You're using the legacy IDEA build config, right? You probably need to set the duplicate JAR reference to Provided.

e: Gradle handles that kind of thing automatically, so whenever you get into that it'll save a lot of trouble.

zeekner
Jul 14, 2007

mod sassinator posted:

Starting to feel like I really need to use maven. Looking at how to use Dagger and it seems like manually installing it isn't documented, and is pretty sucky (all kinds of wackiness with configuring a new compiler library and such). Is there any good overview of how to use maven and the android sdk? I've seen a bunch of stack overflow questions that seem to say different things.

To make sure I understand stuff correctly too, maven is basically a replacement build system that also does dependency management (like downloading dependencies from a central repository), right? I.e. if I switch to maven my project needs to switch away from its ant-based build system.

And just to humor me, is gradle yet another build system to consider? Do gradle and maven work together?

Sorry for the basic questions--still pretty new to Android development.

edit: Ah, this SO question has a great breakdown of each system: http://stackoverflow.com/questions/1163173/why-use-gradle-instead-of-ant-or-maven

I really don't like clunky XML-based build systems and like what gradle is trying to achieve. Sounds like I should give gradle a second shot.

Yea, gradle is the way to go. Maven support is only through third-party build plugins and it's a bit of a pain to manage. Thankfully gradle does make use of the maven repository, so you still have access to almost everything maven would have.

This site is pretty useful when you need to find dependencies: http://gradleplease.appspot.com/ It'll look up the package name and give you the most recent version.

If you want a quick and dirty way to convert to gradle, you can do it in a few steps:
1. Create a new dummy project in Android Studio, it doesn't matter the package name or anything.
2. Copy these files from the dummy to your project:
gradlew
gradlew.bat
gradle/ (copy the folder and contents, skip .gradle as it's just a temp folder)
gradle.properties (if it exists, it'll probably be empty)
build.gradle
settings.gradle (edit this and replace the dummy folder name)
(AppName)/build.gradle (you'll need to edit this to add any dependencies/signing configs/ect)

Once you've copied the files over, you just need to move the folders for src, assets, res, and the manifest. The standard layout is this:
(AppName)/src/main/java/(com/whatever/yourname)
(AppName)/src/main/assets/
(AppName)/src/main/res/
(AppName)/src/main/AndroidManifest.xml

For tests:
(AppName)/src/instrumentTest/java/

Some conversion guides just use a modified build.gradle that overrides the folder locations to point to the old folder structure, but I figure it's easier in the long run to just move them.

Delete any .iml files and the .idea folder to prevent any IDE issues.

Then just open the project in Android Studio, it'll automatically import and try to build it. One little bug to watch out for: when AS tries to import the project, make sure it's not trying to point to (ProjectFolder)/gradle, and make sure the gradle wrapper option is selected.

If you have JAR files in the libs folder, they'll automatically be included like normal, but it's a good idea to replace them with maven references. Using local copies of android libraries is a little bit of work, try to find a maven version to save you some trouble.

That should leave you with a build, from there you can add a signing configurations to handle release builds.

If you run into any snags, try to compare the config to your dummy project. Also make sure to hit the "Sync Gradle" button when you edit a gradle file. AS will pop up a little reminder at the top of the window.

zeekner fucked around with this message at 09:26 on Feb 22, 2014

zeekner
Jul 14, 2007

LibGDX is pretty nice, it's not a pre-built game engine like GameMaker but definitely a pretty nice framework. They set up the project structure such that you can run the same game on Android or directly on the desktop, so you can quickly jump between them.

zeekner
Jul 14, 2007

fritz posted:

Cool, I'll check that out too, thanks.

I'm having some trouble even getting going, I'm trying to follow the tutorial here: https://developer.android.com/training/basics/firstapp/index.html and if I try to start a new project in Eclipse, it looks like it's not creating all the right files (such as R.java). I can do an "android create project ... " and get a thing that I can compile and put on the emulator. I'd like to get that project into Eclipse, but I can't figure out the magic to do so.
Maybe it worked? I had to totally blow away my Eclipse project directory but stuff seems to be happening.

R.java is autogenerated when the project builds. I always had issues with Eclipse failing to rebuild it automatically, I'd have to clean workspace + rebuild to fix it.

zeekner
Jul 14, 2007

fritz posted:

but I'm getting a java.lang.NoSuchMethodException from eclipse:
code:
com.example.drawer.MainActivity.TheView failed to instantiate.
It builds and does something anyway tho, but the TheView is taking up the whole display.

Is it just the preview pane throwing an exception? That's normal and can be ignored. There is a View.isInEditMode() method you can use in your custom view to work around the code that would crash in that preview.

You can use a RelativeLayout to have views overlap each other. Make sure to place the buttons below the custom view in the XML file, they will draw over anything above them. RelativeLayout offers the "android:layout_alignParentBottom" and related arguments to help you position everything the way you want.

zeekner
Jul 14, 2007

fritz posted:

That's what I thought I was doing, but no luck:

You are on the right track, but the major problem is here:
code:
		TV = new TrailView(this);
		setContentView(TV);
You should be calling setContentView(R.layout.whatever_activity_layout) and that should be happening in onCreate(). The contents of that XML file are only used when you specify that layout in the setContentView call.

e: Also, anything configuring views (like setting the button onClickListener) should happen shortly after the setContentView call in onCreate, not in onResume. Anything in onResume will happen every time the screen turns off, the user hits the home button and returns, or you launch another activity and return.

The activity lifecycle is really critical, make sure you read through this page: http://developer.android.com/reference/android/app/Activity.html
e: Actually this one is better: http://developer.android.com/guide/components/activities.html

To clarify, you will need something like this in onCreate:

code:
setContentView(R.layout.activity_main);
TV = (TrailView) findViewById(R.id.trailview);  //set android:id="@+id/trailview" for the TrailView in your XML
myButtonOne = (Button) findViewById(R.id.button1);
myButtonOne.setOnClickListener(ect ect)

zeekner fucked around with this message at 20:34 on Mar 24, 2014

zeekner
Jul 14, 2007

Oh, right, having the TrailView inside the activity class complicates things. It's usually better to split them into separate classes.

To reference it like you have now you'll need to use the generic view item in the layout xml:
code:
<view class="com.example.drawer.MainActivity$TrailView"
	android:layout_width="match_parent"
	ect ect />
e: The dollar sign indicates that the class is an inner class.

zeekner fucked around with this message at 21:03 on Mar 24, 2014

zeekner
Jul 14, 2007

fritz posted:

Oh, cool, that worked (plus I had to change the constructor in the View to take an AttributeSet and make some fields static).

Thanks!

:toot:

ETA: also the reason I nested the classes is because I wanted the inner class to see state belonging to the parent class, I suppose I should have implemented getter/setter methods in TrailView instead and call those?

Yea, the normal way to handle this is to split the view class into a separate file and interface with it like any other class. Once you get the hang of it you'll figure out the proper separation of concerns and an easy way to communicate between view and activity. It's probably little daunting to jump straight into a custom view as part of your first app.

zeekner
Jul 14, 2007

fritz posted:

OK, so I made a TrailView.java and put all the TrailView code in there, then updated activity_main.xml:

<view class="com.example.drawer.TrailView"
android:id="@+id/trailview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@+id/button1"
android:layout_alignParentRight="true" />
and it works.

But (and this was happening before) in onCreate I do:
code:
TV = (TrailView)findViewById(R.id.trailview);
and TV is null.

With the class separated you can use the normal class syntax:
code:
<com.example.drawer.TrailView
    android:id="@+id/trailview" 
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    .../>
The findViewById call must happen after setContentView, the views are not created until the setContentView call.
The TrailView class is extending View, right?

zeekner
Jul 14, 2007


Odd, you should be working at this point, especially if you can get buttons that exist on the same layout. Only thing slightly unusual is that you don't need class="com.example.drawer.TrailView" anymore, that's handled by the tag itself. If you can't get it to work can you post a gist with the current activity code in full?

zeekner
Jul 14, 2007

Just a heads up, google released a bad update to the gradle build tools (0.9.2). It will automatically cause your builds to fail if you use:
code:
classpath 'com.android.tools.build:gradle:0.9.+'
So use 0.9.1 for now I guess.

this isn't even the first time this has happened in the last few months ffs

e: Everyone should use specific point versions for this exact reason, but newly generated projects use that classpath line so this will hit a lot of people.

e2: If you get this error: "Unable to load class 'com.android.builder.testing.api.DeviceProvider'." this is the cause.

zeekner fucked around with this message at 20:27 on Mar 26, 2014

zeekner
Jul 14, 2007

Update to the 0.9.2 issue:
Turns out the issue was caused by the gradle build tools being released before some of the dependency files were uploaded. 0.9.2 should work now, but if you continue to run into that error you need to clear the gradle cache. Either delete the '~/.gradle/caches' folder or run 'gradle --cache rebuild' if you have a local install of gradle.

zeekner
Jul 14, 2007

Jo posted:

Some beginner conceptual questions here. I'm not grokking the logical flow of the average Android app. I can use Buttons in Views to signal Intents which trigger changes to new Activities which have different Views, yes? Or have I completely lost it? Fragments, then, are when you have n ways of looking at the same data and don't want to pass it between activities?

That's a bit off. This is a bit complicated so I apologize in advance if I make things worse.

Views are simply UI elements, combined together inside ViewGroups to form the interface. Buttons are just a type of view, one specifically designed around its onClick function. Most views can actually be used like a button, the base View class that every UI element extends from has onClick callbacks. Most of the UI elements you need already exist (TextView/ImageView/EditText/ect). Treat them like lego blocks, plug them in wherever you need them then control them from the parent Activity or Fragment.

Activities encapsulate those views and handle lifecycle and most interaction logic. An activity should contain the UI logic for a "page" (for lack of a better term). For example, you could have a single activity to handle a login process, and another activity to show a list of content items, and another one to display the actual content itself. The lifecycle is the change between states in the activity when launching or exiting. This hopefully explains the whole cycle better than I ever could.

Intents are essentially messages used to start new activities, send broadcasts, and do more advanced stuff. The most basic use is to start a new activity, for example: when the user completes the login, you would call startActivity() with an intent that pointed to your next activity, like the content list. You can include extra data in that intent, and it's typical to include enough information that the target activity knows exactly what it needs to do. The intent used to start an activity is always accessible by calling getIntent(), and the intent has get_Extra() methods to grab that extra data.

Fragments are essentially sub-activities, they replicate most of the functionality of an Activity but must be placed within an Activity. They were introduced to allow for multi-pane layouts on tablets and are great for code re-use. You can design a content-list fragment and a content-view fragment, then on a tablet you can place both side-by-side in the same activity. Otherwise on a phone you can show just the content-list fragment, then when someone selects an item it starts a new activity that only has the content-view fragment. Most of the activity logic can be moved into the fragment, and that fragment can be inserted into any activity. If your just starting out, it might be a good idea to start with a normal Activity. You'll need to learn fragments at some point though, most modern apps depend on them.

It's probably a good idea to just start here and keep reading. Maybe get a book as well. (I have no idea what book to recommend)

e: wrong link

zeekner fucked around with this message at 06:43 on Mar 29, 2014

zeekner
Jul 14, 2007

Haha, I spent forever writing that and we managed to post within minutes of each other.

For some additional help, google has a ton of sample programs where each cover a specific topic. http://developer.android.com/samples/index.html

You can also generate certain pre-defined patterns when you create a new project. For example it can generate a simple list-content dual-fragment project that you can look through.

Adbot
ADBOT LOVES YOU

zeekner
Jul 14, 2007

BLE on android is a special type of terrible. I spent hours trying to get a consistent connection with both the official sample project and a TI example app, nothing worked more than once in a rare while. I had to physically reboot the phone to regain connection. That was with an N4, I've heard the N5 works better but gently caress that noise.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply