duy anh hoang
duy anh hoang

Reputation: 195

Resource$NotFoundException while getting String by resource ID

I encountered this error

android.content.res.Resources$NotFoundException: String resource ID #0x0
at android.content.res.Resources.getText(Resources.java:244)
at android.support.v7.widget.ResourcesWrapper.getText(ResourcesWrapper.java:52)
at android.widget.TextView.setText(TextView.java:3940)
at com.example.android.tourrior.TourAdapter.getView(TourAdapter.java:43)

The error said my problem lies here

TextView address = (TextView) listItemView.findViewById(R.id.address);
if (currentPosition.hasAddress()) {
    address.setText(currentPosition.getAddress());
} else {
    address.setVisibility(address.GONE);
}

The getAddress method is declared here

public class Tour {
private int mName;
private int mPhoneNumber;
private int mAddress;
private int mOpeningHours;
private int mDescription;
private int mImageResourceId;
private static final int UNAVAILABLE = -1;

public Tour(int name,int address, int description, int phoneNumber, int openingHours, int image) {
    mName = name;
    mAddress = address;
    mDescription = description;
    mPhoneNumber = phoneNumber;
    mOpeningHours = openingHours;
    mImageResourceId = image;
}
public Tour(int name,int description, int openingHours, int image) {
    mName = name;
    mDescription = description;
    mOpeningHours = openingHours;
    mImageResourceId = image;
}
public Tour(int name, int address, int openingHours){
    mName = name;
    mAddress = address;
    mOpeningHours = openingHours;
}

public Tour(int name,int address, int description, int openingHours, int phoneNumber) {
    mName = name;
    mAddress = address;
    mDescription = description;
    mOpeningHours = openingHours;
    mPhoneNumber = phoneNumber;
}


public int getName() {
    return mName;
}

public int getAddress() {
    return mAddress;
}

public int getDescription() {
    return mDescription;
}

public int getOpeningHours() {
    return mOpeningHours;
}

public int getPhoneNumber() {
    return mPhoneNumber;
}

public int getImageResourceId() {
    return mImageResourceId;
}

I tried to change the code in the error line to this

address.setText("" + currentPosition.getAddress());

and it returns 0. I'm making an adapter for 4 children activities, each contains 4 objects with 3 to 6 states (shown above) and one of them is address. This is one of my activity:

public class MallsActivity extends AppCompatActivity{
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.places);
    ArrayList<Tour> tour = new ArrayList<Tour>();
    tour.add(new Tour(R.string.mall1_name,R.string.mall1_address,R.string.mall1_opening_hours));
    tour.add(new Tour(R.string.mall2_name,R.string.mall2_address,R.string.mall2_opening_hours));
    tour.add(new Tour(R.string.mall3_name,R.string.mall3_address,R.string.mall3_opening_hours));
    tour.add(new Tour(R.string.mall4_name,R.string.mall4_address,R.string.mall4_opening_hours));
    TourAdapter adapter = new TourAdapter(this, tour);

    ListView listView = (ListView) findViewById(R.id.list);

    listView.setAdapter(adapter);
}

} My adapter until the address view

public class TourAdapter extends ArrayAdapter<Tour> {
public TourAdapter(Context context, ArrayList<Tour> tour) {
    super(context, 0, tour);
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // Check if the existing view is being reused, otherwise inflate the view
    View listItemView = convertView;
    if (listItemView == null) {
        listItemView = LayoutInflater.from(getContext()).inflate(
                R.layout.list_item, parent, false);
    }
    Tour currentPosition = getItem(position);
    TextView name = (TextView) listItemView.findViewById(R.id.name);
    name.setText(currentPosition.getName());

    TextView description = (TextView) listItemView.findViewById(R.id.description);
    if (currentPosition.hasDescription()) {
        description.setText(currentPosition.getDescription());
    } else {
        description.setVisibility(View.GONE);
    }

    TextView address = (TextView) listItemView.findViewById(R.id.address);
    if (currentPosition.hasAddress()) {
        address.setText(currentPosition.getAddress());
    } else {
        address.setVisibility(View.GONE);
    }

Upvotes: 0

Views: 487

Answers (3)

duy anh hoang
duy anh hoang

Reputation: 195

The answer lies in where I think was not important and did not post it, here it is

public boolean hasImage(){
    return mImageResourceId != UNAVAILABLE;
}
public boolean hasDescription(){
    return mDescription != UNAVAILABLE;
}
public boolean hasPhoneNumber(){
    return mPhoneNumber != UNAVAILABLE;
}
public boolean hasAddress(){
    return mAddress != UNAVAILABLE;
}

} here is the example for hasDescription method

TextView description = (TextView) listItemView.findViewById(R.id.description);
if (currentPosition.hasDescription()) {
    description.setText(currentPosition.getDescription());
} else {
    description.setVisibility(View.GONE);
}

What I was trying to do in this section is to check if my object has these fields or not, since they are different from each other. I set the UNAVAILABLE constant to -1 and expect if the ID points to nowhere it will return -1 and erase that field. However, in fact it return 0, making my method useless, since it will never return -1, the field will always exist no matter what. So what I fixed was simply change the UNAVAILABLE constant

private static final int UNAVAILABLE = 0;

And that's all

Upvotes: 0

OneCricketeer
OneCricketeer

Reputation: 191874

Try to simplify your class.

public class Tour {

    private int mName;
    private int mPhoneNumber;
    private int mAddress;
    private int mOpeningHours;
    private int mDescription;
    private int mImageResourceId;
    private static final int UNAVAILABLE = -1;

    public Tour(int name,int address, int description, int phoneNumber, int openingHours, int image) {
        mName = name;
        mAddress = address;
        mDescription = description;
        mPhoneNumber = phoneNumber;
        mOpeningHours = openingHours;
        mImageResourceId = image;
    }
    public Tour(int name,int description, int openingHours, int image) {
        this(name, 0, description, 0, openingHours, image);
    }
    public Tour(int name, int address, int openingHours){
        this(name, address, 0, 0, openingHours, 0);
    }

    public Tour(int name,int address, int description, int openingHours, int phoneNumber) {
        this(name, address, description, phoneNumber, openingHours, 0);
    }

    // Getters, setters
}

Then, you should set a breakpoint in the debugger at

Tour currentPosition = getItem(position);

Check each one of your fields of that object. The error states that one of them is returning as 0, or a non-existent ID value.

Note: You can simplify that object adding...

final Resources res = getResources();
final String packageName = getPackageName();
for (int i = 1; i <= 4; i++) {
    String resName = "mall"+i; 
    tour.add(
        new Tour(
            res.getIdentifier(resName+"_name", "string", packageName),
            res.getIdentifier(resName+"_address", "string", packageName),
            res.getIdentifier(resName+"_opening_hours", "string", packageName)));
}

Upvotes: 0

Shivam
Shivam

Reputation: 532

First, make sure that your getAddress is returning correct "String resource Id".

And for getting String from res id call following:

address.setText(getResources().getString("YOUR_INT_RES_ID"));

Upvotes: 1

Related Questions