后台服务需要将GPS位置发送到服务器。

13

我在我的Android应用程序中遇到了问题。我需要一个应用程序,每10分钟将GPS位置以后台方式发送到服务器(这里我有一个正在工作的WCF服务)。即使应用程序被关闭,应用程序也需要发送数据。因此,我创建了一个服务(用于测试目的),向我发送服务器上的时间。但是,当我在我的服务中插入获取GPS位置的代码时,一切都失败了(意外停止)。

我已经阅读过一些内容,需要放置一些接收器或类似的东西,但目前没有任何作品。所以,如果有人能帮我,我将非常高兴。

  <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.biromatik.GPS"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk android:minSdkVersion="4" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name=".ETMGPSServiceActivity" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:name=".MyApplication" >
    <service
        android:enabled="true"
        android:name=".MonitorService" >
    </service>
    <receiver
        android:enabled="true"
        android:name=".LocationReceiver" >
        <intent-filter >
            <action android:name="com.biromatik.intent.action.LOCATION" />
        </intent-filter>
    </receiver>
</application>


     <uses-permission android:name="android.permission.INTERNET"></uses-permission>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.SEND_SMS"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />




</manifest>

"我的服务出了问题,一切都失败了(意外停止)" -> 你收到了什么错误信息? - Hoff
在CatLog中我得到了这个:11-11 15:25:49.541: E/AndroidRuntime(229): 未捕获的处理程序:由于未捕获的异常,主线程正在退出。 - Mihael Meklav
1个回答

35

我在我的应用程序中完成了与您提出的相同任务。

在我的服务中,我添加了以下内容:

@Override
public void onStart(Intent intent, int startId) {

    super.onStart(intent, startId);
    addLocationListener();
}

private void addLocationListener()
{
    triggerService = new Thread(new Runnable(){
        public void run(){
            try{
                Looper.prepare();//Initialise the current thread as a looper.
                lm = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

                Criteria c = new Criteria();
                c.setAccuracy(Criteria.ACCURACY_COARSE);

                final String PROVIDER = lm.getBestProvider(c, true);

                MyLocationListener myLocationListener = new MyLocationListener();
                lm.requestLocationUpdates(PROVIDER, 600000, 0, myLocationListener);
                Log.d("LOC_SERVICE", "Service RUNNING!");
                Looper.loop();
            }catch(Exception ex){
                ex.printStackTrace();
            }
        }
    }, "LocationThread");
    triggerService.start();
}

public static void updateLocation(Location location)
{
    Context appCtx = MyApplication.getAppContext();

    double latitude, longitude;

    latitude = location.getLatitude();
    longitude = location.getLongitude();

    Intent filterRes = new Intent();
    filterRes.setAction("xxx.yyy.intent.action.LOCATION");
    filterRes.putExtra("latitude", latitude);
    filterRes.putExtra("longitude", longitude);
    appCtx.sendBroadcast(filterRes);
}


class MyLocationListener implements LocationListener
{

    @Override
    public void onLocationChanged(Location location)
    {
        updateLocation(location);
    }
}

注意:看到我使用 MyApplication.getAppContext();,那是因为我正在使用自己的Application类来添加上下文。

然后我有一个具有以下代码的BroadcastReceiver:

public class LocationReceiver extends BroadcastReceiver {

    double latitude, longitude;

    @Override
    public void onReceive(final Context context, final Intent calledIntent)
    {
        Log.d("LOC_RECEIVER", "Location RECEIVED!");

        latitude = calledIntent.getDoubleExtra("latitude", -1);
        longitude = calledIntent.getDoubleExtra("longitude", -1);

        updateRemote(latitude, longitude);

    }

    private void updateRemote(final double latitude, final double longitude )
    {
        //HERE YOU CAN PUT YOUR ASYNCTASK TO UPDATE THE LOCATION ON YOUR SERVER
    }
}

Application类:

public class MyApplication extends Application {


    private static Context context;

    /* (non-Javadoc)
     * @see android.app.Application#onCreate()
     */
    @Override
    public void onCreate() {            
        MyApplication.context=getApplicationContext();
    }

    public static Context getAppContext() {
        return MyApplication.context;
    }
}

另外,在您的清单文件中,您需要添加以下两个内容:

<application
    android:icon="@drawable/icon"
    android:label="@string/app_name"
    android:name=".MyApplication" >

    //YOUR ACTIVITIES HERE...

    <service
        android:enabled="true"
        android:name=".LocationService" >
    </service>

    <receiver
        android:enabled="true"
        android:name=".LocationReceiver" >
        <intent-filter >
            <action android:name="xxx.yyy.intent.action.LOCATION" />
        </intent-filter>
    </receiver>
</application>

检测服务是否正在运行的方法。我在我的第一个Activity中这样做:

/**
 * Check location service.
 */
private void checkLocationService()
{
    Log.d("CHECK_SERVICE", "Service running: " + (settings.getBoolean("locationService", false)?"YES":"NO"));

    if(settings.getBoolean("locationService", false))
        return;

    Intent mServiceIntent = new Intent(this, LocationService.class);
    startService(mServiceIntent);
}

显然,你需要控制SharedPreferences (settings) 来设置 locationService 变量为 true/false,如果服务正在运行 (onStart) 或者未运行 (onDestroy)。


就像我之前所说的,你需要创建一个继承自Application的类(并将其添加到你的清单文件中)。xxx.yyy.intent.action.LOCATION可以是任何你想要的东西,比如你的包名,然后添加intent.action.LOCATION来使它更加具体。我将在我的回答中编辑这个应用程序类。 - SERPRO
现在我明白了:W/ActivityManager(51): 无法启动服务 Intent { act=com.biromatik.GPS.MonitorService }: 未找到。你能告诉我如何启动该服务吗? - Mihael Meklav
你的服务类是否与应用程序在同一个包中? - SERPRO
请在您的问题中发布您的服务类。 - SERPRO
我添加了我使用的方法。如果你想使用相同的方法,请不要忘记在SharedPreferences中设置locationService的值。 - SERPRO
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接