Blending enabled
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
Texture loaded as
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureId);
GLUtils.texImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, texture, 0);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
Shader is
private static final String VERTEX_SHADER_CODE =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"attribute vec2 aTexCoord;" +
"varying vec2 vTexCoord;" +
"void main() {" +
" gl_Position = uMVPMatrix * vPosition;" +
" vTexCoord = aTexCoord;" +
"}";
private static final String FRAGMENT_SHADER_CODE =
"precision mediump float;" +
"varying vec2 vTexCoord;" +
"uniform sampler2D sTexture;" +
"void main() {" +
" gl_FragColor = texture2D(sTexture, vTexCoord);" +
"}";
Clear color:
GLES20.glClearColor(1f, 1f, 1f, 1f);
Antialiasing: 4x
EGL10.EGL_SAMPLE_BUFFERS, 1,
EGL10.EGL_SAMPLES, 4
Texture (white circle with white transparent background):
Output: textures have visible outline


Your texture isn't entirely white - it's a white circle on a black background. White texels have a 1.0 alpha, black texels have a 0.0 alpha.
Now enable linear filtering around the edge and get a texel sample which is interpolated between a black and white texel, and you're going to get something which is somewhat grey in the color channel, and partially transparent in the alpha channel.
Basically just remember that OpenGL and OpenGL ES use post-multiplied alpha blending, and that the color channel is really important even for texels where the alpha value is zero ...
If you set the color value to white all over, and just have a zero or non-zero alpha it would behave as you expect.