SurfaceView is never available for drawing after creation.
Other SO questions indicate that it can be managed with the callback functions handed to it, and it must be assigned to setContentView before the lifecycle starts.
Logcat indicates that the callbacks are assigned successfully, however they are never fired.
Full code here but I think relevant parts can be found in the main activity:
package com.example.gavin.pixelarraytest;
import android.app.Activity;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GameView theGame = new GameView(this, 0,0);
SurfaceHolder testt;
testt = theGame.getHolder();
setContentView(theGame);
while(true){
if(testt.getSurface().isValid()){ // this never becomes true. isCreating is also consistently false at this point
theGame.prepareCanvas();
break;
}
}
}
}
And in the SurfaceView object:
package com.example.gavin.pixelarraytest;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.WindowManager;
public class GameView extends SurfaceView implements Runnable {
private Paint paint;
private Canvas canvas;
private Bitmap _buffer;
private SurfaceHolder ourHolder;
private boolean running;
private boolean paused = false;
private long fps;
public GameView(Context context, int screenX, int screenY){
ourHolder = getHolder();
ourHolder.addCallback(new MyCallback());
paint = new Paint();
}
public void prepareCanvas(){
running = true;
run();
}
#Override
public void run(){
while(running){
long startFrameTime = System.currentTimeMillis();
draw();
long endFrameTime = System.currentTimeMillis() - startFrameTime;
if(endFrameTime >= 1){
fps = 1000 / endFrameTime;
}
}
private void update(){
class MyCallback implements SurfaceHolder.Callback {
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
}
private void draw(){
this.setWillNotDraw(false);
if(ourHolder.getSurface().isValid()){
canvas = ourHolder.lockCanvas();
canvas.drawColor(Color.argb(255,100,40,40));
int width = 100;
int height = 100;
int colors[] = new int[width*height];
for (int i = 0; i < colors.length; i++){
int a = 255, r = 40, g = 100, b = 40;
colors[i] = (a << 24) | (r << 16) | (g << 8) | b;
_buffer = Bitmap.createBitmap(colors, width, height, Bitmap.Config.RGB_565);
canvas.drawBitmap(_buffer, 0,0,null);
}
}
}
Am I misunderstanding how SurfaceView is used or am I using it incorrectly in the above?
To inflate a canvas object you can try this:
First create a layout file in res>layout
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent">
<GameView
android:id="+#id/mGameView"
android:layout_height="match_parent"
android:layout_width="match_parent"
/>
</LinearLayout>
Then you can inflate this by calling
setContentView(R.layout.your_file_name);
And finally access the gameview by using:
GameView gameView = findViewById(R.id.mGameView);
gameView.prepareCanvas();
Related
Well i heard that there is a camera class already on android studio.
What Im trying to do is Im trying to make an app that turns on the camera when pressed on it and its only front camera and then when it detects the face it self it says something like "You look great today!" i want to record my own voice and put it as my own voice.
So if anyone can guide me how to do something like that, that would be amazing! I researched everywhere!
I've downloaded this already made face detect interface. It works but all i really need to do now is add my voice to it.
Open the app
Waits until face is detected
Says "You look good today"
Thats all i really want! Can you give me some advice or atleast give me some steps how to do it?
Im a noob so take it easy when explaining
Simply use the face detection libraries of native android (and not OpenCV or something more complex) and as soon as the app starts, also keeps track of your face.
You can also put an if statement to check if the face is recognized and also if the vocal message has already been playes.
if(recognized_faces != 0 && message_already_played == false){
//play the message
}
This is a piece of code (an Activity) which takes all the photograms from the frontal camera and analyze them. Originally the code painted with a canvas on the photograms and shows them sequentially (like it was a video stream) into "miaImmagine2". If you don't want it, just do not show miaImmagine2 and show only the video camera layer. I've erased many parts of code unnecessary to you, so that probably there is a lot of code to be erased or adjusted. But it can be a nice help for you. So here is the code:
package mawashi.alex.driveawake;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.ImageFormat;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PointF;
import android.graphics.Rect;
import android.graphics.YuvImage;
import android.hardware.Camera;
import android.hardware.Camera.ErrorCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.media.AudioManager;
import android.media.FaceDetector;
import android.media.MediaMetadataRetriever;
import android.media.MediaPlayer;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceHolder.Callback;
import android.view.SurfaceView;
import android.view.View;
import android.view.Window;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.lang.reflect.Method;
import java.util.List;
#SuppressLint("NewApi")
public class AwakeActivity extends Activity {
SurfaceView mVideoCaptureView;
Camera mCamera;
public Bitmap mFaceBitmap;
public TextView Testo;
public Bitmap mFace2Bitmap;
public ImageView miaImmagine2;
private MediaPlayer player;
public SurfaceView mSurfaceView;
public SurfaceHolder mSurfaceHolder;
private static final int MAX_FACES = 1;
int mFaceWidth;
int mFaceHeight;
int cameraType = 1; // front
int frame_sec = 1000000;
byte[] callbackBuffer;
PreviewCallback cb;
public FrameLayout preview;
Bitmap bmp;
Bitmap b;
MediaMetadataRetriever mediaMetadataRetriever=null;
Bitmap bmFrame = null;
FaceDetector.Face[] faces;
Activity activity;
Context mContext;
int index_sleep = 0;
int consec = 0;
boolean sleep = false;
public float scala = 1;
public int offset = 0;
int m = 1;
int Colore = Color.GRAY;
private MediaPlayer player2;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.detection);
mVideoCaptureView = (SurfaceView) findViewById(R.id.Surface);
miaImmagine2 = (ImageView) findViewById(R.id.imageView2);
Testo = (TextView) findViewById(R.id.textView1);
SurfaceHolder videoCaptureViewHolder = mVideoCaptureView.getHolder();
videoCaptureViewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
setVolumeControlStream(AudioManager.STREAM_MUSIC);
player = MediaPlayer.create(this, R.raw.you_look_good);
videoCaptureViewHolder.addCallback(new Callback() {
public void surfaceDestroyed(SurfaceHolder holder) {
}
public void surfaceCreated(SurfaceHolder holder) {
startVideo();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {}
});
}
////////////////////////////////////////////////////////////////////////////////////////
//************BUTTONS***************************************************************
//ROTATE THE IMAGE OF 90 DEGREES
protected void setDisplayOrientation(Camera mCamera, int angle){
Method downPolymorphic;
try{
downPolymorphic = mCamera.getClass().getMethod("setDisplayOrientation", new Class[] { int.class });
if (downPolymorphic != null)
downPolymorphic.invoke(mCamera, new Object[] { angle });
}catch (Exception e1){ }
}
/////////////////////////////////////////////////////////////////////////////////////////////
//******************************************************************************************
#Override
public void onPause(){
super.onPause();
player.pause();
}
//**************************************************************************************
//*******************************STARTVIDEO*********************************************
#SuppressLint("NewApi")
private void startVideo() {
SurfaceHolder videoCaptureViewHolder = null;
try {
mCamera = Camera.open(1);
} catch (RuntimeException e) {
Log.e("CameraTest", "Camera Open filed");
return;
}
mCamera.setErrorCallback(new ErrorCallback() {
public void onError(int error, Camera camera) {
}
});
Camera.Parameters parameters = mCamera.getParameters();
List<Camera.Size> previewSizes = parameters.getSupportedPreviewSizes();
Camera.Size cs = previewSizes.get(0);
parameters.setPreviewSize(cs.width,cs.height);
setDisplayOrientation(mCamera, 90);
mCamera.setParameters(parameters);
if (null != mVideoCaptureView)
videoCaptureViewHolder = mVideoCaptureView.getHolder();
try {
mCamera.setPreviewDisplay(videoCaptureViewHolder);
} catch (Throwable t) {
}
Log.v("CameraTest","Camera PreviewFrameRate = "+mCamera.getParameters().getPreviewFrameRate());
Size previewSize=mCamera.getParameters().getPreviewSize();
int dataBufferSize=(int)(previewSize.height*previewSize.width* (ImageFormat.getBitsPerPixel(mCamera.getParameters().getPreviewFormat())/8.0));
mCamera.addCallbackBuffer(new byte[dataBufferSize]);
mCamera.setPreviewCallbackWithBuffer(new Camera.PreviewCallback() {
private long timestamp=0;
public synchronized void onPreviewFrame(byte[] data, Camera camera) {
Size previewSize=camera.getParameters().getPreviewSize();
YuvImage yuvImage= new YuvImage(data,ImageFormat.NV21, previewSize.width, previewSize.height, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
yuvImage.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height),80, baos);
byte jpgData[]=baos.toByteArray();
bmp = BitmapFactory.decodeByteArray(jpgData, 0, jpgData.length);
Bitmap bmp2 = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Bitmap.Config.RGB_565);
Canvas canvas=new Canvas(bmp2);
Paint paint=new Paint();
paint.setColor(Color.RED);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(2);
Matrix matrix = new Matrix();
matrix.setRotate(270,bmp.getWidth()/2,bmp.getHeight()/2);
canvas.drawBitmap(bmp, matrix, paint);
faces = new FaceDetector.Face[MAX_FACES];
int mFaceWidth = bmp2.getWidth();
int mFaceHeight = bmp2.getHeight();
PointF midPoint = new PointF(); //inizializza Punto di coordinate float
FaceDetector detector = new FaceDetector(mFaceWidth, mFaceHeight,MAX_FACES);
int facesFound = detector.findFaces(bmp2, faces); //bmp
if(facesFound > 0 && message_started==false){
faces[0].getMidPoint(midPoint);
float eyeDistance = faces[0].eyesDistance();
float confidence = faces[0].confidence();
player.start(); //play of "You look good today!"
message_started = true;
}
miaImmagine2.setImageBitmap(bmp2);
//+++++++++++++++++++++PARTE FINALE++++++++++++++++++++++++++++++++++++++++
try{
camera.addCallbackBuffer(data);
}catch (Exception e) {
Log.e("CameraTest", "addCallbackBuffer error");
return;
}
return;
}
});
try {
mCamera.startPreview();
} catch (Throwable e) {
mCamera.release();
mCamera = null;
return;
}
}
//*************************************STARTVIDEO_END***************************************
////////////////////////////////////////////////////////////////////////////////////////////
//*************************************STOPVIDEO********************************************
private void stopVideo() {
if(null==mCamera)
return;
try {
mCamera.stopPreview();
mCamera.setPreviewDisplay(null);
mCamera.setPreviewCallbackWithBuffer(null);
mCamera.release();
} catch (IOException e) {
e.printStackTrace();
return;
}
mCamera = null;
}
//**********************************STOPVIDEO_END********************************************
//////////////////////////////////////////////////////////////////////////////////////////////
//**********************************FINISH***************************************************
public void finish(){
stopVideo();
super.finish();
};
//**********************************FINISH_END***********************************************
}
i am new to android and stuck with getting screen size. Here is my code,
package com.piyush.droidz;
import android.app.Activity;
import android.content.Context;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.piyush.droidz.model.boy;
public class MainGamePanel extends SurfaceView implements SurfaceHolder.Callback {
private static final String TAG = MainGamePanel.class.getSimpleName();
private GameThread td;
private boy b1;
private int s_width;
private int s_height;
public MainGamePanel(Context context) {
super(context);
getHolder().addCallback(this);
Log.d(TAG, "Screen width=" + s_width);
b1 = new boy(BitmapFactory.decodeResource(getResources(), R.drawable.boy), 50, 50);
td = new GameThread(getHolder(), this);
setFocusable(true);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
s_width = getHolder().getSurfaceFrame().width();
Log.d(TAG, "Present Screen width=" + s_width);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
td.setRunning(true);
td.start();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
td.setRunning(false);
}
#Override
public boolean onTouchEvent(MotionEvent event) {
if (event.getAction() == MotionEvent.ACTION_DOWN) {
b1.handleActionDown((int)event.getX(), (int)event.getY());
if (event.getY()>getHeight()-50) {
td.setRunning(false);
((Activity) getContext()).finish();
}
else {
Log.d(TAG, "Coordinates: X="+event.getX()+", Y="+event.getY());
}
}
if (event.getAction()==MotionEvent.ACTION_MOVE) {
if (b1.isTouched()) {
b1.setX((int)event.getX());
b1.setY((int)event.getY());
}
}
if (event.getAction()==MotionEvent.ACTION_UP) {
b1.setTouched(false);
}
return true;
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.parseColor("#ff0000"));
b1.draw(canvas);
}
}
in the first log-tag it shows 0 where as in the second log-tag it shows exact width of emulator. I have tried initializing the "s_width" with getHolder().getSurfaceFrame().width() even before the constructor but still "s_width" is 0. Also tried WindowManagerand getwindowManager() but it is not recognized by IDE in this class. Here is my Activity class,
package com.piyush.droidz;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class DroidzActivity extends Activity {
MainGamePanel mgp;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mgp = new MainGamePanel(this);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(mgp);
}
}
please help!
Have you tried?
DisplayMetrics metrics = new DisplayMetrics();
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
windowManager.getDefaultDisplay().getMetrics(metrics);
You need to use context for getting the WindowManager. please see the documentation
http://developer.android.com/reference/android/view/WindowManager.html
Preferably the above should be done inside the constructor
public MainGamePanel(Context context) {}
Hope it helps. :)
Hey :) I have a code of a ball that using the motion sensor and I want to make my app count time and when you lose, save this time for a record, so I did it, but my problem is, I can't extend my fragment layout, here is my full code:
package com.example.theball;
import java.util.Timer;
import java.util.TimerTask;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.Fragment;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.content.pm.ActivityInfo;
import android.graphics.Canvas;
import android.graphics.Point;
import android.graphics.drawable.ShapeDrawable;
import android.graphics.drawable.shapes.OvalShape;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.view.Display;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
#SuppressLint("NewApi") public class MainActivity extends Activity implements SensorEventListener {
private SensorManager sensorManager;
private Sensor accelerometer;
#SuppressWarnings("unused")
private long lastUpdate;
AnimatedView animatedView = null;
ShapeDrawable mDrawable = new ShapeDrawable();
public static int x;
public static int y;
public static final int width = 50;
public static final int height = 50;
public boolean firstDraw = true;
private int screen_width;
private int screen_height;
private int sensorX;
private Timer t;
private int TimeCounter = 0;
private int sensorY;
private static int score = 0;
private static SharedPreferences prefs;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setRequestedOrientation (ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
accelerometer = sensorManager
.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
lastUpdate = System.currentTimeMillis();
animatedView = new AnimatedView(this);
setContentView(animatedView);
t=new Timer();
t.scheduleAtFixedRate(new TimerTask() {
public void run() {
runOnUiThread(new Runnable() {
public void run() {
TimeCounter++;
}
});
}
}, 0, 1000);
}
public static class MainFragment extends Fragment {
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.activity_main, container, false);
TextView highscore_int = (TextView)v.findViewById(R.id.highscore_int );
score = prefs.getInt("key", 0);
highscore_int.setText("Highscore:" + score +" seconds.");
return v;
}
}
#Override
protected void onResume() {
super.onResume();
sensorManager.registerListener(this, accelerometer,
SensorManager.SENSOR_DELAY_GAME);
}
#Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
#Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
sensorY = (int) event.values[1];
sensorX = (int) event.values[0];
x -= sensorX*3;
y += sensorY*3;
if(x <= 0 || x >= screen_width || y <= 0 || y >= screen_height) {
SharedPreferences prefs = this.getSharedPreferences("myPrefsKey", Context.MODE_PRIVATE);
int oldScore = prefs.getInt("key", 0);
if( TimeCounter > oldScore ){
Editor edit = prefs.edit();
edit.putInt("key", TimeCounter);
edit.commit(); }
Intent myIntent = new Intent(this, YouLost.class);
startActivity(myIntent);
}
}
}
public class AnimatedView extends ImageView {
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
static final int width = 50;
static final int height = 50;
#SuppressLint("NewApi")
public AnimatedView(Context context) {
super(context);
// TODO Auto-generated constructor stub
display.getSize(size);
screen_width = size.x;
screen_height = size.y;
mDrawable = new ShapeDrawable(new OvalShape());
mDrawable.getPaint().setColor(0xffffAC23);
mDrawable.setBounds(0, 0, screen_width, screen_height);
}
#Override
protected void onDraw(Canvas canvas) {
mDrawable.setBounds(x, y, x + width, y + height);
if(firstDraw) {
x = screen_width / 2;
y = screen_height / 2;
firstDraw = false;
}
mDrawable.draw(canvas);
invalidate();
}
}
}
XML FILE:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="#+id/highscore_int"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginLeft="0dp"
android:layout_marginTop="0dp"
android:layout_weight="0.14"
android:text="12312312"
android:textColor="#android:color/black"
android:textSize="40sp" />
</LinearLayout>
I can't see the highscore_int on my device, only at the eclipse xml file grahpic layout.
You have defined MainActivity twice. Rename the second one to e.g. MainFragment (or something else) and you should be fine.
But I would also recommend to move the Fragment to a different file as well.
I am new in libGDX and making a simple game like bomber-man.I want to move a sprite in accordance with my touch. for example , if i touch below the image it have to move downside,if i touch in right side of image or sprite it should move in right direction. this should be happened continuously i.e when i touch screen any where,sprite should move continuously and when i release the touch,it should stop there.
Thanks in advance..
here is my code
package com.kamal.bomberman;
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.GL10;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.input.GestureDetector.GestureListener;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.sun.org.apache.bcel.internal.generic.RETURN;
public class Bomberman implements ApplicationListener {
private SpriteBatch batch;
private Texture textureBg,textureBman;
private TextureRegion regionBg , regionBman;
float x = 5 , y = 630 ;
#Override
public void create() {
textureBg = new Texture(Gdx.files.internal("data/bg.png"));
textureBman = new Texture(Gdx.files.internal("data/bm.png"));
regionBman = new TextureRegion(textureBman,0,0,256,512);
regionBg = new TextureRegion(textureBg,6,5,256,192);
batch = new SpriteBatch();
}
#Override
public void dispose() {
}
#Override
public void render() {
batch.begin();
batch.draw(regionBg,0,0,800,1280);
batch.draw(textureBman,x,y,300,300);
batch.end();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}
I am developing a game for android. Between stages, i want to show a part of a map with a route, and move it from a city to city (stage to stage).
First i want to do it on my phone, this a Samsung Galaxy Y, 240x320 Qvga ldpi.
So i have the map file in jpg format. This picture is 2463x602, this is a world map.
I did it, everything is done except one thing. This "animation" is slow for me.
When i start with this, i thought, it will be so fast, and i will handle the speed with a Thread.sleep(); but the matter is, it is not fast.
How can i make it more faster this?
Here is my code:
package hu.mycompany.myproject;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Rect;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class MapActivity extends Activity {
DrawView drawView;
SoundPool soundPool;
int soundId;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
this.setVolumeControlStream(AudioManager.STREAM_MUSIC);
soundPool = new SoundPool(1, AudioManager.STREAM_MUSIC, 0);
soundId = soundPool.load(this, R.raw.airplane, 1);
drawView = new DrawView(this);
setContentView(drawView);
}
public void playSound() {
soundPool.play(soundId, 1f, 1f, 1, 0, 1f);
}
#Override
public void onResume() {
super.onResume();
playSound();
drawView.resume();
}
#Override
public void onPause() {
super.onPause();
drawView.pause();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_map, menu);
return true;
}
public class DrawView extends SurfaceView implements Runnable {
Bitmap gameMap = null;
Thread gameLoop = null;
SurfaceHolder surface;
Rect rect;
volatile boolean running;
volatile boolean moved;
public DrawView(Context context) {
super(context);
moved = false;
surface = getHolder();
gameMap = BitmapFactory.decodeResource(getResources(),
R.drawable.map);
}
public void resume() {
running = true;
gameLoop = new Thread(this);
gameLoop.start();
}
public void pause() {
running = false;
while (true) {
try {
gameLoop.join();
} catch (InterruptedException e) {
}
}
}
#Override
public void run() {
Rect canvasSize = new Rect(0, 0, 240, 320);
Paint paint = new Paint();
paint.setAntiAlias(true);
while (running) {
if (!surface.getSurface().isValid()) {
continue;
}
if (!moved) {
int i;
for (i = 80; i <= 830; i++) {
Canvas canvas = surface.lockCanvas();
rect = new Rect(i, 250, (i + 240), 570);
canvas.drawBitmap(gameMap, rect, canvasSize, paint);
surface.unlockCanvasAndPost(canvas);
}
moved = true;
}
}
}
}
}
1-try to reduce picture size by exporting it save for web in photoshop and select png as extension type
2- You should create two class one for handling thread and other for rendering and game logic. The thread will manage it by locking canvas when system is rendering. Take a look at this link
http://android-er.blogspot.com/2010/05/android-surfaceview.html