如何在前台服务中从MainActivity启动方法



我有一个MainActivity,点击按钮即可获得当前位置。在活动中,位置用三种不同的方法存储在中

  1. 共享首选项
  2. 一个在线SQL数据库
  3. 在设备上的文本文件中

我有另一个类来启动前台服务(ForegroundService.java(,它从单击MainAcivity中的另一个按钮开始,到第三个按钮停止。

我的计划是使用ForegroundService和JobService定期(间隔1小时(更新位置。因此,如果我们在MainActivity中单击StartService按钮,前台服务应该启动并定期调用MainActivity中的方法:getCurrentGPSPosition(获取位置(,以及存储信息的三个方法。

MainActivity运行良好。ForegroundService可以启动和停止,bud我不知道如何让它从MainActivity调用方法。这是代码-ForegroundService.java:


import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import static com.example.currentlocation.App.CHANNEL_ID;
public class ForegroundService extends Service {
@Override
public void onCreate() {
super.onCreate();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
//String input = intent.getStringExtra("inputExtra");
Intent notificationIntent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this,
0, notificationIntent, 0);
Notification notification = new NotificationCompat.Builder(this, CHANNEL_ID)
.setContentTitle("GPS position tracker")
//.setContentText(input)
.setSmallIcon(R.drawable.ic_baseline_gps_fixed_24)
.setContentIntent(pendingIntent)
.build();
startForeground(1, notification);
return START_NOT_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

App.java


import android.app.Application;
import android.app.NotificationChannel;
import android.app.NotificationManager;
public class App extends Application {
public static final String CHANNEL_ID = "CurrentLocationServiceChannel";
@Override
public void onCreate() {
super.onCreate();
createNotificationChannel();
}
private void createNotificationChannel(){
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel serviceChannel = new NotificationChannel(
CHANNEL_ID,
"Current Location Service Channel",
NotificationManager.IMPORTANCE_DEFAULT
);
NotificationManager manager = getSystemService(NotificationManager.class);
manager.createNotificationChannel(serviceChannel);
}

}
}

在主活动中,以下部分:

public class MainActivity extends AppCompatActivity {
........
//Backgroundservice
public void startService(View v){
//   String input = editTextInput.getText().toString();
Intent serviceIntent = new Intent(this, ForegroundService.class);
//  serviceIntent.putExtra("inputExtra", input);
startService(serviceIntent);
}
public void stopService(View v){
Intent serviceIntent = new Intent(this, ForegroundService.class);
stopService(serviceIntent);
}
//Method to store in SQL online
public void  OnReg() {.......code....}
//Method to save data in SharedPreferences
public void saveData() {.......code....}
//Method to save data in Internal File
public void saveToFile() {.......code....}
//method for GPS request
getCurrentGPSLocation() {.......code....}
}

有人知道如何解决这个问题吗?或者你需要更多的细节吗?谢谢你的帮助!

不要将这些函数放在MainActivity中。如果您需要从活动和服务中调用它们,请将它们放在一个单独的类中,该类可以根据需要实例化。如果因为MainActivity中有两个都需要的数据而无法做到这一点,请重新思考您的体系结构——无论如何,当作业服务启动时,这些数据都不可用。

好的,第一个解决方案是创建一个新的类(Functions.java(,并使用intent从MainActivity中调用这个类,然后在那里进行位置请求,然后将数据返回给MainActivity。第二步是从前台服务执行同样的操作。问题是,函数类没有从方法中获取数据。如果我将硬编码字符串放入intent中,它们将被传输到MainActivity,因此intent可以工作。因此,这只是完整解决方案的一部分。这是代码:

public class Functions extends AppCompatActivity {
//initialize variable
FusedLocationProviderClient fusedLocationProviderClient;
private double ser_Latitude;
private double ser_Longitude;
private String ser_Accuracy;
private String ser_Altitude;
private String currentDateandTime;
private String ser_Location;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Boolean precision = getIntent().getBooleanExtra("precision", true);
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(
Functions.this);
getCurrentGPSLocation();
Intent intent = new Intent();
intent.putExtra("latitude", ser_Latitude);
intent.putExtra("longitude", ser_Longitude);
intent.putExtra("accuracy", ser_Accuracy);
intent.putExtra("altitude", ser_Altitude);
intent.putExtra("location", ser_Location);
intent.putExtra("currentDateandTime", currentDateandTime);
setResult(RESULT_OK, intent);
Functions.this.finish();
}
//Force new GPS Location Request
private void getCurrentGPSLocation() {
// get the new location from the fused client
// update the UI - i.e. set all properties in their associated text view items
//Initialize new location request
LocationRequest locationRequest = new LocationRequest()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(3000)
.setFastestInterval(2000)
.setNumUpdates(1)
;
//Initialize location call back
LocationCallback locationCallback = new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
//Initialize location1
Location location1 = locationResult.getLastLocation();
//Set latitude
ser_Latitude = location1.getLatitude();
//Set longitude
ser_Longitude = location1.getLongitude();
//Set Accuracy
double ser_accura1 = location1.getAccuracy();
ser_Accuracy = new DecimalFormat("##.##").format(ser_accura1) + " m";
//Set Altitude
double ser_altit1 = location1.getAltitude();
ser_Altitude = new DecimalFormat("##.##").format(ser_altit1) + " m";
//Get Adress
/*  Geocoder geocoder = new Geocoder(getApplicationContext(), Locale.getDefault());
try {
List<Address> listAddresses = geocoder.getFromLocation(ser_Latitude, ser_Longitude, 1);
if (null != listAddresses && listAddresses.size() > 0) {
String _Location1 = listAddresses.get(0).getAddressLine(0);
//Set Location
//ser_Location = String.valueOf(_Location1);
}
} catch (IOException e) {
e.printStackTrace();
}*/

//Set location as hard-coded string for testing
ser_Location = "London";
//Set Update Time
SimpleDateFormat sdf = new SimpleDateFormat("dd.MM.yyyy 'um ' HH:mm:ss z");
currentDateandTime = sdf.format(new Date());
}
};

//Request location updates
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
fusedLocationProviderClient.requestLocationUpdates(locationRequest
, locationCallback, Looper.myLooper());
}

}

新的GPS请求被触发,因为我可以看到正在运行应用程序,但没有从方法getCurrentGPSLocation((向意图传递任何信息,我可以看到这一点,因为即使是硬编码的位置字符串也没有传递。这需要修改。

最新更新