#java #android #listview #android-arrayadapter
#Android #исключение nullpointerexception
Вопрос:
Я пытаюсь получить имя контактов в одном массиве и их типы в другом массиве, но не могу получить исключение с нулевым указателем.вот мой код.Я указал строку, в которой я получаю исключение с нулевым указателем.пожалуйста, помогите .. заранее спасибо.
package application.test;
import android.app.Activity;
import android.content.ContentResolver;
import android.database.Cursor;
import android.database.SQLException;
import android.os.Bundle;
import android.provider.ContactsContract;
import android.provider.ContactsContract.CommonDataKinds.Phone;
import android.provider.ContactsContract.Contacts.Data;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.ViewGroup.LayoutParams;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
public final class TestActivity extends Activity {
String[] name;
String[] phoneType;
ListView lv;
ListViewAdapter lva;
public static final String TAG = "ContactManager";
@Override
public void onCreate(Bundle savedInstanceState)
{
Log.v(TAG, "Activity State: onCreate()");
super.onCreate(savedInstanceState);
LayoutParams params = new RelativeLayout.LayoutParams(LayoutParams.FILL_PARENT,LayoutParams.WRAP_CONTENT);
LinearLayout mainLayout=new LinearLayout(this);
mainLayout.setOrientation(LinearLayout.VERTICAL);
LayoutInflater layoutInflater = getLayoutInflater();
mainLayout.addView(layoutInflater.inflate(R.layout.main,null));
mainLayout.addView(layoutInflater.inflate(R.layout.extra,null));
this.addContentView(mainLayout, params);
lv = (ListView)findViewById(android.R.id.list);
lva = new ListViewAdapter(this,name,phoneType);
lv.setAdapter(lva);
testGetContacts();
}
private void testGetContacts() {
ContentResolver cr = getContentResolver();
String[] projection = new String[] { Data._ID,
ContactsContract.Contacts.DISPLAY_NAME, Phone.TYPE};
Cursor cur = cr.query(ContactsContract.Data.CONTENT_URI,
projection, null, null, null);
if (cur != null amp;amp; cur.moveToFirst()) {
try {
int indexID = cur.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
int indexName = cur.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
int indexPhoneType = cur.getColumnIndexOrThrow(Phone.TYPE);
while (cur.moveToNext()) {
int i=1;
String id = cur.getString(indexID);
//HERE LIES NULL POINTER EXCEPTION name[i] = cur.getString(indexName);
//HERE TOO phoneType[i] = cur.getString(indexPhoneType);
i ;
System.out.println(id "n");
System.out.println(name "n");
System.out.println(phoneType "n");
}
} catch (SQLException sqle) {
//handling exception
} finally {
if (!cur.isClosed()) {
cur.close();
}
}
}
}
}
Комментарии:
1. не обращайте внимания на это, ваши
name
иphoneType
не инициализированы, поэтому они равны нулю2. создайте свой listview следующим образом: lv = (ListView)findViewById(R.id.listview);
Ответ №1:
Вы не инициализируете свое String[] name, поэтому при попытке получить к нему доступ вы получаете исключение с нулевым указателем. Я бы предложил использовать более значимые имена переменных. ‘name’ очень неоднозначно.
Комментарии:
1. ну, программа запущена, но не может получить имя и тип .. пустой экран — это то, что я получаю. есть идеи
2. Теперь вы имеете дело с совершенно другим вопросом. Я и другие ответили на ваш вопрос. Ваш первоначальный вопрос был об исключении с нулевой ссылкой. Я бы посоветовал попытаться найти некоторые ресурсы, чтобы узнать о вашей новой проблеме, и при необходимости задать новый вопрос о переполнении стека.
3. Кроме того, похоже, что вы задаете две новые вещи. Отображение и извлечение — это разные операции.
Ответ №2:
Массивы вашего имени и телефона не были инициализированы.
String[] name = new String[EXPECTED_SIZE];
String[] phoneType = new String[EXPECTED_SIZE];
Любая подходящая среда IDE должна сообщить вам об этом, прежде чем вы попытаетесь ее запустить. Вы используете Eclipse или IntelliJ? Вы должны!
Комментарии:
1. ну, программа запущена, но не может получить имя и тип .. пустой экран — это то, что я получаю. есть идеи
Ответ №3:
Инициализируйте String[]
имя перед его использованием. Вы можете сделать это следующим образом:
name=new String[cur.getCount()];
String s="";
while (cur.moveToNext()) {
int i=1;
String id = cur.getString(indexID);
name[i] = cur.getString(indexName);
phoneType[i] = cur.getString(indexPhoneType);
//System.out.println(id "n");
//System.out.println(name "n");
//System.out.println(phoneType "n");
s=s "id=" id " name=" name[i] " phoneType=" phoneType[i] "n";
i ;
}
Toast.makeText(getApplicationContext(),i " - " s).show();
Редактировать :
Создайте XML-файл в папке layout.
main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" android:orientation="vertical" >
<ListView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@ id/listview"
android:cacheColorHint="#0000"
/>
</LinearLayout>
теперь в вашем TestActivity.class:
public final class TestActivity extends Activity {
String[] name;
String[] phoneType;
ListView lv;
String s[];
public static final String TAG = "ContactManager";
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.id.main);
testGetContacts();
lv = (ListView)findViewById(R.id.listview);
ArrayAdapter<String> sa=new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1,s);
lv.setAdapter(sa);
}
private void testGetContacts() {
ContentResolver cr = getContentResolver();
String[] projection = new String[] { Data._ID,
ContactsContract.Contacts.DISPLAY_NAME, Phone.TYPE};
Cursor cur = cr.query(ContactsContract.Data.CONTENT_URI,
projection, null, null, null);
if (cur != null amp;amp; cur.moveToFirst()) {
try {
int indexID = cur.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
int indexName = cur.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
int indexPhoneType = cur.getColumnIndexOrThrow(Phone.TYPE);
name=new String[cur.getCount()];
s=new String[cur.getCount()];
while (cur.moveToNext()) {
int i=1;
String id = cur.getString(indexID);
name[i-1] = cur.getString(indexName);
phoneType[i-1] = cur.getString(indexPhoneType);
String temp="id=" id "-name=" name[i-1] "-phoneType=" phoneType[i-1];
s[i-1]=temp;
i ;
}
}
Комментарии:
1. ну, программа запущена, но не может получить имя и тип .. пустой экран — это то, что я получаю. есть идеи
2. Это потому, что вы не отображали объекты на экране. Вы увидите, что это напечатано с помощью System.out.println(«»); в консоли. Попробуйте использовать Toast или TextView, чтобы увидеть эти вещи на экране.
3. Пожалуйста, посмотрите правку в ответе. Я показал элементы в listview.
4. Я пытался запустить ваш код, но получил исключение с нулевым указателем в (lv.setadapter (sa)).. Я занимаюсь этим неделю и сейчас исчерпан. пожалуйста, помогите..
5. пожалуйста, посмотрите мой отредактированный ответ. Это было по ошибке s = new String[cur,getCount()]; а также я обновил s [i] на s [i-1] в цикле while.
Ответ №4:
Вы получаете нулевой указатель, потому что вы обращаетесь к неправильному индексу.
попробуйте это:
s=new String[cur.getCount()];
int i=1;
while (cur.moveToNext()) {
String id = cur.getString(indexID);
name[i-1] = cur.getString(indexName);
phoneType[i-1] = cur.getString(indexPhoneType);
String temp="id=" id "-name=" name[i-1] "-phoneType=" phoneType[i-1];
s[i-1]=temp;
i ;
}
а также lv=(ListView)findViewById(R.id.listview);
вместо lv=(ListView)findViewById(android.R.id.list);
Здесь следует добавить условие:
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
testGetContacts();
if(s.length()>0)
{
lv = (ListView)findViewById(R.id.listview);
ArrayAdapter<String> sa=new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1,s);
lv.setAdapter(sa);
}
else
{
Toast.makeText(getApplicationContext(),"Nothing Found",Toast.LENGTH_SHORT).show();
}
Комментарии:
1. я пробовал этот индекс .. все то же исключение и нулевые значения
2. смотрите отредактированный ответ. внесите все изменения и расскажите, что происходит.
3. вам также нужно поместить efforts.it должно быть s.length()> 0.
4. s.длина абсолютно правильная… что я вижу во время отладки, что в строках [Идентификатор строки = cur.getString(indexID); name [i-1] = cur.getString(IndexName); PhoneType [i-1] = cur.getString(indexPhoneType); ], indexid получает 0,indexname = 1 и indexphonetype = 2; я думаю, что все они должны получить одинаковый индекс…
5. поместите int i= 1 вне while … из-за этого он всегда записывает новую строку в одно и то же место… попробуйте это
Ответ №5:
Попробуйте это и скажите мне, что это помогло:
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
lv = (ListView)findViewById(R.id.listview);
testGetContacts();
ArrayAdapter<String> sa=new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1,s);
lv.setAdapter(sa);
}//method
private void testGetContacts() {
ContentResolver cr = getContentResolver();
String[] projection = new String[] { Data._ID,
ContactsContract.Contacts.DISPLAY_NAME, Phone.TYPE};
Cursor cur = cr.query(ContactsContract.Data.CONTENT_URI,
projection, null, null, null);
if (cur != null amp;amp; cur.moveToFirst()) {
try {
int indexID = cur.getColumnIndexOrThrow(ContactsContract.Contacts._ID);
int indexName = cur.getColumnIndexOrThrow(ContactsContract.Contacts.DISPLAY_NAME);
int indexPhoneType = cur.getColumnIndexOrThrow(Phone.TYPE);
name=new String[cur.getCount()];
phoneType=new String[cur.getCount()];
s=new String[cur.getCount()];
int i=1;
while (cur.moveToNext()) {
String id = cur.getString(indexID);
name[i] = cur.getString(indexName);
phoneType[i] = cur.getString(indexPhoneType);
String temp="id=" id "-name=" name[i] "-phoneType=" phoneType[i];
s[i-1]=temp;
i ;
}//while
ArrayAdapter<String> sa=new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1,s);
lv.setAdapter(sa);
}catch(Exception e){
e.printStackTrace();
}//catch
}//if
}//method
Комментарии:
1. Я попробовал это и смог получить представление списка, но не так, как я ожидал. во-первых, я получаю вдвое больше контактов, которые я сохранил в AVD, а во-вторых, имя и типы телефонов показывают одно и то же, то есть имя контакта. Я не смог получить типы, то есть (дом, работа).