簡體   English   中英

如何在前台服務中從 MainActivity 啟動方法

[英]How to start a method from MainActivity in a foreground service

我有一個 MainActivity,它通過單擊按鈕獲取當前位置。 在活動中,位置用三種不同的方法存儲在

  1. 共享首選項
  2. 一個在線SQL數據庫
  3. 在設備上的文本文件中

我有另一個 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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM