killing a task in android by handler - java

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

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.

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

Related

Why does the UI stop updating countdown after restarting the app while using intent service?

I am trying to show a countdown in a textview from a loop inside an Intent Service. I am using the result receiver class for the communication between Intent Service and Activity. It works fine when I start the service for the first time. The textview shows the countdown for each time the loop runs in the service.
But when I close and launch the app again the textview doesn't show the countdown and only shows the hard coded text, while on the other hand the service stills runs in the background.
Here is my code snippet for the MainActivity
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
public static final String RECEIVER_INTENT_EXTRA_NAME = "message_receiver_intent_extra";
private static final String TAG = "MainActivity";
private Intent intent;
MyIntentService myIntentService;
public TextView serviceCountdown;
private Button startButton, stopButton;
private Handler handler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getSupportActionBar().hide();
myIntentService = new MyIntentService();
startButton = findViewById(R.id.startServiceButton);
stopButton = findViewById(R.id.stopServiceButton);
startButton.setOnClickListener(this);
stopButton.setOnClickListener(this);
handler = new Handler();
serviceCountdown = findViewById(R.id.serviceCountdown);
MessageReceiver messageReceiver = new MessageReceiver(handler);
// send intent service
intent = new Intent(this, MyIntentService.class);
intent.putExtra(RECEIVER_INTENT_EXTRA_NAME, messageReceiver);
}
#Override
public void onClick(View v) {
if (startButton.equals(v)) {
ContextCompat.startForegroundService(getApplicationContext(), intent);
}
if (stopButton.equals(v)){
stopService(intent);
}
}
public class MessageReceiver extends ResultReceiver {
public MessageReceiver(Handler handler) {
super(handler);
}
#Override
protected void onReceiveResult(int resultCode, Bundle resultData) {
super.onReceiveResult(resultCode, resultData);
if (resultCode == 1 && resultData != null){
final String countdown = resultData.getString("countdown");
handler.post(new Runnable() {
#Override
public void run() {
serviceCountdown.setText(countdown);
}
});
}
}
}
}
And here is my code for the Intent Service Class
public class MyIntentService extends IntentService {
private static final String CHANNEL_ID = "my_channel_id";
private static final String TAG = "MyIntentService";
public MyIntentService() {
super("MyIntentService");
setIntentRedelivery(true);
}
#Override
public void onCreate() {
super.onCreate();
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent,0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("My Service Title")
.setContentText("This is sample notification text")
.setSmallIcon(R.drawable.ic_battery)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
}
#Override
protected void onHandleIntent(#Nullable Intent intent) {
ResultReceiver resultReceiver = intent.getParcelableExtra(MainActivity.RECEIVER_INTENT_EXTRA_NAME);
Log.d(TAG, "onHandleIntent: called");
synchronized (this) {
for (int i = 10; i >= 0; i--) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Log.d(TAG, "Service is looping : " + i);
Bundle bundle = new Bundle();
bundle.putString("countdown", String.valueOf(i));
resultReceiver.send(1, bundle);
}
}
}
#Override
public void onDestroy() {
Log.d(TAG, "onDestroy: called");
super.onDestroy();
}
}
In the real project, my intention is not to using the loop to show a countdown. It is just for testing and debugging purpose.
Use Local Broadcast Receiver from your service to activity. Now you getting the ResultReceiver from the MainActivity Intent. When the activity destroyed intents are also destroyed.
Use this Broadcast Receiver code in your service class.
LocalBroadcastManager localBroadcastManager =
LocalBroadcastManager.getInstance(this);
Intent sendIntent = new Intent(INTENT_ACTION_KEY);
sendIntent.putExtra(DATA_KEY, data);
localBroadcastManager.sendBroadcast(sendIntent);
Get this local broadcast receiver in your activity.
BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
//Perform your logic.
}
}
};
Make sure you register this broadcast when activity starts and unregister it when stop.
#Override
public void onStart() {
super.onStart();
LocalBroadcastManager.getInstance(this).registerReceiver((broadcastReceiver),
new IntentFilter(INTENT_ACTION_KEY));
}
#Override
public void onStop() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
super.onStop();
}

Try to invoke virtual method on a null object reference [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
I am trying to make a barcode scanner app, and I want to add scan results to a certain list. In the MainActivity, I have a certain button that should send me to MyList activity, but then the app crashes and I don't know how to solve it.
So here is my code:
public class MainActivity extends AbsRuntimePermission implements ZXingScannerView.ResultHandler{
private ZXingScannerView zXingScannerView;
private static final int REQUEST_PERMISSION = 10;
boolean ok = false, chk = false;
private String scanResult;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chk = getIntent().getBooleanExtra("check", chk);
if(chk) {
chk = false;
ok = true;
zXingScannerView = new ZXingScannerView(getApplicationContext());
setContentView(zXingScannerView);
zXingScannerView.setResultHandler(this);
zXingScannerView.startCamera();
}
}
public void scan(View view){
requestAppPermissions(new String[]{Manifest.permission.CAMERA}, R.string.msg, REQUEST_PERMISSION);
ok = true;
zXingScannerView = new ZXingScannerView(getApplicationContext());
setContentView(zXingScannerView);
zXingScannerView.setResultHandler(this);
zXingScannerView.startCamera();
}
#Override
public void onPermissionGranted(int requestCode) {
if(ok)
Toast.makeText(getApplicationContext(), "Permission Granted", Toast.LENGTH_LONG).show();
}
#Override
public void onResume(){
super.onResume();
if(ok)
{
if(zXingScannerView == null)
{
zXingScannerView = new ZXingScannerView(this);
setContentView(zXingScannerView);
}
zXingScannerView.setResultHandler(this);
zXingScannerView.startCamera();
}
}
#Override
protected void onPause() {
super.onPause();
zXingScannerView.stopCamera();
}
#Override
public void handleResult(final Result result) {
scanResult = result.getText();
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setTitle("Result");
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
zXingScannerView.resumeCameraPreview(MainActivity.this);
}
});
builder.setNeutralButton("GO", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
try
{
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(scanResult));
startActivity(intent);
}catch (Exception ex)
{
Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
intent.putExtra(SearchManager.QUERY, scanResult);
startActivity(intent);
}
}
});
builder.setNegativeButton("Add to list", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(MainActivity.this, MyList.class);
intent.putExtra("CODE", scanResult);
startActivity(intent);
}
});
builder.setMessage(scanResult);
AlertDialog alert = builder.create();
alert.show();
}
public void Lista(View view){
Intent iNtent = new Intent(MainActivity.this, MyList.class);
startActivity(iNtent);
}
}`
And this is my error report:
01-12 09:42:26.013 2670-2670/com.example.tchibo.justqr E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.tchibo.justqr, PID: 2670
java.lang.RuntimeException: Unable to pause activity {com.example.tchibo.justqr/com.example.tchibo.justqr.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'void me.dm7.barcodescanner.zxing.ZXingScannerView.stopCamera()' on a null object reference at android.app.ActivityThread.performPauseActivityIfNeeded(ActivityThread.java:3976)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3942)
at android.app.ActivityThread.performPauseActivity(ActivityThread.java:3916)
at android.app.ActivityThread.handlePauseActivity(ActivityThread.java:3890)
at android.app.ActivityThread.-wrap15(Unknown Source:0)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1605)
at android.os.Handler.dispatchMessage(Handler.java:105)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6541)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'void me.dm7.barcodescanner.zxing.ZXingScannerView.stopCamera()' on a null object reference
Actually, it says that is trying to invoke virtual method void me.dm7.barcodescanner.zxing.ZXingScannerView.stopCamera() on a null object reference.
(sorry for the post style but i'm not familiar with it)
Well you create method scan(View view) in this method you initialize your camera(ZXingScannerView ) object but din't call anywhere. have look for solution
in onCreate():
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
chk = getIntent().getBooleanExtra("check", chk);
zXingScannerView = new ZXingScannerView(getApplicationContext());
if(chk) {
chk = false;
ok = true;
zXingScannerView = new ZXingScannerView(getApplicationContext());
setContentView(zXingScannerView);
zXingScannerView.setResultHandler(this);
zXingScannerView.startCamera();
}
}
in onPause()
#Override
protected void onPause() {
super.onPause();
if(zXingScannerView!=null)
zXingScannerView.stopCamera();
}
You can check zXingScannerView before using it.
if (zXingScannerView != null){
zXingScannerView.stopCamera();
}
java.lang.RuntimeException: Unable to pause activity
{com.example.tchibo.justqr/com.example.tchibo.justqr.MainActivity}:
java.lang.NullPointerException: Attempt to invoke virtual method 'void
me.dm7.barcodescanner.zxing.ZXingScannerView.stopCamera()' on a null
object reference
the logcat is telling you the problem, which is this line :
zXingScannerView.stopCamera();
your app is trying to stop something that does not exist !!
trivial solution :
if(zXingScannerView!=null){
zXingScannerView.stopCamera();
}

How do I store data in an object rather than a class

I am trying to create a messaging app with several different xml views/classes:
one for the main menu (MainActivity);
one for the sending message screen (SendMsg);
one for storing sent messages (Logs).
In SendMsg, I want to store my message into an object called msgLog, which I had created in MainActivity. Just for testing, I have set SendMsg to display the Logs class upon pressing the SEND button, and the sent message does indeed appear there.
However, it is not storing it into the msgLog variable that I created, so that I can't access again from MainActivity.
How do I store it into a variable, so that it will always be there when I access it? Any help would be much appreciated.
=========================================================
public class MainActivity extends AppCompatActivity {
Logs msgLog = new Logs();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void sendOnClick (View view){
Intent intent = new Intent("com.example.android.attone.SendMsg");
startActivity(intent);
}
public void logsOnClick (View view){
Intent intent = new Intent(this, Logs.class);
startActivity(intent);
}
}
=========================================================
public class SendMsg extends AppCompatActivity {
EditText txtPhoneNo;
EditText txtMessage;
Button btnSend;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_msg);
txtPhoneNo = (EditText) this.findViewById(R.id.txtPhoneNo);
txtMessage = (EditText) this.findViewById(R.id.txtMessage);
btnSend = (Button) this.findViewById(R.id.btnSend);
btnSend.setOnClickListener(new View.OnClickListener()
{
#Override
public void onClick(View view)
{
// Get phone number and message sms
String phoneNo = txtPhoneNo.getText().toString();
String message = txtMessage.getText().toString();
Intent writeLog = new Intent(getApplicationContext(), Logs.class);
writeLog.putExtra("link", message);
startActivity(writeLog);
// If phone number and message is not empty
if (phoneNo.length() > 0 && message.length() > 0)
{
sendMessage(phoneNo, message);
}
else
{
Toast.makeText(getBaseContext(), "Please enter both number and message", Toast.LENGTH_LONG).show();
}
}
});
}
// Function send message sms
private void sendMessage(String phoneNo, String message)
{
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 failed. Please try again!", Toast.LENGTH_LONG).show();
e.printStackTrace();
}
}
}
=========================================================
public class Logs extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_logs);
String logging = getIntent().getStringExtra("link");
TextView textView = (TextView) findViewById(R.id.txtLog);
textView.setText(logging);
Button log2menu = (Button)findViewById(R.id.logToMenu);
log2menu.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(getApplicationContext(), MainActivity.class);
startActivity(intent);
}
});
}
}
You can use SharedPreferences to store such data.
One more thing you can try if you don't want to save the data after the app closes is storing the data in a static variable of a separate class.

Handler doesn't stop on button click

I have a runnable which starts an activity and a handler, which lets the runnable repeat after 5 seconds. However, i implemented a "stop button" which should stop that handler, but somehow it doesn't work.
I would appreciate some help why it doesn't stop the loop.
public class MainActivity extends Activity {
private Button callBtn;
private Button stopBtn;
Handler handler = new Handler();
Runnable redial=new Runnable(){
#Override public void run(){Intent callIntent=new Intent(Intent.ACTION_CALL,Uri.parse("tel:+49888888"));startActivity(callIntent);
}};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
callBtn = (Button) findViewById(R.id.call);
stopBtn = (Button) findViewById(R.id.stop);
// add PhoneStateListener for monitoring
MyPhoneListener phoneListener = new MyPhoneListener();
TelephonyManager telephonyManager = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
// receive notifications of telephony state changes
telephonyManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
callBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
redial.run();
}
});
stopBtn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
handler.removeCallbacks(redial);
}
});
}
private class MyPhoneListener extends PhoneStateListener {
private boolean onCall = false;
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
// phone ringing...
Toast.makeText(MainActivity.this, incomingNumber + " calls you",
Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// one call exists that is dialing, active, or on hold
Toast.makeText(MainActivity.this, "on call...",
Toast.LENGTH_LONG).show();
//because user answers the incoming call
onCall = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
// in initialization of the class and at the end of phone call
// detect flag from CALL_STATE_OFFHOOK
if (onCall == true) {
Toast.makeText(MainActivity.this, "restart app after call",
Toast.LENGTH_LONG).show();
// restart our application
Intent restart = getBaseContext().getPackageManager().
getLaunchIntentForPackage(getBaseContext().getPackageName());
restart.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(restart);
onCall = false;
handler.postDelayed(redial, 5000);
}
break;
default:
break;
}
}
}

Terminating timer in android

I am a begineer in android app development, i have stoptimertask function in my mainactivity, and a button stop in another activity. What i want to do is when i press this stop button from my 2nd activity(which is maps.class), i want the stoptimertask to stop i.e. stop the tasks. However the app crashes.
Here is my code of mainactivity.java
public class MainActivity extends FragmentActivity{
protected static final int CONTACT_PICKER_RESULT = 0;
int count=0;
Timer timer;
TimerTask timerTask;
final Handler handler = new Handler();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
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() {
timer = new Timer();
initializeTimerTask();
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() {
handler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "your message has been sent, the message(s) sent are:-"+count++,Toast.LENGTH_LONG).show();
sendSMSMessage();
}
});
}
};
}
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;
count = 0;
}
MainActivity.this.finish();
}
}
Here is the maps.java(2nd activity)
public class maps extends FragmentActivity implements LocationListener {
MainActivity call=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)
{
Intent toAnotherActivity = new Intent(aView.getContext(), MainActivity.class);
startActivityForResult(toAnotherActivity, 0);
Toast.makeText(getApplicationContext(), "Stop button pressed",Toast.LENGTH_LONG).show();
maps.this.finish();
call.stoptimertask(aView);
}
});
here is the logcat
FATAL EXCEPTION: main
Process: com.example.textmessage, PID: 19869
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:167)
at com.example.textmessage.maps$1.onClick(maps.java:49)
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)
Best use for this kind of scenario is Singleton pattern.
MainActivity.java
public class MainActivity extends FragmentActivity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initializeTools();
// Find reference of "sendBtn" with "findViewById" or other stuff
sendBtn.setOnClickListener(
new View.OnClickListener()
{
#Override
public void onClick(View v)
{
startTimer();
}
});
// Rest of your code
}
private void initializeTools()
{
// Give context to Timers instance
Timers.getInstance().giveContext(this);
}
private void startTimer()
{
// Starts the timer when you click on "sendBtn"
Timers.getInstance().startTimers();
}
}
Timers.java
public class Timers
{
private final ScheduledExecutorService scheduledExecutorService;
private final Runnable myTask;
private ScheduledFuture<?> futureTask;
private int count = 0;
private Context _context;
private static volatile Timers _timers;
private Timers()
{
super();
// Your "futureTask manager"
scheduledExecutorService = Executors.newScheduledThreadPool(5);
// Good use is to instanciate task since it won't change on runtime
myTask = new Runnable()
{
#Override
public void run()
{
// Your code to run after the delay has expired
Toast.makeText(_context, "your message has been sent, the message(s) sent are:-" + count++, Toast.LENGTH_LONG).show();
// Same as the whole example, you should use the Singleton pattern to handle communications thanks to the Singleton class "Communicator"
Communicator.getInstance().sendSMSMessage();
}
};
}
// Allow only one instance of the class running. Anyone can get reference of the class with the static function Timers.getInstance();
public static Timers getInstance()
{
if (Timers._timers == null)
{
synchronized (Timers.class)
{
if (Timers._timers == null)
{
Timers._timers = new Timers();
}
}
}
return Timers._timers;
}
// For Toasts and other useful stuff
public void giveContext(Context context)
{
this._context = context;
}
// Stop the timer
public void stopTimer()
{
if (futureTask != null)
{
futureTask.cancel(true);
}
}
// Starts the task to happen in 10 seconds
public void startTimers()
{
futureTask = scheduledExecutorService.schedule(myTask, 10, TimeUnit.SECONDS);
}
}
And inside any class of your application, use Timers.getInstance().stopTimer(); to stop the timer and Timers.getInstance().startTimer(); to start it again.
Did you try?
mTimer = new Runnable() {
#Override
public void run() {
**return;**

Categories

Resources