[英]How to start a method from MainActivity in a foreground service
我有一個 MainActivity,它通過單擊按鈕獲取當前位置。 在活動中,位置用三種不同的方法存儲在
我有另一個 class 來啟動前台服務 (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,
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);
}
}
}
在 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 調用它們,請將它們放在可以根據需要實例化的單獨 class 中。 如果您因為 MainActivity 中的數據都需要而無法做到這一點,請重新考慮您的架構 - 當作業服務無論如何觸發時,這些數據將不可用。
好的,第一個解決方案是創建一個新的 class (Functions.java) 並使用意圖從 MainActivity 調用此 class,然后在那里執行位置請求,然后將數據返回給 MainActivity。 然后第二步是從前台服務中執行相同的操作。 問題是,函數 class 沒有從方法中獲取數據。 如果我將硬編碼的字符串放入 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() 向意圖傳遞任何信息,我可以看到這是因為即使是硬編碼的位置字符串也沒有傳遞。 這需要修改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.