2017-01-25 5 views
0

У меня есть основное действие и безголовый фрагмент.
Фрагмент без головы должен получить номер IMEI телефона для записи и вернуться к основной операции.
У меня была эта ошибка в течение нескольких часов, и я не могу ее потрясти.Android Studio: ошибка java.lang.NullPointerException, когда безголовый фрагмент называется

Вот 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. 

А вот соответствующая часть кода в 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())); 
     } 

А вот код HeadlessFragment:

//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; 
    } 
} 

Я пробовал разные вещи, но не повезло. Я думаю, getActivity().getApplicationContext() указывает, где нет, что означает, что это называется до того, как безгласный фрагмент привязан к mainactivity?
Я застрял в этом довольно долгое время и нуждаюсь в некоторой помощи.

+0

http://stackoverflow.com/questions/36615896/attempt-to-invoke-virtual-method-android-content-context- android-support-v4-app –

+0

блокировать эту строку 'mActivity = null;' from' onDetach() ' –

+0

@IntelliJAmiya Это все равно дает мне ту же ошибку. – Zack

ответ

0

Изменение Эта линия

mNumber = mFragment.loadIMEI(); 

Для

mNumber = mFragment.loadIMEI(MainActivity.this); 

И ваша функция будет так.

public String loadIMEI(Context context) { 
     //Context context = getActivity().getApplicationContext(); 
     //Activity activity = context instanceof Activity ? (Activity) context : null; 
     //mActivity = activity; 
     // Check if the READ_PHONE_STATE permission is already available. 
     //this.context = getActivity().getApplicationContext(); 

     if (ActivityCompat.checkSelfPermission(context, 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; 
    } 
+0

Так я и раньше. Я попробовал еще раз, чтобы быть в безопасности, но это дает мне ту же ошибку. – Zack

+0

@Zack показать мне свой фрагмент полный код – Amy

+0

Код обновлен. Я оставил прокомментированные части, которые я пытаюсь заставить работать, я подумал, что это может быть полезно. – Zack

2

Я думаю, что вы собираетесь об этой идее «безголовый Фрагмент» неправильно, так как ...

Отрывок представляет собой поведение или часть пользовательского интерфейса в деятельности.

Вам, похоже, нужен статический класс полезности, который содержит контекст и может вызвать некоторые действия с правами. Заберите extends Fragment из кода и других ответов, и это в основном то, с чем вы остались.

Включите его в одноэлементный режим, и вам не нужен параметр контекста во всем мире.

(код тестировался)

не может полностью работать. Например, не знаете, как работает ActivityCompat.OnRequestPermissionsResultCallback ...

Но он предоставляет вам функциональные возможности, не работая вокруг жизненного цикла фрагмента.

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; 
    } 


} 

И вы можете использовать его в деятельности, как

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) { 
     ... 

    } 
+0

Тестирование этого сейчас. Почему здесь используется неверный фрагмент? Только для моей справки. – Zack

+1

Я написал это как отдельный класс, но вы можете его вложить. В любом случае, я никогда не использовал безгласный фрагмент, лично. Насколько я могу судить по обоим проектам - это способы сделать то же самое. Однако вы можете использовать этот класс из всех видов деятельности, и это шаблон Java, который я изучил отдельно от Android. http://luboganev.github.io/blog/headless-fragments/ –

+0

Разрешение пользователя является проблемой. Есть ли способ сделать это с использованием вышеуказанного метода? – Zack