0

I just finished adding a search feature to my android widget to search through a list of the users installed applications. My app installs fine and everything but when I go to search something the app force closes and I get this error:

10-18 10:08:39.404: E/AndroidRuntime(8965): FATAL EXCEPTION: main
10-18 10:08:39.404: E/AndroidRuntime(8965): java.lang.NullPointerException
10-18 10:08:39.404: E/AndroidRuntime(8965):     at com.example.awesomefilebuilderwidget.Drag_and_Drop_App$2.onTextChanged(Drag_and_Drop_App.java:61)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.widget.TextView.sendOnTextChanged(TextView.java:6576)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.widget.TextView.handleTextChanged(TextView.java:6785)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.widget.TextView$ChangeWatcher.onTextChanged(TextView.java:7001)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at     android.text.SpannableStringBuilder.sendTextChange(SpannableStringBuilder.java:889)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:352)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.text.SpannableStringBuilder.change(SpannableStringBuilder.java:269)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:432)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.text.SpannableStringBuilder.replace(SpannableStringBuilder.java:409)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.view.inputmethod.BaseInputConnection.replaceText(BaseInputConnection.java:679)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.view.inputmethod.BaseInputConnection.commitText(BaseInputConnection.java:185)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at com.android.internal.widget.EditableInputConnection.commitText(EditableInputConnection.java:120)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at com.android.internal.view.IInputConnectionWrapper.executeMessage(IInputConnectionWrapper.java:332)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at com.android.internal.view.IInputConnectionWrapper$MyHandler.handleMessage(IInputConnectionWrapper.java:86)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.os.Handler.dispatchMessage(Handler.java:99)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.os.Looper.loop(Looper.java:150)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at android.app.ActivityThread.main(ActivityThread.java:4333)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at java.lang.reflect.Method.invokeNative(Native Method)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at java.lang.reflect.Method.invoke(Method.java:507)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
10-18 10:08:39.404: E/AndroidRuntime(8965):     at dalvik.system.NativeStart.main(Native Method)

Here is Drag_and_Drop_App.java:

package com.example.awesomefilebuilderwidget;

import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;

public class Drag_and_Drop_App extends Activity {
private ListView mListAppInfo;
// Search EditText
EditText inputSearch;
AppInfoAdapter adapter;


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // set layout for the main screen
    setContentView(R.layout.drag_and_drop_app);
    // import buttons
    Button btnLinkToFeedback = (Button) findViewById(R.id.btnLinkToFeedback);

    // Link to Feedback Screen
    btnLinkToFeedback.setOnClickListener(new View.OnClickListener() {

        public void onClick(View view) {
            Intent i = new Intent(getApplicationContext(),
                    Feedback.class);
            startActivity(i);
            finish();
        }
    });
    // create new adapter
    @SuppressWarnings("unchecked")
    AppInfoAdapter adapter = new AppInfoAdapter(this, (List<ApplicationInfo>) Utilities.getInstalledApplication(this), getPackageManager());
    // load list application
   mListAppInfo = (ListView)findViewById(R.id.lvApps);
    // set adapter to list view
    mListAppInfo.setAdapter(adapter);
    // search bar
    inputSearch = (EditText) findViewById(R.id.inputSearch);

    inputSearch.addTextChangedListener(new TextWatcher() {

        @Override
        public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {

            // When user changed the Text
            // Drag_and_Drop_App.this.adapter.getFilter().filter(cs);  
            Drag_and_Drop_App.this.adapter.getFilter().filter(cs);

        }

        @Override
        public void beforeTextChanged(CharSequence arg0, int arg1, int arg2,
                int arg3) {
            // TODO Auto-generated method stub

        }

        @Override
        public void afterTextChanged(Editable arg0) {
            // TODO Auto-generated method stub                          
        }
        });


    // implement event when an item on list view is selected
    mListAppInfo.setOnItemClickListener(new OnItemClickListener() {

        @Override
        public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {
            // get the list adapter
            AppInfoAdapter appInfoAdapter = (AppInfoAdapter)parent.getAdapter();
            // get selected item on the list
            ApplicationInfo appInfo = (ApplicationInfo)appInfoAdapter.getItem(pos);
            // launch the selected application
            Utilities.launchApp(parent.getContext(), getPackageManager(), appInfo.packageName);
        }

    });

    // implement event when an item on list view is selected via long-click for drag and drop
    mListAppInfo.setOnItemLongClickListener(new OnItemLongClickListener(){

        @Override
        public boolean onItemLongClick(AdapterView<?> parent, View view,
                int pos, long id) {
            // TODO Auto-generated method stub
            // get the list adapter
            AppInfoAdapter appInfoAdapter = (AppInfoAdapter)parent.getAdapter();
            // get selected item on the list
            ApplicationInfo appInfo = (ApplicationInfo)appInfoAdapter.getItem(pos);
            // launch the selected application
            Utilities.launchApp(parent.getContext(), getPackageManager(), appInfo.packageName);
            return true;
        }


    });
}
}

Here is line 61:

Drag_and_Drop_App.this.adapter.getFilter().filter(cs);

I just finished adding a filter so I might have messed up somewhere along the line:

package com.example.awesomefilebuilderwidget;

import java.util.ArrayList;
import java.util.List;

import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.ImageView;
import android.widget.TextView;

public class AppInfoAdapter extends BaseAdapter implements Filterable {
private Context mContext;
private List<ApplicationInfo> mListAppInfo;
private PackageManager mPackManager;
private List<ApplicationInfo> originalListAppInfo;
private Filter filter;

public AppInfoAdapter(Context c, List<ApplicationInfo> listApp, PackageManager pm) {
    mContext = c;
    this.originalListAppInfo = this.mListAppInfo = listApp;
    mPackManager = pm;
    }

@Override
public int getCount() {
    return mListAppInfo.size();
}

@Override
public Object getItem(int position) {
    return mListAppInfo.get(position);
}

@Override
public long getItemId(int position) {
    return position;
}

@Override
public View getView(int position, View convertView, ViewGroup parent) {
    // get the selected entry
    ApplicationInfo entry = (ApplicationInfo) mListAppInfo.get(position);

    // reference to convertView
    View v = convertView;

    // inflate new layout if null
    if(v == null) {
        LayoutInflater inflater = LayoutInflater.from(mContext);
        v = inflater.inflate(R.layout.layout_appinfo, null);
    }

    // load controls from layout resources
    ImageView ivAppIcon = (ImageView)v.findViewById(R.id.ivIcon);
    TextView tvAppName = (TextView)v.findViewById(R.id.tvName);
    TextView tvPkgName = (TextView)v.findViewById(R.id.tvPack);

    // set data to display
    ivAppIcon.setImageDrawable(entry.loadIcon(mPackManager));
    tvAppName.setText(entry.loadLabel(mPackManager));
    tvPkgName.setText(entry.packageName);

    // return view
    return v;
}
@Override
public Filter getFilter() {
    if(filter == null) {
        filter = new Filter() {
            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                List<ApplicationInfo> myFilteredAppList = new ArrayList<ApplicationInfo>();
                constraint = constraint.toString().toLowerCase();

                for (ApplicationInfo appInfo : originalListAppInfo) {
                    String somefield = appInfo.name;
                    if (somefield.toLowerCase().contains(constraint.toString())) {
                        myFilteredAppList.add(appInfo);
                    }
                }
                results.count = myFilteredAppList.size();
                results.values = myFilteredAppList;
                return results;
            }

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                mListAppInfo = (List<ApplicationInfo>)results.values;
                notifyDataSetChanged();
            }
        };
    }
    return filter;
}

}

The one line I am worried about is this line in my filter:

                        String somefield = appInfo.name;
                    if (somefield.toLowerCase().contains(constraint.toString())) {

I'm not sure what field I should filter in appInfo. If it helps any here is my xml layout (snippet):

                <!-- Editext for Search -->
<EditText android:id="@+id/inputSearch"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:hint="@string/Search_applications"
    android:inputType="textVisiblePassword"/>

<ListView
    android:id="@+id/lvApps"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"     

What's the problem?

ADDED: enter image description here

2
  • 1
    This is not the resolution or the problem but you should defenitly read this... Commented Oct 18, 2013 at 16:27
  • Originally it used a "get" method instead of just appInfo.name (so it was originally "appInfo.getsomefield") if that's what your asking for Commented Oct 18, 2013 at 16:32

2 Answers 2

1

I completely agree with Mikel's comment, there's a lot of nested calls going on in your code, which makes it 1. difficult to read and 2. difficult to debug.

I haven't had a chance to test, but I'm wondering if the call Drag_and_Drop_App.this.adapter is coming back null. If you want to test where the null is coming from, write a quick test like so:

public void onTextChanged(CharSequence cs, int arg1, int arg2, int arg3) {
    // When user changed the Text
    // Drag_and_Drop_App.this.adapter.getFilter().filter(cs);  
     if (Drag_and_Drop_App.this.adapter == null){
         // some print statement saying it is null
     }
        Drag_and_Drop_App.this.adapter.getFilter().filter(cs);

    }

I somehow suspect that you're not declaring adapter correctly. You haven't declared it static, yet you're trying to call it as such. It's not the best practice to have a whole bunch of global static variables, instead you should be more inclined to write "getter" and "setter" methods such as

public void setAdapter(AppInfoAdapter adapter){
    this.adapter = adapter;
}

public AppInfoAdapter getAdapter(){
    return this.adapter
}

But try declaring adapter correctly, see if that fixes the immediate problem.

EDIT:

Like I said, while this isn't the best practice, see if declaring adapter as static will at least get you a little further.

public static AppInfoAdapter adapter;
Sign up to request clarification or add additional context in comments.

7 Comments

Yes my adapter is coming back as null
How would I declare the adapter as static? Didn't I already declare the adapter when I created it and then at the top of the class?
see my edit. No, you declared it as AppInfoAdapter adapter, but that does not automatically make the variable static.
Sorry about the slow response my SDK kept messing up for a while there. And no it didn't change anything, I still get the same errors as before
See the other answer as well. I had the right idea about it being null, but I believe I was wrong about why.
|
1

You have already declared AppInfoAdapter as member variable. Inside oncreate It should be:

adapter = new AppInfoAdapter(this, (List<ApplicationInfo>)   Utilities.getInstalledApplication(this), getPackageManager());

not

AppInfoAdapter  adapter = new AppInfoAdapter(this, (List<ApplicationInfo>)   Utilities.getInstalledApplication(this), getPackageManager());

6 Comments

I didn't notice that. Also take into account this answer.
also remove @SuppressWarnings("unchecked")
I get a different error here (Note updated question--look at the picture)
I think it's interfering with this line: public AppInfoAdapter(Context c, List<ApplicationInfo> listApp, PackageManager pm) { in my AppInfoAdapter class
Actually nevermind I fixed that error. I'll test it out and let you know the result!
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.