android GPS still getting postion when i'm not moving - android

I'm developing a tracking app. and i have problem with GPS module. The app must record a route. App work fine, but sometimes when the device is not moving, GPS still receive
continuous coordinate that don't indicate my position, error is within a radius of 20 meter, and when I'm moving again work fine.
Please give me some tips that can help me to fix this problem. Thanks a lot.
I have 3 calsses
1 - GPSReceiver here is method for get location
public void getMyLoction(){
_locationManager = (LocationManager) _context.getSystemService(LOCATION_SERVICE);
_isGPSEnabled =_locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
if (_isGPSEnabled) {
if (_location == null) {
_locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,0,0, this);
if (_locationManager != null) {
_location = _locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
setLocation(_location);
}
}
}
}
2 RecordingActivity (take coordonates form services and processes then) work fine, a comment in method what they do.
public class RecordingActivity extends FragmentActivity {
public final static String BROADCAST_ACTION = "map.trackv";
public BroadcastReceiver receiver;
private GoogleMap map;
private TextView _messageToUser;
private Coordinate _pointFromService;
private long _timeWhenStartButtonWasPressed;
private List<Coordinate> _unprocessedCoords;
private List<Coordinate> _processedCoords;
private Button _stopButton;
private Button _startButton;
private String _startRecordingDate;
private String _stopRecordingDate;
private GPSReceiver _gps;
private DataBaseOperations _dataSource;
private boolean _recording;
private boolean _gpsStatus;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recording_route);
initActvity();
checkIfGPSisOn();
try {
Runtime.getRuntime().exec("logcat -f" + " /sdcard/Logcat.txt");
} catch (IOException e) {
// TODO Auto-generated catch block
Log.d("nu pot", "DDDDD");
e.printStackTrace();
}
receveirWork();
IntentFilter intentFilt = new IntentFilter(BROADCAST_ACTION);
registerReceiver(receiver, intentFilt);
}
public void checkIfGPSisOn() {
//check on start
}
public void receveirWork() {
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// request points and process then,
}
};
}
#Override
protected void onDestroy() {
super.onDestroy();
if (_stopButton.isEnabled())
{
stopService(new Intent(this, RecordingService.class));
_unprocessedCoords = null;
_processedCoords = null;
}
unregisterReceiver(receiver);
}
#Override
protected void onResume() {
if (!_stopButton.isEnabled()) {
_startButton.setEnabled(true);
_messageToUser.setText(Constants.PRESS_START_BUTTON);
map.clear();
}
super.onResume();
}
// actiune buton start;
public void startButtonEvent(View V) {
buttonsStateAndMessageToShow(false, true, Constants.MESSAGE_TO_WAIT);
_timeWhenStartButtonWasPressed = System.currentTimeMillis();
startService(new Intent(this, RecordingService.class));
// start service to get position
}
public void stopButtonEvent(View V) {
stopService(new Intent(this, RecordingService.class));
// stop service
// save route in BD
// resetData;
}
public void initActvity() {
// init date
}
#Override
protected void onSaveInstanceState(Bundle outState) {
// save state
}
}
3 RecordingServices class, ii think here is the problem.
public class RecordingService extends Service {
private Thread _backgroundWork;
private boolean _threadCanRun;
private GPSReceiver _gps;
private Coordinate _pointToSent;
public void onCreate() {
super.onCreate();
_threadCanRun = true;
_backgroundWork = new Thread(new Runnable() {
#Override
public void run() {
Looper.prepare();
getLocationFromGPS();
Looper.loop();
}
});
}
public int onStartCommand(Intent intent, int flags, int startId) {//
_backgroundWork.start();
return super.onStartCommand(intent, flags, startId);
}
public void onDestroy() {
_threadCanRun = false;
super.onDestroy();
}
public IBinder onBind(Intent intent) {
return null;
}
public void getLocationFromGPS() {
while (_threadCanRun) {
Intent _intent = new Intent(RecordingActivity.BROADCAST_ACTION);
_gps = new GPSReceiver(this);
_gps.getMyLoction();
if (_gps.getIsGPSEnabled()) {
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {}
sentPoint(_intent);
} else {
try {
TimeUnit.MILLISECONDS.sleep(500);
} catch (InterruptedException e) {}
_intent.putExtra("latitude", 0);
_intent.putExtra("longitude", 0);
_intent.putExtra("time", 0);
_intent.putExtra("GPSstatus", false);
sendBroadcast(_intent);
}
}
}
private void sentPoint(Intent _intent) {
_pointToSent = new Coordinate(_gps.getLatitude(), _gps.getLongitude(), _gps.getTime());
_intent.putExtra("latitude", _pointToSent.getLatitude());
_intent.putExtra("longitude", _pointToSent.getlongitude());
_intent.putExtra("time", _pointToSent.getTime());
_intent.putExtra("GPSstatus", _gps.getIsGPSEnabled());
sendBroadcast(_intent);
_pointToSent = null;
}
}

repeating the Location update request depends on how u implemented your tracking system
but in general(which is not recommended , just change your request update rate to save client Battery usage) you can find the distance between your locations by location1.distanceTo(location2) so if the distance is smaller than 30m then put the new location away

Related

how to manage timer in a Service to run in background

I am Trying to Implement a service where when I a select a time, the timer starts and runs in the background. the thing is working fine. but when I select another time, the timer overlaps on one another. I want my app to work in such a way that different services should run for different time. also, when I kill the app and reopen it, I get the remaining time in all the services.
however my data is coming from a web service and this web service contains a field with time. when I click the time, the above concept should start.
I have implemented my code as,
BroadCastService.java
public class BroadCastService extends Service {
private long totalTimeCountInMilliseconds;
private long timeBlinkInMilliseconds;
private CountDownTimer countDownTimer;
private boolean blink;
String getTime;
public static final String COUNTDOWN_BR = "project.uop.assignment8";
Intent bi = new Intent(COUNTDOWN_BR);
public BroadCastService() {
}
#Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//return super.onStartCommand(intent, flags, startId);
getTime = intent.getStringExtra("time");
setTimer();
startTimer();
Log.i("madhura","madhura");
return START_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
}
private void setTimer() {
int time = 0;
//if (getTime.equals("")) {
time = Integer.parseInt(getTime);
// } else
/* Toast.makeText(BroadCastService.this, "Please Enter Minutes...",
Toast.LENGTH_LONG).show();*/
totalTimeCountInMilliseconds = 60 * time * 1000;
timeBlinkInMilliseconds = 30 * 1000;
}
private void startTimer() {
countDownTimer = new CountDownTimer(totalTimeCountInMilliseconds, 500) {
#Override
public void onTick(long leftTimeInMilliseconds) {
long seconds = leftTimeInMilliseconds / 1000;
if (leftTimeInMilliseconds < timeBlinkInMilliseconds) {
if (blink) {
// mTextField.setVisibility(View.VISIBLE);
// if blink is true, textview will be visible
} else {
// mTextField.setVisibility(View.INVISIBLE);
}
blink = !blink;
}
String a = String.format("%02d", seconds / 60) + ":" + String.format("%02d", seconds % 60);
bi.putExtra("countdown", a);
sendBroadcast(bi);
}
#Override
public void onFinish() {
Toast.makeText(BroadCastService.this, "Finished", Toast.LENGTH_SHORT).show();
}
}.start();
}
}
and my TimerActivity.class
public class TimerActivity extends AppCompatActivity {
TextView mTextField;
TextView hotel;
private long totalTimeCountInMilliseconds;
private long timeBlinkInMilliseconds;
private CountDownTimer countDownTimer;
private boolean blink;
String getTime;
SessionManager sessionManager;
Toolbar toolbar;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_timer);
InitializeToolbar();
Intent in = getIntent();
getTime = in.getStringExtra("time");
Intent intent = new Intent(this,BroadCastService.class);
intent.putExtra("time",getTime);
this.startService(intent);
sessionManager = new SessionManager(this);
hotel = findViewById(R.id.textView);
hotel.setText(sessionManager.getUserName());
Log.i("started", "Started service");
mTextField = findViewById(R.id.timer);
}
public void InitializeToolbar(){
toolbar = findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
getSupportActionBar().setTitle("Order Notification");
}
private BroadcastReceiver br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
updateGUI(intent); // or whatever method used to update your GUI fields
}
};
#Override
public void onResume() {
super.onResume();
registerReceiver(br, new IntentFilter(BroadCastService.COUNTDOWN_BR));
Log.i("efgh", "Registered broacast receiver");
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(br);
Log.i("abcd", "Unregistered broadcast receiver");
}
#Override
public void onStop() {
try {
unregisterReceiver(br);
} catch (Exception e) {
// Receiver was probably already stopped in onPause()
}
super.onStop();
}
#Override
public void onDestroy() {
stopService(new Intent(this, BroadCastService.class));
Log.i("Stopped", "Stopped service");
super.onDestroy();
}
private void updateGUI(Intent intent) {
if (intent.getExtras() != null) {
String millisUntilFinished = intent.getStringExtra("countdown");
mTextField.setText(millisUntilFinished);
}
}
}
thanks in advance.
Use Handler and #Overide its method Handler#handleMessage(Message msg)
See this: https://gist.github.com/mjohnsullivan/403149218ecb480e7759

Altbeacon library with android version 6

I'm updating the altbeacon library to the latest 2.9.1 but I don't get any beacon when I range for it, this is using android 6.0.1.
public class BeaconService extends IntentService implements BeaconConsumer {
private BeaconManager mBeaconManager;
private static ArrayList<Beacon> beaconsList=new ArrayList<Beacon>();
private Region region=new Region("rid", null, null, null);
private static final String LOGTAG = "BeaconService";
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*/
public BeaconService() {
super(Constants.BEACON_SERVICE);
}
#Override
public void onBeaconServiceConnect() {
try {
mBeaconManager.startRangingBeaconsInRegion(region);
mBeaconManager.setRangeNotifier(new RangeNotifier() {
#Override
public void didRangeBeaconsInRegion(Collection<Beacon> beacons, Region region) {
Intent localIntent =new Intent(Constants.BEACON_ACTION);
beaconsList.clear();
beaconsList.addAll(beacons);
Collections.sort(beaconsList,new Comparator<Beacon>() {
#Override
public int compare(Beacon lhs, Beacon rhs) {
return Double.compare(lhs.getDistance(), rhs.getDistance());
}
});
localIntent.putParcelableArrayListExtra(Constants.BEACON_LIST,beaconsList);
LocalBroadcastManager.getInstance(BeaconService.this).sendBroadcast(localIntent);
}
});
} catch (RemoteException e) {
Log.e(LOGTAG,"Error BeaconService",e);
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return Service.START_NOT_STICKY;
}
#Override
public void onCreate() {
super.onCreate();
mBeaconManager = BeaconManager.getInstanceForApplication(this);
mBeaconManager.getBeaconParsers().add(new BeaconParser().setBeaconLayout("m:2-3=0215,i:4-19,i:20-21,i:22-23,p:24-24"));
mBeaconManager.bind(this);
}
#Override
public void onDestroy() {
super.onDestroy();
mBeaconManager.unbind(this);
}
/**
* Stop Scanning
*/
public void stopRanging(){
try {
mBeaconManager.stopRangingBeaconsInRegion(region);
} catch (RemoteException e) {
Log.e(LOGTAG,"Error BeaconService - StopRanging",e);
}
}
/**
* Start Scanning
*/
public void startRanging(){
try {
mBeaconManager.startRangingBeaconsInRegion(region);
} catch (RemoteException e) {
Log.e(LOGTAG,"Error BeaconService - StartRanging",e);
}
}
#Override
public IBinder onBind(Intent intent) {
return new LocalBinder();
}
#Override
protected void onHandleIntent(Intent intent) {
}
public class LocalBinder extends Binder {
public BeaconService getService() {
return BeaconService.this;
}
}
I did try changing to monitoring and the same result, also I did try adding more layouts but I don't get any beacons on the list
looks like you need to add the permission at runtime, I did fix it by doing this
#Override
public void initialize(final CordovaInterface cordova, CordovaWebView webView) {
Log.i(LOGTAG, "initialize");
context = webView.getContext();
beaconServiceIntent = new Intent(context, BeaconService.class);
context.bindService(beaconServiceIntent, serviceBeaconConnection, Service.BIND_AUTO_CREATE);
BeaconReceiver beaconReciever = new BeaconReceiver();
IntentFilter intentFilter = new IntentFilter(Constants.BEACON_ACTION);
LocalBroadcastManager.getInstance(context).registerReceiver(beaconReciever, intentFilter);
mainActiviy = (Activity) context;
checkPermission();
}
#TargetApi(Build.VERSION_CODES.M)
private void checkPermission() {
if(this.mainActiviy.checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED){
AlertDialog.Builder builder = new AlertDialog.Builder(((Activity)context));
builder.setTitle("This app needs location access");
builder.setMessage("Please grant location access so this app can detect beacons.");
builder.setPositiveButton(android.R.string.ok, null);
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
#Override
public void onDismiss(DialogInterface dialog) {
mainActiviy.requestPermissions(new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},PERMISSION_REQUEST_COARSE_LOCATION);
}
});
builder.show();
}
}

How to stop a service in block method in Android?

I run the code and get the following result, but I hope that the App can run at the order "A" -> "Service OnDestroy" -> "B" -> "C", how can I do ?
In My Way 2 section, I try to place the code into the function new Handler().postDelayed(new Runnable() {}, it's OK , it ran at the order "A" -> "Service OnDestroy" ->"B" ->"C",
I don't konw why the way can success, I don't know if the way is good way!
Result
11-13 10:04:32.137 27947-27947/info.dodata.screenrecorder E/My﹕ A
11-13 10:04:32.147 27947-27947/info.dodata.screenrecorder E/My﹕ B
11-13 10:04:32.157 27947-27947/info.dodata.screenrecorder E/My﹕ C
11-13 10:04:32.157 27947-27947/info.dodata.screenrecorder E/My﹕ Service OnDestroy
UIAbou.cs
public class UIAbout extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_about);
Intent intent1 = new Intent(UIAbout.this,bll.RecordService.class);
startService(intent1);
Button btnReturn = (Button) findViewById(R.id.btnReturn);
btnReturn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e("My", "A");
Intent intent1 = new Intent(UIAbout.this,bll.RecordService.class);
stopService(intent1);
Log.e("My", "B");
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_LONG).show();
Log.e("My", "C");
}
});
}
}
RecordService.cs
public class RecordService extends Service {
private Context mContext;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
}
#Override
public void onDestroy(){
Log.e("My","Service OnDestroy");
super.onDestroy(); //It seems that the APP is OK if I remove this.
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent,flags,startId);
}
}
=======================My Way 1 ======================================
I set a mark isServiceStoped to monitor if Stop Service is finished, but my app is hang up after disply the result "11-13 11:31:23.107 7599-7599/info.dodata.screenrecorder E/My﹕ A"
New UIAbout.cs
public class UIAbout extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_about);
Intent intent1 = new Intent(UIAbout.this,bll.RecordService.class);
startService(intent1);
Button btnReturn = (Button) findViewById(R.id.btnReturn);
btnReturn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e("My", "A");
Intent intent1 = new Intent(UIAbout.this, bll.RecordService.class);
stopService(intent1);
while (RecordService.isServiceStoped==false){
//It block
}
Log.e("My", "B");
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_LONG).show();
Log.e("My", "C");
}
});
}
}
New RecordService.cs
public class RecordService extends Service {
public static boolean isServiceStoped=true;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
}
#Override
public void onDestroy(){
Log.e("My", "Service OnDestroy");
isServiceStoped=true;
super.onDestroy(); //It seems that the APP is OK if I remove this.
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
isServiceStoped=false;
return super.onStartCommand(intent,flags,startId);
}
}
=====================My Way 2==========================================
I try to place the code into the function new Handler().postDelayed(new Runnable() {}, it's OK , it ran at the order "A" -> "Service OnDestroy" ->"B" ->"C",
I don't konw why the way can success, I don't know if the way is good way
The last UIAbout.cs
public class UIAbout extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_about);
Intent intent1 = new Intent(UIAbout.this,bll.RecordService.class);
startService(intent1);
Button btnReturn = (Button) findViewById(R.id.btnReturn);
btnReturn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e("My", "A");
Intent intent1 = new Intent(UIAbout.this, bll.RecordService.class);
stopService(intent1);
new Handler().postDelayed(new Runnable() {
public void run() {
Log.e("My", "B");
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_LONG).show();
Log.e("My", "C");
}
}, 1);
}
});
}
}
The last RecordService.cs
public class RecordService extends Service {
private Context mContext;
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate(){
}
#Override
public void onDestroy(){
Log.e("My", "Service OnDestroy");
super.onDestroy(); //It seems that the APP is OK if I remove this.
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent,flags,startId);
}
}
No, you can't stop a service synchronously. stopService() is request to stop the service. It will stop sometime later, as soon as it can.
No, you can't remove super.onDestroy() from your onDestroy() method and still have it work properly.
You can not control the timing to completely stop the running service. Use stopService() and the rest is out of your hands. You can use an handler to monitor is the service has stopped before moving to B although I am not sure why would you do it. Not a good practice.
Yeah you can remove super.onDestroy() in onDestroy but I would not advise you to do so. Your app may run but it will be leaving unwanted resources around.
Here how onDestroy() looks like in the android SDK:
#CallSuper
protected void onDestroy() {
if (DEBUG_LIFECYCLE) Slog.v(TAG, "onDestroy " + this);
mCalled = true;
// dismiss any dialogs we are managing.
if (mManagedDialogs != null) {
final int numDialogs = mManagedDialogs.size();
for (int i = 0; i < numDialogs; i++) {
final ManagedDialog md = mManagedDialogs.valueAt(i);
if (md.mDialog.isShowing()) {
md.mDialog.dismiss();
}
}
mManagedDialogs = null;
}
// close any cursors we are managing.
synchronized (mManagedCursors) {
int numCursors = mManagedCursors.size();
for (int i = 0; i < numCursors; i++) {
ManagedCursor c = mManagedCursors.get(i);
if (c != null) {
c.mCursor.close();
}
}
mManagedCursors.clear();
}
// Close any open search dialog
if (mSearchManager != null) {
mSearchManager.stopSearch();
}
getApplication().dispatchActivityDestroyed(this);
}
* Sample *
There could be some compile errors, but you will get the idea.
public class UIAbout extends Activity {
private Handler mHandler = new Handler();
private Runnable checkServiceHandler;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layout_about);
Intent intent1 = new Intent(UIAbout.this,bll.RecordService.class);
startService(intent1);
Button btnReturn = (Button) findViewById(R.id.btnReturn);
btnReturn.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Log.e("My", "A");
Intent intent1 = new Intent(UIAbout.this, bll.RecordService.class);
stopService(intent1);
checkServiceHandler = new Runnable() {
public void run() {
if(RecordService.isServiceStoped){
mHandler.removeCallbacks(checkServiceHandler );
somemethod();
} else{
mHandler.postDelayed(checkServiceHandler, 500);
}
}
};
mHandler.postDelayed(checkServiceHandler, 500); }
});
}
private void somemethod(){
Log.e("My", "B");
Toast.makeText(getApplicationContext(), "OK", Toast.LENGTH_LONG).show();
Log.e("My", "C");
}
}
You should implement your code in a way that you don't care when exactly your service is destroyed.
Anyway. If you really need the exact moment, you can fire an intent from your service using Android's broadcast system.
In your service:
#Override
public void onDestroy()
{
super.onDestroy();
LocalBroadcastManager.getInstance(this).sendBroadcast(new Intent(CONST_SERVICE_DESTROYED));
}
In your activity:
private BroadcastReceiver receiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
// your B here
// your C here
}
};
And you need to register and unregister your receiver like this:
#Override
protected void onResume()
{
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter(CONST_SERVICE_DESTROYED));
}
#Override
protected void onPause()
{
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
A good explanation and examples of Android's broadcast system can be found here

Bound service won't start

I have spend all day dealing with this problem, I can't solve it. I am exhausted ,have no ideas what to do with it. Please help.
I want to create service that plays music in background.But receiving always null instead of service. Sometimes onServiceConnected is called, sometimes not
public class SoundService extends Service {
private IBinder myBinder = new MyLocalBinder() ;
private static boolean isSoundOn = false;
private static boolean isBgMusicOn = false;
private static int[] soundPoolIds = null;
private Context appContext = null;
private static SoundPlayer instance = null;
private MediaPlayer mp = null;
private SoundPool sndPool = null;
public class MyLocalBinder extends Binder {
public SoundService getService() {
return SoundService.this;
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return myBinder;
}
#Override
public void onCreate() {
super.onCreate();
// initSoundPools();
}
#Override
public void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
}
#Override
public boolean onUnbind(Intent intent) {
// TODO Auto-generated method stub
return super.onUnbind(intent);
}
#Override
public void onRebind(Intent intent) {
// TODO Auto-generated method stub
super.onRebind(intent);
}
public long getCurrentTime() {
Time time = new Time();
time.setToNow();
return time.toMillis(false);
}
#SuppressLint("NewApi")
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
private void initBackground() {
//Some magic code here
}
private void playMusic(MediaPlayer mp) {
//Some magic code here
}
private boolean musicIsPlaying(MediaPlayer mp) {
//Some magic code here
}
return false;
}
public void stopPlayingBackground() {
//Some magic code here
}
private void stopPlaying(MediaPlayer mp,boolean release) {
//Some magic code here
}
private int randInt(int min, int max) {
//Some magic code here
}
private void initSoundPools() {
//Some magic code here
}
public void turnSoundOn(boolean on) {
isSoundOn = on;
}
public void turnMusicOn(boolean on) {
isBgMusicOn = on;
}
public void playBackgroundMusic() {
//Some magic code here
}
public void playSoundFx(int id) {
//Some magic code here
}
}
}
Here is Class that extends another that in turn extends Activity
public class MainActivity extends LGame {
p
private static final String TAG = "DEBUG";
private static SoundService soundService;
private static boolean isBound = false;
private Thread serviceThread;
private ServiceConnection myConnection;
#Override
public void onGamePaused() {
}
#Override
public void onGameResumed() {
// TODO Auto-generated method stub
}
#Override
protected void onDestroy() {
}
if (soundService!=null) {
soundService.stopSelf();
}
super.onDestroy();
}
public static SoundService getSoundService() {
return soundService;
}
#Override
public void onMain() {
LTexture.ALL_LINEAR = true;
LSetting setting = new LSetting();
setting.width = 800;
setting.height = 480;
setting.fps = 30;
setting.landscape = true;
setting.showFPS = false;
myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
MyLocalBinder binder = (MyLocalBinder) service;
soundService = binder.getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
serviceThread = new Thread(){
public void run(){
Intent intent = new Intent(getApplicationContext(), SoundService.class);
getApplicationContext().bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
}
};
serviceThread.start();
register(setting, MainGame.class);
}
Firstly I tried to start service in main thread but nothing changed in both cases.
Of course I've declared service in manifest.
I hope someone can help me with this.
Thx for help in advance.
EDIT
I have mentioned that I have already tried to start it like in your post but nothing changed
HELP !! I have tried almost everything
You should never bind a service in different thread, if you want to do async tasks you should create the threads inside the service itself.
#Override
public void onMain() {
LTexture.ALL_LINEAR = true;
LSetting setting = new LSetting();
setting.width = 800;
setting.height = 480;
setting.fps = 30;
setting.landscape = true;
setting.showFPS = false;
myConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className,
IBinder service) {
MyLocalBinder binder = (MyLocalBinder) service;
soundService = binder.getService();
isBound = true;
}
public void onServiceDisconnected(ComponentName arg0) {
isBound = false;
}
};
Intent intent = new Intent(getApplicationContext(), SoundService.class);
getApplicationContext().bindService(intent, myConnection, Context.BIND_AUTO_CREATE);
register(setting, MainGame.class);
}
From Android documentation :
The bindService() method returns immediately without a value.
So binding your service in the UI thread will not cause any delaying nor UI freezing.

android - how can I stop the thread inside the service?

I have a checked button in my MainActivity. If that button is checked it should start the service but if a user unchecked the button I want to stop the service.
So in uncheck condition I have written this stopService(intentname); but the problem is the service is not stopping. Here is my code snippet:
Service Class
public class SimpleService extends Service
{
String selectedAudioPath = "";
private MyThread myythread;
public Intent intent;
public boolean isRunning = false;
long interval=30000;
#Override
public IBinder onBind(Intent arg0)
{
return null;
}
#Override
public void onCreate()
{
super.onCreate();
myythread = new MyThread(interval);
}
#Override
public synchronized void onDestroy()
{
super.onDestroy();
if(!isRunning)
{
myythread.interrupt();
myythread.stop();
isRunning = false;
}
}
#Override
public synchronized void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
if(!isRunning)
{
//this.intent = intent;
//System.out.println("the intent is" + intent);
myythread.start();
isRunning = true;
}
}
class MyThread extends Thread
{
long interval;
public MyThread(long interval)
{
this.interval=interval;
}
#Override
public void run()
{
while(isRunning)
{
System.out.println("Service running");
try
{
String myString = intent.getStringExtra("name");
if(myString == null)
Log.d("Service","null");
else
{
Log.d("Service","not null");
if(myString.equalsIgnoreCase("image"))
{
uploadImages();
Thread.sleep(interval);
}
else if(myString.equalsIgnoreCase("audio"))
{
uploadAudio();
Thread.sleep(interval);
}
}
}
catch (InterruptedException e)
{
isRunning = false;
e.printStackTrace();
}
}
}
You can't stop a thread that has a running unstoppable loop like this
while(true)
{
}
To stop that thread, declare a boolean variable and use it in while-loop condition.
public class MyService extends Service {
...
private Thread mythread;
private boolean running;
#Override
public void onDestroy()
{
running = false;
super.onDestroy();
}
#Override
public void onStart(Intent intent, int startid) {
running = true;
mythread = new Thread() {
#Override
public void run() {
while(running) {
MY CODE TO RUN;
}
}
};
};
mythread.start();
}
Source: Stopping a thread inside a service
Don't use Threads. Use AsyncTask instead.
public class MyService extends Service {
private AsyncTask<Void,Void,Void> myTask;
#Override
public void onDestroy(){
super.onDestroy();
myTask.cancel(true);
}
#Override
public void onStart(Intent intent, int startid) {
myTask = new AsyncTask<Void,Void,Void>(){
#Override
public void doInBackground(Void aVoid[]){
doYourWorkHere();
}
}
myTask.execute();
}
}

Categories

Resources