服务每20米或3秒获取一次位置

时间:2018-02-04 20:12:29

标签: android service broadcastreceiver

我有一个拥有数据库和内容提供商的应用。在一个活动中,用户输入用户ID,经度,纬度和时间戳 我现在需要在手机启动时收集位置并每隔20米或3秒将其保存在数据库中,当飞机停止服务或关闭时启动服务。

这是代码:

服务:

public class MyService extends Service implements LocationListener {
    LocationManager locationManager;
    boolean isGPSEnable = false;
    boolean isNetworkenable = false;
    double latitude,longitude;
    long td;
    Location location;
    MyBinder myBinder = new MyBinder();


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

    Toast.makeText(this, "Service is started", Toast.LENGTH_SHORT).show();
    locationManager = (LocationManager) getApplication().getSystemService(LOCATION_SERVICE);
    isGPSEnable = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
    isNetworkenable = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

    if (!isGPSEnable && !isGPSEnable) {
        Toast.makeText(this, "GPS IS DISABLE!!", Toast.LENGTH_SHORT).show();
    } else {
        try {
            if (isGPSEnable) {
                location = null;
                //checkPermission(LocationManager.NETWORK_PROVIDER, 1, 0);
                locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 3000, 20, this);
                if (locationManager != null) {
                    location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                    Log.e("latitude", location.getLatitude() + "");
                    Log.e("longitude", location.getLongitude() + "");
                    latitude = location.getLatitude();
                    longitude = location.getLongitude();
                    td=location.getTime();
                    Toast.makeText(this, "DT:"+td+"lat:"+latitude+"Long: "+longitude, Toast.LENGTH_SHORT).show();
                }


            }
        } catch (SecurityException e) {
            e.printStackTrace();
        }

    }
    ContentResolver resolver = this.getContentResolver();
    Uri url = Uri.parse("content://gr.hua.android.contentproviderapp/COORDINATES");

    ContentValues values = new ContentValues();
    values.put("_LONGITUDE",longitude );
    values.put("_LATITUDE", latitude);
    values.put("_DT", td);
    resolver.insert(url, values);

    return START_NOT_STICKY;
}

@Override
public void onCreate() {
    super.onCreate();
    Toast.makeText(this, "Service is Created", Toast.LENGTH_SHORT).show();

}

@Override
public IBinder onBind(Intent intent) {
    return myBinder;
}



@Override
public void onLocationChanged(Location location) {

}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {

}

@Override
public void onProviderEnabled(String provider) {

}

@Override
public void onProviderDisabled(String provider) {

}
public class MyBinder extends Binder{
    public MyService getService(){
        return MyService.this;
    }

}
public Location loc(){
    return location;
}

}

在这个服务中我获取位置并将其放入变量并在使用contentresolver将其发送到db之后

public class startReceiver1 extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Intent i = new Intent(context,MyService.class);
        context.startService(i);
    }
}

在手机启动时启动服务

public class startReceiver extends BroadcastReceiver {


    @RequiresApi(api = Build.VERSION_CODES.N)
    @Override
    public void onReceive(Context context, Intent intent) {
        AlarmManager alarmManager=(AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
            Intent i = new Intent();
            i.setClass(context,MyService.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0,i,PendingIntent.FLAG_CANCEL_CURRENT);
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.SECOND,3);
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(),3000,pendingIntent);
    }
}

每3秒启动一次该服务

public class ScheduledStartReceiver extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent intent) {
    IntentFilter intentfilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
    intentfilter.addAction(Intent.ACTION_AIRPLANE_MODE_CHANGED);
    Log.d("AirplaneMode","Service state change"); // debugging
    boolean airplane_active = isAirplaneModeOn(context);
    Intent i = new Intent();
    i.setClass(context,MyService.class);
    if (!airplane_active) {
        context.startService(i);
    }else{
        context.stopService(i);
        Toast.makeText(context, "Airplane on", Toast.LENGTH_LONG).show();
    }
}


    public static boolean isAirplaneModeOn(Context context) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN_MR1) {
            return Settings.System.getInt(context.getContentResolver(),
                    Settings.System.AIRPLANE_MODE_ON, 0) != 0;
        } else {
            return Settings.Global.getInt(context.getContentResolver(),
                    Settings.Global.AIRPLANE_MODE_ON, 0) != 0;
        }
    }
}

和飞机模式的接收器在开启时停止服务以及何时关闭以启动服务

清单:

<uses-permission android:name="android.permission.INTERNET" />
<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_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".FirstActivity">

        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".SecondActivity" />
    <activity android:name=".ThirdActivity" />

    <service
        android:name=".MyService">

    </service>
    <receiver android:name=".startReceiver">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED">
            </action>
        </intent-filter>
    </receiver>
    <receiver android:name=".startReceiver1">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
        </intent-filter>
    </receiver>
    <receiver android:name=".ScheduledStartReceiver">
        <intent-filter>
            <action android:name="android.intent.action.AIRPLANE_MODE"/>
        </intent-filter>
    </receiver>
</application>

问题是服务永远不会开始..

我不知道这是否是一个很好的逻辑来实现这个我是Android的初学者,所以如果你能用代码或简单的单词解释..

提前Thnx!

1 个答案:

答案 0 :(得分:0)

也许不同的方法是使用调度程序。看看https://developer.android.com/topic/performance/scheduling.html。这将让您了解可用的选项。根据您的目标API级别进行选择。这些将为您处理飞机模式,数据连接丢失等。

我们最近使用了由EverNote团队开发的Android-Job。 https://github.com/evernote/android-job

我们选择此选项的原因在于它会自动为您选择正确的计划选项。然后我们可以轻松地在多个Android版本中应用相同的逻辑。