InflateException in Google Cardboard tutorial - android

I'm a trying to render a Google Cardboard app rendering droidar objects, but for now i'm trying to display a simple cardboardview using the official tutorial (https://developers.google.com/cardboard/android/get-started) but I have an exception :
Caused by: android.view.InflateException: Binary XML file line #21: Error inflating class com.google.vrtoolkit.cardboard.CardboardView
And i can't find a solution, it's starting to drive me crazy...
Could you help me, please? Here's my code :
My Manifest.xml :
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="lp.s3im.cardboarddemo"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="19" />
<uses-feature
android:glEsVersion="0x00020000"
android:required="true" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:screenOrientation="landscape" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="com.google.intent.category.CARDBOARD" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity :
package lp.s3im.cardboarddemo;
import java.nio.FloatBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import com.google.vrtoolkit.cardboard.CardboardActivity;
import com.google.vrtoolkit.cardboard.CardboardView;
import com.google.vrtoolkit.cardboard.Eye;
import com.google.vrtoolkit.cardboard.HeadTransform;
import com.google.vrtoolkit.cardboard.Viewport;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Vibrator;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends CardboardActivity implements
CardboardView.StereoRenderer {
private static final String TAG = "MainActivity";
private static final float Z_NEAR = 0.1f;
private static final float Z_FAR = 100.0f;
private static final float CAMERA_Z = 0.01f;
private static final float TIME_DELTA = 0.3f;
private static final float YAW_LIMIT = 0.12f;
private static final float PITCH_LIMIT = 0.12f;
private static final int COORDS_PER_VERTEX = 3;
// We keep the light always position just above the user.
private static final float[] LIGHT_POS_IN_WORLD_SPACE = new float[] { 0.0f,
2.0f, 0.0f, 1.0f };
private final float[] lightPosInEyeSpace = new float[4];
private FloatBuffer floorVertices;
private FloatBuffer floorColors;
private FloatBuffer floorNormals;
private FloatBuffer cubeVertices;
private FloatBuffer cubeColors;
private FloatBuffer cubeFoundColors;
private FloatBuffer cubeNormals;
private int cubeProgram;
private int floorProgram;
private int cubePositionParam;
private int cubeNormalParam;
private int cubeColorParam;
private int cubeModelParam;
private int cubeModelViewParam;
private int cubeModelViewProjectionParam;
private int cubeLightPosParam;
private int floorPositionParam;
private int floorNormalParam;
private int floorColorParam;
private int floorModelParam;
private int floorModelViewParam;
private int floorModelViewProjectionParam;
private int floorLightPosParam;
private float[] modelCube;
private float[] camera;
private float[] view;
private float[] headView;
private float[] modelViewProjection;
private float[] modelView;
private float[] modelFloor;
private int score = 0;
private float objectDistance = 12f;
private float floorDepth = 20f;
private Vibrator vibrator;
// private CardboardOverlayView overlayView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CardboardView cardboardView = (CardboardView) findViewById(R.id.cardboard_view);
// Associate a CardboardView.StereoRenderer with cardboardView.
cardboardView.setRenderer(this);
// Associate the cardboardView with this activity.
setCardboardView(cardboardView);
// Initialize other objects here.
modelCube = new float[16];
camera = new float[16];
view = new float[16];
modelViewProjection = new float[16];
modelView = new float[16];
modelFloor = new float[16];
headView = new float[16];
vibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onDrawEye(Eye arg0) {
// TODO Auto-generated method stub
}
#Override
public void onFinishFrame(Viewport arg0) {
// TODO Auto-generated method stub
}
#Override
public void onNewFrame(HeadTransform arg0) {
// TODO Auto-generated method stub
arg0.getHeadView(headView, 0);
}
#Override
public void onRendererShutdown() {
// TODO Auto-generated method stub
}
#Override
public void onSurfaceChanged(int arg0, int arg1) {
// TODO Auto-generated method stub
}
#Override
public void onSurfaceCreated(EGLConfig arg0) {
// TODO Auto-generated method stub
}
}
activity_main.xml
<RelativeLayout 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:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="lp.s3im.cardboarddemo.MainActivity" >
<com.google.vrtoolkit.cardboard.CardboardView
android:id="#+id/cardboard_view"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
Edit : With the following code i can display the camera with the starpreview method, but i can't use the preview of the andAR library (https://code.google.com/p/andar/), which does a black screen. I don"t understand if it is because it's overloaded or not.
package edu.dhbw.andar.sample;
import java.io.IOException;
import java.util.List;
import android.content.Intent;
import android.hardware.Camera;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import edu.dhbw.andar.ARToolkit;
import edu.dhbw.andar.AndARActivity;
import edu.dhbw.andar.exceptions.AndARException;
/**
* Example of an application that makes use of the AndAR toolkit.
*
* #author Tobi
*
*/
public class CustomActivity extends AndARActivity implements SurfaceHolder.Callback {
CustomObject someObject;
ARToolkit artoolkit;
SurfaceView surfaceView;
SurfaceHolder surfaceHolder;
Camera camera;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
CustomRenderer renderer = new CustomRenderer();// optional, may be set
// to null
super.setNonARRenderer(renderer);// or might be omited
try {
// register a object for each marker type
artoolkit = super.getArtoolkit();
someObject = new CustomObject("test", "patt.hiro", 80.0,
new double[] { 0, 0 });
artoolkit.registerARObject(someObject);
someObject = new CustomObject("test", "android.patt", 80.0,
new double[] { 0, 0 });
artoolkit.registerARObject(someObject);
someObject = new CustomObject("test", "barcode.patt", 80.0,
new double[] { 0, 0 });
artoolkit.registerARObject(someObject);
} catch (AndARException ex) {
// handle the exception, that means: show the user what happened
System.out.println("");
}
surfaceView = (SurfaceView) findViewById(R.id.surfaceView);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
startCamera(holder, width, height);
}
#Override
public SurfaceView getSurfaceView() {
// TODO Auto-generated method stub
return super.getSurfaceView();
}
#Override
public void startPreview() {
// TODO Auto-generated method stub
super.startPreview();
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
super.surfaceDestroyed(holder);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
camera = Camera.open();
try {
camera.setPreviewDisplay(holder);
} catch (IOException e) {
}
}
/**
* Inform the user about exceptions that occurred in background threads.
* This exception is rather severe and can not be recovered from. TODO
* Inform the user and shut down the application.
*/
#Override
public void uncaughtException(Thread thread, Throwable ex) {
Log.e("AndAR EXCEPTION", ex.getMessage());
finish();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
// getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
switch (id) {
// case R.id.settings:
// break;
default:
break;
}
return super.onOptionsItemSelected(item);
}
private void startCamera(SurfaceHolder sh, int width, int height) {
Camera.Parameters parameters = camera.getParameters();
List<Camera.Size> sizes = parameters.getSupportedPreviewSizes();
Camera.Size cs = sizes.get(0);
parameters.setPreviewSize(cs.width, cs.height);
camera.setParameters(parameters);
try {
camera.setPreviewDisplay(sh);
} catch (Exception e) {
}
camera.startPreview();
}
private void stopCamera() {
//camera.removeCallback(this);
camera.stopPreview();
camera.release();
}
}

Include the libprotobuf-java-2.3-nano.jar file in your build path.

Related

My onDraw() method is never called

My issue is that no matter what I do, no matter how many questions and answers I read through on the internet, I cant get a simple rectangle to draw on my android device screen. Let me rephrase that, it shows up on screen but it wont change. I cant get an animation to update. onDraw() never calls multiple times, just once on startup. why? Here is my view objects code:
package prospect_industries.es;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
public class TestView extends View {
//Variables
public static final int SIZE = 300;
public float TOP = 0.0f;
public float LEFT = 0.0f;
public float RIGHT = 100f;
public float BOTTOM = 100f;
private Paint rectanglePaint;
private RectF rect1;
//Constructors
public TestView(final Context context, final AttributeSet attrs, final int defStyle) {
super(context, attrs, defStyle);
init();
}
public TestView(final Context context, final AttributeSet attrs) {
super(context, attrs, 0);
init();
}
public TestView(final Context context) {
super(context, null, 0);
init();
}
//View methods
#Override
protected void onDraw(final Canvas canvas){
canvas.drawRect(rect1, rectanglePaint);
Log.i("test1", "in onDraw");
}
#Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec) {
final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
final int chosenWidth = chooseDimension(widthMode, widthSize);
final int chosenHeight = chooseDimension(heightMode, heightSize);
setMeasuredDimension(chosenWidth, chosenHeight);
Log.i("test1", String.valueOf(chosenWidth));
Log.i("test1",String.valueOf(chosenHeight));
}
//Class Methods
private int chooseDimension(final int mode, final int size) {
switch (mode) {
case MeasureSpec.AT_MOST:
case MeasureSpec.EXACTLY:
return size;
case MeasureSpec.UNSPECIFIED:
default:
return getDefaultDimension();
}
}
private int getDefaultDimension() { return SIZE; }
private void init(){
requestFocus();
rectanglePaint = new Paint(Paint.ANTI_ALIAS_FLAG);
rectanglePaint.setColor(-1);
rectanglePaint.setStyle(Paint.Style.FILL);
rect1 = new RectF(LEFT, TOP, RIGHT, BOTTOM);
}
public void update() {
RIGHT += 10;
BOTTOM += 10;
rect1 = new RectF(LEFT, TOP, RIGHT, BOTTOM);
invalidate();
Log.i("test1", "in update");
}
}
Here is my main class which has a few methods for other things Im working on as well as a timer which calls the update() method inside of my test view object.
package prospect_industries.es;
import android.app.Activity;
import android.content.Context;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import java.io.IOException;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
public class MainActivity extends Activity {
private boolean setup = false;
public int waitDelay = 1000; //Milliseconds - currently 1 second
private Timer checkTime;
private TimerTask listen;
private MediaRecorder mRecorder;
//Splashscreen
private Timer splashScreen;
private int waitTime = 3000; //3 seconds
private GaugeView mGaugeView;
private final Random RAND = new Random();
private TestView testview;
private SurfaceHolder surfaceHolder;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.content_main);
//mGaugeView = (GaugeView) findViewById(R.id.gauge_view);
testview = (TestView) findViewById(R.id.test_view);
}
#Override
public void onStart() {
super.onStart();
//Timers
//1 second wait tick
checkTime = new Timer();
checkTime.schedule(new TimerTask() {
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
//mGaugeView.setTargetValue(RAND.nextInt(101));
testview.update();
}
});
}
}, 0, waitDelay);
//Set splash screen wait timer
splashScreen = new Timer();
splashScreen.schedule(new TimerTask() {
public void run() {
MainActivity.this.runOnUiThread(new Runnable() {
public void run() {
setContentView(R.layout.content_main);
}
});
splashScreen.cancel();
}
}, waitTime);
//set welcome screen
setContentView(R.layout.activity_welcome);
}
#Override
public void onStop() {
super.onStop();
if(checkTime != null) {
checkTime.cancel();
stop();
}
}
public void stop() {
if (mRecorder != null) {
mRecorder.stop();
mRecorder.release();
mRecorder = null;
}
}
public double getAmplitude() {
if (mRecorder != null)
return mRecorder.getMaxAmplitude();
else
return 0;
}
public void checkSound(){
if (mRecorder == null) {
mRecorder = new MediaRecorder();
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
mRecorder.setOutputFile("/dev/null");
try {
mRecorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
mRecorder.start();
}
}
private static class MainView extends SurfaceView implements SurfaceHolder.Callback {
private SurfaceHolder surfaceHolder;
public MainView(Context context) {
super(context);
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
}
Lastly, here is the xml layout file which loads in the test view object.
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
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:background="#103681"
tools:context="prospect_industries.es.MainActivity">
<prospect_industries.es.TestView
android:layout_width="200dp"
android:layout_height="200dp"
android:id="#+id/test_view"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" />
</RelativeLayout>
I have been looking all over stackExchange for hours but I cant fix my problem, onDraw is only called once and never again no matter what I do. Right now the rectangle should be expanding out but it isnt being redrawn.
The problem is that you initialize the rectangle to be 1px wide and 1px tall and never resize it. You should be able to see 1 white pixel somewhere in the top left corner of your TestView.
Try changing the rect1 size to 0,0,100,100 and see if the problem persists.
public static final float TOP = 0.0f;
public static final float LEFT = 0.0f;
public static final float RIGHT = 100.0f;
public static final float BOTTOM = 100.0f;

ImageView not moving at all with animation- Android

I am trying to move a imageview(ball image) using sensorchange (on accelerometer) by using TranslateAnimation in my android application. But the application does not move the imageview. My logs look like the app is not even registering the accelerometer and I only see the ball imageview on the screen constant at a place. Can anybody please help me in resolving what am I doing wrong here? My code and logs are as follow:
public class MainActivity extends Activity implements SensorEventListener {
private ImageView ball=null;
public static int nwidth, nheight;
public static float xPosition, yPosition,oldx=0,oldy=0;
private float xAcceleration=0.0f,xVelocity = 0.0f;
private float yAcceleration=0.0f,yVelocity = 0.0f;
private float zAcceleration=0.0f;
public float frameTime = 0.999f;
private float mAlpha = 0.9f;
private static final String TAG = "Readings";
String toWrite=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ball = (ImageView) findViewById(R.id.image_ball);
getScreenSize();
setContentView(R.layout.activity_main);
}
private void getScreenSize()
{
Point displaySize = new Point();
getWindowManager().getDefaultDisplay().getRealSize(displaySize);
Rect windowSize = new Rect();
getWindow().getDecorView().getWindowVisibleDisplayFrame(windowSize);
nwidth = displaySize.x - Math.abs(windowSize.width());
nheight = displaySize.y - Math.abs(windowSize.height());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onSensorChanged(SensorEvent sensorEvent)
{
{
if (sensorEvent.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
yAcceleration = lowPass(sensorEvent.values[1], yAcceleration);
xAcceleration = lowPass(sensorEvent.values[2],xAcceleration);
zAcceleration = lowPass(sensorEvent.values[0],zAcceleration);
toWrite = sensorEvent.values[0] + "," + sensorEvent.values[2] + "\n";
writeCSV(toWrite);
Log.i(TAG, "x:" + xAcceleration + " y:" + yAcceleration + "z:" + zAcceleration);
updateBall();
}
}
}
// simple low-pass filter
float lowPass(float current, float filtered) {
return mAlpha * current + (1.0f - mAlpha) * filtered;
}
private void writeCSV(String txtData)
{
try {
File myFile = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/"+ "Readings.txt");
myFile.createNewFile();
FileOutputStream fOut = new FileOutputStream(myFile,true);
OutputStreamWriter myOutWriter =
new OutputStreamWriter(fOut);
myOutWriter.append(txtData);
myOutWriter.close();
fOut.close();
} catch (Exception e) {
Toast.makeText(getBaseContext(), e.getMessage(),
Toast.LENGTH_SHORT).show();
}
}
private void updateBall() {
//for landscape orientation, treating z axis as x.
xVelocity = (-zAcceleration * frameTime);
float xS = (xVelocity)*frameTime;
xPosition += xS;
// yPosition += yS;
yPosition++;
setPosition();
Log.i(TAG,"x:" + xAcceleration +" y:" + yAcceleration);
}
private void setPosition()
{
TranslateAnimation animation = new TranslateAnimation(oldx, xPosition, oldy, yPosition);
animation.setDuration(10);
animation.setFillAfter(false);
animation.setAnimationListener(new MyAnimationListener(ball));
ball.startAnimation(animation);
oldx=xPosition;
oldy=yPosition;
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
class MyAnimationListener implements Animation.AnimationListener {
ImageView imageView=null;
public MyAnimationListener(ImageView image)
{
imageView=image;
}
#Override
public void onAnimationEnd(Animation animation) {
imageView.clearAnimation();
ViewGroup.LayoutParams lp = new ViewGroup.LayoutParams(imageView.getWidth(), imageView.getHeight());
// lp.setMargins(50, 100, 0, 0);
imageView.setLayoutParams(lp);
}
#Override
public void onAnimationRepeat(Animation animation) {
}
#Override
public void onAnimationStart(Animation animation) {
}
}
08-12 01:03:21.348: I/art(3404): Late-enabling -Xcheck:jni
08-12 01:03:21.386: E/art(3404): Failed sending reply to debugger: Broken pipe
08-12 01:03:21.386: I/art(3404): Debugger is no longer active
08-12 01:03:21.516: D/OpenGLRenderer(3404): Render dirty regions requested: true
08-12 01:03:21.522: D/Atlas(3404): Validating map...
08-12 01:03:21.568: I/OpenGLRenderer(3404): Initialized EGL, version 1.4
08-12 01:03:21.609: D/OpenGLRenderer(3404): Enabling debug mode 0
Thanks!
package com.example.test;
import android.app.Activity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
public class MainActivity extends Activity implements SensorEventListener {
SensorManager mSensorManager;
Sensor mSensor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
mSensorManager.unregisterListener(this);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
}
}

How to draw on a surfaceview?

Hi guys I was trying to make a QRCode reader so I used the used the QRCodeReaderView library provided by dlzaaro66 which provides easy implementation of Zxing library. The code is scanning the qrcode but i wanted to make sort of a reference box so as to indicate the whereabouts of where the code is being scanned from on the camera surface view I tried to use the normal draw technique. Its not giving any error but its not drawing either could you help me with where the problem might be occurring.
This my activity class.
import android.app.Activity;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PointF;
import android.net.Uri;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.CompoundButton;
import android.widget.Switch;
import android.widget.Toast;
import com.dlazaro66.qrcodereaderview.QRCodeReaderView;
import com.dlazaro66.qrcodereaderview.QRCodeReaderView.OnQRCodeReadListener;
public class MyActivity extends Activity implements OnQRCodeReadListener{
QRCodeReaderView decoder;
Switch start_stop;
Paint paint;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
decoder = (QRCodeReaderView) findViewById(R.id.view2);
decoder.setOnQRCodeReadListener(this);
start_stop=(Switch) findViewById(R.id.switch1);
start_stop.setChecked(true);
start_stop.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton compoundButton, boolean b) {
if(b){
decoder.getCameraManager().startPreview();
}
else{
decoder.getCameraManager().stopPreview();
}
}
});
paint= new Paint();
paint.setColor(Color.RED);
paint.setStrokeWidth(100);
paint.setAntiAlias(true);
paint.setStyle(Paint.Style.STROKE);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.my, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onQRCodeRead(String text, PointF[] points) {
start_stop.setChecked(false);
if(text.startsWith("http")){
Toast.makeText(getApplicationContext(),text,Toast.LENGTH_SHORT).show();
final Intent intent = new Intent(Intent.ACTION_VIEW).setData(Uri.parse(text));
startActivity(intent);
}
else{
Toast.makeText(getApplicationContext(),text,Toast.LENGTH_SHORT).show();
}
Canvas canvas=new Canvas();
for(int i=0;i<points.length-1;i++){
canvas.drawLine(points[i].x,points[i].y,points[i+1].x,points[i+1].y,paint);
}
}
#Override
public void cameraNotFound() {
}
#Override
public void QRCodeNotFoundOnCamImage() {
}
}
This is the library project class from where I am getting the methods and the custom surfaceview
public class QRCodeReaderView extends SurfaceView implements SurfaceHolder.Callback,Camera.PreviewCallback {
public interface OnQRCodeReadListener {
public void onQRCodeRead(String text, PointF[] points);
public void cameraNotFound();
public void QRCodeNotFoundOnCamImage();
}
private OnQRCodeReadListener mOnQRCodeReadListener;
private static final String TAG = QRCodeReaderView.class.getName();
private QRCodeReader mQRCodeReader;
private int mPreviewWidth;
private int mPreviewHeight;
private SurfaceHolder mHolder;
private CameraManager mCameraManager;
public QRCodeReaderView(Context context) {
super(context);
init();
}
public QRCodeReaderView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public void setOnQRCodeReadListener(OnQRCodeReadListener onQRCodeReadListener) {
mOnQRCodeReadListener = onQRCodeReadListener;
}
public CameraManager getCameraManager() {
return mCameraManager;
}
#SuppressWarnings("deprecation")
private void init() {
if (checkCameraHardware(getContext())){
mCameraManager = new CameraManager(getContext());
mHolder = this.getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // Need to set this flag despite it's deprecated
} else {
Log.e(TAG, "Error: Camera not found");
mOnQRCodeReadListener.cameraNotFound();
}
}
/****************************************************
* SurfaceHolder.Callback,Camera.PreviewCallback
****************************************************/
#Override
public void surfaceCreated(SurfaceHolder holder) {
try {
// Indicate camera, our View dimensions
mCameraManager.openDriver(holder,this.getWidth(),this.getHeight());
} catch (IOException e) {
Log.w(TAG, "Can not openDriver: "+e.getMessage());
mCameraManager.closeDriver();
}
try {
mQRCodeReader = new QRCodeReader();
mCameraManager.startPreview();
} catch (Exception e) {
Log.e(TAG, "Exception: " + e.getMessage());
mCameraManager.closeDriver();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d(TAG, "surfaceDestroyed");
mCameraManager.getCamera().setPreviewCallback(null);
mCameraManager.getCamera().stopPreview();
mCameraManager.getCamera().release();
mCameraManager.closeDriver();
}
// Called when camera take a frame
#Override
public void onPreviewFrame(byte[] data, Camera camera) {
PlanarYUVLuminanceSource source = mCameraManager.buildLuminanceSource(data, mPreviewWidth, mPreviewHeight);
HybridBinarizer hybBin = new HybridBinarizer(source);
BinaryBitmap bitmap = new BinaryBitmap(hybBin);
try {
Result result = mQRCodeReader.decode(bitmap);
// Notify We're found a QRCode
if (mOnQRCodeReadListener != null) {
// Transform resultPoints to View coordinates
PointF[] transformedPoints = transformToViewCoordinates(result.getResultPoints());
mOnQRCodeReadListener.onQRCodeRead(result.getText(), transformedPoints);
}
} catch (ChecksumException e) {
Log.d(TAG, "ChecksumException");
e.printStackTrace();
} catch (NotFoundException e) {
// Notify QR not found
if (mOnQRCodeReadListener != null) {
mOnQRCodeReadListener.QRCodeNotFoundOnCamImage();
}
} catch (FormatException e) {
Log.d(TAG, "FormatException");
e.printStackTrace();
} finally {
mQRCodeReader.reset();
}
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
Log.d(TAG, "surfaceChanged");
if (mHolder.getSurface() == null){
Log.e(TAG, "Error: preview surface does not exist");
return;
}
//preview_width = width;
//preview_height = height;
mPreviewWidth = mCameraManager.getPreviewSize().x;
mPreviewHeight = mCameraManager.getPreviewSize().y;
mCameraManager.stopPreview();
mCameraManager.getCamera().setPreviewCallback(this);
mCameraManager.getCamera().setDisplayOrientation(90); // Portrait mode
mCameraManager.startPreview();
}
/**
* Transform result to surfaceView coordinates
*
* This method is needed because coordinates are given in landscape camera coordinates.
* Now is working but transform operations aren't very explained
*
* TODO re-write this method explaining each single value
*
* #return a new PointF array with transformed points
*/
private PointF[] transformToViewCoordinates(ResultPoint[] resultPoints) {
PointF[] transformedPoints = new PointF[resultPoints.length];
int index = 0;
if (resultPoints != null){
float previewX = mCameraManager.getPreviewSize().x;
float previewY = mCameraManager.getPreviewSize().y;
float scaleX = this.getWidth()/previewY;
float scaleY = this.getHeight()/previewX;
for (ResultPoint point :resultPoints){
PointF tmppoint = new PointF((previewY- point.getY())*scaleX, point.getX()*scaleY);
transformedPoints[index] = tmppoint;
index++;
}
}
return transformedPoints;
}
/** Check if this device has a camera */
private boolean checkCameraHardware(Context context) {
if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)){
// this device has a camera
return true;
}
else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FRONT)){
// this device has a front camera
return true;
}
else if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY)){
// this device has any camera
return true;
}
else {
// no camera on this device
return false;
}
}
}
A Surface is part of a producer-consumer buffer queue arrangement. Your application is on the producer end, and for a SurfaceView the system compositor (SurfaceFlinger) is on the consumer end.
A surface can have only one producer at a time. You've established the camera preview as the producer, so it's not possible to also connect a Canvas to perform drawing. You're not seeing failures because you're using new Canvas to create a Canvas in a vacuum -- it's not connected to anything. (Normally you'd use Surface#lockCanvas() to get the Canvas associated with the Surface.)
The surface is a completely separate layer, composited behind everything else by default, which means you can draw on top of it with a custom View. I don't think you need an additional view object though -- I believe you can do it with the 'view' part of the SurfaceView itself, which should have a transparent background. See the "custom drawing" documentation.
If you want to get fancy you can feed the camera preview to OpenGL ES, but that's probably excessive for what you need. (Some examples here.) Also, if you want to learn more about the Android graphics architecture, see this document.

Background & title cannot be resolved or be a field

I'm following the Android Game Programming for Dummies by: Derek James. It looks outdated too me because in the book it doesn't include the fragment_main. So I just copied the fragment_main and replaced it in the activity_main and deleted the fragment_main (I followed the how to get rid of fragment_main tutorial on this forum).
I'm trying to make the whack a mole game in the book.
Anyways I get two errors when I followed the book and it said I can run the program now but I am unable to do that because of:
background cannot be resolved or is not a field
title cannot be resolved or is not a field
I have everything the same as the book but why do I get these errors, I checked all over Google to find an answer or something similar but I can't find the error, I would really appreciate if someone can help me out. Sorry for writing a whole paragraph but I should let you know what I did.
This is my WhackAMoleView.java
package com.whackamole;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class WhackAMoleView extends SurfaceView implements
SurfaceHolder.Callback {
private Context myContext;
private SurfaceHolder mySurfaceHolder;
private Bitmap backgroundImg;
private int screenW = 1;
private int screenH = 1;
private boolean running = false;
private boolean onTitle = true;
private WhackAMoleThread thread;
public WhackAMoleView(Context context, AttributeSet attrs) {
super(context, attrs);
SurfaceHolder holder = getHolder();
holder.addCallback(this);
thread = new WhackAMoleThread(holder, context, new Handler()
{
#Override
public void handleMessage(Message m) {
}
});
setFocusable(true);
}
public WhackAMoleThread getThread() {
return thread;
}
class WhackAMoleThread extends Thread {
public WhackAMoleThread(SurfaceHolder surfaceHolder, Context context,
Handler handler) {
mySurfaceHolder = surfaceHolder;
myContext = context;
backgroundImg = BitmapFactory.decodeResource(
context.getResources(), R.drawable.title);
}
#Override
public void run() {
while (running) {
Canvas c = null;
try {
c = mySurfaceHolder.lockCanvas(null);
synchronized (mySurfaceHolder) {
draw(c);
}
} finally {
if (c != null) {
mySurfaceHolderunlockCanvasAndPost(c);
}
}
}
}
private void mySurfaceHolderunlockCanvasAndPost(Canvas c) {
// TODO Auto-generated method stub
}
private void draw(Canvas canvas) {
try {
canvas.drawBitmap(backgroundImg, 0, 0, null);
} catch (Exception e) {
}
}
boolean doTouchEvent(MotionEvent event) {
synchronized (mySurfaceHolder) {
int eventaction = event.getAction();
int x = (int) event.getX();
int Y = (int) event.getY();
switch (eventaction) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
break;
case MotionEvent.ACTION_UP:
if (onTitle) {
backgroundImg = BitmapFactory
.decodeResource(myContext.getResources(),
R.drawable.background);
backgroundImg = Bitmap.createScaledBitmap(
backgroundImg, screenW, screenH, true);
onTitle = false;
}
break;
}
}
return true;
}
public void setSurfaceSize(int width, int height) {
synchronized (mySurfaceHolder) {
screenW = width;
screenH = height;
backgroundImg = Bitmap.createScaledBitmap(backgroundImg, width,
height, true);
}
}
public void setRunning(boolean b) {
running = b;
}
}
#Override
public boolean onTouchEvent(MotionEvent event) {
return thread.doTouchEvent(event);
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
thread.setSurfaceSize(width, height);
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
thread.setRunning(true);
if (thread.getState() == Thread.State.NEW) {
thread.start();
}
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
thread.setRunning(false);
}
}
This is my MainActivity.java
package com.whackamole;
import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {
private WhackAMoleView myWhackAMoleView;
/**Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags
(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.whackamole_layout);
myWhackAMoleView = (WhackAMoleView)
findViewById(R.id.mole);
myWhackAMoleView.setKeepScreenOn(true);
}
}
This is my AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.whackamole"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name">
<activity
android:name="com.whackamole.MainActivity"
android:screenOrientation="landscape"
android:configChanges="keyboardHidden|orientation"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
mySurfaceHolderunlockCanvasAndPost(c);
}
}
}
}
mySurfaceHolderunlockCanvasAndPost should be mySurfaceHolder.unlockCanvasAndPost
*private void mySurfaceHolderunlockCanvasAndPost(Canvas c) {
// TODO Auto-generated method stub
}* should not be here

Android Live Wallpaper image(video) sequence works...preferences / setting not work (crash app!)

What is wrong with my coding clicking settings will crash app.
I cant read default settings values from prefs.xml
image sequence working like i want and now it's
moving right to left while images continue change (like a video)
someone genious see any problems ? :)
AndroidManifest.xml
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.mywallpaper"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="7" android:targetSdkVersion="12" />
<uses-feature android:name="android.software.live_wallpaper" />
<uses-permission android:name="android.permission.SET_WALLPAPER" />
<uses-permission android:name="android.permission.BIND_WALLPAPER" />
<application
android:label="#string/app_name"
android:icon="#drawable/ic_launcher"
android:theme="#style/AppTheme">
<service
android:label="#string/app_name"
android:name=".MyWallpaperService"
android:enabled="true"
android:permission="android.permission.BIND_WALLPAPER">
<intent-filter android:priority="1">
<action
android:name="android.service.wallpaper.WallpaperService">
</action>
</intent-filter>
<meta-data
android:name="android.service.wallpaper"
android:resource="#xml/wallpaper" >
</meta-data>
</service>
<activity
android:label="myPrefs"
android:name="com.example.mywallpaper.Prefs"
android:permission="android.permission.BIND_WALLPAPER"
android:enabled="true"
android:exported="true">
<intent-filter>
<category android:name="android.intent.category.PREFERENCE" />
</intent-filter>
</activity>
</application>
</manifest>
wallpaper.xml
<wallpaper
xmlns:android="http://schemas.android.com/apk/res/android"
android:name="something"
android:thumbnail="#drawable/ic_launcher"
android:description="#string/app_name"
android:settingsActivity="com.example.mywallpaper.Prefs">
</wallpaper>
prefs.xml
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android"
android:title="Title Preference"
android:key="myPrefs">
<CheckBoxPreference
android:title="Touch"
android:key="touch"
android:summary="Touch enable"
android:defaultValue="true"
/>
<EditTextPreference
android:title="Speed"
android:key="speed"
android:summary="Animation speed"
android:defaultValue="500"
/>
</PreferenceScreen>
Prefs.java
package com.example.mywallpaper;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.preference.PreferenceActivity;
public class Prefs extends PreferenceActivity
implements
SharedPreferences.OnSharedPreferenceChangeListener {
#SuppressWarnings("deprecation")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getPreferenceManager().setSharedPreferencesName(MyWallpaperService.SHARED_PREFS_NAME);
addPreferencesFromResource(R.xml.prefs);
getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
}
#Override
protected void onResume() {
super.onResume();
}
#SuppressWarnings("deprecation")
#Override
protected void onDestroy() {
getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
super.onDestroy();
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences,
String key) {
// TODO Auto-generated method stub
}
}
MyWallpaperService.java
package com.example.mywallpaper;
import android.content.SharedPreferences;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Handler;
import android.service.wallpaper.WallpaperService;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
public class MyWallpaperService extends WallpaperService {
public static final String SHARED_PREFS_NAME = "myPrefs";
//drawable image array
int[] myImageList = new int[]{
R.drawable.bg,
R.drawable.bg1,
R.drawable.bg2,
R.drawable.bg3,
R.drawable.bg4,
R.drawable.bg5,
R.drawable.bg6,
R.drawable.bg7,
R.drawable.bg8,
R.drawable.bg9,
R.drawable.bg10,
R.drawable.bg11,
R.drawable.bg12,
R.drawable.bg13,
R.drawable.bg14,
R.drawable.bg15,
R.drawable.bg16
};
public boolean runUp = true;
public boolean touchEnabled = true;
public int mSpeed = 100;
public int bgNumber = 0;
public int bgFrame = 0;
public int bgFrameMax = 20;
#Override
public Engine onCreateEngine() {
return new WallpaperEngine();
}
private class WallpaperEngine extends Engine
implements SharedPreferences.OnSharedPreferenceChangeListener {
private SharedPreferences mPrefs;
private boolean mVisible = false;
private Bitmap backgroundImage;
private final Handler mHandler = new Handler();
private final Runnable mUpdateDisplay = new Runnable() {
public void run() {
draw();
}
};
private void draw() {
SurfaceHolder holder = getSurfaceHolder();
Canvas c = null;
try {
c = holder.lockCanvas();
if (c != null) {
//paint black
Paint p = new Paint();
p.setColor(Color.BLACK);
c.drawRect(0, 0, c.getWidth(), c.getHeight(), p);
drawBG(c);
}
} finally {
if (c != null)
holder.unlockCanvasAndPost(c);
}
mHandler.removeCallbacks(mUpdateDisplay);
if (mVisible) {
mHandler.postDelayed(mUpdateDisplay, mSpeed);
}
}
WallpaperEngine() {
mPrefs = MyWallpaperService.this.getSharedPreferences(SHARED_PREFS_NAME, 0);
mPrefs.registerOnSharedPreferenceChangeListener(this);
onSharedPreferenceChanged(mPrefs, null);
}
#Override
public void onTouchEvent(MotionEvent event) {
//super.onTouchEvent(event);
if(touchEnabled){
bgNumber = 0;
}
}
public void drawBG(Canvas c){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPurgeable = true;
Resources res = getResources();
backgroundImage = BitmapFactory.decodeResource(res,myImageList[bgNumber], options);
//move looping imagas (video) right to left
int CH = c.getHeight();
int CW = c.getWidth();
double BH = backgroundImage.getHeight();
double BW = backgroundImage.getWidth();
double hScale = (BH/BW);
int bgSlideX = (CW/bgFrameMax);
int wallPH = (int) (CW*hScale);
int wLeft = 0+(CW-(bgSlideX*bgFrame));
int wTop = (int) ((CH/2)-(BH/2));
int wRight = CW+(CW-(bgSlideX*bgFrame));
int wBottom = wTop+wallPH;
Rect dest = new Rect(wLeft, wTop, wRight, wBottom);
Paint paint = new Paint();
paint.setFilterBitmap(true);
c.drawBitmap(backgroundImage, null, dest, paint);
bgFrame+=1;
if (bgFrame == bgFrameMax*2){
bgFrame = 0;
}
//Loop images up and down
if (runUp = true){
bgNumber += 1;
if (bgNumber == myImageList.length){
bgNumber=0;
runUp = false;
}
}
else if(runUp = false){
bgNumber -= 1;
if (bgNumber == 0){
bgNumber+=1;
runUp = true;
}
}
backgroundImage.recycle();
}
#Override
public void onVisibilityChanged(boolean visible) {
mVisible = visible;
if (visible) {
draw();
}
else {
mHandler.removeCallbacks(mUpdateDisplay);
}
}
#Override
public void onSurfaceChanged(SurfaceHolder holder, int format, int width, int height) {
draw();
}
#Override
public void onSurfaceDestroyed(SurfaceHolder holder) {
super.onSurfaceDestroyed(holder);
mVisible = false;
mHandler.removeCallbacks(mUpdateDisplay);
}
#Override
public void onDestroy() {
super.onDestroy();
mVisible = false;
mHandler.removeCallbacks(mUpdateDisplay);
}
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
mSpeed = Integer.valueOf(sharedPreferences.getString("speed", "5000"));
//sharedPreferences.getInt("speed", 100);
touchEnabled = sharedPreferences.getBoolean("touch", true);
//mHandler.post(mUpdateDisplay);
}
}
public void onPause(){
super.onDestroy();
}
}
Based on the code you posted I can already see that you never closed the tag in your prefs.xml. That would cause a problem. You need to add a at the end of your prefs.xml to close it.

Categories

Resources