2017-02-13 54 views
1

所以我工作的一个应用程序,我有这部分的日工作,进出没有它只是无缘无故拦工作...安卓片段未连接到活动错误

我也当我尝试在我的MainActivity中使用另一个无头片段时出现同样的错误,但最终用MainActivity内部的方法替换片段,并且所有内容都恢复正常工作。

但是,我不能重写每一点我只是为了避免使用片段的代码。片段代码如下。

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

误差如下:

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)  

这是我的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)); 
     } 

我字面上完全相同的代码了一个多星期的工作。任何人都知道可能是什么问题?

编辑1:错误指向requestPermissions我的片段内

+0

为什么多重覆盖onAttach()? – CSmith

+0

@CSmith如果我没有记错,它是针对不同的构建版本,因为某些方法已被弃用。我会尝试将其中一个出来,看看它是否影响任何东西。 – Zack

+0

你当然不能从onAttach()调用getActivity()并期望它能够工作。摆脱onAttach()覆盖和onDetach(),它们不是必需的。如果您需要访问上下文,请使用getActivity()。遵循@Blattman的指导 – CSmith

回答

0

片段应自包含尽可能多的。您正在从活动直接拨打您的IMEIFragment,

  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) 

您不能那样做。通过活动中的事务添加片段是异步操作。例如,当commit()方法完成时,片段不被初始化。而且,你无法知道什么时候被初始化。这就是为什么它应该是自成体系的。片段决定何时调用loadIMEI(),而不是活动。

如果你真的需要它由活动发起,您可以从片段添加一个回调的活动一样,

void onFragmentReady(Fragment f); 

什么的。

是的,onCreateView()应该返回一些东西。如果你的片段根本没有任何UI,你不需要它是一个片段。

+0

我想我最想说的是你想说的话。所以,在我的MainActivity中,我应该改变这个>> if(mFragment!= null)mNumber = mFragment.loadIMEI(MainActivity.this); mDeviceCode.setText(Html.fromHtml(“IMEI:”+ mNumber));如果(mFragment!= null && mFragment.isAdded()){ } mNumber = mFragment.loadIMEI mDeviceCode.setText(Html。fromHtml(“IMEI:”+ mNumber)); } << – Zack

+0

或者我应该在onResume()内而不是从Activity中调用loadIMEI? – Zack

+0

你的活动不应该调用你的片段类的任何方法。你的片段应该把'loadIMEI()'作为其生命周期的一部分。考虑我上面的评论重新:你真的需要一个片段? –