How to create the Surface for the SurfaceHolder? - android

I'm trying to get an application to paint something on a canvas every half a second, but the SurfaceHolder.getSurface().isValid() returns false, and when I call SurfaceHolder.lockCanvas() this returns null.
As per this SO question, I should use a SurfaceHolder.Callback.surfaceCreated but the surface is never created.
The onCreate method from my main Activity
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
ChartPainter p = new ChartPainter(this);
}
And part of my ChartPainter.java
public ChartPainter(Context context) {
super(context);
holder = getHolder();
final boolean a[] = new boolean[1];
a[0] = false;
holder.addCallback(new Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
a[0] = true;
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format,
int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
});
} [...]//more omitted code here
How do I create the surface for the SurfaceHolder?

Does ChartPainter extends SurfaceView?
Note: SurfaceHolder is usually used with SurfaceView. When the activity goes to the foreground and its SurfaceView is about to be rendered, WindowManager will ask SurfaceFlinger to create a new surface. Then SurfaceHolder's surfaceCreated() will be called.

Related

surfaceview gives darker shade

I am new to graphics and surfaceviews etc. I have heard that it is better to draw on a seperate thread than on the main thread. i have 2 activities one which is drawn using ondraw of the view, the other uses surface view. both have the same code for drawing. however the latter gives a much darker backgroung color-even at max alpha setting(255). If I comment out the drawargb line I get a black background. I tried many things like setting background color of surfaceview object and setting pixelformat to rgb888 or transparent but none of these work.Following is the code:
SurfaceHolder ourHolder;Boolean isRunning=true;
Thread ourThread;ArrayList<Float> amtint=new ArrayList();float max;
String names[];String company;
public GraphSview(Context c) {
super(c);
ourHolder=getHolder();
ourThread=new Thread(this);
ourThread.start();}
public void pause(){
isRunning=false;
while(true){try {
ourThread.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}break;}ourThread=null;
}
public void Resume()
{
isRunning=true;
ourThread=new Thread(this);
ourThread.start();}
#Override
public void run() {
// TODO Auto-generated method stub
while(isRunning){
if(!ourHolder.getSurface().isValid())continue;
Canvas canvas=ourHolder.lockCanvas();
canvas.drawARGB(255, 33, 181, 238);
.... ourHolder.unlockCanvasAndPost(canvas);
code for the main activity is
public class GraphS extends Activity{
GraphSview ourSview;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
ourSview=new GraphSview(this);
ourSview.getHolder().setFormat(PixelFormat.TRANSPARENT);
setContentView(ourSview);
//ourSview.setBackgroundColor(0Xffffffff);
}
#Override
protected void onPause() {
ourSview.pause();
super.onPause();
}
#Override
protected void onResume() {
ourSview.Resume(); // TODO Auto-generated method stub
super.onResume();
}
}
is there something wrong with the code?
is there any alternate way of creating and displaying graphs other than surface view?

Android camera preview is not resumed after Pause

I successfully created a camera surface view, and it works when the app is started/restarted. But it just shows a black screen, after I pause the game and resume it (pressing home screen). Am I missing something here?
Here's the code for the surface (which is created from a Main Activity:
public class CameraView extends SurfaceView implements SurfaceHolder.Callback{
static Camera camera = null;
Surface camSurface;
String TAG = "CameraView";
static SurfaceHolder mHolder;
public CameraView(Context context) {
super(context);
getHolder().addCallback(this);
getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
// TODO Auto-generated constructor stub
}
#Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder arg0) {
// TODO Auto-generated method stub
Log.e(TAG, "Camera view created");
mHolder = getHolder();
if(camera == null){
camera = Camera.open();
}
if(camera == null){
Log.e(TAG, "Null camera");
}
try {
camera.setPreviewDisplay(getHolder());
} catch (IOException e) {
// TODO Auto-generated catch block
camera.release();
camera = null;
e.printStackTrace();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder arg0) {
// TODO Auto-generated method stub
synchronized(mHolder){
if(camera!=null){
camera.stopPreview();
camera.release();
camera = null;
}
}
}
}
When you leave and return to your app, you still need to call camera.startPreview() at some point. I would have this in my surfaceChanged() method.
Make sure you have a valid instance of your camera as when you first start it up.

surfaceCreated is not called and so thread does not start

following is my simple code, actually i want to log HELLO in the draw() method repeatedly but my surfacecreated method is not called and so thread is not started. plz help me
public class MainActivity extends Activity{
private MyThread myThread ;
Panel _View;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
_View = new Panel(this);
}
public class Panel extends SurfaceView implements SurfaceHolder.Callback {
Canvas canvas;
public Panel(Context context) {
super(context);
getHolder().addCallback(this);
}//end of panel
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
myThread= new MyThread(this);
myThread.setRunning(true);
myThread.start();
}
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
myThread.setRunning(false);
}
public void Draw(Canvas canvas){
super.draw(canvas);
this.canvas = canvas;
Log.d("HELLO", 0+"");
}//end of DRAW()
}//end of Panel class
public class MyThread extends Thread {
Panel panel;
private SurfaceHolder myHolder;
boolean mRun=false;
public MyThread(Panel panel)
{
this.panel= panel;
this.myHolder = panel.getHolder();
}
public void setRunning(boolean run){
this.mRun=run;
}
public void run(){
Canvas canvas = null;
while(mRun)
{
canvas=myHolder.lockCanvas();
if(canvas!=null)
{
panel.Draw(canvas);
}
myHolder.unlockCanvasAndPost(canvas);
}
}
}//MyThread class ends
}//end of bird mania activity
The surface is not created until you add it to the View hierarchy. If it is your only View, you can set it with
setContentView( _View);
in your onCreate() method.

two strange problems

I got two strange problems:
1-i'm using previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); in an App and it works normally and I tried to use the same method in another App, I found eclipse cross this method with a black line and says this method is deprecated while I'm using the same method in another App and it works correctly without any problems
JAVA CODE:
public class AugReal00 extends Activity {
SurfaceView cameraPreview;
SurfaceHolder previewHolder;
Camera camera;
Boolean inPreview;
SurfaceHolder.Callback surfaceCallback = new Callback() {
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera.stopPreview();
camera.release();
camera = null;
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
try {
//Open The Camera
this.camera = android.hardware.Camera.open();
this.camera.setPreviewDisplay(this.holder);
}
catch(IOException ioe) {
ioe.printStackTrace(System.out);
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
android.hardware.Camera.Parameters parameters = camera.getParameters();
parameters.setSceneMode(parameters.SCENE_MODE_SPORTS);
parameters.setFlashMode(parameters.FLASH_MODE_ON);
parameters.setPreviewSize(width/2, height/2);
parameters.setPictureSize(width/2, height/2);
camera.setParameters(parameters);
camera.startPreview();
}
};// end of surfaceCallback Listener
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_aug_real00);
inPreview = false;
cameraPreview = (SurfaceView) findViewById(R.id.cameraPreview);
previewHolder = cameraPreview.getHolder();
previewHolder.addCallback(surfaceCallback);
previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
//previewHolder.se;
}
public void OnResume() {
super.onResume();
camera = Camera.open();
}// end of OnResume
public void OnPause() {
if (inPreview) {
camera.stopPreview();
}
camera.release();
camera=null;
inPreview=false;
super.onPause();
}// end of OnPause.
2-I wrote a simple program and i found that eclipse gives me the following error
syntax error, insert } to complete class body
while all the brackets are closed and every thing should work fine. I don't know how to solve this issue.
Check your old app sdk version number. The same api can be deprecated in next versions.
You have not closed an opened brace. Make sure all the braces are properly inserted.

SurfaceView implements Runnable - Thread does not start

Have been looking on some tutorials for drawing canvas using SurfaceView, but the only thing that shows up is a black background.
public class FighterActivity extends Activity implements OnTouchListener {
/** Called when the activity is first created. */
SurfaceController surface;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
surface = new SurfaceController(this);
surface.setOnTouchListener(this);
setContentView(surface);
}
#Override
protected void onPause() {
// TODO Auto-generated method stub
super.onPause();
surface.pause();
}
#Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
surface.resume();
}
public class SurfaceController extends SurfaceView implements Runnable{
Thread thread = null;
SurfaceHolder holder;
public SurfaceController(Context context) {
super(context);
// TODO Auto-generated constructor stub
holder = getHolder();
System.out.println("HERE");
}
public void run() {
// TODO Auto-generated method stub
System.out.println("Hello World2");
while(true){
if(!holder.getSurface().isValid()){
System.out.println("NOT VALID");
continue;
}
System.out.println("VALID!");
Canvas can = holder.lockCanvas();
can.drawARGB(255, 150, 150, 0);
holder.unlockCanvasAndPost(can);
}
}
public void pause(){
}
public void resume(){
}
}
public boolean onTouch(View view, MotionEvent me) {
// TODO Auto-generated method stub
return false;
}
}
It gets to the System.out.println("HERE"); and prints out HERE, but nothing more happends, In other words the thread does not get started since "Hello World2" is not printed, what is the problem?
Thanks for any help
I'm assuming you're building off of this: http://android-coding.blogspot.ca/2011/05/drawing-on-surfaceview.html
You'll notice there the onResumeMySurfaceView and onPauseMySurfaceView (resume and pause in your SurfaceController, respectively) start the actual thread. You'll need to do that in your code, too, e.g. in SurfaceController:
protected boolean running = false;
public void resume() {
running = true;
thread = new Thread(this);
thread.start();
}

Categories

Resources