I've been looking for a way to change an icon in my view by broadcast receiver, but I'm not managing to find a way to do so.
First, I created a receiver:
public class BroadcastChangeReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, final Intent intent) {
NetworkStatus conStatus = new NetworkActivity().getConnectionType(context);
String status = "Connection type: " + conStatus.getType().toString() + " -- Internet: " + conStatus.isConnected();
Toast.makeText(context, status, Toast.LENGTH_LONG).show();
}
}
it works fine when a network shows up. But now I need to check if there is a connectivity from time to time. To make that, I created a method that will ping my service that is somewhere in the internet each 5 seconds, but I don`t know how, from the broadcast receiver, will I change the icon in my activity. I cant use findViewById. This is my sample code to change and Icon (which is not working):
private void startInternetMonitoring(Context context) {
ScheduledExecutorService scheduleTaskExecutor = Executors
.newScheduledThreadPool(5);
// Run task every 5 seconds
scheduleTaskExecutor.scheduleAtFixedRate(new Runnable() {
int count = 0;
public void run() {
ImageView img = (ImageView) findViewById(R.id.networkStatusIcon);
switch (count) {
case 0:
img.setImageResource(R.drawable.connecting_icon);
count = 1;
break;
case 1:
img.setImageResource(R.drawable.offline_icon);
count = 2;
break;
case 2:
img.setImageResource(R.drawable.online_icon);
count = 0;
break;
}
}
}, 0, 5000, TimeUnit.MILLISECONDS);
}
any help or tips will be appreciated.
First off, I think a TimerTask is a better use for this case.
From http://android-er.blogspot.com/2013/12/example-of-using-timer-and-timertask-on.html
package com.example.androidtimer;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.CheckBox;
import android.widget.TextView;
import android.app.Activity;
public class MainActivity extends Activity {
CheckBox optSingleShot;
Button btnStart, btnCancel;
TextView textCounter;
Timer timer;
MyTimerTask myTimerTask;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
optSingleShot = (CheckBox)findViewById(R.id.singleshot);
btnStart = (Button)findViewById(R.id.start);
btnCancel = (Button)findViewById(R.id.cancel);
textCounter = (TextView)findViewById(R.id.counter);
btnStart.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View arg0) {
if(timer != null){
timer.cancel();
}
//re-schedule timer here
//otherwise, IllegalStateException of
//"TimerTask is scheduled already"
//will be thrown
timer = new Timer();
myTimerTask = new MyTimerTask();
if(optSingleShot.isChecked()){
//singleshot delay 1000 ms
timer.schedule(myTimerTask, 1000);
}else{
//delay 1000ms, repeat in 5000ms
timer.schedule(myTimerTask, 1000, 5000);
}
}});
btnCancel.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
if (timer!=null){
timer.cancel();
timer = null;
}
}
});
}
class MyTimerTask extends TimerTask {
#Override
public void run() {
Calendar calendar = Calendar.getInstance();
SimpleDateFormat simpleDateFormat =
new SimpleDateFormat("dd:MMMM:yyyy HH:mm:ss a");
final String strDate = simpleDateFormat.format(calendar.getTime());
runOnUiThread(new Runnable(){
#Override
public void run() {
textCounter.setText(strDate);
}});
}
}
}
The issue seems to be that you "cant use findViewById".
Perhaps move your broadcastreceiver into your activity and register it there. That way you have access to you activity and views from the receiver when it is called.
Related
I want to make an android application that have punch in and punch out functionality. Scenario is when the user entered in an application it enters its task and press punch in button, When punch in button is press current date and time is saved in a local database and timer is running on background even i close an application but issue is it cannot run in background when i close an application and starts again timer starts from beginning.
How to figure out that my service is running and get that data?
MainActivity.java
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button startButton;
private Button pauseButton;
private TextView timerValue;
Intent intent;
long timeSwapBuff = 0L;
long updatedTime = 0L;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
timerValue = (TextView) findViewById(R.id.timerValue);
startButton = (Button) findViewById(R.id.startButton);
startButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(MyService.BROADCAST_ACTION));
}
});
pauseButton = (Button) findViewById(R.id.pauseButton);
pauseButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) {
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
});
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent)
{
updateUI(intent);
}
};
private void updateUI(Intent intent) {
int time = intent.getIntExtra("time", 0);
Log.d("Hello", "Time " + time);
int mins = time / 60;
int secs = time % 60;
timerValue.setText("" + mins + ":" + String.format("%02d", secs));
}
#Override
protected void onStop() {
super.onStop();
intent = new Intent(MainActivity.this, MyService.class);
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(MyService.BROADCAST_ACTION));
}
}
MyService.java
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.support.annotation.Nullable;
import android.widget.Toast;
public class MyService extends Service
{
private Intent intent;
public static final String BROADCAST_ACTION = "com.example.wajid.service";
private Handler handler = new Handler();
private long initial_time;
long timeInMilliseconds = 0L;
#Override
public void onCreate() {
super.onCreate();
initial_time = SystemClock.uptimeMillis();
intent = new Intent(BROADCAST_ACTION);
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
DisplayLoggingInfo();
handler.postDelayed(this, 1000); // 1 seconds
}
};
private void DisplayLoggingInfo() {
timeInMilliseconds = SystemClock.uptimeMillis() - initial_time;
int timer = (int) timeInMilliseconds / 1000;
intent.putExtra("time", timer);
sendBroadcast(intent);
}
#Override
public void onDestroy() {
super.onDestroy();
handler.removeCallbacks(sendUpdatesToUI);
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
Why do you want to run a timer? Instead, simply save the check-in time in shared preferences. On check-out, the two can be compared and the relevant time calculated.
If you are worried that the user might try to manipulate the local device clock, then instead of getting the local time, you can use network time.
i have made a countdown timer using progressbar and a thread,Now i want to stop the progress at the same time when user clicks on a button.I have tried thread.stop(),but it says there is .no such method,I have tried interruot method too with no luck,So can any buddy please help me by viewing my code.My code is as below:
code
package com.amar.lyricalgenius;
import com.amar.lyricalgenius.LoadingActivity.MyCountDownTimer;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;
public class SinglePlayerOption extends Activity implements OnClickListener {
// visible gone
private int progressStatus = 0;
private Handler handler = new Handler();
Intent i;
TextView text_player_second;
ImageView vs_word;
ImageView player_second_pic, player_second_box;
ImageButton red_point1;
TextView text_number_pt1;
TextView text_number1;
ProgressBar pg_loading;
private CountDownTimer countDownTimer;
TextView timer_text;
private final long startTime = 8 * 1000;
private final long interval = 1 * 1000;
Button opt_1, opt_2, opt_3, opt_4;
Thread splashThread;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.single_player_option);
init();
}
private void init() {
// TODO Auto-generated method stub
text_player_second = (TextView) findViewById(R.id.text_player_second);
vs_word = (ImageView) findViewById(R.id.vs_word);
player_second_pic = (ImageView) findViewById(R.id.player_second_pic);
player_second_box = (ImageView) findViewById(R.id.player_second_box);
red_point1 = (ImageButton) findViewById(R.id.red_point1);
text_number_pt1 = (TextView) findViewById(R.id.text_number_pt1);
text_number1 = (TextView) findViewById(R.id.text_number1);
opt_1 = (Button) findViewById(R.id.option_1);
opt_2 = (Button) findViewById(R.id.option_2);
opt_3 = (Button) findViewById(R.id.option_3);
opt_4 = (Button) findViewById(R.id.option_4);
opt_1.setOnClickListener(this);
opt_2.setOnClickListener(this);
opt_3.setOnClickListener(this);
opt_4.setOnClickListener(this);
text_player_second.setVisibility(View.GONE);
vs_word.setVisibility(View.GONE);
player_second_pic.setVisibility(View.GONE);
player_second_box.setVisibility(View.GONE);
red_point1.setVisibility(View.GONE);
text_number_pt1.setVisibility(View.GONE);
text_number1.setVisibility(View.GONE);
countDownTimer = new MyCountDownTimer(startTime, interval);
timer_text.setText(timer_text.getText()
+ String.valueOf(startTime / 1000));
countDownTimer.start();
new Thread(new Runnable() {
public void run() {
while (progressStatus < 100) {
progressStatus += 1;
// Update the progress bar and display the
// current value in the text view
handler.post(new Runnable() {
public void run() {
pg_loading.setProgress(progressStatus);
}
});
try {
// Sleep for 200 milliseconds.
// Just to display the progress slowly
Thread.sleep(62);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
splashThread = new Thread() {
public void run() {
try {
sleep(6000);
// Utils.systemUpgrade(SplashActivity.this);
} catch (InterruptedException e) {
e.printStackTrace();
}
Intent intent = null;
intent = new Intent(SinglePlayerOption.this,
NoResponseActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
startActivity(intent);
finish();
}
};
splashThread.start();
}
#SuppressWarnings("deprecation")
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
Intent i;
switch (v.getId()) {
case R.id.option_1:
splashThread.stop();
countDownTimer.onFinish();
Toast.makeText(SinglePlayerOption.this,
timer_text.getText().toString(), 1).show();
i = new Intent(SinglePlayerOption.this,
DialogLeaderboardActivity.class);
startActivity(i);
break;
}
}
public class MyCountDownTimer extends CountDownTimer {
public MyCountDownTimer(long startTime, long interval) {
super(startTime, interval);
}
#Override
public void onFinish() {
timer_text.setText("Time's up!");
}
#Override
public void onTick(long millisUntilFinished) {
timer_text.setText("" + millisUntilFinished / 1000);
}
}
}
Thread th = new Thread(new Runnable() {
public void run() { ....
th.start();//starts
th.interrupt();//this stops.
and use
while (progressStatus < 100 && (!Thread.currentThread().isInterrupted())){....
instead of
while (progressStatus < 100) {....
Now i want to stop the progress at the same time when user clicks on
a button.I have tried thread.stop()
Thread.stop() is deprecated and you should not use it. The basic concept to understand is that a thread terminates is execution when the last line of code of his run method is executed. In the case of your "ProgressBar Thread*, when the user press the button, you have to set the exit condition of your while-loop (progressStatus = 100) in order to make it terminate
I want to implement a simple messenger application for Android devices,I'm working with a web service which contains all the required methods for sending and receiving(by pressing the send button a record will be inserted in the DB and by calling the receive method all the rows related to this receiver(user) are retrieved).
I've written a service in a separate class and in onStart() I check the receive method of my .Net web service,I start the service in onCreate() of my activity ,so the service is in the background and receives the incoming messages perfectly,I can show the new message by using a toast directly in my service code,but I know that for accessing the views which are in my activity I should use pendingintent and maybe a BroadcastReceiver,so I can add the new messages to the main screen of my activity(for example a textview).
Now I want to find a way to access the textview of my activity and set the text of it through my service or anything else...
please help me on this issue,
Here is my activity:
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class MyOwnActivity extends Activity
{
Button btnSend;
Button btnExtra;
EditText txtMessageBody;
TextView lblMessages;
BerryService BS = new BerryService();
public void SetMessageHistory(String value)
{
txtMessageBody.setText(value);
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnSend = (Button) findViewById(R.id.btnSend);
btnExtra = (Button) findViewById(R.id.btnExtraIntent);
txtMessageBody = (EditText) findViewById(R.id.txtMessageBody);
lblMessages = (TextView) findViewById(R.id.lblMessages);
/////////
//////////
startService(new Intent(this, IncomingMessageService.class));
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// call webservice method to send
BS.SetSoapAction("http://tempuri.org/Send");
BS.SetMethodName("Send");
String a = BS.SendMessage(txtMessageBody.getText().toString());
lblMessages.setText(lblMessages.getText().toString() + "\n"
+ txtMessageBody.getText().toString());
txtMessageBody.setText("");
}
});
}
}
Here is my service:
import java.util.Timer;
import java.util.TimerTask;
import android.app.ActivityManager;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.SystemClock;
import android.widget.Toast;
public class IncomingMessageService extends Service
{
private static final int NOTIFY_ME_ID = 12;
BerryService BS = new BerryService();
String text = "";
#Override
public IBinder onBind(Intent intent) {
throw new UnsupportedOperationException("Bind Failed");
}
#Override
public void onCreate() {
Toast.makeText(this, "onCreate", 5000).show();
}
#Override
public void onStart(Intent intent, int startId) {
// ////////////////////////
Toast.makeText(this, "onStart ", 1000).show();
// Timer Tick
final Handler handler = new Handler();
Timer _t = new Timer();
TimerTask tt = new TimerTask() {
#Override
public void run() {
handler.post(new Runnable() {
public void run() {
Toast.makeText(getApplicationContext(), "tick ", 1000)
.show();
// here the receive method should be called
BS.SetSoapAction("http://tempuri.org/RecieveMessage");
BS.SetMethodName("RecieveMessage");
String receivedMsg = BS.ReceiveMessage("sh");
//Instead of toast I want to access the textview in my activity!!!!!
Toast.makeText(getApplicationContext(), receivedMsg, 5000).show();
}
});
}
};
_t.scheduleAtFixedRate(tt, 0, 1000);
}
// /
#Override
public void onDestroy() {
Toast.makeText(this, "onDestroy", 5000).show();
}
}
You need to understand the concept of Broadcast, in your case it is the correct solution.
Start Broadcast in its activity
public static final String ACTION = "com.yourapp.ACTION.TEXT_RECEIVED";
private BroadcastReceiver mReceiver;
#Override
public void onCreate(Bundle savedInstanceState) {
////////
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String msg = intent.getStringExtra("msg");
yourTextView.setText(msg);
}
};
IntentFilter filter = new IntentFilter(ACTION);
filter.addCategory(Intent.CATEGORY_DEFAULT);
registerReceiver(mReceiver, filter);
////////
}
protected void onDestroy() {
// remember to unregister the receiver
super.onDestroy();
if (mReceiver != null) {
unregisterReceiver(mReceiver);
}
}
When you need to send the message of service you should use:
Intent i = new Intent();
i.setAction(MyOwnActivity.ACTION);
i.addCategory(Intent.CATEGORY_DEFAULT);
i.putExtra("msg", "the message received by webservice");
i.putExtras(b);
sendBroadcast(i);
Have a look here: http://developer.android.com/reference/android/content/BroadcastReceiver.html
Using a broadcast manager is great but I personally prefer to use square's Otto because it is just so easy to perform communication between components in an android application.
http://square.github.io/otto/
If you do choose to use otto, you are going to have to override the Bus's post method to be able to talk post messages to a bus on the foreground. Here is the code for that:
public class MainThreadBus extends Bus {
private final Handler handler = new Handler(Looper.getMainLooper());
#Override public void post(final Object event) {
if (Looper.myLooper() == Looper.getMainLooper()) {
super.post(event);
} else {
handler.post(new Runnable() {
#Override
public void run() {
post(event);
}
});
}
}
}
I am having problem in stopping a CountDownTimer. I have searched a lot but couldn't understand how to do that.
Below is my MainActivity. How can I stop the timer if RadioButton b is pressed?
import java.util.Timer;
import java.util.TimerTask;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.app.Activity;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.RadioButton;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
TextView mTextField;
RadioButton a, b, c, d, e;
final static long interval = 1000;
long timeout = 15000;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mTextField = (TextView) findViewById(R.id.tv);
a = (RadioButton) findViewById(R.id.rB1a);
b = (RadioButton) findViewById(R.id.rB2a);
c = (RadioButton) findViewById(R.id.rB3a);
d = (RadioButton) findViewById(R.id.rB4a);
e = (RadioButton) findViewById(R.id.rB5a);
//Timer timer = new Timer();
//timer.scheduleAtFixedRate(task, interval, interval);
TimerTask task = new TimerTask() {
#Override
public void run() {
timeout = timeout - interval;
if (timeout == 0) {
this.cancel();
displayText("finished");
return;
}
if (timeout >= 0) {
displayText("time remaining: " + String.valueOf(timeout / 1000));
a.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "Wrong Answer!!! ", Toast.LENGTH_LONG).show();
Intent openWordlist = new Intent("com.example.the_vocab_master.AA");
startActivity(openWordlist);
}
});
b.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
Toast.makeText(getApplicationContext(), "GREAT...!!! ", Toast.LENGTH_LONG).show();
}
});
}
//displayText("time remaining: " + String.valueOf(timeout / 1000));
}
};
Timer timer = new Timer();
timer.scheduleAtFixedRate(task, interval, interval);
}
private void displayText(final String text) {
this.runOnUiThread(new Runnable() {
#Override
public void run() {
mTextField.setText(text);
}
});
}
}
To cancel the timer use
timer.cancel();
in your onClick listener. It's very difficult to see in your code, because the indentation is very bad, but I think you need to declare your timer variable in the class, instead of in onCreate();
Additionally, I'd suggest you to take both setOnClickListener calls OUTSIDE of the timer run() method. What you're doing doesn't make sense.
In this android service I wanna display a toast of value of second at current time. but this again and again show the same value. timer is scheduled to update at interval of 1 second but the value don't refresh and toast shows the previous value again. I don't what the issue.
package net.learn2develop.Services;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;
import android.app.Service;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.widget.Toast;
public class MyService extends Service{
Handler handler = new Handler();
Calendar c = Calendar.getInstance();
Timer t = new Timer();
int second = c.get(Calendar.SECOND);
int temp = 6;
#Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Service Created", Toast.LENGTH_SHORT).show();
}
#Override
public IBinder onBind(Intent arg0) {
return null;
}
public int onStartCommand(Intent intent, int flags, int startId){
Toast.makeText(this,"service started",Toast.LENGTH_SHORT).show();
TimerTask task = new TimerTask() {
#Override
public void run() {
second = timeSecond();
handler.post(new Runnable() {
#Override
public void run() {
// Toast.makeText(getBaseContext(),String.valueOf(second), Toast.LENGTH_SHORT).show();
}
});
}
};
t.scheduleAtFixedRate(task, 0, 4* 1000);
return START_STICKY;
}
public void onDestroy(){
super.onDestroy();
t.cancel();
Toast.makeText(this, "Service Stopped", Toast.LENGTH_SHORT).show();
}
public int timeSecond() {
handler.post(new Runnable() {
#Override
public void run() {
Toast.makeText(getBaseContext(),String.valueOf(c.get(Calendar.SECOND)), Toast.LENGTH_SHORT).show();
}
});
return c.get(Calendar.SECOND);
}
}
This statement:
Calendar c = Calendar.getInstance();
returns a calendar whose time fields have been initialized with the current date and time. Those values do not then change as time passes. So when you use:
String.valueOf(c.get(Calendar.SECOND))
you are getting the same values every time. You need a new instance of calendar in each iteration of your timer.