如何在gcmbaseintentservice中获取位置

时间:2014-12-19 08:15:04

标签: android location google-cloud-messaging locationmanager

我希望在收到消息时获取位置 所以我使用了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>

1 个答案:

答案 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 ...
    }

}