Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
176 views
in Technique[技术] by (71.8m points)

Android Studio: Error of java.lang.NullPointerException when the headlessfragment called

I have a main Activity and a headless Fragment.
The headless Fragment is supposed to get the IMEI number of the phone to be recorded and returned to the main Activity.
I had this bug for a few hours now and I can't seem to shake it off.

Here's the logcat:

E/AndroidRuntime: FATAL EXCEPTION: main
                      Process: com.androidproject.example, PID: 5418
                      java.lang.RuntimeException: Unable to start activity ComponentInfo{com.androidproject.example/com.androidproject.example.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.app.Activity.getApplicationContext()' on a null object reference
                          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                          at android.app.ActivityThread.-wrap11(ActivityThread.java)
                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                          at android.os.Handler.dispatchMessage(Handler.java:102)
                          at android.os.Looper.loop(Looper.java:148)
                          at android.app.ActivityThread.main(ActivityThread.java:5417)
                          at java.lang.reflect.Method.invoke(Native Method)
                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                       Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.app.Activity.getApplicationContext()' on a null object reference
                          at com.androidproject.example.HeadlessFragment.loadIMEI(HeadlessFragment.java:110)
                          at com.androidproject.example.MainActivity.onCreate(MainActivity.java:40)
                          at android.app.Activity.performCreate(Activity.java:6237)
                          at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                          at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                          at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)?
                          at android.app.ActivityThread.-wrap11(ActivityThread.java)?
                          at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)?
                          at android.os.Handler.dispatchMessage(Handler.java:102)?
                          at android.os.Looper.loop(Looper.java:148)?
                          at android.app.ActivityThread.main(ActivityThread.java:5417)?
                          at java.lang.reflect.Method.invoke(Native Method)?
                          at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)?
                          at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)?
    Application terminated.

And here's the relevant part of the code in the MainActivity:

protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mDeviceCode = (TextView)findViewById(R.id.device_code);

        // Initializing headless fragment
        mFragment =
                (HeadlessFragment) getFragmentManager()
                        .findFragmentByTag("IMEILoader");

        if(mFragment == null) {
            mFragment = new HeadlessFragment();
            getFragmentManager().beginTransaction()
                    .add(mFragment, "IMEILoader").commit();
        }
        if(mFragment != null){
            mNumber = mFragment.loadIMEI(); //Here's the error
            mDeviceCode.setText(Html.fromHtml("<b>IMEI</b>: " + mFragment.loadIMEI()));
        }

And here's the HeadlessFragment code:

    //Called when the 'loadIMEI' function is triggered.
    public String loadIMEI() {

        if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.READ_PHONE_STATE)
                != PackageManager.PERMISSION_GRANTED) {
            // READ_PHONE_STATE permission has not been granted.
            requestPermissions();
        } else {
            // READ_PHONE_STATE permission is already been granted.
            RecordedIMEI = permissionGrantedActions();
        }
        if(RecordedIMEI != null) {
            Log.i("loadIMEIService", "IMEI number returned!");
        }
        return RecordedIMEI;
    }

    public String permissionGrantedActions() {


        //Get IMEI Number of Phone
        TelephonyManager tm =(TelephonyManager)getActivity().getSystemService(Context.TELEPHONY_SERVICE);

        String IMEINumber = tm.getDeviceId();

        //RecordedIMEI = IMEINumber;

        if(IMEINumber != null) {
            Log.i("IMEI Loader", "IMEI number recorded!");
        }
        return IMEINumber;
    }
}

I tried different things but no luck. I think getActivity().getApplicationContext() is pointing no where, which means this is being called before headless fragment is attached to mainactivity?
I've been stuck on this for quite some time and need some help.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

I think you're going about this "headless Fragment" idea wrong since...

A Fragment represents a behavior or a portion of user interface in an Activity.

You seem to want a static utility class that holds a Context and can call some permission things. Take away the extends Fragment from the code and other answer(s), and this is basically what you are left with.

Turn it into a singleton, and you don't need the Context parameter everywhere.

(code untested)

May not completely work. For example, not sure how the ActivityCompat.OnRequestPermissionsResultCallback works...

But it exposes the functionality you need without working around a Fragment lifecycle.

public final class IMEILoader {
    public static IMEILoader mInstance;
    private Context mContext;

    private IMEILoader() {}
    private IMEILoader(Context c) {
        this.mContext = c;
    }

    // Singleton pattern
    public static IMEILoader getInstance(Context c) {
        if (!(c instanceof ActivityCompat.OnRequestPermissionsResultCallback)) {
            throw new Exception("Passed context not implementing permission callbacks");
        }
        if (mInstance == null) mInstance = new IMEILoader(c);
        return mInstance;
    }

    public String load() {
        String recordedIMEI = null;

        if (ActivityCompat.checkSelfPermission(mContext, Manifest.permission.READ_PHONE_STATE)
            != PackageManager.PERMISSION_GRANTED) {
            // READ_PHONE_STATE permission has not been granted.
            requestPermissions();
        } else {
            // READ_PHONE_STATE permission is already been granted.
            recordedIMEI = permissionGrantedActions();
        }
        if(recordedIMEI != null) {
            Log.i("loadIMEIService", "IMEI number returned!");
        }
        return recordedIMEI;
    }    

    public String permissionGrantedActions() {
        return null;
    }


}

And you can use that in the Activity like

class FooActivity extends AppCompatActivity impelements ActivityCompat.OnRequestPermissionsResultCallback {
    private IMEILoader loader;
    ...  

    public void onCreate(Bundle b) {
        ...
        loader = IMEILoader.getInstance(MainActivity.this);
        String blah = loader.load();
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        ...

    }

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...