I have app on the Android Market called Speed Anatomy. It has been working and stable for months. Now before Android 3.2 came out with its pixel-scaling feature, my (canvas based) app appeared un-scaled on some tablets with a large black border. I ended up implementing pixel scaling myself therefore it doesn't use the new 3.2 mechanism. This was fairly easy
public void setSurfaceSize(int width, int height) {
synchronized (mSurfaceHolder) {
matrix.reset();
float cancasScaleFactorY=height/(480.0f*scale);
float cancasScaleFactorX=width/(320.0f*scale);
float cancasScaleFactor=Math.min(cancasScaleFactorY, cancasScaleFactorX);
matrix.postScale(cancasScaleFactor,cancasScaleFactor);
...
public void doDraw(Canvas canvas) {
canvas.setMatrix(matrix);
...
boolean doTouchEvent(MotionEvent event) {
float[] xy=new float[2];
xy[0]=event.getX();
xy[1]=event.getY();
matrixI.set(matrix);
matrixI.invert(matrixI);
//revert touch coordinate to the original unscaled coordinate space.
matrixI.mapPoints(xy);
...
This works with all devices I have tested, including most tablets, the simulators on 3.0, 3.1 etc.
Last week I received an e-mail from a user, saying he had a Sony S with Android 3.2 tablet and the touch coordinates were off by a few centimeters. As I don't have an actual tablet, I went to my local Staples store where they have multiple Android tablets on display. Loaded my app on an eee Transformer with Android 3.2 and a Galaxy tab 10.1 with Android 3.1 and they both ran my app flawlessly.
So I figured the user had made a mistake and used an older version of my app (although he specifically told me he had the latest version of my app from the Android Market).
Yesterday night I was at a concert and there was a booth from Canadian carrier Telus with some Galaxy Tabs 10.1 on display. As I was waiting for some friends and had some time to kill, I loaded my apps on it to do one last test.
To my surprise, the touch detection was all off! Basically it acted like the scaling was done on doDraw(), that is the app was full screen and pixel scaled (except for text which gets rendered at hi-res with my method) but the touch coordinates were not scaled, that is, I had to touch the screen in the top left 320x480 corner or the touches would register outside the screen.
So I have two Galaxy tabs 10.1 with Android 3.1 on it, touches scale properly on one but not the other. I also have a user which claim problems on a Sony S with Android 3.2 and I have it working correctly on a transformer with 3.2. There seems to be a problem with matrix operations on those that don't work correctly. Either it's an intermittent problem or there is some other factor that I haven't thought of. Oh I just thought about the fact that it is probable that the second GT10.1 was a 3g since it was outside on the street while the others were wifi, (I don't know about the user's) but I can't see this affecting matrix transformations, right?
I've never had problems with Android Fragmentation before this, in fact it has been easier than dealing with the different iOS versions.
Any clue what could be causing this and how I fix the problem?
There is a free version of the app if you want to try it. Let me know if it works on your device.
EDIT:I just thought of something else. Is it possible that the Android Market is randomly serving an older version of my app once in a while? I'm not sure but I think this bug may have existed in a version that was briefly up on the Market. It has been fixed and updated more than a month ago however.
After weeks of struggle, I believe I have found the source of the problem in the method:
void android.graphics.Matrix.mapPoints(float[] dst, float[] src)
Since: API Level 1
Apply this matrix to the array of 2D points specified by src, and
write the transformed points into the array of points specified by
dst. The two arrays represent their "points" as pairs of floats [x,
y].
Parameters
dst The array of dst points (x,y pairs)
src The array of src points (x,y pairs)
On some devices, this function cannot take the same array for src and dst. I myself has never been able to reproduce the bug. I debugged this blindly by changing things in my code, making releases and asking some users who had reported the problem if it was fixed.
Changing every instance of:
matrix.mapPoints(xy,xy);
to
float[] tempxy = new float[2];
tempxy[0] = xy[0]; tempxy[1] = xy[1];
matrix.mapPoints(xy,tempxy);
seems to have fixed things.
I found another dev reported the issue here:
http://androidforums.com/developer-101/172225-android-graphics-matrix-mappoints-fail.html
This dev mentions it only happening on older versions of Android whereas to me it seems like a regression happening when users upgrade to Gingerbread. Although it doesn't affect all gingerbread devices as my Galaxy SII X was never affected. I was unable to reproduce it on the Android simulator.
Another hint that Gingerbread is affected is that lately with its rising popularity, users have been reporting the issue more often and the active installation count of my app started to go down. After I implemented the fix, it started going up again.
I hope this helps someone.
Matrix invert_m = new Matrix();
matrixI.invert(invert_m);
invert_m.mapPoints(xy );
You need a new instance of Matrix for return the invert one;
Related
I've been looking for a way to detect the finger orientation together with a simplification of the touch area in the form of an ellipse, when using a mobile touch device. I choose Android rather than iOS since I found three usefull methods (getTouchMajor(), getTouchMinor(), and getOrientation()) in the Android reference for the MotionEvent class.
But I've tried to implement these three methods in my app, and sadly they does not return the wanted values. The orientation stays at 0, no matter what, while the getTouchMajor and getTouchMinor is exactly the same each time.
So my question is: Am I doing somethign wrong or is these methods just not implemented yet?
(I've tried the functions on several different devices including: Nexus 5, Nexus 7, and HTC One)
As we work together I know you know this answer, but I just wanted to put it up such that fellow users of Stackoverflow can have it as well.
We have found suggestive comments that maybe the touch screen drivers for most devices do not provide this data to the system.
We originally tested: Samsung Galaxy S2, HTC One, Nexus 5 (by LG) and Nexus 7 (by Asus), Samsung Galaxy Tap 3.
As opposed to the others the Samsung Galaxy Tap 3, gave different values for getTouchMajor() and getTouchMinor(), but this relationship was seen getTouchMajor() = getTouchMinor() * 3, and getOrientation() was always 0, as with all the other devices.
About 2 months later we discovered that the Google Nexus 10 can show an ellipse with a direction line, when you activate Input: Pointer Location under developer settings.
The initial conclusion was that most devices do not support, getTouchMajor(), getTouchMinor(). or getOrientation(), Which could be a limitation of the capacitative touch screens.
But seeing the Nexus 10, and the tracking of the ellipse and orientation gives hope for new interaction design.
It indicates to me that some devices do deliver on getTouchMinor and getTouchMajor as well as orientation. (or historical versions of the same functions).
I have not had the chance to code anything for the device myself but it seems plausible.
I'll try to be precise as much as possible.
I wrote an app, the full code itself doesn't matter
public void onWindowFocusChanged(boolean hasFocus){
super.onWindowFocusChanged(hasFocus);
if(hasFocus){
globalWidth = mainLayout.getWidth();
refillData();
}
}
it works perfectly on my device (sgs2 DarkyROM hd2.1 android version 4.0.3 also checked it on systems based 2.3 version for sgs2), another sgs2 with PilotX2.1, also it works on ASUS Transformer (android v4.2.1) and many other devices with different screen sizes.
I must say that it has different look depending on what device it run (it builds the main layout dynamically so its really notable if app run correctly or not).
But on some devices it has strange behavior. For example on HTC (htc sense 2.1) running android version 2.3.5 its somehow at line getWidth() returns the half or the actual screen's width. Or sgs2 4.2.1 android version it also returns strange result.
I tried to look up in google and stack overflow to find out are there any specific system differences that should be considered that has such a big influence on app but nothing. I don't use any kind of particular hardware of a device that could be implemented differently by system's developer.
What's the problem that I didn't take in mind? Can be that different kernels make the "problematic" behavior for my app? I thought it could be different ROMs, but I checked at least 6-8 different ROMs and had no problem.
If anyone familiar with that subject or met something similar, I would glad even for a link to webpage. I really frustrated.
Maybe you can correct your measures by using View.makeMeasureSpec
mainLayout.measure(
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
int height = mainLayout.getMeasuredHeight();
int width = mainLayout.getMeasuredWidth();
I have an OpenGL ES 2 app running on Android. I have tested on a few devices:
Samsung Galaxy S2
LG Optimus G
HTC One X
Kindle Fire
Kindle Fire HD
And the app runs as expected. However, there is a lingering issue on my Samsung Galaxy S3. In my demo, I render a bunch of spheres. I can also pan the camera around by touching and dragging my finger on the screen.
What I notice is "ghosting" when I move the camera. It's difficult to describe, but I can see the previous outlines of the sphere as I move the camera. And, I can continue to see the previous outlines as the camera moves. I don't see all the previous outlines -- only the last few (it's difficult to quantify things here). And, I only see the outlines within the sphere -- as far as I can tell, the previous outlines cease to exist outside of the sphere.
However, once the camera stops, the outlines catch up and disappear within ~1s. Simply put, when things are stationary, everything renders correctly.
I recently had some texturing issues (related to mipmapping) and I solved them the other day. The problem and solution are outlined here:
Black Artifacts on Android in OpenGL ES 2
Could my texturing fix be related to this? I realize that I'm leaving out A LOT of details, but I'm wondering if the symptoms are enough to go on? Any ideas?
Thanks.
Additional details:
The ghosting does not show up when taking a screenshot using the NDK.
A photo of the problem:
A temporary solution is on your phone, under Developer options, check the box to "Disable hardware overlays."
I'm not yet sure if there's a way to force this behavior when running your app.
Im testing my new game prior to release and i have found that on some devices the Z positions seemed to be mixed up in some cases and objects that should appear on top were appearing underneath.
I'm running opengl es 1 and it runs perfectly on my Samsung Galaxy S2 (and all the samsung devices i tested on) but went wrong on a HTC Desire.
Does anyone have any ideas?
Can you provide us with some pictures and source code? Common depth buffer problems cause some banding problems but your problem seems more related to some default driver state that is set differently value depending on which hardware are you running on.
I suggest you to generate a very simple example and start from the scratch until you find where is the problem, I don't think we can help you with so little information.
Hope that helps.
I'm working on a Honeycomb tablet app that needs to scale some UI views as the user interacts with it. So far I've been using Property Animations and it's working pretty well with ImageViews and TextViews but behaves strangely with a WebView.
webView.animate().scaleX(2).setDuration(400);
This code behaves exactly as I want with ImageView and TextView. It smoothly zooms the UI up to double its original size (in this case only in the X direction).
With a WebView it will scale the view to double its original size, but the viewport remains stationary. If I throw a translationX animation in there that doesn't affect the position of the viewport either. How can I get the WebView's contents to scale along with the view?
UPDATE: It turns out that the code I entered here works perfectly in the Android 3.1 emulator. The strange behavior I'm seeing only happens on the actual device. The device I have is a Verizon Motorola Xoom with Android 3.1. I unfortunately don't have any other devices to test it on so I don't know if it's model specific or just a quirk in the release build of the code.
I'm starting to think this is an Android or Xoom bug.
On this forum thread u can see the whole discussion.
In my case I animate().translationX(value) the frameLayout that contains the webView but the webView fails to draw it's content in the new position.
Myself and some people from the forum ran it on an advent vega running VegaComb 3.2 all of them getting the same bug. On the other hand running on several emulators with different screen sizes and pixel densities or an Asus Transformer it behaves the way it should.