我希望在收到消息时获取位置 所以我使用了GCM服务,但它不适用于LocationListener 是否可以在GCMBaseIntentService中使用LocationListener?如果没有,我可以使用什么呢?
这是我的源代码:
@Override
public void onMessage(Context context, Intent intent) {
String type = intent.getStringExtra("type");
String fromId = intent.getStringExtra("fromId");
String fromNumber = intent.getStringExtra("fromNumber");
final String address;
if(type.equals("request_position")){
if( hasId(context, fromNumber)){
Message message = new Message();
message.obj = intent;
MyService.handler.sendMessage(message);
}else{
String addressStr = "사용자의 친구가 아닙니다.";
new SendMessage().execute("response_position",fromId,Info.get(context).getRegId(),addressStr);
}
}else if(type.equals("response_position")){
address = intent.getStringExtra("address");
Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
public void run() {
FindPhoneFragment.resultTv.setText(address);
}
});
}
}
public class MyLocation {
private Context context;
private LocationManager manager;
private MyLocationListener listener;
private Location location;
private long minTime = 1000;
private float minDistance = 1;
private String fromId;
public MyLocation(Context context){
this.context = context;
manager = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
listener = new MyLocationListener();
}
public void getMyLocation(String fromId){
manager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, minTime, minDistance, listener);
manager.requestLocationUpdates(LocationManager.GPS_PROVIDER, minTime, minDistance, listener);
}
public void sendLocation(Location location){
Geocoder geocoder = new Geocoder(context ,Locale.KOREA);
List<Address> address;
Double latitude;
Double longitude;
latitude = location.getLatitude();
longitude = location.getLongitude();
String addressStr;
try{
if(geocoder !=null){
address = geocoder.getFromLocation(latitude, longitude, 1);
if(address != null && address.size() > 0){
addressStr = address.get(0).getAddressLine(0).toString();
new SendMessage().execute("response_position",fromId,Info.get(context).getRegId(),addressStr);
}else{
Log.d("GCM", "좌표없음");
}
}
}catch(IOException e){
//TODO
}
}
class MyLocationListener implements LocationListener{
@Override
public void onLocationChanged(Location location) {
sendLocation(location);
manager.removeUpdates(listener);
}
@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
}
}
}
public class Util {
private static Util sUtil;
private Context mAppContext;
private MyLocation myLocation;
private Util(Context appContext){
mAppContext = appContext;
myLocation = new MyLocation(appContext);
}
public static Util get(Context c){
if(sUtil == null)
sUtil = new Util(c.getApplicationContext());
return sUtil;
}
public MyLocation getLocation(){
return myLocation;
}
}
public class MyService extends Service {
public static Handler handler = new Handler(){
@Override
public void handleMessage(Message msg) {
Intent intent = (Intent)msg.obj;
onMessage( intent);
}
public void onMessage( Intent intent){
String fromId =intent.getStringExtra("fromId");
Util.get().getLocation().getMyLocation(fromId);
}
};
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
android:versionCode="1"
android:versionName="1.0" xmlns:android="http://schemas.android.com/apk/res/android">
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<!-- GCM 권한 -->
<permission
android:name="com.catcha.simplefindphone.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="com.catcha.simplefindphone.permission.C2D_MESSAGE" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-feature android:glEsVersion="0x00020000" android:required="true"/>
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity android:name="com.catcha.sfp.main.MainActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.catcha.sfp.main.MemberListActivity"></activity>
<activity android:name="com.catcha.sfp.main.MapActivity"></activity>
<!-- GCM 처리 서비스 -->
<receiver
android:name="com.google.android.gcm.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.catcha.simplefindphone" />
</intent-filter>
</receiver>
<service android:name=".GCMIntentService" />
<meta-data android:name="com.google.android.maps.v2.API_KEY" android:value="AIzaSyC7PbU9IsNdkwBb6w9uSBdPi-w0wXeRVBc"/>
<meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version"/>
</application>
答案 0 :(得分:0)
IntentService是一种只要需要就会保持活动状态的服务。在GCM的情况下,它可能在处理消息后自行停止。
您可以阅读更多相关信息here。
如果您将IntentService注册为该位置的侦听器,则当locationManager尝试调用该侦听器时,它不再存在,意思是你没有获得位置。
至于你的代码,我建议你创建一个将在后台运行的常规Service。当您收到gcm消息时,将其转移到服务并在那里处理。
传输消息的方法可以通过在服务(而不是在IntentService)创建处理程序来完成。处理程序的好处是它们在创建它们的线程中执行代码。这意味着你将在一个活着的上下文中运行你的代码。
gCMBaseIntentService类:
public class gCMBaseIntentService extends GCMBaseIntentService{
public ActivityRecognitionIntentService() {
super("ActivityRecognitionService");
}
@Override
public void onMessage(Context context, Intent intent) {
Message message = new Message();
message.obj = intent;
MyService.handler.sendMessage(message);
}
}
新服务:
public class MyService extends Service {
public static Handler handler = new Handler() {
@Override
public void handleMessage(Message msg) {
Intent intent = (Intent) msg.obj;
onMessage(this, intent);
}
};
public void onMessage(Context context, Intent intent) {
... your original onMessage goes here ...
}
}