Palette class is crashing my app on some images

1.7k Views Asked by At

I am making the Google I/O 2014 music player, and I am having trouble with the color extraction from album art. Here is my albums screen class:

package com.animbus.music;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.PorterDuff;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.graphics.Palette;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ImageButton;
import android.widget.ImageView;

import java.security.spec.PSSParameterSpec;


public class albums_activity extends AppCompatActivity {

    public Bundle b;
    public String AlbumName;
    public String AlbumArtist;
    public int AlbumArt;
    public int PrimaryColor;
    public int AccentColor;
    public int TitleTextColor;
    public int SubtitleTextColor;
    public int fabIcon;
    public Palette palette;

    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_albums_activity);
        //Get intent data and set it to something easier to handle and use
        b = getIntent().getExtras();
        AlbumName = b.getString("ALBUM_NAME");
        AlbumArtist = b.getString("ALBUM_ARTIST");
        AlbumArt = b.getInt("ALBUM_ART");
        Drawable AlbumArtDrawable = getDrawable(AlbumArt);
        Bitmap albumArt = BitmapFactory.decodeResource(getResources(), AlbumArt);

        ImageView albumArtView = (ImageView) findViewById(R.id.albums_activity_albumart);
        ImageButton playAll = (ImageButton) findViewById(R.id.play_all_FAB);
        //Make sure that the colors aren't null
        PrimaryColor = getResources().getColor(R.color.accent);
        AccentColor = getResources().getColor(R.color.accent);
        TitleTextColor = getResources().getColor(R.color.accent);
        SubtitleTextColor = getResources().getColor(R.color.accent);
        fabIcon = getResources().getColor(R.color.accent);

        //Convert Palette to resources
        palette = Palette.from(albumArt).generate();

        PrimaryColor = palette.getVibrantSwatch().getRgb();
        AccentColor = palette.getLightVibrantSwatch().getRgb();
        TitleTextColor = palette.getVibrantSwatch().getTitleTextColor();
        SubtitleTextColor = palette.getVibrantSwatch().getBodyTextColor();
        fabIcon = palette.getLightVibrantSwatch().getTitleTextColor();

        //Toolbar, setting toolbar as Actionbar,Setting the back arrow to be shown, and setting the title to nothing
        android.support.v7.widget.Toolbar toolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.album_toolbar);
        android.support.v7.widget.Toolbar infoToolbar = (android.support.v7.widget.Toolbar) findViewById(R.id.album_info_toolbar);
        setSupportActionBar(toolbar);
        //noinspection ConstantConditions
        getSupportActionBar().setDisplayHomeAsUpEnabled(true);
        toolbar.setTitle("");
        //Sets the title to the intent's data
        infoToolbar.setTitle(AlbumName);
        infoToolbar.setSubtitle(AlbumArtist);
        //Sets the albumart
        albumArtView.setImageResource(AlbumArt);
        //Sets the color of the Info Toolbar based on the albumart
        infoToolbar.setBackgroundColor(PrimaryColor);
        infoToolbar.setTitleTextColor(TitleTextColor);
        infoToolbar.setSubtitleTextColor(SubtitleTextColor);
        //Sets accent color based on album art
        playAll.getBackground().setColorFilter(AccentColor, PorterDuff.Mode.SRC_ATOP);
        playAll.getDrawable().setColorFilter(fabIcon,PorterDuff.Mode.SRC_ATOP);
    }

    @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_albums_activity, 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);
    }
}

Here is my problem. I have the app with three buttons, Album, Album Alt, and Album Alt 2. Only album alt opens. the others throw:

java.lang.RuntimeException: Unable to start activity ComponentInfo{com.animbus.music/com.animbus.music.albums_activity}: java.lang.NullPointerException: Attempt to invoke virtual method 'int android.support.v7.graphics.Palette$Swatch.getRgb()' on a null object reference

and the app crashes. It says the problem is at:

PrimaryColor = palette.getVibrantSwatch().getRgb();

I think it might be because of palette.getVibrantSwatch().getRgb() equaling null. I don't know but please help, for now i have to disable palette and continue making the app but please help

3

There are 3 best solutions below

1
On BEST ANSWER

Its not necessary that Palette will always return VibrantSwatch. Check for null before calling getRgb().

Palette.Swatch vibrantSwatch = palette.getVibrantSwatch();
  if(vibrantSwatch != null) {
    //get rgb
  } else {
    //get another swatch
}

You can also get all swatches available from Palette using getSwatches(). Then, to get most used color, pick the swatch having maximum pixel population. You can get pixel population by calling getPopulation() on swatches.

0
On

Palette may not get colors that match the criteria for the swatch you are trying to get so you should perform a check to make sure the swatch is not null before proceeding t

0
On

I had the same issue and I came to same conclusion that sometime palette!!.vibrantSwatch returns null for some images:

Adding detailed snippet for future reference

 Palette.from(bitmap).generate { palette ->
            // Use generated instance
            val vibrant = palette!!.vibrantSwatch
            if (vibrant != null) {
                // If we have a vibrant color
                // update the title TextView
                val mutedColor = palette.getMutedColor(R.attr.colorPrimary); 
                //mutedColor = palette.vibrantSwatch!!.getRgb()
                collapseToolbar.setBackgroundColor(mutedColor)
                collapseToolbar.setStatusBarScrimColor(palette.getDarkMutedColor(mutedColor))
                collapseToolbar.setContentScrimColor(palette.getMutedColor(mutedColor))

            }