-1

I am scheduling few functions by using timer handler.This is what happens.

When i press the button the timer starts sending sms and it opens another activity. Then in the another activity i have put the stop button to terminate the timer and return back to main activity. The timer terminates but it crashes the app and return back to main activity.

Here is the code

MainActivity.java

public class MainActivity extends FragmentActivity{
     protected static final int CONTACT_PICKER_RESULT = 0;


    int count=0;


     private RadioButton radioBtnten;
      private RadioButton radioBtnone;

   Button sendBtn,contact;
   EditText txtphoneNo;
   EditText txtMessage;
   GPSTracker gps;
   Timer timer;

    TimerTask timerTask;
    final Handler handler = new Handler();
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      LocationManager service = (LocationManager) getSystemService(LOCATION_SERVICE);
      boolean enabled = service.isProviderEnabled(LocationManager.GPS_PROVIDER);
      if (!enabled) 
      {
        Toast.makeText(getApplicationContext(), "Your GPS IS NOT ON SWITCH IT ON HERE",Toast.LENGTH_LONG).show();
        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
        startActivity(intent);
      } 
      radioBtnten=(RadioButton)findViewById(R.id.ten);
      radioBtnone=(RadioButton)findViewById(R.id.one);
      sendBtn = (Button) findViewById(R.id.btnSendSMS);
      txtphoneNo= (EditText) findViewById(R.id.editTextPhoneNo);
     contact = (Button)findViewById(R.id.contact);
      //txtMessage //= (EditText) findViewById(R.id.editTextSMS);
      gps = new GPSTracker(MainActivity.this);

      contact.setOnClickListener(new View.OnClickListener() {
          public void onClick(View view) {
              Intent intent = new Intent(Intent.ACTION_PICK,ContactsContract.Contacts.CONTENT_URI);
              intent.setType(ContactsContract.CommonDataKinds.Phone.CONTENT_TYPE);
              startActivityForResult(intent, CONTACT_PICKER_RESULT);

          }
       });


      sendBtn.setOnClickListener(new View.OnClickListener() {
         public void onClick(View view) {
             startTimer();
            sendSMSMessage();
            Intent toAnotherActivity = new Intent(MainActivity.this, maps.class);
            startActivityForResult(toAnotherActivity, 0);

         }
      });
   }


   public void startTimer() {
        //set a new Timer
        timer = new Timer();

        //initialize the TimerTask's job
        initializeTimerTask();

        //schedule the timer, after the first 5000ms the TimerTask will run every 10000ms//
         if(radioBtnten.isChecked()==true)
        timer.schedule(timerTask, 5000, 10000);
        // if(radioBtn2.isSelected()==true)
         else if(radioBtnone.isChecked()==true)
        timer.schedule(timerTask, 5000, 1000);
    }
   public void initializeTimerTask() {

        timerTask = new TimerTask() {
            public void run() {

                //use a handler to run a toast that shows the current timestamp
                handler.post(new Runnable() {
                    public void run() {
                        //get the current timeStamp


                        Toast.makeText(getApplicationContext(), "your message has been sent, the message(s) sent are:-"+count++,Toast.LENGTH_LONG).show();
                        sendSMSMessage();

                        //show the toast


                    }
                });
            }
        };
    }

   public void stoptimertask(View v) 
   {
        //stop the timer, if it's not already null

       Toast.makeText(getApplicationContext(), "Stop button pressed",Toast.LENGTH_LONG).show();

        if (timer != null) 
        {
            timer.cancel();
            timer = null;
        }
    }
   protected void sendSMSMessage() {
      Log.i("Send SMS", "");
    double latitude = gps.getLatitude();
    double longitude = gps.getLongitude();

      String phoneNo = txtphoneNo.getText().toString();
      String message = "These are my co-ordinates:-"+ latitude + ", " + longitude; 

      try {
         SmsManager smsManager = SmsManager.getDefault();
         smsManager.sendTextMessage(phoneNo, null, message, null, null);
         Toast.makeText(getApplicationContext(), "SMS sent.",
         Toast.LENGTH_LONG).show();
      } catch (Exception e) {
         Toast.makeText(getApplicationContext(),
         "SMS faild, please try again.",
         Toast.LENGTH_LONG).show();
         e.printStackTrace();
      }
   }

The next activity is this

maps.java

public class maps extends FragmentActivity implements LocationListener {
MainActivity maine= new MainActivity();
    GoogleMap googleMap;
    Button stop;
    Timer timer;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        //show error dialog if GoolglePlayServices not available
        if (!isGooglePlayServicesAvailable()) {
            finish();
        }
        setContentView(R.layout.maps);
        stop = (Button)findViewById(R.id.stop);
        stop.setOnClickListener(new View.OnClickListener()
        {
            public void onClick(View aView)
                        {
                                maine.stoptimertask(aView);
                               Intent toAnotherActivity = new Intent(aView.getContext(), MainActivity.class);
                               startActivityForResult(toAnotherActivity, 0);
                               //stop the timer, if it's not already null
                               Toast.makeText(getApplicationContext(), "Stop button pressed",Toast.LENGTH_LONG).show();

                        }
        }); 

i created an object of mainactivity and called the stoptimertask method. The app crashes with this log cat :-

 FATAL EXCEPTION: main
Process: com.example.textmessage, PID: 27301
 java.lang.NullPointerException: Attempt to invoke virtual method 'android.content.Context android.content.Context.getApplicationContext()' on a null object reference
    at android.content.ContextWrapper.getApplicationContext(ContextWrapper.java:105)
    at com.example.textmessage.MainActivity.stoptimertask(MainActivity.java:129)
    at com.example.textmessage.maps$1.onClick(maps.java:42)
    at android.view.View.performClick(View.java:4756)
    at android.view.View$PerformClick.run(View.java:19749)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:135)
    at android.app.ActivityThread.main(ActivityThread.java:5221)
    at java.lang.reflect.Method.invoke(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:372)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)

What i want is when the button stop is pressed in maps.java, the sending sms function should stop and it should return back to MainActivity.java

2 Answers2

2

You can't create an Activity by using new. It will not be a valid activity. Only the Android framework can create a valid Activity object. To start a new Activity, call startActivity. WHile using new to create an Activity will compile, that object will not be properly initialized and weird crashes will result.

Gabe Sechan
  • 90,003
  • 9
  • 87
  • 127
  • i am not trying to create an activity by new, i am just getting the method from mainactivity. –  Feb 22 '15 at 18:52
  • Yes you are- you have the line MainActivity maine= new MainActivity(); in your code – Gabe Sechan Feb 22 '15 at 18:53
  • Regardless- calling directly into another activity like that is a bad idea. There's at least a dozen ways I can think of that will cause it to have really bad results. Activities should be independent and not call functions on each other- ever. If you must communicate between activities it should be by either return codes from finishing activities or by changing singleton data shared between them. I'm not sure exactly what you're trying to accomplish, but there's almost certainly a better way. – Gabe Sechan Feb 22 '15 at 18:57
0

The maine.stoptimertask(aView); does not contain the correct instance.

Basically you have to in your

stop.setOnClickListener (new View.OnClickListener ()
{
            public void onClick(View aView)
            {
                 Intent returnIntent = new Intent();
                 setResult(RESULT_OK,returnIntent);
                 this.finish();
                 //stop the timer, if it's not already null
                 Toast.makeText(getApplicationContext(), "Stop button pressed",Toast.LENGTH_LONG).show();
             }
});

returning to MainActivity the value you want to go there and implement a

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check which request we're responding to
    if (requestCode == 0) { // because you startActivityForResult(toAnotherActivity, 0);
        // Make sure the request was successful
        if (resultCode == RESULT_OK) {
            stoptimertask(); // forget view you don't need
        }
    }
}

to find out that there was an action in your activity maps.

See documentation for getting a result from an Activity in this link: http://developer.android.com/training/basics/intents/result.html

Johnitro
  • 31
  • 6
  • Can you be more elaborate ? –  Feb 22 '15 at 18:54
  • such as [Gabe Sechan](http://stackoverflow.com/questions/28661411/killing-a-task-in-android-by-handler/28661678?noredirect=1#comment45618885_28661594) said. you to doing this maine.stoptimertask (Aview); these trying to access something that does not exist, because before you did MainActivity maine MainActivity = new (); and so not these accessing the instance you wish to obtain. I go edit my answer. – Johnitro Feb 22 '15 at 19:04