Q:

Lighting + texture shader on Android OpenGL ES (and Cardboard SDK) doesn't show texture

I'm working some projects in Google Cardboard SDK, and having some trouble with my first example involving textures.  I've pieced together my example with code from the Cardboard SDK example and some online tutorials.  You can browse and checkout the project source here.
My issue should be pretty self-evident if you clone and build the project.  I also made a "lighting" branch that represents my attempt to add lighting to the textured shader.  The only change is to set the normals vertex attribute pointer, and multiply in the diffuse value into the color in the shader.  This change turns my display from this:

to this:

Clearly, the first image has no lighting on the earth, and the second has lighting but no texture.  What gives?
I'm sure that I'm Doing It Wrong™.  I just can't for the life of me figure out what I am doing wrong.  I've also been trying to recreate a minimal example from scratch, but without just copying the code into a new project, I keep running into unrelated issues.  I got stuck on my latest attempt just trying to get my solid_color_lighting material to work on a normal cube.
In case you're too lazy to go look at my stash repo, here is some of the important code ;)
Draw function:
public void draw(float[] view, float[] perspective, float[] model) {
    GLES20.glUseProgram(program);

    // Set the active texture unit to texture unit 0.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);

    // Bind the texture to this unit.
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);

    // Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
    GLES20.glUniform1i(textureParam, 0);

    Matrix.multiplyMM(modelView, 0, view, 0, model, 0);
    Matrix.multiplyMM(modelViewProjection, 0, perspective, 0, modelView, 0);

    GLES20.glUniform3fv(lightPosParam, 1, RenderBox.instance.mainLight.lightPosInEyeSpace, 0);
    GLES20.glUniform4fv(lightColParam, 1, RenderBox.instance.mainLight.color, 0);

    // Set the ModelView in the shader, used to calculate lighting
    GLES20.glUniformMatrix4fv(MVParam, 1, false, modelView, 0);

    // Set the position of the cube
    GLES20.glVertexAttribPointer(positionParam, 3, GLES20.GL_FLOAT, false, 0, vertexBuffer);

    // Set the ModelViewProjection matrix in the shader.
    GLES20.glUniformMatrix4fv(MVPParam, 1, false, modelViewProjection, 0);

    // Set the normal positions of the cube, again for shading
    if(normalParam > -1)
        GLES20.glVertexAttribPointer(normalParam, 3, GLES20.GL_FLOAT, false, 0, normalBuffer);
    GLES20.glVertexAttribPointer(texCoordParam, 2, GLES20.GL_FLOAT, false, 0, texCoordBuffer);

    GLES20.glDrawElements(GLES20.GL_TRIANGLES, numIndices, GLES20.GL_UNSIGNED_SHORT, indexBuffer);
}

The vertex shader:
uniform mat4 u_MVPMatrix;
uniform mat4 u_MVMatrix;

attribute vec4 a_Position;
attribute vec3 a_Normal;
attribute vec2 a_TexCoordinate;

varying vec3 v_Position;
varying vec3 v_Normal;
varying vec2 v_TexCoordinate;

void main() {
   // Transform the vertex into eye space.
   v_Position = vec3(u_MVMatrix * a_Position);

  // Pass through the color.
  //v_Color = a_Color;

  // Pass through the texture coordinate.
  v_TexCoordinate = a_TexCoordinate;

  // Transform the normal's orientation into eye space.
  v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));

  // Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
  gl_Position = u_MVPMatrix * a_Position;
}

The fragment shader:
precision mediump float;        // Set the default precision to medium. We don't need as high of a
                            // precision in the fragment shader.
uniform vec3 u_LightPos;        // The position of the light in eye space.
uniform vec4 u_LightCol;
uniform sampler2D u_Texture;    // The input texture.

varying vec3 v_Position;        // Interpolated position for this fragment.
                            // triangle per fragment.
varying vec3 v_Normal;          // Interpolated normal for this fragment.
varying vec2 v_TexCoordinate;   // Interpolated texture coordinate per fragment.

// The entry point for our fragment shader.
void main() {
    // Will be used for attenuation.
    float distance = length(u_LightPos - v_Position);

    // Get a lighting direction vector from the light to the vertex.
    vec3 lightVector = normalize(u_LightPos - v_Position);

    // Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
    // pointing in the same direction then it will get max illumination.
    float diffuse = max(dot(v_Normal, lightVector), 0.0);

    // Add attenuation.
    //diffuse = diffuse * (1.0 / (1.0 + (0.1 * distance)));

    // Add ambient lighting
    //diffuse = diffuse + 0.3;  //No ambient lighting.... this is space

    // Multiply the color by the diffuse illumination level and texture value to get final output color.
    //gl_FragColor = (v_Color * diffuse * texture2D(u_Texture, v_TexCoordinate));
    //gl_FragColor = u_LightCol * diffuse * texture2D(u_Texture, v_TexCoordinate);
    //gl_FragColor = texture2D(u_Texture, v_TexCoordinate);
    gl_FragColor = texture2D(u_Texture, v_TexCoordinate) * diffuse;
    //gl_FragColor = u_LightCol * diffuse;
}

A:

I found the answer! Thanks to @jimbo00000 for pointing out that I need to call glEnableVertexAttribArray for all of my attributes! I wasn't calling it at all for that particular material.  I knew it would be something simple!
To be clear, I just needed to add
GLES20.glEnableVertexAttribArray(positionParam);
GLES20.glEnableVertexAttribArray(normalParam);
GLES20.glEnableVertexAttribArray(texCoordParam);

in my shader setup step.

