I am getting the following error on devices Galaxy Nexus (maguro),Nexus 4 (mako),Nexus 7 (flo), Xperia Z (C6603) but my device Note2 4.1.1 works fine. What I am doing is using a Visualizer with my sound file to show the user cool graph-like feedback from their audio files.
I am using com.pheelicks.visualizer in my app and it works fine on my device but it has been crashing for some of my users. This is hard for me to test since I don't have a new device, but if someone can confirm why I am getting the error I would greatly appreciate it! I am note sure if it has anything to do with it, but I also start with the view's visibility as view.GONE and then set it to visible when the time is right, and then start an animation. I will include this code below just in case this is what is the problem.
java.lang.IllegalArgumentException: width and height must be > 0
at android.graphics.Bitmap.createBitmap(Bitmap.java:695)
at android.graphics.Bitmap.createBitmap(Bitmap.java:674)
at android.graphics.Bitmap.createBitmap(Bitmap.java:641)
at com.pheelicks.visualizer.VisualizerView.onDraw(VisualizerView.java:193)
at android.view.View.draw(View.java:13944)
at android.view.View.getDisplayList(View.java:12838)
at android.view.View.getDisplayList(View.java:12880)
at android.view.View.draw(View.java:13657)
at android.view.ViewGroup.drawChild(ViewGroup.java:3083)
at android.view.ViewGroup.dispatchDraw(ViewGroup.java:2920)
at android.view.View.draw(View.java:13947)
at android.view.View.getDisplayList(View.java:12838)
at android.view.View.getDisplayList(View.java:12880)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3057)
at android.view.View.getDisplayList(View.java:12775)
at android.view.View.getDisplayList(View.java:12880)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3057)
at android.view.View.getDisplayList(View.java:12775)
at android.view.View.getDisplayList(View.java:12880)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3057)
at android.view.View.getDisplayList(View.java:12775)
at android.view.View.getDisplayList(View.java:12880)
at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:3057)
at android.view.View.getDisplayList(View.java:12775)
at android.view.View.getDisplayList(View.java:12880)
at android.view.HardwareRenderer$GlRenderer.buildDisplayList(HardwareRenderer.java:1411)
at android.view.HardwareRenderer$GlRenderer.draw(HardwareRenderer.java:1359)
at android.view.ViewRootImpl.draw(ViewRootImpl.java:2367)
at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:2239)
at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:1872)
at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1004)
at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:5481)
at android.view.Choreographer$CallbackRecord.run(Choreographer.java:749)
at android.view.Choreographer.doCallbacks(Choreographer.java:562)
at android.view.Choreographer.doFrame(Choreographer.java:532)
at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:735)
at android.os.Handler.handleCallback(Handler.java:730)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5103)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
at dalvik.system.NativeStart.main(Native Method)
For Reference here is the custome VisualizerView
public class VisualizerView extends View {
private static final String TAG = "VisualizerView";
private boolean isLinked = false;
private byte[] mBytes;
private byte[] mFFTBytes;
private Rect mRect = new Rect();
private Visualizer mVisualizer;
private Set<Renderer> mRenderers;
private Paint mFlashPaint = new Paint();
private Paint mFadePaint = new Paint();
public VisualizerView(Context context, AttributeSet attrs, int defStyle)
{
super(context, attrs);
init();
}
public VisualizerView(Context context, AttributeSet attrs)
{
this(context, attrs, 0);
}
public VisualizerView(Context context)
{
this(context, null, 0);
}
private void init() {
mBytes = null;
mFFTBytes = null;
mFlashPaint.setColor(Color.argb(122, 255, 255, 255));
mFadePaint.setColor(Color.argb(150, 255, 255, 255)); // Adjust alpha to change how quickly the image fades
mFadePaint.setXfermode(new PorterDuffXfermode(Mode.MULTIPLY));
mRenderers = new HashSet<Renderer>();
}
/**
* Links the visualizer to a player
* @param player - MediaPlayer instance to link to
*/
public void link(MediaPlayer player)
{
if(player == null)
{
throw new NullPointerException("Cannot link to null MediaPlayer");
}
// Create the Visualizer object and attach it to our media player.
mVisualizer = new Visualizer(player.getAudioSessionId());
mVisualizer.setCaptureSize(Visualizer.getCaptureSizeRange()[1]);
// Pass through Visualizer data to VisualizerView
Visualizer.OnDataCaptureListener captureListener = new Visualizer.OnDataCaptureListener()
{
@Override
public void onWaveFormDataCapture(Visualizer visualizer, byte[] bytes,
int samplingRate)
{
updateVisualizer(bytes);
}
@Override
public void onFftDataCapture(Visualizer visualizer, byte[] bytes,
int samplingRate)
{
updateVisualizerFFT(bytes);
}
};
mVisualizer.setDataCaptureListener(captureListener,
Visualizer.getMaxCaptureRate() / 2, true, true);
// Enabled Visualizer and disable when we're done with the stream
mVisualizer.setEnabled(true);
player.setOnCompletionListener(new MediaPlayer.OnCompletionListener()
{
@Override
public void onCompletion(MediaPlayer mediaPlayer)
{
mVisualizer.setEnabled(false);
}
});
this.setLinked(true);
}
public void addRenderer(Renderer renderer)
{
if(renderer != null)
{
mRenderers.add(renderer);
}
}
public void clearRenderers()
{
mRenderers.clear();
}
/**
* Call to release the resources used by VisualizerView. Like with the
* MediaPlayer it is good practice to call this method
*/
public void release()
{
mVisualizer.release();
this.setLinked(false);
}
/**
* Pass data to the visualizer. Typically this will be obtained from the
* Android Visualizer.OnDataCaptureListener call back. See
* {@link Visualizer.OnDataCaptureListener#onWaveFormDataCapture }
* @param bytes
*/
public void updateVisualizer(byte[] bytes) {
mBytes = bytes;
invalidate();
}
/**
* Pass FFT data to the visualizer. Typically this will be obtained from the
* Android Visualizer.OnDataCaptureListener call back. See
* {@link Visualizer.OnDataCaptureListener#onFftDataCapture }
* @param bytes
*/
public void updateVisualizerFFT(byte[] bytes) {
mFFTBytes = bytes;
invalidate();
}
boolean mFlash = false;
/**
* Call this to make the visualizer flash. Useful for flashing at the start
* of a song/loop etc...
*/
public void flash() {
mFlash = true;
invalidate();
}
Bitmap mCanvasBitmap;
Canvas mCanvas;
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
// Create canvas once we're ready to draw
mRect.set(0, 0, getWidth(), getHeight());
if(mCanvasBitmap == null)
{
mCanvasBitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), Config.ARGB_8888); // THIS IS WHERE THE ERROR IS OCCURRING
}
if(mCanvas == null)
{
mCanvas = new Canvas(mCanvasBitmap);
}
if (mBytes != null) {
// Render all audio renderers
AudioData audioData = new AudioData(mBytes);
for(Renderer r : mRenderers)
{
r.render(mCanvas, audioData, mRect);
}
}
if (mFFTBytes != null) {
// Render all FFT renderers
FFTData fftData = new FFTData(mFFTBytes);
for(Renderer r : mRenderers)
{
r.render(mCanvas, fftData, mRect);
}
}
// Fade out old contents
mCanvas.drawPaint(mFadePaint);
if(mFlash)
{
mFlash = false;
mCanvas.drawPaint(mFlashPaint);
}
canvas.drawBitmap(mCanvasBitmap, new Matrix(), null);
}
public boolean isLinked() {
return isLinked;
}
private void setLinked(boolean isLinked) {
this.isLinked = isLinked;
}
}
OnCreate in Activity (the visualizer_container has the visualizerView inside it)
this.visualizer_container = (RelativeLayout) findViewById(R.id.visualizer_layout);
this.visualizer_container.setVisibility(View.GONE);
Later in activity
sAnimation = AnimationUtils.loadAnimation(this, R.anim.slide_bottom);
sAnimation.setInterpolator(new AccelerateInterpolator());
sAnimation.setStartOffset(400);
sAnimation.setDuration(1000);
this.mVisualizerView.setAnimation(sAnimation);