Poonam Anthony
Poonam Anthony

Reputation: 1998

android activity with fragments exits when orientation of the device is changed

My app consists of one activity made up of two fragments. The first fragment is added through XML and the second fragment is added dynamically depending on the inputs from the first fragment. The app works perfectly on the emulator. But when tested on a real device (Samsung galaxy tab) the app simply exits upon changing the device orientation (without crashing and without any errors). I'm using android 4.0. I searched for this problem a lot and tried out the various solutions given on this site and others, but the problem persists. I would also like to add that the version of my app which does not use fragments works fine on both orientations.

the main layout file (activity_main.xml)

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" 
android:orientation="vertical" >

<fragment 
android:name="androiapps.autoqos.FirstFragment"
android:id="@+id/fragment"
android:layout_weight="2"
android:layout_width="fill_parent"
android:layout_height="0dp" 
/>

<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_weight="1"
android:layout_height="0dp"
android:orientation="vertical"
android:id="@+id/frameLayout" >

</FrameLayout>
</LinearLayout>

MainActivity.java

public class MainActivity extends FragmentActivity implements OnInputReceivedListener, MessageSendListener{
//variable declarations 

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

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.activity_main, menu);
    return true;
}

@Override
public void onConfirm(Bundle bundle) {
    // TODO Auto-generated method stub
    if(bundle!=null){
        //int PT = bundle.getInt("PT");
        System.out.println("Got:"+bundle.getString("ip")+bundle.getString("port")+bundle.getString("tcpip")
                +bundle.getString("tcpport")+bundle.getInt("PT",0));
        udpHost=bundle.getString("ip");
        udpPort=bundle.getString("port");
        tcpHost=bundle.getString("tcpip");
        tcpPort=bundle.getString("tcpport");
        pType=bundle.getInt("pType",0);
        FragmentManager fragmentManager = getSupportFragmentManager();
        MessageFragment fragment = new MessageFragment();
        fragment.setArguments(bundle);
        FragmentTransaction transaction = fragmentManager.beginTransaction();
        transaction.replace(R.id.frameLayout, fragment);
        transaction.commit();
    }
}

@Override
public void send(Bundle bundle) {
    // TODO Auto-generated method stub
    if(bundle==null)
        return;

    msg = bundle.getString("msg");
    delay = bundle.getInt("delay",0);
    System.out.println("Got: "+msg+delay);          
    startTransmission();
}
void startTransmission(){
    System.out.println("\nTrying to send data");
    sendFilter = new IntentFilter(UdpResponseReceiver.ACTION_RESP1);
    sendFilter.addCategory(Intent.CATEGORY_DEFAULT);
    receiver1 = new UdpResponseReceiver(); 
    receiveFilter = new IntentFilter(UdpHandlerReceiver.ACTION_RESP2);
    receiveFilter.addCategory(Intent.CATEGORY_DEFAULT);
    receiver2 = new UdpHandlerReceiver();
    registerReceiver(receiver1, sendFilter);
    registerReceiver(receiver2, receiveFilter);
    udpServiceIntent = new Intent(MainActivity.this,UdpSendService.class);
    udpReceiveIntent = new Intent(MainActivity.this,UdpReceiveService.class);
    udpServiceIntent.putExtra("host",udpHost);
    udpServiceIntent.putExtra("port", udpPort);
    udpServiceIntent.putExtra("msg",msg);
    udpServiceIntent.putExtra("delay",delay);
    udpServiceIntent.putExtra("pType",pType);
    startService(udpServiceIntent);
    udpReceiveIntent.putExtra("tcpHost", tcpHost);
    udpReceiveIntent.putExtra("tcpPort", tcpPort);
    startService(udpReceiveIntent);
}
public class UdpResponseReceiver extends BroadcastReceiver {
    public static final String ACTION_RESP1 = "com.example.udpmessageclient.intent.action.MESSAGE_PROCESSED";
    @Override
    public void onReceive(Context context, Intent intent) {

        // Update UI, new "message" processed by SimpleIntentService
        System.out.println(intent.getStringExtra(UdpSendService.PARAM_OUT_MSG));

    }      
}   
public class UdpHandlerReceiver extends BroadcastReceiver {
    public static final String ACTION_RESP2 = "com.example.udpmessageclient.intent.action.MESSAGE_RECEIVED";
    @Override
    public void onReceive(Context context, Intent intent) {

        // Update UI, new "message" processed by SimpleIntentService
        System.out.println("Received message from server: "+intent.getStringExtra(UdpReceiveService.OUT_MSG));

    }    
}

@Override
public void stop() {
    // TODO Auto-generated method stub
    endTransmission();
    Button btn = (Button)findViewById(R.id.btn_confirm);
    btn.setEnabled(true);

}
void endTransmission(){
    UdpSendService.send=false;
    if(receiver1!=null && receiver2!=null){
        unregisterReceiver(receiver1);
        unregisterReceiver(receiver2);
        receiver1=null;
        receiver2=null;
    }
    //while(stopService(udpReceiveIntent)!=true);
    if(udpReceiveIntent!=null)
        stopService(udpReceiveIntent);
    System.out.println("\nreceive service stopped");
    //while(stopService(udpServiceIntent)!=true);
    if(udpServiceIntent!=null)
        stopService(udpServiceIntent);
    System.out.println("\nsend service stopped");
    return;
}
@Override
public void onBackPressed() {
    if(UdpSendService.send)
        stop();
    finish();

}
@Override
public void onStop() {
    super.onStop();
    stop();
    finish();
}

    }

FirstFragment.java

public class FirstFragment extends Fragment{
//variable declarations
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View contentView = inflater.inflate(R.layout.activity_message_form, null);
    contentView.setDrawingCacheEnabled(false);
    text1 = (EditText) contentView.findViewById(R.id.ip);
    text2 = (EditText) contentView.findViewById(R.id.port);
    text3 = (EditText) contentView.findViewById(R.id.tcpip);
    text4 = (EditText) contentView.findViewById(R.id.tcpport);
    if(onSaveInstance!=null){
        text1.setText(onSaveInstance.getString("ip"));
        text2.setText(onSaveInstance.getString("port"));
        text3.setText(onSaveInstance.getString("tcpip"));
        text4.setText(onSaveInstance.getString("tcpport"));
    }
    button= (Button) contentView.findViewById(R.id.btn_confirm);
    rb1 = (RadioButton) contentView.findViewById(R.id.rbtn_1);
    rb2 = (RadioButton) contentView.findViewById(R.id.rbtn_2);
    rb3 = (RadioButton) contentView.findViewById(R.id.rbtn_3);
    rb4 = (RadioButton) contentView.findViewById(R.id.rbtn_4);
    confirmButtonListener = new OnClickListener(){
        public void onClick(View view){
            button.setEnabled(false);
            if (rb1.isChecked())
                PT = 0;
            else if (rb2.isChecked())
                PT = 1;
            else if (rb3.isChecked())
                PT = 2;
            else if (rb4.isChecked())
                PT = 3;
            else
                PT = 0;
            ip = text1.getText().toString().trim();
            port = text2.getText().toString().trim();
            tcpip=text3.getText().toString().trim();
            tcpport=text4.getText().toString().trim();
            if(ip=="" || port=="" || tcpip == "" || tcpport ==""){
                Toast.makeText(getActivity(), "Please fill in all the fields", Toast.LENGTH_SHORT).show();
            }
            else{
                Bundle b = new Bundle();
                b.putString("ip",ip);
                b.putString("port", port);
                b.putString("tcpip",tcpip);
                b.putString("tcpport", tcpport);
                b.putInt("pType", PT);

                if ( listener != null ){
                    System.out.println("Bundle:"+ip+port+tcpip+tcpport+PT);
                    listener.onConfirm(b);
                }
            }
            }
    };
    return contentView;
}
@Override
public void onStart(){
super.onStart();
button.setOnClickListener(confirmButtonListener);
}
@Override
public void onAttach(Activity activity) {
// TODO Auto-generated method stub
super.onAttach(activity);
try {
    listener = (OnInputReceivedListener)activity;
}catch (ClassCastException e) {
    Toast.makeText( activity, "Activity must implement this interface.", Toast.LENGTH_SHORT).show();
}
}
public interface OnInputReceivedListener{
    public void onConfirm(Bundle bundle);
}
@Override
public void onPause(){
    super.onPause();
    onSaveInstance = new Bundle();
    onSaveInstance.putString("udpHost", ip);
    onSaveInstance.putString("udpPort", port);
    onSaveInstance.putString("tcpHost", tcpip);
    onSaveInstance.putString("tcpPort", tcpport);

}
@Override
public void onResume(){
    super.onResume();
    if(onSaveInstance!=null){
        text1.setText(onSaveInstance.getString("ip"));
        text2.setText(onSaveInstance.getString("port"));
        text3.setText(onSaveInstance.getString("tcpip"));
        text4.setText(onSaveInstance.getString("tcpport"));
    }
}
}

MessageFragment.java

public class MessageFragment extends Fragment{
//variable declarations
public View onCreateView(LayoutInflater inflater, ViewGroup container,
        Bundle savedInstanceState) {
    View contentView = inflater.inflate(R.layout.activity_message, null);
    contentView.setDrawingCacheEnabled(false);
    msgText = (EditText) contentView.findViewById(R.id.msg);
    sendBtn = (Button) contentView.findViewById(R.id.btn_send);
    stopBtn = (Button) contentView.findViewById(R.id.btn_stop);
    if(onSaveInstance!=null){
        msgText.setText(onSaveInstance.getString("msg"));
        delayField.setText(onSaveInstance.getInt("delay", 0));
    }
    b = getArguments();
    System.out.println("PT="+b.getInt("pType",0));
    if(b!=null){
        int pType = b.getInt("pType");
        if(pType==1 || pType== 3){
            delayField = (EditText) contentView.findViewById(R.id.delay);
            tvDelay = (TextView) contentView.findViewById(R.id.tvDelay);
            tvDelay.setVisibility(View.VISIBLE);
            delayField.setVisibility(View.VISIBLE);
        }
    }
    sendButtonListener=new OnClickListener(){

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            sendBtn.setEnabled(false);
            Bundle b = new Bundle();
            msg=msgText.getText().toString();
            delay=Integer.parseInt(delayField.getText().toString());
            b.putString("msg", msg);
            if(delayField!=null)
                b.putInt("delay",delay);
            if(mListener!=null)
                mListener.send(b);
        }
    };
    stopButtonListener = new OnClickListener(){

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            sendBtn.setEnabled(true);
            mListener.stop();
        }
    };
    return contentView;
}
@Override
public void onStart(){
    super.onStart();
    sendBtn.setOnClickListener(sendButtonListener);
    stopBtn.setOnClickListener(stopButtonListener);
}
@Override
public void onAttach(Activity activity) {
    // TODO Auto-generated method stub
    super.onAttach(activity);
    try {
        mListener = (MessageSendListener)activity;
    }catch (ClassCastException e) {
        Toast.makeText( activity, "Activity must implement this interface.", Toast.LENGTH_SHORT).show();
    }
}
public interface MessageSendListener{
    public void send(Bundle bundle);
    public void stop();
}
@Override
public void onPause(){
    super.onPause();
    onSaveInstance = new Bundle();
    onSaveInstance.putString("msg", msg);
    onSaveInstance.putInt("delay", delay);
}
@Override
public void onResume(){
    super.onResume();
    if(onSaveInstance!=null){
        msgText.setText(onSaveInstance.getString("msg"));
        delayField.setText(onSaveInstance.getInt("delay", 0));
    }
}
}

Upvotes: 1

Views: 660

Answers (2)

Simon
Simon

Reputation: 14472

public void onStop() {
    super.onStop();
    stop();
    finish();

Why finish()? Your app is doing exactly what you coded it to do. When the orientation changes, onStop() is called. You then finish() your activity.

Upvotes: 2

Janmejoy
Janmejoy

Reputation: 2731

Did you use this code

android:configChanges="keyboard|keyboardHidden|orientation"

For more info check this link

Upvotes: 2

Related Questions