问题描述
我有一个 MainActivity,它可以通过单击按钮获取当前位置。在activity中,位置用三种不同的方法存储在
我有另一个类来启动前台服务 (ForegroundService.java),该服务从单击 MainAcivity 中的另一个按钮开始,到第三个按钮停止。
我的计划是使用 ForegroundService 和 JobService 定期(1 小时间隔)更新位置。因此,如果我们点击 MainActivity 中的 StartService 按钮,前台服务应该启动并定期调用 MainActivity 中的方法:getCurrentGPSPosition(获取位置)以及存储信息的三个方法。
MainActivity 工作正常。 ForegroundService 可以启动和停止,但我不知道如何让它从 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,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);
}
}
}
在 MainActivity 中的以下部分:
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 中。如果您需要从 Activity 和 Service 调用它们,请将它们放在可以根据需要实例化的单独类中。如果因为 MainActivity 中的数据两者都需要而无法这样做,请重新考虑您的架构 - 无论如何,当作业服务触发时,数据将不可用。
,好的,第一个解决方案是创建一个新类(Functions.java)并使用意图从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() 传递到意图,我可以看到这是因为甚至没有传递硬编码的位置字符串。 这需要修改。