【问题标题】:trying to make an Android service尝试制作 Android 服务
【发布时间】:2014-06-03 09:55:08
【问题描述】:

我正在尝试制作一个 Android 服务,它应该在设备启动时启动。它应该每 5 分钟通过 POST 向 php Web 服务发送位置数据到 mySQL 数据库。

它应该发送以下数据:

regID = same regId it used to register to GCM
name = a user name
latitude = the current latitude
longitude = the current longitude

我以前从未做过服务,所以我对正确的方法感到很困惑。

如果您能引导我走向正确的方向,我将不胜感激。

这是我到目前为止所做的:

package servicio;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import android.app.Service;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;

import com.google.android.gcm.GCMRegistrar;

public class GeoService extends Service {

    LocationManager manejador;
    String proveedor;
    Location localizacion;
    LocationListener locListener;
    String latitud, longitud;
    final String regId = GCMRegistrar
            .getRegistrationId(getApplicationContext());

    // double latitud, longitud;

    @Override
    public void onCreate() {
        manejador = (LocationManager) getSystemService(LOCATION_SERVICE);

    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {

        Criteria req = new Criteria();
        req.setAccuracy(Criteria.ACCURACY_FINE);

        // Lista de proveedores por criterio
        proveedor = manejador.getBestProvider(req, false);
        localizacion = manejador.getLastKnownLocation(proveedor);

        // location listener
        locListener = new LocationListener() {

            @Override
            public void onLocationChanged(Location location) {
                latitud = String.valueOf(location.getLatitude());
                longitud = String.valueOf(location.getLongitude());

                Thread sendGpsPositionToDB = new Thread(new Runnable() {

                    @Override
                    public void run() {
                        String server = "http://www.grupobcn.es/aquacleanmessenger/";
                        String serverUrl = server + "addposicion.php";
                        List<NameValuePair> params = new ArrayList<NameValuePair>();
                        params.add(new BasicNameValuePair("iddevice", regId));
                        params.add(new BasicNameValuePair("latitud", latitud));
                        params.add(new BasicNameValuePair("longitud", longitud));

                        HttpClient httpclient = new DefaultHttpClient();
                        HttpPost httppost = new HttpPost(serverUrl);

                        try {
                            httppost.setEntity(new UrlEncodedFormEntity(params));
                            HttpResponse response = httpclient
                                    .execute(httppost);
                        } catch (IOException e) {
                        }
                    }

                });

                sendGpsPositionToDB.start();
            }

            @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

            }

        };

        manejador.requestLocationUpdates(LocationManager.GPS_PROVIDER, 300000,
                0, locListener);

        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

    @Override
    public IBinder onBind(Intent intencion) {
        return null;
    }

}

【问题讨论】:

    标签: php android mysql android-service


    【解决方案1】:

    您可以通过注册广播接收器并定义 RECEIVE_BOOT_COMPLETED 权限来实现此目的。

    当用户安装应用程序时,操作系统会查看清单并注册自动启动。每当设备启动时,操作系统都会调用您的 onReceive(),以便您可以在那里启动服务,如下所示:

    在您的清单中:

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
    
    <service android:name=".GeoService" />
    
    <receiver android:name="servicio.AutoStartGeo">  
        <intent-filter>  
            <action android:name="android.intent.action.BOOT_COMPLETED" />  
        </intent-filter>  
    </receiver>
    

    定义 AutoStartGeo 类:

    public class AutoStartGeo extends BroadcastReceiver{
    
    @Override
    public void onReceive(Context context, Intent intent) {
          if (intent.getAction() != null){
        Intent startServiceIntent = new Intent(context, GeoService.class);
        context.startService(startServiceIntent);       
    }
    }
    
    }
    

    并不是说如果应用安装在 SD 卡上,这将不起作用,因为在 android.intent.action.BOOT_COMPLETED 事件之后应用将不可用。您必须将此通知用户或强制您的应用通过以下方式在内部安装:android:installLocation="internalOnly"

    同样note that 在 Android 3.0 及更高版本上,用户需要至少启动一次应用程序才能接收 android.intent.action.BOOT_COMPLETED 事件。

    【讨论】:

    • 谢谢,这对于启动问题非常有用。服务本身呢?我发布的代码有任何意义吗?对吗?
    • 有道理。使用警报管理器或 timertask 安排每 5 分钟一次的 REST 调用。在这里查看更多信息 - stackoverflow.com/questions/10221996/…
    猜你喜欢
    • 2011-02-16
    • 2016-07-12
    • 2017-04-03
    • 2014-08-26
    • 1970-01-01
    • 2012-11-27
    • 2021-06-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多