Android Canvas always drawing a blackscreen - java

i've a problem canvas always draw a black screen no matter what i want to draw.
no matter when i want that the contentview is the View class or i take a layout and
add the class or i let the canvas draw a background and so on
public class GameSurface extends SurfaceView {
private SurfaceHolder holder;
GameThread gameThread;
Bitmap background;
public GameSurface(Context context) {
super(context);
holder = getHolder();
gameThread = new GameThread(this);
background = BitmapFactory.decodeResource(getResources(), R.drawable.background1);
holder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
gameThread.setRunning(true);
gameThread.start();
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
boolean retry = true;
gameThread.setRunning(false);
while (retry){
try {
gameThread.join();
retry = false;
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawBitmap(background,0,0,new Paint());
}
}
Rebuild and clean brings nothing!
Whats the Problem?
Thank You!

Related

Camera not saving image and drops exception

I'm creating camera app. I'm doing that in fragment. I have FrameLayout where I add the camera, and one button for capture. There are 2 problems.
Camera not saves the image.
When I click second time on capture image, drops exception java.lang.RuntimeException: takePicture failed
I don't know where's the problem, I'm using camera API first time.
Camera I'm using only in portrait mode. And in manifests I added the permissions for camera and write external storage.
I have one class where I'm extending SurfaceView. Let me show you the code.
public class ShowCamera extends SurfaceView implements SurfaceHolder.Callback{
Camera camera;
SurfaceHolder holder;
public ShowCamera(Context context, Camera camera) {
super(context);
this.camera = camera;
holder = getHolder();
holder.addCallback(this);
}
#Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
Camera.Parameters params = camera.getParameters();
List<Camera.Size> sizes = params.getSupportedPictureSizes();
Camera.Size mSize = null;
for (Camera.Size size : sizes){
mSize = size;
}
camera.setDisplayOrientation(90);
params.setRotation(90);
params.setPictureSize(mSize.width, mSize.height);
camera.setParameters(params);
try {
camera.setPreviewDisplay(surfaceHolder);
camera.startPreview();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
#Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
camera.stopPreview();
camera.release();
}
}
Ok and here's the fragment for camera.
public class CameraActivity extends BaseFragment{
View mainView;
FrameLayout cameraLayout;
Camera camera;
ShowCamera showCamera;
ImageButton captureImage;
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
mainView = inflater.inflate(R.layout.camera_fragment, container, false);
cameraLayout = (FrameLayout) mainView.findViewById(R.id.cameraContainer);
captureImage = (ImageButton) mainView.findViewById(R.id.imageButton);
camera = Camera.open();
showCamera = new ShowCamera(getActivity(), camera);
cameraLayout.addView(showCamera);
capture();
return mainView;
}
Camera.PictureCallback mPictureCallback = new Camera.PictureCallback() {
#Override
public void onPictureTaken(byte[] bytes, Camera camera) {
if(bytes != null){
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
if(bitmap != null){
File file = new File(String.valueOf(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM)));
if(!file.isDirectory()){
file.mkdir();
}
file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),
System.currentTimeMillis() + ".jpg");
try {
FileOutputStream fileOutputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close();
} catch (Exception e){
e.printStackTrace();
}
}
}
}
};
public void capture(){
captureImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(camera != null){
camera.takePicture(null, null, mPictureCallback);
}
}
});
}
}

SurfaceView shows black screen except icon

I used the old guide according to which the icon should appear in surfaceview.
Unfortunately the app dispalys the entire black surfaceview except icon.
I do not
know how to fix this because android studio does not display errors.
What i should add or change?
public class mySurfaceView extends SurfaceView {
private SurfaceHolder surfaceHolder;
private Bitmap bmpIcon;
public mySurfaceView(Context context) {
super(context);
init();
}
public mySurfaceView(Context context,
AttributeSet attrs) {
super(context, attrs);
init();
}
public mySurfaceView(Context context,
AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
private void init(){
surfaceHolder = getHolder();
bmpIcon = BitmapFactory.decodeResource(getResources(),
R.drawable.icon);
surfaceHolder.addCallback(new SurfaceHolder.Callback(){
#Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas canvas = holder.lockCanvas(null);
drawSomething(canvas);
holder.unlockCanvasAndPost(canvas);
}
#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
}});
}
protected void drawSomething(Canvas canvas) {
canvas.drawColor(Color.BLACK);
if (bmpIcon != null){ canvas.drawBitmap(bmpIcon,
getWidth()/2, getHeight()/2, null);
}
}
}
ScreenShot
my icon
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24.0"
android:viewportHeight="24.0">
<path
android:fillColor="#FF020000"
android:pathData="M6,18c0,0.55 0.45,1 1,1h1v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L11,19h2v3.5c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5L16,19h1c0.55,0 1,-0.45 1,-1L18,8L6,8v10zM3.5,8C2.67,8 2,8.67 2,9.5v7c0,0.83 0.67,1.5 1.5,1.5S5,17.33 5,16.5v-7C5,8.67 4.33,8 3.5,8zM20.5,8c-0.83,0 -1.5,0.67 -1.5,1.5v7c0,0.83 0.67,1.5 1.5,1.5s1.5,-0.67 1.5,-1.5v-7c0,-0.83 -0.67,-1.5 -1.5,-1.5zM15.53,2.16l1.3,-1.3c0.2,-0.2 0.2,-0.51 0,-0.71 -0.2,-0.2 -0.51,-0.2 -0.71,0l-1.48,1.48C13.85,1.23 12.95,1 12,1c-0.96,0 -1.86,0.23 -2.66,0.63L7.85,0.15c-0.2,-0.2 -0.51,-0.2 -0.71,0 -0.2,0.2 -0.2,0.51 0,0.71l1.31,1.31C6.97,3.26 6,5.01 6,7h12c0,-1.99 -0.97,-3.75 -2.47,-4.84zM10,5L9,5L9,4h1v1zM15,5h-1L14,4h1v1z"/>
</vector>
You gave black color in drawSomething method, If you change the color your background will change.
protected void drawSomething(Canvas canvas) {
//canvas.drawColor(Color.BLACK);
canvas.drawColor(Color.RED); // here i changed black to red(add you expected color here)
if (bmpIcon != null) {
canvas.drawBitmap(bmpIcon,
getWidth() / 2, getHeight() / 2, null);
}
}
As your drawble is vector drawable so use the following function to convert into bitmap
public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
drawable = (DrawableCompat.wrap(drawable)).mutate();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
and create your bitmap like this
bmpIcon = getBitmapFromVectorDrawable(getContext(), R.drawable.icon);
it will work fine.
and your final code will be like this,
public class MySurface extends SurfaceView {
private SurfaceHolder surfaceHolder;
private Bitmap bmpIcon;
public MySurface(Context context) {
super(context);
init();
}
public MySurface(Context context,
AttributeSet attrs) {
super(context, attrs);
init();
}
public MySurface(Context context,
AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}
public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
drawable = (DrawableCompat.wrap(drawable)).mutate();
}
Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
}
private void init() {
surfaceHolder = getHolder();
bmpIcon = getBitmapFromVectorDrawable(getContext(), R.drawable.icon);
surfaceHolder.addCallback(new SurfaceHolder.Callback() {
#Override
public void surfaceCreated(SurfaceHolder holder) {
Canvas canvas = holder.lockCanvas(null);
drawSomething(canvas);
holder.unlockCanvasAndPost(canvas);
}
#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
}
});
}
protected void drawSomething(Canvas canvas) {
canvas.drawColor(Color.RED);
if (bmpIcon != null) {
canvas.drawBitmap(bmpIcon,
getWidth() / 2, getHeight() / 2, null);
}
}
}

Surfaceview to draw Thread error NULLPointerException

I'm a beginner in android. I'm creating a simple surface view to draw a thread (draw rectangle), but it keeps getting error like this :
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.graphics.Canvas.drawColor(int)' on a null object reference
and this is my code :
myActivity.java :
public class myActivity extends AppCompatActivity {
mySurfaceView mysurfaceview;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_ball);
//mysurfaceview = new mySurfaceView(this);
mysurfaceview = (mySurfaceView) findViewById(R.id.mySurfaceView);
mysurfaceview.RunThread();
}
mySurfaceview.java :
public class mySurfaceView extends SurfaceView implements SurfaceHolder.Callback {
public DrawThread DrawThread;
private Rect myrectangle;
private Paint myPaint;
int moveX = 0;
private void init() {
myrectangle = new Rect(150, 150, 700, 500);
myPaint = new Paint();
myPaint.setColor(Color.BLUE);
}
public mySurfaceView(Context context) {
super(context);
//init();
}
public mySurfaceView(Context context, AttributeSet attrs, int defStyle){ super(context, attrs, defStyle); }
public mySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); }
public void onDrawSomething(Canvas canvas) {
canvas.drawColor(Color.BLACK);
canvas.drawRect(myrectangle, myPaint);
}
#Override
public void surfaceCreated(SurfaceHolder holder) { }
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { }
#Override
public void surfaceDestroyed(SurfaceHolder holder) { }
public void update(){
}
public void RunThread() {
init();
DrawThread = new DrawThread(getHolder(), this);
DrawThread.setRunning(true);
DrawThread.start();
}
public class DrawThread extends Thread {
//var definition
public boolean run = false;
private SurfaceHolder surfaceHolder;
mySurfaceView mysurfaceView;
public DrawThread(SurfaceHolder surfaceHolder, mySurfaceView mysurfaceView) {
this.surfaceHolder = surfaceHolder;
this.mysurfaceView = mysurfaceView;
}
public void setRunning(boolean run) {
this.run = run;
}
#Override
public void run() {
while(run)
{
//implement fps counter
Canvas canvas = null;
try {
canvas = surfaceHolder.lockCanvas();
synchronized (surfaceHolder) {
mysurfaceView.onDrawSomething(canvas);
//mysurfaceView.update();
}
} finally {
if(canvas != null)
{
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
}
}
}
And this is my XML code to show surface view :
<com.example.firstapp_aurelia.mySurfaceView
android:id="#+id/mySurfaceView"
android:layout_width="match_parent"
android:layout_height="match_parent" />
Did I do anything wrong here? Thank you so much.
I didn't run you code but do not initial mySurfaceView twice
mysurfaceview = new mySurfaceView(this);
mysurfaceview = (mySurfaceView) findViewById(R.id.mySurfaceView);

Can't create surfaceView in a fragment

Could someone help me to create SurfaceView in a fragment? Below is my code. It always stops at thr line: if (!surfaceHolder.getSurface().isValid()) and I don't know why.
Fragment code:
<pre>
public class FirstActivity extends Fragment/* implements OnTouchListener*/ {
CameraView cameraView;
#Override
public void onActivityCreated(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
/* instantiating the surface view */
cameraView = new CameraView(this.getActivity());
/* setting the listener - this, because it is defined within the activity */
// cameraView.setOnTouchListener(this);
}
// public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
// View v = inflater.inflate(R.layout.lin, null);
//
// cameraView = (CameraView) v.findViewById(R.id.cameraView);
//
// return v;
//
// }
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return new CameraView(getActivity());
}
// #Override
// public boolean onTouch(View arg0, MotionEvent arg1) {
// // TODO Auto-generated method stub
// return false;
// }
#Override
public void onStart() {
super.onStart();
}
#Override
public void onResume() {
super.onResume();
cameraView.onResumeCameraView();
}
#Override
public void onPause() {
super.onPause();
cameraView.onPauseCameraView();
}
}
</pre>
CameraView code:
<pre>
public class CameraView extends SurfaceView implements Runnable {
Thread thread = null;
SurfaceHolder surfaceHolder;
private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Bitmap bitmap;
int WIDTH = 320;
int HEIGHT = 240;
volatile boolean running = false;
public CameraView(Context context) {
super(context);
// TODO Auto-generated constructor stub
surfaceHolder = getHolder();
bitmap = Bitmap.createBitmap(WIDTH, HEIGHT, Bitmap.Config.ARGB_8888/*Bitmap.Config.ALPHA_8*//*Bitmap.Config.RGB_565*/);
Log.d("S3", "stworzono bitmape");
}
public void onResumeCameraView() {
running = true;
thread = new Thread(this);
thread.start();
}
public void onPauseCameraView() {
boolean retry = true;
running = false;
while (retry) {
try {
thread.join();
retry = false;
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
#Override
public void run() {
// TODO Auto-generated method stub
while (running) {
if (!surfaceHolder.getSurface().isValid()) {
Log.d("S3", "blad");
continue;
}
Log.d("S3", "dalej");
Canvas canvas = surfaceHolder.lockCanvas();
canvas.drawColor(Color.WHITE);
paint.setColor(Color.RED);
canvas.drawRect(0, 0, 100, 100, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}
}
}
</pre>
Thank You for help.
Use SurfaceHolder.addCallback() to register a callback interface. It will notify you when the surface to available, destroyed and when it changes.
My onCreateView function looks:
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
RelativeLayout relativeLayout = new RelativeLayout(this.getActivity());
TextView textView = new TextView(this.getActivity());
textView.setText("Simply dummy text");
relativeLayout.addView(textView);
relativeLayout.addView(cameraView);
return relativeLayout;
}
I can create and add textView without any problems. But if I'm trying to add cameraView the application crashes. Why? I'm creating cameraView in function onActivityCreated
I don't see any code in your post that either references a SurfaceView declared in XML or adds the SurfaceView programmatically to the layout. You need to do either of those, or the SurfaceView can't be drawn.
To add progammatically, in onCreateView(...), do:
mCameraView = new CameraView(...);
ViewGroup myRootLayout = (ViewGroup)findViewById(...)
myRootLayout.addView(mCameraView);

ClickListener and TouchListener don't work on a child view

I have 2 custom Views: 1. BoardView 2. BallView. I add The BallView to the BoardView and the BoardView to my layout.
When I click on the BallView with ClickListener and TouchListener nothing happens. As if the BoardView overlaps the BallView area.
Code:
board = new BoardView(this);
ball = new BallModel(100, 200,50,screenWidth, screenHeight);
ballView = new BallView(this, ball);
ballView.setOnTouchListener(new OnTouchListener() {
public boolean onTouch(View v, MotionEvent event)
{
System.out.println("Hey");
return true;
}
});
ballView.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
System.out.println("Hey");
}
});
board.addView(ballView);
Updated:
public class BoardView extends View
{
private List<View> mShapes = new ArrayList<View>();
public BoardView(Context context)
{
super(context);
}
public void addView(View view)
{
mShapes.add(view);
}
#Override
public void onDraw(Canvas canvas)
{
super.onDraw(canvas);
for(int i=0; i<mShapes.size(); i++)
{
View view = mShapes.get(i);
view.draw(canvas);
}
}
}
public class BallView extends View
{
BallModel mBall;
Paint mBallPaint;
public BallView(Context context, BallModel ball)
{
super(context);
mBall = ball;
}
private Paint getPaint()
{
if(mBallPaint == null)
{
mBallPaint = new Paint();
mBallPaint.setColor(mBall.getColor());
}
return mBallPaint;
}
#Override
protected void onDraw(Canvas canvas)
{
super.onDraw(canvas);
Paint paint = getPaint();
paint.setColor(mBall.getColor());
canvas.drawCircle(mBall.getX(), mBall.getY(), mBall.getRadius(), paint);
}
}
Any ideas?

Categories

Resources