I'm new on android developing. I need to make a service to start when gps activated.
That's what I've done so far:
service:
public class MainService extends Service implements LocationListener {
private LocationManager locationManager;
Intent i;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 30000, 1, this);
return super.onStartCommand(intent, flags, startId);
}
#Override
public void onLocationChanged(Location location) {
String msg = "New Latitude: " + location.getLatitude()
+ "New Longitude: " + location.getLongitude();
Log.d("",msg);
}
#Override
public void onProviderDisabled(String provider) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
startActivity(intent);
Log.i("", "------------------->GPS is off");
}
#Override
public void onProviderEnabled(String provider) {
Log.i("", "------------------->Gps is turned on!! ");
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
}
Broadcast Receiver:
public class GPSReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("", "Receiver is on");
if (intent.getAction().matches("android.location.PROVIDERS_CHANGED")) {
// react on GPS provider change action
Intent serviceIntent = new Intent(context, MainService.class);
context.startService(serviceIntent);
}
}
}
Manifest:
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<receiver
android:name="gr.dit.hua.it21370.gpsreciever.GPSReceiver"
android:enabled="true"
android:exported="false">
<intent-filter>
<action android:name="android.location.PROVIDERS_CHANGED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<service
android:name="gr.dit.hua.it21370.gpsreciever.MainService"
android:process=":gps_service">
</service>
</application>
I've tried and I've searched a lot but I didn't manage to fix it.
Please help me.
Thanks in advance :)
Related
I used a Service class in my application. It works fine at other versions, but when I tested it in 5.0.2, it works fine when the application is in running state. But when I closed my Application, the service is stopped. I need the service to run continuously in background.
Here is my Service class:
public class ServiceClass extends Service{
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
UpdateLocation();
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
private void UpdateLocation() {
timer.scheduleAtFixedRate(new TimerTask() {
public void run() {
Thread thread = new Thread() {
#Override
public void run() {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
if (mGoogleApiClient != null) {
mGoogleApiClient.connect();
}
if (mLastLocation != null) {
Log.e("lat", String.valueOf(latitude));
latitude = mLastLocation.getLatitude();
longitude = mLastLocation.getLongitude();
}
GetLocationUpdate();
}
};
thread.start();
}
}, 0, UPDATE_TASK);
}
}
This is my WakefulBroadcastReceiver
public class BootCompleteReceiver extends WakefulBroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent service = new Intent(context, ServiceClass.class);
context.startService(service);
}
}
My Manifest File
<service android:name=".service.ServiceClass" />
<receiver android:name=".service.BootCompleteReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Thanks in advance and please help me.
I am trying to create a service that will run on bootup, however when trying it in my emulator the log is not showing my message through log tag, so clearly something is wrong.
Here is my code.
service.java
public class service extends Service {
private static final String TAG = "myapp.mycomp";
public service() {
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "Service started");
Runnable r = new Runnable() {
#Override
public void run() {
/** something to do **/
}
};
Thread service = new Thread(r);
service.start();
return Service.START_STICKY;
}
#Override
public void onDestroy() {
Log.i(TAG, "Service stopped");
}
#Override
public IBinder onBind(Intent intent) {
return null;
}
MyReceiver.java
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Intent myIntent = new Intent(context, service.class);
context.startService(myIntent);
}
}
XML manifest intent
<receiver android:name=".MyReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
XML manifest permission
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
I use AIDL interface IExtendedNetworkService to get USSD code. But application only work after reboot device. I tried bindservice after install app but it didn't work. So my problem is how way to bind service without reboot device . This is my code:
interface:
package com.android.internal.telephony;
interface IExtendedNetworkService {
void setMmiString(String number);
CharSequence getMmiRunningText();
CharSequence getUserMessage(CharSequence text);
void clearMmiString();
}
Service
public class CDUSSDService extends Service {
private String TAG = "THANG-NGUYEN";
private boolean mActive = false;
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_INSERT)) {
// activity wishes to listen to USSD returns, so activate this
mActive = true;
Log.d(TAG, "activate ussd listener");
} else if (intent.getAction().equals(Intent.ACTION_DELETE)) {
mActive = false;
Log.d(TAG, "deactivate ussd listener");
}
}
};
private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub() {
public void clearMmiString() throws RemoteException {
Log.d(TAG, "called clear");
}
public void setMmiString(String number) throws RemoteException {
Log.d(TAG, "setMmiString:" + number);
}
public CharSequence getMmiRunningText() throws RemoteException {
if (mActive == true) {
return null;
}
return "USSD Running";
}
public CharSequence getUserMessage(CharSequence text)
throws RemoteException {
Log.d(TAG, "get user message " + text);
if (mActive == false) {
// listener is still inactive, so return whatever we got
Log.d(TAG, "inactive " + text);
return text;
}
// listener is active, so broadcast data and suppress it from
// default behavior
// build data to send with intent for activity, format URI as per
// RFC 2396
Uri ussdDataUri = new Uri.Builder()
.scheme(getBaseContext().getString(R.string.uri_scheme))
.authority(
getBaseContext().getString(R.string.uri_authority))
.path(getBaseContext().getString(R.string.uri_path))
.appendQueryParameter(
getBaseContext().getString(R.string.uri_param_name),
text.toString()).build();
sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, ussdDataUri));
mActive = false;
return null;
}
};
public void onCreate() {
Log.i(TAG, "called onCreate");
};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "called onStartCommand");
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "called onbind");
// the insert/delete intents will be fired by activity to
// activate/deactivate listener since service cannot be stopped
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_INSERT);
filter.addAction(Intent.ACTION_DELETE);
filter.addDataScheme(getBaseContext().getString(R.string.uri_scheme));
filter.addDataAuthority(
getBaseContext().getString(R.string.uri_authority), null);
filter.addDataPath(getBaseContext().getString(R.string.uri_path),
PatternMatcher.PATTERN_LITERAL);
registerReceiver(receiver, filter);
return mBinder;
}
}
MainActivity:
public class MainActivity extends Activity {
private Button btnCheckUSSD;
private Context mContext;
private IExtendedNetworkService mService;
private EditText inputUSSD;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mContext = this;
setContentView(R.layout.activity_main);
btnCheckUSSD = (Button) findViewById(R.id.btn_check);
inputUSSD = (EditText) findViewById(R.id.input_ussd);
btnCheckUSSD.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View arg0) {
if (!inputUSSD.getText().toString().isEmpty()) {
Intent service = new Intent(
"com.android.ussd.IExtendedNetworkService");
bindService(service, mConnecton, Context.BIND_AUTO_CREATE);
startActivity(new Intent("android.intent.action.CALL", Uri
.parse("tel:" + inputUSSD.getText().toString()
+ Uri.encode("#"))));
}
}
});
}
ServiceConnection mConnecton = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
}
#Override
public void onServiceConnected(ComponentName name, IBinder iBinder) {
mService = IExtendedNetworkService.Stub
.asInterface((IBinder) iBinder);
}
};
protected void onDestroy() {
super.onDestroy();
Log.d("THANG-NGUYEN", "onDestroy");
unbindService(mConnecton);
}
}
Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="info.example.checkussdcode"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="7"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="info.example.checkussdcode.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="info.example.checkussdcode.service.UssdCodeService"
android:process=":remote" >
<intent-filter>
<action android:name="com.android.ussd.IExtendedNetworkService" >
</action>
</intent-filter>
</service>
<receiver android:name="info.example.checkussdcode.RebootReceiver" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
</manifest>
I found hundreds of topics related to the same problem, but I cannot understand where I get wrong! Because I have written the same code basically...
This is a service which controls the position and adds a promityAlert
public class GeoReminderService extends Service implements LocationListener{
private LocationManager locationManager;
private final String proximityIntentAction = "com.example.geo.ProximityIntentReceiver";
private float latitude;
private float longitude;
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 400, 10, this);
addProximityAlert(45.477872,9.23457);
return Service.START_STICKY;
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onLocationChanged(Location location) {
Log.v("Service","Location changed");
if (location != null) {
Log.v("Location changed : Lat: ", ""+location.getLatitude());
Log.v("Location changed : Lon: ", ""+location.getLongitude());
}
}
#Override
public void onProviderDisabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onProviderEnabled(String provider) {
// TODO Auto-generated method stub
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
// TODO Auto-generated method stub
}
private void addProximityAlert(double latitude, double longitude) {
Log.v("Service","proximity alert added" + latitude +" "+ longitude);
Intent intent = new Intent(proximityIntentAction);
PendingIntent proximityIntent = PendingIntent.getBroadcast(getApplicationContext(), -1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
locationManager.addProximityAlert(latitude, longitude, 3000, -1, proximityIntent);
IntentFilter filter = new IntentFilter(proximityIntentAction);
registerReceiver(new ProximityIntentReceiver(), filter);
}
Instead this one is the receiver which should captures the event
public class ProximityIntentReceiver extends BroadcastReceiver {
private static final int NOTIFICATION_ID = 1000;
#Override
public void onReceive(Context context, Intent intent) {
Log.v("proximity receiver", "alert received");
String key = LocationManager.KEY_PROXIMITY_ENTERING;
Boolean entering = intent.getBooleanExtra(key, false);
if (entering) {
Log.v("ProximityIntentReceiver", "entering");
}
else {
Log.v("ProximityIntentReceiver", "exiting");
}
}
Even if I change the position (I am using the Android emulator) the event onReceive doesn't fire. At the same time I am sure that I am changing the position correctly , since the event locationChanged works. Can anyone help me, please?
Have you declared ProximityIntentReceiver in the manifest?
In the same area of the manifest where you declare activites, etc., you'd also declare your BroadcastReceiver.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.geo"
android:versionCode="001"
android:versionName="0.1"
>
<application>
...
<receiver android:name=".ProximityIntentReceiver">
</receiver>
</application>
</manifest>
My application works as follows:
I have one location listener to every activity
My location listener(which contains location listener) send broadcast on location changed
All activities have broadcast receiver which allows them to set location on map
It has to be working like that, but even my service doesn't start. I'm exhausted writing this app so I place my code here, maybe I overlooked some simple issue. I need help with that topic:
GPS Service:
// package and imports
public class GeoService extends Service {
LocationListener GPSLocationListener, NetworkLocationListener;
LocationManager locationManager;
private IBinder mBinder;
#Override
public void onCreate() {
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
getPosition();
return Service.START_REDELIVER_INTENT;
}
#Override
public IBinder onBind(Intent intent) {
getPosition();
if (mBinder == null) mBinder = new GeoBinder();
return mBinder;
}
private void getPosition() {
GPSLocationListener = new LocationListener() {
public void onLocationChanged(Location location) {
sendPosition(location);
}
public void onProviderDisabled(String provider) {
Toast.makeText(getApplicationContext(), provider + " is now disabled. Turn it on to find better GPS position.", Toast.LENGTH_SHORT).show();
}
public void onProviderEnabled(String provider) {
Toast.makeText(getApplicationContext(), provider.toUpperCase() + " is now enabled. Waiting for better position..", Toast.LENGTH_SHORT).show();
}
public void onStatusChanged(String provider, int status, Bundle extras) {
switch (status) {
case 0:
case 1:
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, NetworkLocationListener);
break;
case 2:
locationManager.removeUpdates(NetworkLocationListener);
break;
}
}
};
NetworkLocationListener = new LocationListener() {
public void onLocationChanged(Location location) {
sendPosition(location);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, GPSLocationListener);
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, NetworkLocationListener);
if (!locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER) && !locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) alert();
}
private void alert() {
AlertDialog.Builder builder = new AlertDialog.Builder(getApplicationContext());
builder.setMessage("Internet connection and GPS are not avaiable!.").setCancelable(false).setTitle("No location provider!").setIcon(android.R.drawable.ic_dialog_alert).setPositiveButton("Change settings", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
startActivity(new Intent(getApplicationContext(), SettingsActivity.class));
}
}).create().show();
}
void sendPosition(Location location) {
Intent gpsPosition = new Intent();
gpsPosition.putExtra("location", location);
gpsPosition.setAction(Context.LOCATION_SERVICE);
sendBroadcast(gpsPosition);
}
public GeoPoint getGeoPoint(final Location loc) {
int lat = (int) (loc.getLatitude() * 1e6);
int lon = (int) (loc.getLongitude() * 1e6);
return new GeoPoint(lat, lon);
}
public GeoPoint getLastLocation() {
GeoPoint lastKnownPoint;
Location lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (lastKnownLocation == null) lastKnownLocation = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (lastKnownLocation != null) lastKnownPoint = getGeoPoint(lastKnownLocation);
else lastKnownPoint = new GeoPoint((int) (51.110582 * 1E6), (int) (17.031509 * 1E6));
return lastKnownPoint;
}
#Override
public void onDestroy() {
locationManager.removeUpdates(GPSLocationListener);
locationManager.removeUpdates(NetworkLocationListener);
}
public class GeoBinder extends Binder {
public GeoService getService() {
return GeoService.this;
}
}
}
One of Activities: (I tried to start or bind service but none method seems to be working).
// package and imports
public class ShareLocationActivity extends MapActivity {
private final int PICK_CONTACT = 123;
MapView.LayoutParams mapMarkerParams;
MapController mapController;
Location lastLocation;
ImageView mapMarker;
GeoPoint current;
MapView map;
private ServiceConnection mConnection;
GeoService mService;
boolean mBound = false;
BroadcastReceiver locationReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
setPosition((Location) intent.getParcelableExtra("location"));
}
};
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_share_location);
mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName name, IBinder service) {
GeoBinder binder = (GeoBinder) service;
mService = binder.getService();
mBound = true;
mapController = map.getController();
mapController.setCenter(mService.getLastLocation());
mapController.setZoom(17);
}
public void onServiceDisconnected(ComponentName name) {
mBound = false;
}
};
Intent intent = new Intent(this, GeoService.class);
startService(intent);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
map = (MapView) findViewById(R.id.shareMapView);
map.setBuiltInZoomControls(true);
map.setSaveEnabled(true);
mapMarker = new ImageView(getApplicationContext());
mapMarker.setImageResource(android.R.drawable.presence_online);
Button share = (Button) findViewById(R.id.shareActivityButton);
share.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
Intent contacts_intent = new Intent(Intent.ACTION_PICK, ContactsContract.Contacts.CONTENT_URI);
startActivityForResult(contacts_intent, PICK_CONTACT);
}
});
IntentFilter filter = new IntentFilter();
filter.addAction(Context.ACTIVITY_SERVICE);
registerReceiver(locationReceiver, filter);
}
#Override
public void onActivityResult(int reqCode, int resultCode, Intent data) {
super.onActivityResult(reqCode, resultCode, data);
switch (reqCode) {
case (PICK_CONTACT):
if (resultCode == Activity.RESULT_OK) {
if (current != null) sendSms(data);
else Toast.makeText(getApplicationContext(), "No GPS data yet..", Toast.LENGTH_SHORT).show();
}
break;
}
}
#Override
protected void onResume() {
super.onResume();
if (!mBound) {
Intent intent = new Intent(this, GeoService.class);
bindService(intent, mConnection, Context.BIND_AUTO_CREATE);
}
};
#Override
protected void onPause() {
map.removeAllViews();
if (mBound) {
unbindService(mConnection);
mBound = false;
}
super.onPause();
}
#Override
protected void onDestroy() {
super.onDestroy();
map.removeAllViews();
}
void setPosition(Location location) {
map.removeAllViews();
current = mService.getGeoPoint(location);
mapMarkerParams = new MapView.LayoutParams(android.view.ViewGroup.LayoutParams.WRAP_CONTENT, android.view.ViewGroup.LayoutParams.WRAP_CONTENT, current, MapView.LayoutParams.TOP_LEFT);
map.addView(mapMarker, mapMarkerParams);
mapController.setCenter(current);
}
#Override
protected boolean isRouteDisplayed() {
return false;
}
}
And to be sure Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="gps.counter"
android:versionCode="1"
android:versionName="1.0" >
<uses-feature android:name="android.hardware.location" />
<uses-feature android:name="android.hardware.location.gps" />
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="15" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.CONTROL_LOCATION_UPDATES" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<application
android:icon="#drawable/ico"
android:label="#string/app_name"
android:theme="#android:style/Theme.NoTitleBar" >
<uses-library android:name="com.google.android.maps" />
<activity android:name=".MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".SaveLocationActivity" />
<activity android:name=".ShareLocationActivity" />
<activity android:name=".RecordTrackActivity" />
<activity android:name=".SettingsActivity" />
<service
android:name=".GeoService"
android:enabled="true" />
</application>
</manifest>
The solution is to keep service and activity which uses it in one package.
It is small issue but can be big problem for someone.