Reputation: 1998
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
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