为什么我的服务在后台不工作?

huangapple go评论74阅读模式
英文:

Why My service don t work in the Backgroung?

问题

以下是MainActivity代码的翻译部分:

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, LocationListener {

    // ... (其他的变量声明和初始化)

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // ... (其他的UI元素初始化和逻辑处理)

        googleApiClient = new GoogleApiClient.Builder(context)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this).build();

        updateFCM(M.getID(context));
    }

    // ... (其他的方法实现)

    @Override
    public void onLocationChanged(Location location) {
        this.currentLocation = location;

        if (currentLocation != null) {
            new setCurrentLocation().execute(String.valueOf(location.getLatitude()),String.valueOf(location.getLongitude()));
        }
    }

    private class setCurrentLocation extends AsyncTask<String, Void, String> {
        @Override
        protected String doInBackground(String... params) {
            // ... (设置位置的网络请求)

            return null;
        }

        @Override
        protected void onPostExecute(String result) {
            // ... (后续处理)
        }

        @Override
        protected void onPreExecute() {
            // ... (预处理)
        }
    }

    // ... (其他的方法实现)

    @Override
    public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
        switch (requestCode) {
            case LOCATION_REQUEST_CODE: {
                if (!isLocationEnabled(context))
                    showMessageEnabledGPS();
                return;
            }
        }
    }

    public void showMessageEnabledGPSClient() {
        // ... (显示GPS设置提示对话框)
    }

    public void showMessageEnabledGPS() {
        // ... (显示GPS设置提示对话框)
    }

    private boolean isLocationEnabled(Context context) {
        // ... (判断GPS是否开启)
    }
}

以下是MyService代码的翻译部分:

import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

public class MyService extends Service implements LocationListener {

    private LocationRequest locationRequest;
    public static Location currentLocation;
    private GoogleApiClient googleApiClient;
    public static Context context;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (ActivityCompat.checkSelfPermission(context,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(context,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // 权限检查

            currentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
            startLocationUpdates();
        }
        return START_STICKY;
    }

    private void startLocationUpdates() {
        locationRequest = new LocationRequest();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(5000);
        locationRequest.setFastestInterval(2000);

        if (ActivityCompat.checkSelfPermission(context,
                Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
                && ActivityCompat.checkSelfPermission(context,
                Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // 权限检查
        }

        LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
    }

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

    @Override
    public void onLocationChanged(Location location) {
        // ... (位置变化监听)
    }
}

请注意,由于你的原始代码中有一些HTML实体编码(如&quot;),在翻译过程中我已将其还原为正常的双引号。另外,为了保持代码的清晰,我省略了一些重复或者与问题关系不大的部分。如果你需要对代码进行修改或添加,请务必注意代码的逻辑和结构。

英文:

Im working on an taxi app that need to keep tracking driver even when the app is in background or the screen is off
I tried to do it through a Service but it dons t work and I cant find the probleme

My second issue it that the app don t upload some kind of images for example whene i take a high quality photo with my phone and i upload it in the server the app keep saying failed but the photo is uploaded on the server / and whene i take a screenshot un upload it it work fine

3Q/ what are the minimun requemendation of a server to use with a taxi app

this is the MainActivity code

public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener, LocationListener {
/** MAP **/
public static GoogleMap mMap;
public static Location currentLocation;
/** GOOGLE API CLIENT **/
private GoogleApiClient googleApiClient;
private static final int PLAY_SERVICES_RESOLUTION_REQUEST = 9000;
private LocationRequest locationRequest;
private static final long UPDATE_INTERVAL = 5000, FASTEST_INTERVAL = 5000; // = 5 seconds
private LocationManager locationManager;
private String provider;
public static String amount,id_ride,position,id_driver,note_,img,comment;
public static AlertDialog alertDialog;
private static TextView title;
private static final String HTTPS = &quot;https://&quot;;
private static final String HTTP = &quot;http://&quot;;
private static TextView ok, time;
private static ProgressBar progressBar2;
private static CountDownTimer countDownTimer = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = MainActivity.this;
activity = this;
connectionDetector=new ConnectionDetector(context);
prefManager = new PrefManager(this);
title = (TextView) findViewById(R.id.title);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
Bundle objetbundle = this.getIntent().getExtras();
String fragment_name = objetbundle.getString(&quot;fragment_name&quot;);
if(!fragment_name.equals(&quot;&quot;)){
notification = true;
if(fragment_name.equals(&quot;ridenewrider&quot;))
selectItem(1);
else if(fragment_name.equals(&quot;ridecompleted&quot;))
selectItem(4);
/*else if(fragment_name.equals(&quot;ridecanceledrider&quot;))
selectItem(1);*/
}
balance = (TextView) findViewById(R.id.balance);
user_photo = (CircleImageView) findViewById(R.id.user_photo);
switch_statut = (SwitchCompat) findViewById(R.id.switch_statut);
user_name = (TextView) findViewById(R.id.user_name);
user_phone = (TextView) findViewById(R.id.user_phone);
statut_conducteur = (TextView) findViewById(R.id.statut_conducteur);
drawer_conducteur = (FrameLayout) findViewById(R.id.drawer_conducteur);
drawer_user = (LinearLayout) findViewById(R.id.drawer_user);
mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(MainActivity.this, mDrawerLayout, toolbar, R.string.drawer_open, R.string.drawer_close);
mDrawerLayout.addDrawerListener(toggle);
toggle.syncState();
NavigationView navigationViewLeft = (NavigationView) findViewById(R.id.nav_view);
mDrawerList = (RecyclerView) findViewById(R.id.rvdrawer);
mDrawerList.setLayoutManager(new LinearLayoutManager(context));
mDrawerList.setHasFixedSize(true);
setDrawer();
if (savedInstanceState == null) {
if(fragment_name.equals(&quot;&quot;))
selectItem(0);
}
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&amp;&amp; ActivityCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, LOCATION_REQUEST_CODE);
}
if(!isLocationEnabled(context))
showMessageEnabledGPS();
balance.setVisibility(View.GONE);
if (M.getStatutConducteur(context).equals(&quot;yes&quot;)) {
switch_statut.setChecked(true);
statut_conducteur.setText(&quot;enabled&quot;);
} else {
switch_statut.setChecked(false);
statut_conducteur.setText(&quot;disabled&quot;);
}
switch_statut.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if(switch_statut.isChecked()) {
M.showLoadingDialog(context);
new changerStatut().execute(&quot;yes&quot;);
}else {
M.showLoadingDialog(context);
new changerStatut().execute(&quot;no&quot;);
}
}
});
if(!M.getPhoto(context).equals(&quot;&quot;)) {
Glide.with(context).load(AppConst.Server_url + &quot;images/app_user/&quot; + M.getPhoto(context))
.skipMemoryCache(false)
.listener(new RequestListener&lt;Drawable&gt;() {
@Override
public boolean onLoadFailed(@Nullable GlideException e, Object model, Target&lt;Drawable&gt; target, boolean isFirstResource) {
user_photo.setImageDrawable(getResources().getDrawable(R.drawable.user_profile));
return false;
}
@Override
public boolean onResourceReady(Drawable resource, Object model, Target&lt;Drawable&gt; target, DataSource dataSource, boolean isFirstResource) {
return false;
}
})
.into(user_photo);
}else{
user_photo.setImageDrawable(getResources().getDrawable(R.drawable.user_profile));
}
locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
Criteria criteria = new Criteria();
provider = locationManager.getBestProvider(criteria, false);
if (provider != null) {
currentLocation = locationManager.getLastKnownLocation(provider);
}
googleApiClient = new GoogleApiClient.Builder(context)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
updateFCM(M.getID(context));
}
public static void setTitle(String title_){
title.setText(title_);
}
@Override
public void onDestroy() {
stopService(new Intent(context, PayPalService.class));
currentLocation = null;
super.onDestroy();
}
/** R&#233;cup&#233;ration user wallet**/
public class getWallet extends AsyncTask&lt;String, Void, String&gt; {
@Override
protected String doInBackground(String... params) {
String url = AppConst.Server_url+&quot;get_wallet.php&quot;;
StringRequest jsonObjReq = new StringRequest(Request.Method.POST,
url,
new Response.Listener&lt;String&gt;() {
@Override
public void onResponse(String response) {
try {
JSONObject json = new JSONObject(response);
JSONObject msg = json.getJSONObject(&quot;msg&quot;);
String etat = msg.getString(&quot;etat&quot;);
if(etat.equals(&quot;1&quot;)){
balance.setText(M.getCurrency(context)+&quot; &quot;+msg.getString(&quot;amount&quot;));
}else{
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map&lt;String, String&gt; getParams() {
Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
params.put(&quot;id_user&quot;, M.getID(context));
params.put(&quot;cat_user&quot;, M.getUserCategorie(context));
return params;
}
};
AppController.getInstance().addToRequestQueue(jsonObjReq);
jsonObjReq.setRetryPolicy(new DefaultRetryPolicy(
10000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
return null;
}
@Override
protected void onPostExecute(String result) {
if (this != null) {
}
}
@Override
protected void onPreExecute() {
}
}
@Override
public void onLocationChanged(Location location) {
this.currentLocation = location;
if (currentLocation != null) {
new setCurrentLocation().execute(String.valueOf(location.getLatitude()),String.valueOf(location.getLongitude()));
}
}
/** Update driver position  **/
private class setCurrentLocation extends AsyncTask&lt;String, Void, String&gt; {
@Override
protected String doInBackground(String... params) {
String url = AppConst.Server_url+&quot;set_position.php&quot;;
final String latitude = params[0];
final String longitude = params[1];
StringRequest jsonObjReq = new StringRequest(Request.Method.POST,
url,
new Response.Listener&lt;String&gt;() {
@Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
}
}) {
@Override
protected Map&lt;String, String&gt; getParams() {
Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
params.put(&quot;id_user&quot;, M.getID(context));
params.put(&quot;user_cat&quot;, M.getUserCategorie(context));
params.put(&quot;latitude&quot;, latitude);
params.put(&quot;longitude&quot;, longitude);
return params;
}
};
AppController.getInstance().addToRequestQueue(jsonObjReq);
jsonObjReq.setRetryPolicy(new DefaultRetryPolicy(
10000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
return null;
}
@Override
protected void onPostExecute(String result) {
if (this != null) {
}
}
@Override
protected void onPreExecute() {
}
}
/** Start COOGLE API Client **/
@Override
public void onStart() {
super.onStart();
if (googleApiClient != null) {
googleApiClient.connect();
}
}
@Override
public void onStop() {
super.onStop();
if (googleApiClient != null) {
googleApiClient.disconnect();
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if (ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&amp;&amp;  ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
// Permissions ok, we get last location
currentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
startLocationUpdates();
}
private void startLocationUpdates() {
locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(UPDATE_INTERVAL);
locationRequest.setFastestInterval(FASTEST_INTERVAL);
if (ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&amp;&amp;  ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
/** Change driver status **/
private class changerStatut extends AsyncTask&lt;String, Void, String&gt; {
@Override
protected String doInBackground(String... params) {
String url = AppConst.Server_url+&quot;change_statut.php&quot;;
final String online = params[0];
StringRequest jsonObjReq = new StringRequest(Request.Method.POST,
url,
new Response.Listener&lt;String&gt;() {
@Override
public void onResponse(String response) {
try {
M.hideLoadingDialog();
JSONObject json = new JSONObject(response);
JSONObject msg = json.getJSONObject(&quot;msg&quot;);
String etat = msg.getString(&quot;etat&quot;);
String online = msg.getString(&quot;online&quot;);
if(etat.equals(&quot;1&quot;)){
if(online.equals(&quot;yes&quot;)) {
switch_statut.setChecked(true);
statut_conducteur.setText(&quot;enabled&quot;);
M.setStatutConducteur(online,context);
}else {
switch_statut.setChecked(false);
statut_conducteur.setText(&quot;disabled&quot;);
M.setStatutConducteur(online,context);
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
M.hideLoadingDialog();
if(switch_statut.isChecked())
switch_statut.setChecked(false);
else
switch_statut.setChecked(true);
}
}) {
@Override
protected Map&lt;String, String&gt; getParams() {
Map&lt;String, String&gt; params = new HashMap&lt;String, String&gt;();
params.put(&quot;id_driver&quot;, M.getID(context));
params.put(&quot;online&quot;, online);
return params;
}
};
AppController.getInstance().addToRequestQueue(jsonObjReq);
jsonObjReq.setRetryPolicy(new DefaultRetryPolicy(
10000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
return null;
}
@Override
protected void onPostExecute(String result) {
//to add spacing between cards
if (this != null) {
}
}
@Override
protected void onPreExecute() {
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case LOCATION_REQUEST_CODE: {
if(!isLocationEnabled(context))
showMessageEnabledGPS();
return;
}
}
}
public void showMessageEnabledGPSClient(){
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(context.getResources().getString(R.string.this_service_requires_the_activation_of_the_gps))
.setCancelable(false)
.setPositiveButton(&quot;Yes&quot;, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
})
.setNegativeButton(&quot;No&quot;, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
public void showMessageEnabledGPS(){
final AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setMessage(&quot;Activez le service GPS pour partager votre position avec les clients. Activez le GPS maintenant ?&quot;)
.setCancelable(false)
.setPositiveButton(&quot;Yes&quot;, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS));
}
})
.setNegativeButton(&quot;No&quot;, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
dialogInterface.cancel();
}
});
final AlertDialog alert = builder.create();
alert.show();
}
private boolean isLocationEnabled(Context context){
boolean enabled = false;
if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.KITKAT){
int mode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE,
Settings.Secure.LOCATION_MODE_OFF);
enabled = (mode != Settings.Secure.LOCATION_MODE_OFF);
}else{
LocationManager service = (LocationManager) context.getSystemService(LOCATION_SERVICE);
enabled =  service.isProviderEnabled(LocationManager.GPS_PROVIDER)||service.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
}
return enabled;
}

and this is the Service

import android.Manifest;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.IBinder;
import androidx.annotation.Nullable;
import androidx.core.app.ActivityCompat;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class MyService extends Service {
private LocationRequest locationRequest;
public static Location currentLocation;
private GoogleApiClient googleApiClient;
public static Context context;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&amp;&amp;  ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
currentLocation = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
startLocationUpdates();
return START_STICKY;
}
private void startLocationUpdates() {
locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(5000);
locationRequest.setFastestInterval(2000);
if (ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED
&amp;&amp;  ActivityCompat.checkSelfPermission(context,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
}
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, (LocationListener) this);
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}

答案1

得分: 0

在 Android O 及以后的版本中,存在对 Android 服务启动的限制。为了进行电池优化,Android 操作系统会在一段时间后终止长时间运行的后台服务或进程(详细解释请参阅此处:https://medium.com/oceanize-geeks/background-services-in-android-o-a38a7c624391 和 https://medium.com/exploring-android/exploring-background-execution-limits-on-android-oreo-ab384762a66c)。

相反,您可以使用前台服务来让您的应用在后台持续运行。前台服务要求持续显示通知,以便用户知道应用 X 正在后台执行某些工作。有关前台服务的实现,请参考 https://codinginflow.com/tutorials/android/foreground-service

英文:

There is a limitation on Android service starting Android O. Android OS kills the long running background services/processes after some time for battery optimization (explained here https://medium.com/oceanize-geeks/background-services-in-android-o-a38a7c624391 & https://medium.com/exploring-android/exploring-background-execution-limits-on-android-oreo-ab384762a66c).

Instead you can use Foreground service to keep your app running in the background. Foreground service requires a continuous Notification to be displayed so that user will be aware that X app is doing some work in background. For Foreground service implementation you can refer https://codinginflow.com/tutorials/android/foreground-service.

huangapple
  • 本文由 发表于 2020年8月24日 22:52:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/63563440.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定