2017-02-13 3 views
1

So auf einer App arbeite ich und ich hatte diesen Teil für Tage arbeiten, und nicht, wo es gerade aufgehört ohne Grund arbeiten ...Android: Fragment ist nicht auf Aktivität Fehler angebracht

ich auch hatte den gleichen Fehler, als ich versuchte, ein anderes kopfloses Fragment in meiner MainActivity zu verwenden, aber am Ende das Fragment durch innere Methoden innerhalb der MainActivity ersetzt hatte und alles wieder korrekt funktionierte.

Allerdings kann ich nicht jedes Bit Code umschreiben, nur um Fragmente zu vermeiden. Der Fragmentcode ist unten.

public class IMEIFragment extends Fragment implements ActivityCompat.OnRequestPermissionsResultCallback{ 


    public static final String TAG_IMEI = "IMEILoader"; 
    protected Activity mActivity; 

    private String RecordedIMEI; 
    //public static final String CHECK_INTERNET = "network_connection"; 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     return null; //Do we need this at all? 
    } 

    @Override 
    public void onAttach(Context context) { 
     super.onAttach(context); 
     Activity activity = context instanceof Activity ? (Activity) context : null; 
     mActivity = activity; 
    } 

    //Is this needed? 
    @SuppressWarnings("deprecation") 

    @Override 
    public void onAttach(Activity activity) { 
     activity = getActivity(); 
     if (isAdded() && activity != null) { 
      super.onAttach(activity); 
     } 

     if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) { 
      mActivity = activity; 
     } 
    } 


    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     setRetainInstance(true); 
    } 

    @Override 
    public void onDetach() { 
     super.onDetach(); 
     mActivity = null; 
    } 

    public String loadIMEI(Context context) { 
     if (Build.VERSION.SDK_INT >= 23) { 
      if (ActivityCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) 
        != PackageManager.PERMISSION_GRANTED) { 
       // READ_PHONE_STATE permission has not been granted. 
       requestPermissions(context); 
      } else { 
       // READ_PHONE_STATE permission is already been granted. 
       RecordedIMEI = permissionGrantedActions(context); 
      } 
      if (RecordedIMEI != null) { 
       Log.i("loadIMEIService", "IMEI number returned!"); 
      } 
     } else { 
      // READ_PHONE_STATE permission is already been granted. 
      RecordedIMEI = permissionGrantedActions(context); 
     } 
     if (RecordedIMEI != null) { 
      Log.i("loadIMEIService", "IMEI number returned!"); 
     } 
     return RecordedIMEI; 
    } 
    private void requestPermissions(Context context) { 
     if (ContextCompat.checkSelfPermission(context, Manifest.permission.READ_PHONE_STATE) != PackageManager.PERMISSION_GRANTED) { 
      Log.i("loadIMEIService", "READ_PHONE_STATE permission not granted, asking for it..."); 

      // TODO create proper notification content 


      PermissionHelper.requestPermissions(((PriceActivity) getActivity()), 
        new String[]{Manifest.permission.READ_PHONE_STATE}, 
        Constants.PERM_REQUEST_PHONE_STATE, 
        getString(R.string.notify_perm_title), 
        getString(R.string.notify_perm_body), 
        R.drawable.ic_security); 
     } 
    } 

    // Callback received when a permissions request has been completed. 
    @Override 
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
     boolean isGranted = false; 
     for (int i = 0; i < grantResults.length; i++) 
      if (permissions[i].equals(Manifest.permission.READ_PHONE_STATE) && (grantResults[i] == PackageManager.PERMISSION_GRANTED)) 
       isGranted = true; 
     if (isGranted) { 
      Context context = getActivity().getApplicationContext(); 
      permissionGrantedActions(context); 
     } 
     else 
      Log.w("loadIMEIService", "READ_PHONE_STATE permission not granted. loadIMEI will not be available."); 
    } 


    public String permissionGrantedActions(Context context) { 
     //Have an object of TelephonyManager 
     TelephonyManager tm =(TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE); 
     //Get IMEI Number of Phone 
     String IMEINumber = tm.getDeviceId(); 

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

Fehler ist unten:

E/AndroidRuntime: FATAL EXCEPTION: main 
        Process: com.android.project1, PID: 5498 
        java.lang.RuntimeException: Unable to start activity ComponentInfo{com.android.project1/com.android.project1.main.MainActivity}: java.lang.IllegalStateException: Fragment IMEIFragment{3e80da7 IMEILoader} not attached to Activity 
         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.IllegalStateException: Fragment IMEIFragment{3e80da7 IMEILoader} not attached to Activity 
         at android.app.Fragment.getResources(Fragment.java:805) 
         at android.app.Fragment.getString(Fragment.java:827) 
         at com.android.project1.fragments.IMEIFragment.requestPermissions(IMEIFragment.java:107) 
         at com.android.project1.fragments.IMEIFragment.loadIMEI(IMEIFragment.java:80) 
         at com.android.project1.main.MainActivity.onCreate(MainActivity.java:108) 
         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)  

Und hier ist der relevante Teil meiner MainActivity:

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

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

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

     if (mFragment == null) { 
      mFragment = new IMEIFragment(); 
      getFragmentManager().beginTransaction() 
        .add(mFragment, "IMEILoader").commit(); 
     } 
     if (mFragment != null) { 
      mNumber = mFragment.loadIMEI(MainActivity.this); 
      mDeviceCode.setText(Html.fromHtml("<b>IMEI</b>: " + mNumber)); 
     } 

Ich hatte buchstäblich genau über eine Woche lang arbeiten gleichen Code. Weiß jemand, was das Problem sein könnte?

Edit 1: Der Fehler zeigt auf requestPermissions in meinem Fragmente

+0

Warum mehrere Überschreibungen auf onAttach()? – CSmith

+0

@CSmith Wenn ich mich recht erinnere, war es für verschiedene Build-Versionen, da einige Methoden veraltet waren. Ich werde versuchen, eins von ihnen herauszunehmen und zu sehen, ob es irgendwas betrifft. – Zack

+0

Sie können getActivity() nicht von onAttach() aufrufen und erwarten, dass es funktioniert. Werden beide onAttach() - Überschreibungen und onDetach() los, werden sie nicht benötigt. Wenn Sie Zugriff auf einen Kontext benötigen, verwenden Sie getActivity(). Befolgen Sie die Anleitung von @Blattman – CSmith

Antwort

0

Fragmente sollten selbst so viel wie möglich enthalten sein. Sie rufen direkt von der Aktivität

  Caused by: java.lang.IllegalStateException: Fragment IMEIFragment{3e80da7 IMEILoader} not attached to Activity 
       at android.app.Fragment.getResources(Fragment.java:805) 
       at android.app.Fragment.getString(Fragment.java:827) 
       at com.android.project1.fragments.IMEIFragment.requestPermissions(IMEIFragment.java:107) 
       at com.android.project1.fragments.IMEIFragment.loadIMEI(IMEIFragment.java:80) 
       at com.android.project1.main.MainActivity.onCreate(MainActivity.java:108) 

in Ihr IMEIFragment auf. Sie können das nicht tun. Das Hinzufügen des Fragments über eine Transaktion aus der Aktivität ist eine asynchrone Operation. Z. B. wenn die commit() Methode abgeschlossen ist, wird das Fragment nicht initialisiert. Darüber hinaus haben Sie keine Möglichkeit zu wissen, wann es initialisiert ist. Deshalb sollte es in sich geschlossen sein. Das Fragment entscheidet, wann loadIMEI() aufgerufen wird, nicht die Aktivität.

Wenn Sie wirklich es müssen durch die Aktivität initiiert werden, können Sie einen Rückruf aus dem Fragment auf die Aktivität hinzufügen wie,

void onFragmentReady(Fragment f); 

Oder etwas.

Und ja, onCreateView() sollte etwas zurückgeben. Wenn Ihr Fragment wirklich keine Benutzeroberfläche hat, brauchen Sie es nicht als Fragment.

+0

Ich denke, ich habe das meiste von dem, was du sagen willst. Also sollte ich das in meiner MainActivity ändern >> if (mFragment! = Null) { mNumber = mFragment.loadIMEI (MainActivity.this); mDeviceCode.setText (Html.fromHtml ("IMEI:" + mNummer)); } << to this>> if (mFragment! = Null && mFragment.isAdded()) { mNummer = mFragment.loadIMEI (MainActivity.this); mDeviceCode.setText (HTML.fromHtml ("IMEI:" + mNummer)); } << – Zack

+0

Oder sollte ich das loadIMEI innerhalb OnResume() statt innerhalb der Aktivität aufrufen? – Zack

+0

Ihre Aktivität sollte keine Methode für Ihre Fragmentklasse aufrufen. Ihr Fragment sollte 'loadIMEI()' als Teil seines Lebenszyklus aufrufen. Beachten Sie meine obigen Kommentare zu: Brauchen Sie wirklich ein Fragment? –

Verwandte Themen