I am trying to ensure that the executor service stops when the Back button or Home button is pressed.
Currently I have this code in my onCreate function in the main activity class:
ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
final Wifi wifiObject = new Wifi((WifiManager) getSystemService(Context.WIFI_SERVICE));
Runnable periodicTask = new Runnable() {
public void run() {
// For each AP in the database, we will fill the AP's ArrayList with their corresponding RSS values
for (Map.Entry<String, String> entry : AccessPoints.entrySet()) {
int APNoToBeSent = 0;
try {
wifiObject.scanWifi(entry.getKey(), accessPointMeanRSSArrayList, accessPointRSSFrequencyArrayList);
}
catch (Exception e) {
}
++APNoToBeSent;
}
System.out.println("Mean AP0 = " + accessPointMeanRSSArrayList.get(0));
System.out.println("Frqcy AP0 = " + accessPointRSSFrequencyArrayList.get(0));
}
};
executor.scheduleAtFixedRate(periodicTask, 0, 2, TimeUnit.SECONDS);
I've been doing some reading on this but am unsure whether this should be happening in onStop() or onPause() or something completely different?
Related
I want to send value from string (distance to obstacle) to my TextView in main activity.
I tried to use Handler, but still not working (crash) or receive nothing.
A part code which receive data from HC-05 (screen where you see in debug value assignet to variable)
enter image description here
#Override
public void run() {
byte[] buffer = new byte[1024];
int bytes;
while(true){
try {
bytes = inputStream.read(buffer);
final String comingMsg = new String(buffer,0,bytes);
Log.d(TAG,"InputStream: " + comingMsg);
/*mHandler2.post(new Runnable() {
#Override
public void run() {
Message message = new Message();
message.obj = comingMsg;
mHandler2.sendMessage(message);
}
});*/
}catch (IOException e){
Log.e(TAG,"Write: Error reading input." + e.getMessage());
active=false;
break;
}
}
}
Here It's parts of code from MainActivity where I tried put something to get values from service.
[I add, that for this moment i want to see something values from bluetooth in textView. Later I want to create parse string and send custom text to custom TextView - example: FL: (Front Left)- to one textView, FR: (Front Right) - to second textView]
There is method implementThreads(), because I wanted to do 6 Threads to 6 TextView which every time is refreshing value from string in Services (there I tried get value from Bluetooth Service)
Log.d(TAG,"Check intent - result");
if(getIntent().getIntExtra("result",0)==RESULT_OK){
mDevice = getIntent().getExtras().getParcelable("bonded device");
myBluetoothService = new MyBluetoothService(getApplicationContext());
startConnection(mDevice,MY_UUID);
Log.d(TAG,"Check is active service");
checkIfActive();
}
Log.d(TAG,"Check intent - connect_to_paired");
if(getIntent().getIntExtra("connect_to_paired",0)==RESULT_OK){
mDevice = getIntent().getExtras().getParcelable("bonded_paired_device");
myBluetoothService = new MyBluetoothService(getApplicationContext());
startConnection(mDevice,MY_UUID);
Log.d(TAG,"Check is active service");
checkIfActive();
}
}
#Override
public void onStart(){
super.onStart();
myBluetoothService = new MyBluetoothService(getApplicationContext());
}
public void checkIfActive(){
Log.d(TAG,"CheckIfActive: Started");
if(myBluetoothService.active){
Log.d(TAG,"CheckIfActive: Running method implementThreads()");
implementThreads();
}
}
public void implementThreads(){
Log.d(TAG,"ImplementThreads: Started");
Thread thread = new Thread(){
#Override
public void run() {
try{
sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
}
};
thread.start();
}
public void startConnection(BluetoothDevice device,UUID uuid){
Log.d(TAG,"StartConnection: Initializing connection");
myBluetoothService.startClient(device,uuid);
}
Thanks all for help, because It's very important for me !
Use this to interect with UI Thread for operations like updating textviews etc.
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
//YOUR CODE HERE
Message message = new Message();
message.obj = comingMsg;
mHandler2.sendMessage(message);
}
});
I am building a quiz application in NodeJS and Android using socket.IO,
I am facing a problem when I emit an event quizzoStatus from the server, the event fires first time once, second time twice and so on.
Here I attach my code snippet
///server side: NodeJS
socket.on('sendQuizzoAnsPoints', async (data)=>{
try {
const obj = JSON.parse(data);
const game = await QuizzoPlayModel.findOne({_id:obj.gameId});
const player = await UserModel.findOne({_id: game.playerId});
const opponent = await UserModel.findOne({_id: game.opponentId});
if(obj.userId == game.opponentId){
let update = {
opponentPoints: game.opponentPoints + obj.points || 0,
opponentWA: game.opponentWA + obj.wrongAns || 0,
};
await QuizzoPlayModel.findByIdAndUpdate(obj.gameId, update).lean().exec();
userNamespace.to(player.socketId).emit('quizzoStatus', {
fullName: opponent.fullName,
points: game.playerPoints + obj.points,
wrongAns: obj.wrongAns,
gameId: obj.gameId
});
}
if(obj.userId == game.playerId) {
let update = {
playerPoints: game.playerPoints + obj.points || 0,
playerWA: game.playerWA + obj.wrongAns || 0,
};
await QuizzoPlayModel.findByIdAndUpdate(obj.gameId, update).lean().exec();
userNamespace.to(opponent.socketId).emit('quizzoStatus', {
fullName: player.fullName,
points: game.playerPoints+ obj.points,
wrongAns: obj.wrongAns,
gameId: obj.gameId
});
}
} catch (e) {
console.log(e);
}
});
Here I listen a event named sendQuizzoAnsPoints and then I emit an event to the player or opponent in another event named quizzoStatus.
The quizzoStatus event fires multiple times from server to android.
Here I attached android code
/// Android code
socket.emit("sendQuizzoAnsPoints", new Gson().toJson(quizzoStatusRequestDto));
socket.on("quizzoStatus", new Emitter.Listener(){
#Override
public void call(Object... args){
runOnUiThread(new Runnable(){
#Override
public void run(){
Log.e("opponet point", opponentPoints + " " + quizzoStatusResponseDto.getPoints());
}
});
}
});
The problem is in Android. You are assigning new listener every time without removing the previous one. You need to create a variable of that Emmiter listener and remove it on onDestroy or somewhere else when the work is done:
//variable of Emmiter.Listener
Emmiter.Listener quizzoStatus = new Emitter.Listener(){
#Override public void call(Object... args){
runOnUiThread(new Runnable(){
#Override public void run(){
Log.e("opponet point", opponentPoints + " " + quizzoStatusResponseDto.getPoints());
}
});
}
};
//assigning the listener
socket.on("quizzoStatus", quizzoStatus);
. . . .
#Override protected void onDestroy(){
super.onDestroy();
//removing the listener...
socket.off("quizzoStatus", quizzoStatus);
}
Hope this will work
Let me start by saying that if image shooting interval is anything more than 1 second it works. For example taking a picture every 2 seconds works perfectly fine. But taking a picture every second sometimes throws java.lang.RuntimeException: takePicture failed. What could be causing this kind of a behaviour?
Here is the code I use and it is in Service:
#Override
public void onCreate()
{
super.onCreate();
prefs = getSharedPreferences("general",Context.MODE_PRIVATE);
handler = new Handler();
shotInterval = prefs.getInt(getString(R.string.prefs_int_imageShootingFrequency),1);
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
Toast.makeText(this, "No camera on this device", Toast.LENGTH_LONG).show();
} else {
cameraId = findBackFacingCamera();
if (cameraId < 0) {
Toast.makeText(this, "No front facing camera found.",Toast.LENGTH_LONG).show();
} else {
camera = Camera.open(cameraId);
}
}
cameraParameters = camera.getParameters();
cameraParameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); //set camera to continuously auto-focus
camera.setParameters(cameraParameters);
pictureTaker.run(); // Start looping
}
Runnable pictureTaker = new Runnable() {
#Override
public void run() {
try {
takePicture();
} finally {
// 100% guarantee that this always happens, even if
// your update method throws an exception
handler.postDelayed(pictureTaker, shotInterval*1000);
}
}
};
private void takePicture(){
SurfaceView view = new SurfaceView(this);
try {
camera.setPreviewDisplay(view.getHolder());
camera.startPreview();
camera.takePicture(null, null,new PhotoHandler(getApplicationContext()));
} catch (IOException e) {
e.printStackTrace();
}
}
You should launch postDelayed() from the onPictureTaken() callback. You can check the system timer on call to takePicture() and reduce the delay respectively, to keep 1000ms repetition, but maybe once in a while, this delay will reach 0.
I am trying to make my application launcha splash screen for 5 seconds while initializing various web services in the background. Here is my code:
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Splash screen view
setContentView(R.layout.splashscreen);
final SplashScreen sPlashScreen = this;
// The thread to wait for splash screen events
mSplashThread = new Thread()
{
#Override
public void run()
{
try {
synchronized(this){
// Wait given period of time or exit on touch
wait(5000);
}
}
catch(InterruptedException ex)
{
}
finally
{
finish();
// Run next activity
Intent intent = new Intent();
intent.setClass(sPlashScreen, Splash_testActivity.class);
startActivity(intent);
stop();
}
}
};
mSplashThread.start();
for (int i=0;i<100;i++)
Log.d("splash test", "initialize web methods");
}
Now what I think should happen is that while the splash screen is displayed, the application should log "initialize web methods."
But what actually happens is that the log is added only after the slash screen disappears.
What am I doing wrong??
Try to do it this way. This tutorial is simple and flexible. This is what you need:
// You initialize _splashTime to any value
// thread for displaying the SplashScreen
Thread splashTread = new Thread() {
#Override
public void run() {
try {
int waited = 0;
while(waited < _splashTime)) {
sleep(100);
waited += 100;
}
}
} catch(InterruptedException e) {
// do nothing
} finally {
finish();
startActivity(new Intent("com.droidnova.android.splashscreen.MyApp"));
stop();
}
}
};
splashTread.start();
Note: This code is adopted from the above url.
Run your Thread Using Handler or AsyncTask.
here I have a function of checkupdate() in which my application check updates available for users, so i need to display two progressdialog one when server is under request(Checking process) and other when synchronization process is ongoing and both the process is done on the load of application.
Now problem is I'm unable to display these two progressdialog boxes, here only the first thread checking updates is running and application is terminated.
Waiting for your valuable answers.
public void CheckUpdate()
{
//----------------Process of checking the updates--------------------------
try
{
progressDialog = ProgressDialog.show(this, "Wait", "Checking update...", false, true);
Thread thr1 = new Thread()
{
public void run()
{
int Flag = call.CheckUserUpdate(UsrId);
Update = Flag;
progressDialog.dismiss();
//stop();
interrupt();
}
};
thr1.start();
}
catch(final Exception e)
{
}
//---------------Process of Synchronization----------------------------------------------
try
{
progressDialog1 = ProgressDialog.show(this, "Wait", "Synchronizing...", false, true);
Thread thr2 = new Thread()
{
public void run()
{
if(Update == 1)
{
SyncData();
final int UpdateFlag = 1;
call.UpdateUserUpdate(UsrId, UpdateFlag);
progressDialog1.dismiss();
}
else
{
progressDialog1.dismiss();
}
progressDialog1.dismiss();
}
};
thr2.start();
}
catch(final Exception e)
{
}
}
Starting the new threads causes them to start executing elsewhere. Your program here starts two threads, gets to the end of main() and exits, causing the JVM/OS to kill your newly started threads that never really got a chance to run very far.
You need to add an idle loop (or similar) that yields control on the main thread while the worker threads to their thing, assuming you don't have any work happening on the main thread.
Do I understand correctly what you want?
Your UI activitiy has two progressbars which should be updated based on either
update check process
synchronization process
then you should create a handler in your UI activity and use two separate threads one for update check and the other for synchronization check
Both send their progress info to the main thread like:
mHandler.obtainMessage(Main_screen.MESSAGE_PGROGRESS_CHANGE_UPDATE, state, -1)
.sendToTarget();
in the other you have
mHandler.obtainMessage(Main_screen.MESSAGE_PGROGRESS_CHANGE_SYNCHRINIZATION, state, -1)
.sendToTarget();
In your UI activity you have the handler looking like this...
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
if (DEBUG)
Log.i(this.getClass().getSimpleName(),
"-> "
+ Thread.currentThread().getStackTrace()[2]
.getMethodName());
switch (msg.what) {
case MESSAGE_PGROGRESS_CHANGE_UPDATE:
if (DEBUG)
Log.i(this.getClass().getSimpleName(),
" MESSAGE_PGROGRESS_CHANGE_UPDATE: " + msg.arg1);
// do your update of progressbar or whatever here
break;
case MESSAGE_PGROGRESS_CHANGE_SYNCHRINIZATION:
if (DEBUG)
Log.i(this.getClass().getSimpleName(),
" MESSAGE_PGROGRESS_CHANGE_SYNCHRINIZATION: " + msg.arg1);
// do your update of progressbar or whatever here
break;