5

I am trying hard to implement a scanner line like animation (up-down), on a camera preview activity in an android exercise app that I am coding.

I have successfully made the animation code to work in a single activity - without the camera preview. No matter how I've tried everything that I've read here on stackoverflow or searching the Net, I always get the camera preview, but not animation overlay.

Here is my xml file:

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/container"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal"
android:background="@android:color/transparent"
android:layout_centerInParent="true">

<SurfaceView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/imageView"
    android:src="@drawable/scanline"
    android:contentDescription="@string/scanline"
    android:layout_gravity="left|center_vertical"
    android:layout_alignParentStart="true"
    android:layout_alignParentEnd="true"
    android:background="@android:color/transparent"
    android:baselineAlignBottom="false"/>

<com.app.arsinoe.ui.widget.CameraPreview
    android:id="@+id/camera_preview"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:background="@android:color/transparent" />

<Button
    android:layout_width="156dp"
    android:layout_height="27dp"
    android:text="@string/exit_button"
    android:id="@+id/aboardButton2"
    android:layout_gravity="bottom|left"
    android:clickable="true"
    android:background="#4e0612"
    android:textColor="@android:color/white"
    android:textStyle="bold"
    android:alpha="1"
    android:paddingEnd="@dimen/activity_horizontal_margin"
    android:paddingStart="@dimen/activity_vertical_margin"
    android:onClick="exitButton"/>

<Button
    android:layout_width="310dp"
    android:layout_height="27dp"
    android:text="@string/scan_button"
    android:id="@+id/scanButton"
    android:layout_gravity="bottom|right"
    android:clickable="true"
    android:textColor="@android:color/white"
    android:textStyle="bold"
    android:alpha="1"
    android:background="#1b4a6c"
    android:paddingEnd="@dimen/activity_horizontal_margin"
    android:paddingStart="@dimen/activity_vertical_margin"
    android:onClick="scanButton"/>
</FrameLayout>

Here is my working code for the scanner line animation Activity:

public class ScanActivity extends Activity{


private View view;

protected void onCreate(Bundle savedInstanceState){
    super.onCreate(savedInstanceState);
    setContentView(R.layout.scan_activity);

    final Context readySnanner = this;
    Handler mHandler = new Handler();

    Runnable
            makeToast = new Runnable() {
        public void run() {
            Toast.makeText(readySnanner,
                    "Bla bla bla...", Toast.LENGTH_LONG).show();
        }
    };
    mHandler.postDelayed(makeToast, 4000);


    Toast.makeText(ScanActivity.this,"Bla bla... Please wait",      Toast.LENGTH_SHORT).show();


    ImageView animatedImage = (ImageView) findViewById(R.id.imageView);

    Animation animation
            = AnimationUtils.loadAnimation(this, R.anim.topdown);
    if (animation != null) {
        animatedImage.startAnimation(animation);}


    final int SPLASH_TIME;// 4 seconds
    SPLASH_TIME = 4 * 1000;


    boolean b;
    b = new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
        }
    }, SPLASH_TIME);
}


public void exitButton(View view) {

    this.finish();
    System.exit(0);
}

public void scanButton(View view) {

    Intent intent = new Intent(ScanActivity.this,
            B.class);
    startActivity(intent);
    ScanActivity.this.finish();
}

Here is my working code for the CameraActivity:

public class CameraActivity extends Activity {

private Camera camera;
private View view;
SurfaceView animatedImage;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.scan_activity);
    setResult(RESULT_CANCELED);
    // Camera may be in use by another activity or the system or not available   at all
    try {
        camera = getCameraInstance();
    } catch (Exception e) {
        e.printStackTrace();
    }
    if(cameraAvailable(camera)){
        initCameraPreview();
    } else {
        finish();
    }
}

// Show the camera view on the activity
private void initCameraPreview() {
    CameraPreview cameraPreview = (CameraPreview) findViewById(R.id.camera_preview);
    cameraPreview.init(camera);}

I do not know how to make these two activities run together as a single activity,using the provided xml file. Please, help a newbie, cause I am stuck on these issue for 5 days!

I am sorry for not providing an image to depict what I'm trying to code, but my reputation is minimal. Any responce, preferably with a working sample would be appreciated.

EDIT

The following image depicts the layout of the activity: enter image description here

The red line should move up and down in animation, ovelay the camera preview. This is coded and working in an ImageView, but is not working with the CameraPreview.

This is my CameraPreview activity, edited as Juan-devtopia.coop suggested:

public class CameraPreview extends SurfaceView implements SurfaceHolder.Callback {

private Context context;
private Camera camera;

public CameraPreview(Context context, AttributeSet attrs, int defStyle) {
    super(context, attrs, defStyle);
}

public CameraPreview(Context context, AttributeSet attrs) {
    super(context, attrs);
}

public CameraPreview(Context context, Camera camera) {
    super(context);
    this.context = context;
    this.camera = camera;
}

public void init(Camera camera) {
    this.camera = camera;
    initSurfaceHolder();
}

@SuppressWarnings("deprecation") // needed for < 3.0
private void initSurfaceHolder() {
    SurfaceHolder holder = getHolder();
    if (holder != null) {
        holder.addCallback(this);
    }
    if (holder != null) {
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
}

@Override
public void surfaceCreated(SurfaceHolder holder) {
    initCamera(holder);
}

private void initCamera(SurfaceHolder holder) {
    try {
        camera.setPreviewDisplay(holder);
        camera.startPreview();
    } catch (Exception ignored) {
    }
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
}

public void setContext(Context context) {
    this.context = context;
}


public class Animation extends Activity {

    ImageView animatedImage = (ImageView) findViewById(R.id.imageView);

    android.view.animation.Animation animation;

    {
        animatedImage.startAnimation(animation);
        animation = AnimationUtils.loadAnimation(this, R.anim.topdown);
    }

 }

Upon compilation and run on device, in logcat I get a "java.lang.RuntimeException: Unable to instantiate activity", caused by "Caused by: java.lang.InstantiationException: com.app.myapp.ui.widget.CameraPreview. Any suggestions?

CodeBugging
  • 321
  • 12
  • 28

1 Answers1

1

Place the ImageView in the same layout as the preview, so that it renders on top of it. Then have both codes in the same activity, the one where you initialise the camera preview and the one where you animate the ImageView

Treat CameraPreview as another View from your layout.

In other words, you initialise your camera preview, as in your code but also start the animation there, leaving your init camera method like this:

 // Show the camera view on the activity and show overlay animation
    private void initCameraPreview() {
        CameraPreview cameraPreview = (CameraPreview) findViewById(R.id.view);
        cameraPreview.init(camera);


        ImageView animatedImage = (ImageView) findViewById(R.id.imageView);
        Animation animation = AnimationUtils.loadAnimation(this, R.anim.rotate);
        animatedImage.startAnimation(animation);
    }

Note that I changed the id's and animations since I had to recreate this to test it. The layout simply contains the surface and the imageview, placing the imageView further down in the code (meaning it will be rendered over the surface view). enter image description here

In my code sample (I uploaded it to gitHub for you here) the ic_launcher simply rotates over the camera preview, but I assume using your animation and making sure it loops and not only animates once, should work.

Juan Cortés
  • 20,634
  • 8
  • 68
  • 91
  • Thank you Juan-devtopia.coop, for your answer. I will try to edit my code as you have suggested, and If everything works o.k, I will mark your answer as acceped. – CodeBugging Feb 21 '14 at 14:36
  • I've tried to edit code as you suggested, with not success. I believe there is something wrong with my layout for the CameraPreview, as I do not have a explict layout for that activity. Should I create a new xml having ImageView and camera_preview layout as a FrameWork or something? Could you give a second look at my posted code, as I edited now, adding the CameraPreview activity? – CodeBugging Feb 21 '14 at 19:11
  • Uploaded a git sample project for you, and edited my question, good luck with your project – Juan Cortés Feb 21 '14 at 20:11
  • Juan - devtopia.coop, your uploaded git sample is very welcomed. I will give it a try as soon as possible, and I'll report my success (or not) here. I hope this should work. Thank you anyway, for your time and efford. – CodeBugging Feb 21 '14 at 20:36
  • Just giving back a little of what this site users' gave me already. You should set a username and join us more often ;) – Juan Cortés Feb 21 '14 at 21:21
  • your uploaded git sample and your suggestions was very helpful to solve out my problematic code. Thank you again for your time, and efford. Accepted as correct answer. – CodeBugging Feb 22 '14 at 00:04