开发者

Random resize problems Android tablets

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;

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜