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
hooah
Feb 6, 2006
WTF?

hooah posted:

I've got another problem I can't figure out. The course showed us how to add one type of preference to set the location via a postal code. Now we're to create a setting to choose which type of units. I know I need to use a ListPreference, but I'm having trouble getting the XML to cooperate. I found a tutorial that recommended creating an arrays.xml file and defining the arrays for android:entries and android:entryValues[fixed]. I did that fine, but in the pref_general.xml file where I try to use those arrays like [fixed]android:entries="@arrays/pref_temperature_type", I get an error "Unknown resource type arrays". I'm likely mistaken, but it seems to me that Android Studio doesn't know where arrays.xml is, even though it's in app/src/main/res/values. If that's the problem, how do I fix it? If not, then what is the problem?

I was able to fix this by changing arrays.xml (and references to the file) to array.xml. Why?

Another problem: I'm trying to add a share button to my weather details fragment, but having compatibility issues. The course has us using a minimum SDK version of 10, but when I do that, the third line in this code gives an error that it can't cast android.support.v4.view.ActionProvider to android.widget.ShareActionProvider:
Java code:
@Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            inflater.inflate(R.menu.detail_fragment, menu);
            MenuItem item = menu.findItem(R.id.action_share);
            ShareActionProvider mShareActionProvider =
                    (ShareActionProvider) MenuItemCompat.getActionProvider(item);
            //ShareActionProvider mShareActionProvider = (ShareActionProvider) item.getActionProvider();
            if(mShareActionProvider != null) {
                mShareActionProvider.setShareIntent(createShareIntent());
            } else {
                Log.d(LOG_TAG, "Share action provider is null");
            }
        }
If I change the minSdkVersion to 14 as suggested by the IDE and then use the currently commented-out line, then I get a runtime error telling me that that's not supported, and to use MenuItemCompat.getActionProvider instead. How can I resolve this?

Adbot
ADBOT LOVES YOU

speng31b
May 8, 2010

You can call your XML files whatever you want, you don't reference resources by filename but but resource type, and the convention is singular not plural, so @string @array etc will all work. It just happened to work when you changed it because you lucked into the convention. You can even mix resource types in XML files. If you felt like it you could define all your app's resources in a single file called buttpoo.xml, strings ints arrays and all!

hooah
Feb 6, 2006
WTF?

speng31b posted:

You can call your XML files whatever you want, you don't reference resources by filename but but resource type, and the convention is singular not plural, so @string @array etc will all work. It just happened to work when you changed it because you lucked into the convention. You can even mix resource types in XML files. If you felt like it you could define all your app's resources in a single file called buttpoo.xml, strings ints arrays and all!

Oh, ok, that's good to know! I know this course expects a fair amount of Java knowledge, but that particular convention wasn't explained at all.

zeekner
Jul 14, 2007

hooah posted:

Oh, ok, that's good to know! I know this course expects a fair amount of Java knowledge, but that particular convention wasn't explained at all.

It's an android-specific feature. The resource system lets you place assets that are specialized by device/language/screen-size/ect. The file name of the XML doesn't matter at all, just the type named in the xml itself (the <string> or <array>). The folder it's in determines whether it's used, it's a pretty cool thing that makes a lot of stuff possible. This page explains how the folder structure works, it was probably one of my most referenced pages.

hooah
Feb 6, 2006
WTF?
That does look to be a good resource. Any ideas on my ShareActionProvider compatibility problem?

zeekner
Jul 14, 2007

hooah posted:

That does look to be a good resource. Any ideas on my ShareActionProvider compatibility problem?

Ah, didn't see that post. There are two ShareActionProviders, the compat version and the native version for v14+. This applies to most things in the compat library.

Since you are using the compat version, you'll need to make sure you never import the native version. So check your import statements at the top of your file, if ShareActionProvider doesn't have 'support.v7' in the path you'll need to change it.

speng31b
May 8, 2010

hooah posted:

That does look to be a good resource. Any ideas on my ShareActionProvider compatibility problem?

Take a look at the return types of the stuff you're using and make sure you have the Android docs handy. MenuItemCompat.getActionProvider returns one of these: http://developer.android.com/reference/android/support/v4/view/ActionProvider.html

and you cannot cast a v4 support lib ActionProvider to a ShareActionProvider, which is what your code is trying to do. I think your code is a trying to hybridize usage of the support lib alternative with boilerplate non-support lib code, so you just have to make sure when using support lib alternative classes that your types all align with what the support lib methods return. This is especially tricky because sometimes classes are named the exact same things as their non-support lib versions, so you have to even check your imports to make sure you're importing only support lib classes and not accidentally mixing usage.

Just keep the documentation handy. Support libs are cool and useful but as babby's first Android learning project I'm not sure I'd recommend working with them at all, just target a sufficiently high SDK version and go wild.

hooah
Feb 6, 2006
WTF?

speng31b posted:

but as babby's first Android learning project I'm not sure I'd recommend working with them at all, just target a sufficiently high SDK version and go wild.

Yeah, that's what I'm starting to think. Since this is just for myself, I can easily use 14 as the minimum SDK version. However, like I said, when I do that, I get a runtime error. Now that you guys have told me a little more about the support lib, I suspect it's because I'm using that elsewhere (previously unbeknownst to me). Is there an easy (or at least accurate) way to re-jigger all of the support stuff into current stuff?

speng31b
May 8, 2010

hooah posted:

Yeah, that's what I'm starting to think. Since this is just for myself, I can easily use 14 as the minimum SDK version. However, like I said, when I do that, I get a runtime error. Now that you guys have told me a little more about the support lib, I suspect it's because I'm using that elsewhere (previously unbeknownst to me). Is there an easy (or at least accurate) way to re-jigger all of the support stuff into current stuff?

Look through your imports, comment out all imports with the word "support" or "appcompat" or "v7" or "v4" in them, and research/refactor until your code compiles again without those imports. Also if this is just for learning I'd target even higher than 14, at least 17, or hell go nuts and target 21 unless you have some personal device you want to test on that's limiting it.

speng31b fucked around with this message at 21:41 on Dec 21, 2014

Tunga
May 7, 2004

Grimey Drawer
You could also just remove the support lib from your project and then hunt down all the red underlines.

hooah
Feb 6, 2006
WTF?
Alright, I set min SDK to 17, and at least nothing crashes now. However, the fragment that's supposed to display weather details doesn't have an action bar (since ActionBarActivity is no longer an option), so it's not showing the share button (correct?). I did a little searching in the documentation but couldn't find anything that talked about the action bar disappearing. I do see that ActionBar is its own class after API 11, but I can't figure out how to make the transition. Here's what I have in my Details view so far:
Java code:
package com.example.ben.sunshine;

// Imports, no support lib stuff

public class DetailActivity extends Activity {

    public final String LOG_TAG = DetailActivity.class.getSimpleName();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_detail);
        if (savedInstanceState == null) {
            getFragmentManager().beginTransaction()
                    .add(R.id.container, new DetailFragment())
                    .commit();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_detail, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            startActivity(new Intent(this, SettingsActivity.class));
            return true;
        }

        return super.onOptionsItemSelected(item);
    }

    /**
     * A placeholder fragment containing a simple view.
     */
    public static class DetailFragment extends Fragment {

        private static final String LOG_TAG = DetailFragment.class.getSimpleName();

        private static final String FORECAST_SHARE_HASHTAG = " #SunshineApp";
        private String mForecastStr;

        public DetailFragment() {
            setHasOptionsMenu(true);
        }

        @Override
        public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
            inflater.inflate(R.menu.detail_fragment, menu);
            MenuItem item = menu.findItem(R.id.action_share);
            //ShareActionProvider mShareActionProvider =
            //        (ShareActionProvider) MenuItemCompat.getActionProvider(item);
            ShareActionProvider mShareActionProvider = (ShareActionProvider) item.getActionProvider();
            if(mShareActionProvider != null) {
                mShareActionProvider.setShareIntent(createShareIntent());
            } else {
                Log.d(LOG_TAG, "Share action provider is null");
            }
        }

        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container,
                                 Bundle savedInstanceState) {
            View rootView = inflater.inflate(R.layout.fragment_detail, container, false);
            Intent intent = getActivity().getIntent();
            if(intent != null && intent.hasExtra(Intent.EXTRA_TEXT)){
                TextView detailView = (TextView) rootView.findViewById(R.id.detail_text);
                mForecastStr = intent.getStringExtra(Intent.EXTRA_TEXT);
                detailView.setText(mForecastStr);
            }
            return rootView;
        }

        private Intent createShareIntent() {
            Intent shareIntent = new Intent(Intent.ACTION_SEND);
            shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
            shareIntent.setType("text/plain");
            shareIntent.putExtra(Intent.EXTRA_TEXT, mForecastStr + FORECAST_SHARE_HASHTAG);
            return shareIntent;
        }
    }
}

speng31b
May 8, 2010

Every Activity is an ActionBarActivity on a high enough API level, so you just have to make sure the Activity's theme is one that includes an ActionBar. So check out what theme your Activity is using in XML, do some research on ActionBar enabling and styling in XML themes, etc.

hooah
Feb 6, 2006
WTF?

speng31b posted:

Every Activity is an ActionBarActivity on a high enough API level, so you just have to make sure the Activity's theme is one that includes an ActionBar. So check out what theme your Activity is using in XML, do some research on ActionBar enabling and styling in XML themes, etc.

Great, that helped out a lot. Thanks!

hooah
Feb 6, 2006
WTF?
I kinda hate to be asking so many questions, but I've been struggling with this now for a couple days and just can't figure out what needs to be done. Still on the sharing thing (I thought about just junking it, but learning is good): In the videos, they tell us to put the share menu item code in onCreateOptionsMenu in the fragment that's nested in the activity, like so:
Java code:
public static class DetailFragment extends Fragment {

    private static final String LOG_TAG = DetailFragment.class.getSimpleName();
    private static final String FORECAST_SHARE_HASHTAG = " #SunshineApp";
    private String mForecastStr;

    public DetailFragment() { setHasOptionsMenu(true); }

    @Override
    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
        inflater.inflate(R.menu.detail_fragment, menu);
        MenuItem item = menu.findItem(R.id.action_share);

        ShareActionProvider mShareActionProvider = (ShareActionProvider) item.getActionProvider();
        if(mShareActionProvider != null) {
            mShareActionProvider.setShareIntent(createShareIntent());
        } else {
            Log.d(LOG_TAG, "Share action provider is null");
        }
    }
}
However, when I run that and tap on a forecast line to view the details, I see the debug message about the share action provider being null. I can't find anywhere that they mentioned setting that for the MenuItem, though.

So, I thought I'd just put the sharing in the menu, rather than having it on the action bar. I added an else block to the Activity's onOptionsItemSelected method:
Java code:
@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        startActivity(new Intent(this, SettingsActivity.class));
        return true;
    } else if (id == R.id.action_share) {
        DetailFragment details = (DetailFragment) getFragmentManager().findFragmentByTag("detailFragment");
        startActivity(details.createShareIntent());
    }

    return super.onOptionsItemSelected(item);
}
The problem with this approach is I get a null pointer exception when I try to call createShareIntent on the details item. I've done a little debugging and the getFragmentManager().findGragmentByTag [I've also tried ById] doesn't find the included fragment. From the documentation I found on getting a fragment from a view, this should work. What's going wrong?

Splinter
Jul 4, 2003
Cowabunga!
I'm just getting started with Android development, and also am in the market for a new phone. What should I be looking for in a phone from a developer's point of view? I unfortunately can't get a Nexus phone because I'm on Verizon and don't want something as big as the 6. Is OS update speed and long term support the primary thing I should be looking for, or are there other important aspects as well (e.g. runs stock Android w/ no third party launcher)? Do you guys typically use your actual phone for development, or have dedicated development devices?

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...

Splinter posted:

I'm just getting started with Android development, and also am in the market for a new phone. What should I be looking for in a phone from a developer's point of view? I unfortunately can't get a Nexus phone because I'm on Verizon and don't want something as big as the 6. Is OS update speed and long term support the primary thing I should be looking for, or are there other important aspects as well (e.g. runs stock Android w/ no third party launcher)? Do you guys typically use your actual phone for development, or have dedicated development devices?

Only nexus phones typically run stock Android. Anything else is going to have the manufacturer's special flavor with all of its awful quirks, coupled with the bloatware and restrictions that the carrier enforced (hope you didn't feel like tethering!). Of course, you can find a phone that can be rooted and flashed with another rom like Cyanogenmod, but that's another story and there's a subforum to discuss that.

People typically use their own phone for development, unless testing particular OS levels, screen sizes, etc from what I've seen. It's important to note if you're coming from iOS dev that Android uses full emulators, not simulators, when testing without a physical device. So, be sure your computer supports virtualization as required or you're in for a relatively painful experience.

As far as what to get, really just try and get a device with relatively recent hardware. You could just get a tablet if you're not doing anything telephony related to be totally honest.

Tunga
May 7, 2004

Grimey Drawer
Is the Verizon Moto X the same model as the regular Moto X or does it run a Verizon-specific build? If it's just the regular Motorola build that should get fast updates, runs almost-stock Android, and would make a decent dev device.

Alternatively just pick up a cheap Moto G or second-hand N4 for dev work.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
N4 might be pushing it for development. N5 is still reasonable.

speng31b
May 8, 2010

If you're in it for pure market sure bang for you buck testing clout it's hard to beat something on the Galaxy S# or Note # spectrum, where # varies from low to high depending on whether you care more about "current top market share" or "trendingest top market share." If you care more about sanity get a Nexus 5, don't even question it or ask any further questions, just get one and use it.

I have to say, deving on a Nexus device is nice, but it does give you a false sense of security. Samsung-only bugs are a big thing, and if one happens, you might as well know about it sooner rather than later. That said, I'd never have one as a personal device even for the market-share testing benefits. Sanity wins every time, and you're never gonna get out all the manufacturer specific bugs in advance of launch without a test farm service anyhow :(

speng31b fucked around with this message at 03:09 on Dec 27, 2014

Tunga
May 7, 2004

Grimey Drawer
Oh yes, if you want to learn about Samsung-only bugs, get something spectacularly lovely like a Galaxy Ace. That thing nearly drove us all insane at my last job.

Volmarias
Dec 31, 2002

EMAIL... THE INTERNET... SEARCH ENGINES...
Edit: wow did I ever misread that post. Yeah, working around device specific bugs is a big PITA that you don't really get with iOS.

Volmarias fucked around with this message at 17:43 on Dec 27, 2014

speng31b
May 8, 2010

Tunga posted:

Oh yes, if you want to learn about Samsung-only bugs, get something spectacularly lovely like a Galaxy Ace. That thing nearly drove us all insane at my last job.

Ah yes, the Ace. In the mighty company of the Galaxy Ring/Prevail/Centura, the worst devices of all time.

My coworker got a 5 dollar microtablet from some sort of bin at Big Lots that was more stable than all of these devices combined.

speng31b fucked around with this message at 16:35 on Dec 27, 2014

EpicCodeMonkey
Feb 19, 2011
How do you all organize the various intent and internal ID strings? I've just gotten started working on an existing application for a company, and it's full of things like:

code:
private static final String PKG = "com.foo.bar";
private static final String PATH_OPEN = "/" + PKG + "/open";
private static final String PATH_ACTIVATE = "/" + PKG + "/activate";
In various activity classes. Some of the strings are in the Android Manifest as they are Broadcast Intents and various services, and some of the strings are duplicated in the main and companion app so that they can pass intents to each other. Surely there's a way to keep these all centralized and in sync?

hooah
Feb 6, 2006
WTF?
I'm very new to Android, but isn't that what the strings.xml file is for?

speng31b
May 8, 2010

EpicCodeMonkey posted:

How do you all organize the various intent and internal ID strings? I've just gotten started working on an existing application for a company, and it's full of things like:

code:
private static final String PKG = "com.foo.bar";
private static final String PATH_OPEN = "/" + PKG + "/open";
private static final String PATH_ACTIVATE = "/" + PKG + "/activate";
In various activity classes. Some of the strings are in the Android Manifest as they are Broadcast Intents and various services, and some of the strings are duplicated in the main and companion app so that they can pass intents to each other. Surely there's a way to keep these all centralized and in sync?

If they're used cross-project you can put them in a library project that everything shares, ideally defined in xml rather than in code.

hooah
Feb 6, 2006
WTF?
I'm still wrestling with the Share intent. I've got everything behaving (i.e. no crashes or error logs), but the Share button doesn't do anything. I asked on StackOverflow. I've excised all references to the compatibility library. Any ideas?

speng31b
May 8, 2010

hooah posted:

I'm still wrestling with the Share intent. I've got everything behaving (i.e. no crashes or error logs), but the Share button doesn't do anything. I asked on StackOverflow. I've excised all references to the compatibility library. Any ideas?

Log stuff and/or set a breakpoint in the share button click event and see what's (not) happening.

hooah
Feb 6, 2006
WTF?

speng31b posted:

Log stuff and/or set a breakpoint in the share button click event and see what's (not) happening.

I think the big part of the problem is I don't have anywhere where the share button click is handled. I thought that was taken care of by the ShareActionProvider. In the nested fragment, I tried overriding onOptionsItemSelected, but this results in null pointer exception on details.createShareIntent(), the same as it does in the same method in the containing View.

speng31b
May 8, 2010

hooah posted:

I think the big part of the problem is I don't have anywhere where the share button click is handled. I thought that was taken care of by the ShareActionProvider. In the nested fragment, I tried overriding onOptionsItemSelected, but this results in null pointer exception on details.createShareIntent(), the same as it does in the same method in the containing View.

Well that's your problem. Figure out why you're getting an NPE. You have to handle button presses and do something with them unless your project came with some boilerplate code that's already doing it, in which case it would be obvious that code existed, not something behind the scenes.

hooah
Feb 6, 2006
WTF?

speng31b posted:

Well that's your problem. Figure out why you're getting an NPE. You have to handle button presses and do something with them unless your project came with some boilerplate code that's already doing it, in which case it would be obvious that code existed, not something behind the scenes.

Hmm. I originally expected to need to do something with the tap event, but the answer didn't mention it (although it is done with the appcompat library, but I wouldn't think that would change that much), and the guy on StackExchange who was helping me was the one who said that event would be handled by ShareActionProvider. In any case, I thought that overriding onOptionsItemSelected would handle the tap on the "Share" action bar item; is that not the case?

kitten smoothie
Dec 29, 2001

hooah posted:

Hmm. I originally expected to need to do something with the tap event, but the answer didn't mention it (although it is done with the appcompat library, but I wouldn't think that would change that much), and the guy on StackExchange who was helping me was the one who said that event would be handled by ShareActionProvider. In any case, I thought that overriding onOptionsItemSelected would handle the tap on the "Share" action bar item; is that not the case?

Don't override onOptionsItemSelected, let the action provider do all the work for you.

Get a look at this doc, this should be more clear. I don't see your menu.xml, did you specify the action provider there? That may well be why you're pulling back a null.

Once you've done that, do as you originally had been doing: pick out the action provider in onCreateOptionsMenu once you've inflated the menu, and then you set the share intent on the action provider.

kitten smoothie fucked around with this message at 01:00 on Jan 3, 2015

hooah
Feb 6, 2006
WTF?
Ah, holy poo poo, thank you! I'd defined the actionProviderClass in the layout xml, rather than in the menu xml! So much trouble for such a little thing.

Glimm
Jul 27, 2005

Time is only gonna pass you by

hooah posted:

So much trouble for such a little thing.

Welcome to Android

Hughlander
May 11, 2005

Has anyone tried Visual Studio 2015 CTP for building/debugging yet? Specifically NDK debugging?

SimonChris
Apr 24, 2008

The Baron's daughter is missing, and you are the man to find her. No problem. With your inexhaustible arsenal of hard-boiled similes, there is nothing you can't handle.
Grimey Drawer
Is anyone else having trouble with the Android 5.0 keyboard? I have an app that uses an EditText control to display a keyboard with a text box above it. This works fine on previous Android versions, but on Lollipop the keyboard is completely unresponsive and the text box is replaced with a horizontal green line. The OnKeyDown event handler never gets called at all.

The only thing I can find on Google is this stackoverflow question, where the only advice is to update the SDK's. I have ensured that I have the newest SDK's and have set the target SDK version to 21, in case the problem was caused by some compatibility bullshit. Nothing I try makes any difference whatsoever.

Has anyone else experienced anything similar?

Tunga
May 7, 2004

Grimey Drawer
What do you mean by "a text box", is it a TextView? What are you actually trying to do? A screenshot might help.

Only suggestions I have initially is to try a third-party keyboard (Swype, SwiftKey, etc.) to see if it does the same thing. That might give you a hint about where this problem lies.

SimonChris
Apr 24, 2008

The Baron's daughter is missing, and you are the man to find her. No problem. With your inexhaustible arsenal of hard-boiled similes, there is nothing you can't handle.
Grimey Drawer
It's a TextView, yes (EditText is a subclass of TextView). The player types in some text and it appears above the keyboard.



Here is a screenshot from a Nexus 5 emulator. As you can see, no text is displayed above the keyboard, nor is there any place where it could be displayed.



This is how it's supposed to look. The text appears in the view above the keyboard. (These screenshots are actually from different apps, but the same problem occurs in both).

Unfortunately, I don't own an Android 5 device myself, but I have had one of my testers install the Swype keyboard and it doesn't work either. It would appear that the problem is with the OS itself, somehow.

SimonChris fucked around with this message at 11:29 on Mar 4, 2015

Tunga
May 7, 2004

Grimey Drawer
That's weird. Can you post your layout file?

Sereri
Sep 30, 2008

awwwrigami

My guess is that it's not an issue with the keyboard but instead the layout works different on Lollipop. The edittext probably just has no height, the other two elements take too much space or something similar.

Adbot
ADBOT LOVES YOU

SimonChris
Apr 24, 2008

The Baron's daughter is missing, and you are the man to find her. No problem. With your inexhaustible arsenal of hard-boiled similes, there is nothing you can't handle.
Grimey Drawer

Sereri posted:

My guess is that it's not an issue with the keyboard but instead the layout works different on Lollipop. The edittext probably just has no height, the other two elements take too much space or something similar.

I thought about that, but in that case shouldn't we expect the keyboard to still send OnKeyDown events? Or does it disable itself if there isn't enough space?

FWIW, here is the layout:

Edit: Never mind, I'm stupid. The layout is dynamically generated in code.

SimonChris fucked around with this message at 13:57 on Mar 4, 2015

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