As the title, I just want to get the keyboard height.
Since there are so many resolution on Android phones, it is hard to handle.
So Is there any API for that?
Thanks for all.
Use this code in your Activity:
iSoftkeyboardHeight = viewMain.getHeight(); // viewMain - root view of your activity
int y = iSoftkeyboardHeight - 2;
int x = 10;
int counter = 0;
int height = y;
int iSoftkeyboardHeightNow = 0;
Instrumentation instrumentation = new Instrumentation();
while( true)
{
final MotionEvent m = MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, x, y, 0);
final MotionEvent m1 = MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0);
boolean ePointerOnSoftkeyboard = false;
try
{
instrumentation.sendPointerSync(m);
instrumentation.sendPointerSync(m1);
}
catch (SecurityException e)
{
ePointerOnSoftkeyboard = true;
}
if( !ePointerOnSoftkeyboard)
{
if( y == height)
{
if( counter++ < 100)
{
Thread.yield();
continue;
}
}
else
if( y > 0)
iSoftkeyboardHeightNow = iSoftkeyboardHeight - y;
break;
}
y--;
m.recycle();
m1.recycle();
}
if( iSoftkeyboardHeightNow > 0) iSoftkeyboardHeight = iSoftkeyboardHeightNow;
else iSoftkeyboardHeight = 0;
// now use iSoftkeyboardHeight
Related
Rajawali Version or Branch
rajawali:1.0.186
Device and Android Version
ADV Nexus 5X API 19 Android 4.4
Summary
I'm trying to make the camera moves when a MotionEvent (touch) occurs. I tried the code from https://github.com/Rajawali/Rajawali/issues/428 but it did not work for me.
My code
public class Renderer extends RajawaliRenderer {
public Context context;
private DirectionalLight directionalLight;
public Renderer(Context context) {
super(context);
this.context = context;
setFrameRate(60);
}
private Object3D object, star;
public void initScene(){
getCurrentScene().setBackgroundColor(Color.rgb(5,104,255));
directionalLight = new DirectionalLight(1f, .2f, -1.0f);
directionalLight.setColor(1.0f, 1.0f, 1.0f);
directionalLight.setPower(2);
getCurrentScene().addLight(directionalLight);
//LoaderOBJ objParser = new LoaderOBJ(this,"Load/1c_obj");
LoaderOBJ objParser = new LoaderOBJ(mContext.getResources(),mTextureManager, R.raw.primo_obj);
LoaderOBJ starParser = new LoaderOBJ(mContext.getResources(),mTextureManager,R.raw.star_obj);
try {
objParser.parse();
starParser.parse();
object = objParser.getParsedObject();
star = starParser.getParsedObject();
getCurrentScene().addChild(star);
getCurrentScene().addChild(object);
} catch (ParsingException e) {
e.printStackTrace();
}
getCurrentCamera().setLookAt(object.getWorldPosition());
Log.d("->",getCurrentCamera().getX()+","+getCurrentCamera().getY()+","+getCurrentCamera().getZ());
getCurrentCamera().setZ(40);
}
#Override
public void onRender(final long elapsedTime, final double deltaTime) {
super.onRender(elapsedTime, deltaTime);
Camera cam = getCurrentCamera();
Vector3 s = cam.getPosition();
if (touchTurn != 0) {
if (flagMulti) {
Double r = Math.sqrt(s.x * s.x + s.z * s.z);
angle += touchTurn;
angle %= 360;
cam.setPosition((float) (r * Math.cos(angle)), s.y, (float) (r * Math.sin(angle)));
cam.setLookAt(object.getLookAt());
}
else{
s.x+=touchTurn*5;
cam.setPosition(s);
}
touchTurn = 0;
}
if (touchTurnUp != 0) {
if (!flagMulti) {
s.z += touchTurnUp * 5;
cam.setPosition(s);
}
touchTurnUp = 0;
}
}
#Override
public void onTouchEvent(MotionEvent me){
Log.d("touch ","Log touch");
int pointerCount = me.getPointerCount();
if(pointerCount == 2)
flagMulti = true;
if (me.getAction() == MotionEvent.ACTION_DOWN) {
xpos = me.getX();
ypos = me.getY();
}
if (me.getAction() == MotionEvent.ACTION_UP) {
xpos = -1;
ypos = -1;
touchTurn = 0;
touchTurnUp = 0;
}
if (me.getAction() == MotionEvent.ACTION_MOVE) {
float xd = me.getX() - xpos;
float yd = me.getY() - ypos;
xpos = me.getX();
ypos = me.getY();
touchTurn = xd / -100f;
touchTurnUp = yd / -100f;
Log.d("touchTurn ", touchTurn+" - "+touchTurnUp);
}
try {
Thread.sleep(15);
} catch (Exception e) {
}
}
public void onOffsetsChanged(float x, float y, float z, float w, int i, int j){
}}
Would you consider arcballCamera and target to your 3D object. You can then rotate the 3D object and zoom in/out with arcballCamera.
I want to make a simple touch screen test application like Samsung Device Diagnostic Tool.
A screenshot from Samsung Device Diagnostic Tool: http://i.stack.imgur.com/7KgKW.jpg
I'm not very familiar with Android App Development. Which way would you suggest me to make a simple application like the tool I mentioned above?
The development of this application easy matter. You need to understand:
How to get the coordinates of click.
#Override
public boolean onTouchEvent(MotionEvent event) {
int x = (int)(event.getX()/tileSize);
int y = (int)(event.getY()/tileSize);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
map[x][y] = true;
break;
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
}
return false;
}
Override method onDraw, to draw rectangles.
private void init(){
tileSize = 10;
paint1 = new Paint();
paint1.setColor(Color.BLUE);
paint1.setStrokeWidth(10);
paint1.setStyle(Paint.Style.STROKE);
paint2 = new Paint();
paint2.setColor(Color.RED);
paint2.setStrokeWidth(10);
paint2.setStyle(Paint.Style.STROKE);
}
#Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
for (int i = 0; i < x; i++){
for (int j = 0; j < y; j++){
Paint p = null;
if(map[i][j]){
p=paint1;
}else{
p=paint2;
}
canvas.drawRect(i*tileSize, j*tileSize, tileSize, tileSize, paint);
}
}
}
}
Recently I also had to make this screen test in my app. So I had figured a solution. I am taking an array of RectF i.e. ArrayList<RectF> arr = new ArrayList<>() and drawing this Rects in following order :
Left vertical line
private void drawLeftLine(int width, int height) {
int leftPoint = 0;
int topPoint = 0;
int rightPoint = 100;
int bottomPoint = 100;
int maxNoOfRect = height / 100;
int lastRectHeight = height % 100;
for (int i = 0; i < maxNoOfRect; i++) {
arr.add(new RectF(leftPoint, topPoint, rightPoint, bottomPoint));
topPoint = bottomPoint;
bottomPoint = bottomPoint + 100;
}
}
Top Horizontal line
private void drawTopLine(int w, int h) {
int leftPoint = 0;
int topPoint = 0;
int rightPoint = 100;
int bottomPoint = 100;
int maxNoOfRect = w / 100;
int lastRectWidth = w % 100;
for (int i = 0; i < maxNoOfRect; i++) {
arr.add(new RectF(leftPoint, topPoint, rightPoint, bottomPoint));
leftPoint = rightPoint;
rightPoint = rightPoint + 100;
}
arr.add(new RectF(leftPoint, topPoint, rightPoint + lastRectWidth, bottomPoint));
}
and similarly; 3. Right vertical line 4. Bottom horizontal line, with the help of collections of RectF of size 100.
So, when user touch a point, check whether that co-ordinate lies in any of the RectF bounds? If yes, remove that RectF from the array.
like :
#Override
public boolean onTouchEvent(MotionEvent event) {
float touchX = event.getX();
float touchY = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
if (mOnViewTouchedListener != null)
mOnViewTouchedListener.onViewTouched();
Point point = new Point();
point.x = (int) event.getX();
point.y = (int) event.getY();
Log.d("TAG", "point: " + point);
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i).contains(point.x, point.y)) {
Log.d("TAG", "Touch IN");
arr.remove(i);
invalidate();
break;
}
}
break;
case MotionEvent.ACTION_MOVE:
if (mOnViewTouchedListener != null)
mOnViewTouchedListener.onViewTouched();
Log.d("TAG", "ACTION_MOVE");
Point point1 = new Point();
point1.x = (int) event.getX();
point1.y = (int) event.getY();
Log.d("TAG", "point: " + point1);
for (int i = 0; i < arr.size(); i++) {
if (arr.get(i).contains(point1.x, point1.y)) {
Log.d("TAG", "Touch IN");
arr.remove(i);
invalidate();
break;
}
}
break;
default:
return false;
}
return true;
}
So, this is the solution for this. Same way the diagonal lines are also drawn.
Diagonal line from top left to bottom right :
private void drawTBDiagonalLine(int w, int h) {
float height = h;
float width = w;
float slope = (height / width);
float left = 0;
float top = 0;
float bottom = 100;
float right = bottom / slope;
int maxNoOfRect = h / 100;
for (int i = 0; i < maxNoOfRect; i++) {
arr.add(new RectF(left, top, right, bottom));
left = right;
top = bottom;
bottom = bottom + 100;
right = bottom / slope;
}
}
I am trying to get android keyboard Height with following code
parentLayout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Rect r = new Rect();
parentLayout.getWindowVisibleDisplayFrame(r);
int screenHeight = parentLayout.getRootView().getHeight();
int heightDifference = screenHeight - (r.bottom);
previousHeightDiffrence = heightDifference;
if (heightDifference > 100) {
isKeyBoardVisible = true;
changeKeyboardHeight(heightDifference);
} else {
if(emojiKeyboard.getVisibility()==View.INVISIBLE){
emojiKeyboard.setVisibility(View.GONE);
}
isKeyBoardVisible = false;
}
}
});
and that works well with android:windowSoftInputMode="adjustPan" but that results my activity screen to move upward when default keyboard shows up.
All I need is to get keyboard height and show my custom keyboard under default keyboard, according to me that's only possible withandroid:windowSoftInputMode="adjustPan" or android:windowSoftInputMode="AdjustNothing".
And if set android:windowSoftInputMode="adjustNothing" then I can't get keyboard height.
I need alternative solution for my problem.
Advance Thanks!
I use this method for calc keyboard height:
public static int getKeyboardHeight() {
// viewMain <-- findViewById( android.R.id.content).getRootView();
if( viewMain != null) iSoftkeyboardHeight = viewMain.getHeight();
int y = iSoftkeyboardHeight - 2;
int x = 10;
int counter = 0;
int height = y;
int iSoftkeyboardHeightNow = 0;
Instrumentation instrumentation = new Instrumentation();
while( true) {
final MotionEvent m = MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_DOWN, x, y, 0);
final MotionEvent m1 = MotionEvent.obtain( SystemClock.uptimeMillis(), SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, x, y, 0);
boolean ePointerOnSoftkeyboard = false;
try {
instrumentation.sendPointerSync(m);
instrumentation.sendPointerSync(m1);
}
catch (SecurityException e) {
ePointerOnSoftkeyboard = true;
}
if( !ePointerOnSoftkeyboard) {
if( y == height) {
if( counter++ < 100) {
Thread.yield();
continue;
}
}
else
if( y > 0)
iSoftkeyboardHeightNow = iSoftkeyboardHeight - y;
break;
}
y--;
m.recycle();
m1.recycle();
}
if( iSoftkeyboardHeightNow > 0) iSoftkeyboardHeight = iSoftkeyboardHeightNow;
else iSoftkeyboardHeight = 0;
return iSoftkeyboardHeight;
}
rootLayout.getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
Rect r = new Rect();
parent.getWindowVisibleDisplayFrame(r);
int screenHeight = parent.getRootView().getHeight();
int heightDifference = screenHeight - (r.bottom - r.top);
Log.d("Keyboard Size", "Size: " + heightDifference);
}
});
Try this code -
public static void hideSoftKeyboard(EditText editText) {
if (null != editText) {
InputMethodManager imm = (InputMethodManager) editText.getContext()
.getSystemService(Context.INPUT_METHOD_SERVICE);
imm.hideSoftInputFromWindow(editText.getWindowToken(), 0);
}
}
I am doing an edit to a driver file that uses Multi-Touch protocol.
My goal is to bind a swipe gesture from (x1,y1) to (x2,y2) that follows a line.
To do this i execute this function inside the key pressure detection function:
static void do_swipe(struct kp *kp, long xstart, long ystart, long xend, long yend,
int id) {
printk("SWIPE! X1 %d Y1 %d X2 %d Y2 %d ID %d \n",xstart,ystart,xend,yend,id);
int sx, sy;
int dx = abs(xend - xstart);
int dy = abs(yend - ystart);
if (xstart < xend)
sx = 1;
else
sx = -1;
if (ystart < yend)
sy = 1;
else
sy = -1;
int err = dx - dy;
long tempx = xstart;
long tempy = ystart;
while (1) {
key_report(kp, tempx, tempy, id);
//Touch is now detected with input_sync
input_sync(kp->input);
if(tempx == xend && tempy == yend) break;
int e2 = 2 * err;
if (e2 > (-1)*dy) {
err = err - dy;
tempx = tempx + sx;
} else if (e2 < dx) {
err = err + dx;
tempy = tempy + sy;
}
}
printk("END! X %d Y %d \n",tempx, tempy);
}
This function is an edited Bresenham's line algorhitm that instead of drawing a line calls key_report to simulate a touch at the given coordinates.
static void key_report(struct kp *kp, long x, long y, int id) {
if (x == 0 && y == 0) {
//printk("---------- zero point --------------\n");
;
} else {
input_report_key(kp->input, BTN_TOUCH, 1);
input_report_abs(kp->input, ABS_MT_TRACKING_ID, id);
input_report_abs(kp->input, ABS_MT_TOUCH_MAJOR, 20);
input_report_abs(kp->input, ABS_MT_WIDTH_MAJOR, 20);
input_report_abs(kp->input, ABS_MT_POSITION_X, x);
input_report_abs(kp->input, ABS_MT_POSITION_Y, y);
input_mt_sync(kp->input);
}
release = 1;
}
Where kp-> input is so defined
struct input_dev *input;
Edit: I updated the code and I'm also attaching the generic code of a key pressure, because I'd like the driver to perform a swipe only once for each key pressure, to avoid swipe looping.
static void kp_work(struct kp *kp) {
int i, code, value;
kp_search_key(kp);
if (key_param[0] == 3) {
if (kp->key_valid[4] == 1) {
value = kp->key_value[4];
kp->flagchan4 = 0;
if (value >= 0 && value <= (9 + 40)) {
if (key_param[99] == 1 ) {
do_swipe(kp, key_param[25], key_param[26], key_param[97],
key_param[98], 12);
} else
key_report(kp, key_param[25], key_param[26], 12);
} else if (value >= 392 - 40 && value <= (392 + 40)) {
if (key_param[102] == 1) {
do_swipe(kp, key_param[23], key_param[24], key_param[100],
key_param[101], 12);
} else
key_report(kp, key_param[23], key_param[24], 12);
}
kp->flagchan4 = 0;
} else {
kp->flagchan4 = 1;
}
}
input_sync(kp->input);
}
Maybe i could set a check on kp->flagchan4...
Edit: Setting a check on flagchan4 did the trick.
#Override protected void onDraw(Canvas canvas) {
//canvas.drawPicture();
canvas.drawColor(Color.CYAN);
Paint p= new Paint();
p.setColor(Color.RED);
p.setStrokeWidth(20);
canvas.drawLine(100, 200, 400, 500, p);
if(movingObjects.size() > 0){
for (MovingObject ball : movingObjects) {
canvas.drawBitmap(ball.getBitmap(), ball.getX(), ball.getY(), null);
}
}
}
public boolean onTouchEvent(MotionEvent event) {
int eventaction = event.getAction();
int X = (int)event.getX();
int Y = (int)event.getY();
boolean redraw = false;
switch (eventaction ) {
case MotionEvent.ACTION_DOWN:
currentMovingObjectId = 0;
for (MovingObject movingObject : movingObjects) {
int topLeftX = movingObject.getX() ;
int topLeftY = movingObject.getY() ;
double imageSize = movingObject.getSize();
double radCircle = Math.sqrt( (double) (((topLeftX-X)*(topLeftX-X)) + (topLeftY-Y)*(topLeftY-Y)));
if ( (radCircle < imageSize) &&
(X- topLeftX) < movingObject.getWidth() && (Y - topLeftY) < movingObject.getHeight() &&
(X- topLeftX) > 0 && (Y- topLeftY) > 0){
currentMovingObjectId = movingObjects.indexOf(movingObject) + 1;
offsetX = X- topLeftX;
offsetY = Y - topLeftY;
redraw = true;
break;
}
}
break;
case MotionEvent.ACTION_MOVE:
if ( currentMovingObjectId > 0) {
drawAtX = X - offsetX;
drawAtY = Y - offsetY;
if(drawAtX < 0 || (drawAtX + movingObjects.get(currentMovingObjectId-1).getWidth()) > MovingObject.screenWidth)
drawAtX = movingObjects.get(currentMovingObjectId-1).getX();
if(drawAtY < 0 || (drawAtY + movingObjects.get(currentMovingObjectId-1).getHeight()) > MovingObject.screenHeight)
drawAtY = movingObjects.get(currentMovingObjectId-1).getY();
if(drawAtX != movingObjects.get(currentMovingObjectId-1).getX() || drawAtY != movingObjects.get(currentMovingObjectId-1).getY()){
movingObjects.get(currentMovingObjectId-1).setX(drawAtX);
movingObjects.get(currentMovingObjectId-1).setY(drawAtY);
redraw = true;
}
}
break;
case MotionEvent.ACTION_UP:
break;
}
if(redraw)
invalidate();
return true;
}
The above code describes the onTouch and onDraw method in my custom view class and i have to prevent image cross the line.As we can implement using matrix where we can move the object horizontal and vertical avoiding the object by setting the wall on 4 sides of cell but i have to move object freely inside a puzzle.Any logic would be helpful i am stuck.Thanks in advance