- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个前台服务,它是在 list 中和不同的进程中定义的,我曾经在我的 Activity 运行并且一切正常时调用它,但突然当我想启动前台服务时,onStartCommand不再调用,只有onCreate方法!我看不到我的登录 onStartCommand 方法...
这是在 list 中声明的我的服务:
<service
android:name=".services.ForegroundService"
android:enabled="true"
android:exported="false"
android:process=":ForegroundService" />
这是我的代码,用于启动服务:
private void startServices() {
new Handler().postDelayed(() -> {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startForegroundService(new Intent(MapBoxActivity.this,ForegroundService.class));
} else {
startService(new Intent(MapBoxActivity.this,ForegroundService.class));
Timber.i("service Started!");
}
TaskScheduler.schedule(MapBoxActivity.this);
}, 10*1000);
}
我在 Activity 的 onCreate 方法中调用 startServices()
方法...
这是我的前台服务的代码:
public class ForegroundService extends Service implements
SensorEventListener, StepListener , MapboxActivityLocationCallback.MapboxLocationListener {
private static final String ACTION_STOP_SERVICE = "stop_service";
public static final String URL_SAVE_PROFILE = "https://www.mohregroup.com/db-mapapa/saveName.php";
private int countedSteps = 0;
private Location originLocation;
private LocationEngine locationEngine;
private long DEFAULT_INTERVAL_IN_MILLISECONDS = 10 * 60 * 1000L;
private long DEFAULT_MAX_WAIT_TIME = DEFAULT_INTERVAL_IN_MILLISECONDS * 3;
private MapboxActivityLocationCallback locationCallback = new MapboxActivityLocationCallback();
private final SparseArray<MarkerItem> treasuresList = new SparseArray<>();
private SparseArray<MarkerItem> sawTreasuresList = new SparseArray<>();
private String JSON_locations = null, JSON_locations_tmp = null, geocodeAddress = null, address;
//Session Manager
private SessionManager sessionManager;
private HashMap<String, Object> user;
//locationChecker
private String zone, currentZone;
private boolean onConnectedFlag = false;
private MyDbAdapter dbAdapter;
private int coins , dailySteps;
private float bagCapacity;
private SteepDetector steepDetector;
private BagBroadcastReceiver receiver;
private PowerManager.WakeLock wakeLock;
public ForegroundService() {
}
@SuppressLint("MissingPermission")
@Override
public void onCreate() {
super.onCreate();
activateLocationEngine();
//###########SEND TO SERVER
registerReceiver(new NetworkStateChecker(), new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
//for updated UI!
BroadcastReceiver sendToServerReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
//TODO : for updated UI!
}
};
registerReceiver(sendToServerReceiver, new IntentFilter(DATA_SAVED_BROADCAST));
syncProfile();
//###########SEND TO SERVER
//TODO : works even screen is off
PowerManager powerManager = (PowerManager)this.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,":ForegroundService");
wakeLock.acquire(5000);
sessionManager = new SessionManager(getApplicationContext());
user = sessionManager.getUserDetails();
coins = (int) user.get(SessionManager.getKeyCoin());
bagCapacity = (float) user.get(SessionManager.getKEY_BagCapacity());
dailySteps = (int) user.get(SessionManager.getKEY_Steps());
Timber.i("foreground_userDetails \n coins: %s \n bagCapacity: %s \n dailySteps: %s" ,
coins , bagCapacity , dailySteps);
dbAdapter = new MyDbAdapter(getApplicationContext());
steepDetector = new SteepDetector();
steepDetector.registerListener(this);
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
if (sensorManager != null) {
//TODO : make sensors great again!
// Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
Sensor sensor2 = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
// if (sensor != null) {
// sensorManager.registerListener(this, sensor, SensorManager.SENSOR_DELAY_UI);
// } else
if (sensor2 != null) {
//we don't have step counter sensor! so we use accelerometer
sensorManager.registerListener(this, sensor2, SensorManager.SENSOR_DELAY_NORMAL);
}
}
locationAdder();
receiver = new BagBroadcastReceiver();
registerReceiver(receiver, new IntentFilter("bag_state"));
new Handler().postDelayed(this::getAdd, 10 * 1000);
locationCallback.registerMapboxLocationListener(this);
updateServer();
}
private void getAdd() {
if (originLocation != null) {
try {
address = new GetAddress(originLocation).execute().get();
// Timber.tag("geocodeR").d("%s \n", address);
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void syncProfile() {
Handler handler = new Handler();
handler.post(() -> {
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL_SAVE_PROFILE,
response -> {
try {
JSONObject obj = new JSONObject(response);
if (!obj.getBoolean("error")) {
//if there is a success
//storing the name to sqlite with status synced
dbAdapter.addProfile(countedSteps, PROFILE_SYNCED_WITH_SERVER);
Timber.tag("OnResponse").d("synced successfully!");
} else {
//if there is some error
//saving the name to sqlite with status unsynced
Timber.tag("OnResponse").d("not synced ");
dbAdapter.addProfile(countedSteps, PROFILE_NOT_SYNCED_WITH_SERVER);
}
} catch (JSONException e) {
e.printStackTrace();
}
},
error -> {
//on error storing the name to sqlite with status unsynced
Timber.tag("OnErrorResponse").d("not synced ");
dbAdapter.addProfile(countedSteps, PROFILE_NOT_SYNCED_WITH_SERVER);
}) {
@Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<>();
params.put("step", String.valueOf(countedSteps));
return params;
}
};
VolleySingleton.getInstance(ForegroundService.this).addToRequestQueue(stringRequest);
});
}
@Override
public void onSensorChanged(SensorEvent event) {
//Step Counter with StepDetector Sensor
if (event.sensor.getType() == Sensor.TYPE_STEP_DETECTOR
&& event.values[0] == 1.0) {
countedSteps++;
int steps;
int prev_odometer_steps = (int) user.get(SessionManager.getKEY_Steps());
if (countedSteps > prev_odometer_steps) {
steps = countedSteps - prev_odometer_steps;
if ((int) user.get(SessionManager.getKeyCoin()) < (float) user.get(SessionManager.getKEY_BagCapacity())) {
BagBroadcastReceiver.isNotified = false;
coins += steps;
}
}
if (coins >= ((float) user.get(SessionManager.getKEY_BagCapacity()))) {
sendBroadcast(new Intent("bag_state"));
Timber.tag("bag_coins").d("%s", coins);
}
} else {
steepDetector.updateAccel(
event.timestamp, event.values[0], event.values[1], event.values[2]);
}
}
private void updateContentProvider() {
ContentValues contentValues = new ContentValues();
contentValues.put(MyContentProvider.COINS , coins);
contentValues.put(MyContentProvider.STEPS , countedSteps);
getContentResolver().update(MyContentProvider.CONTENT_URI , contentValues , null , null);
}
@Override
public void onAccuracyChanged(Sensor sensor, int i) {
}
@Override
public void step(long timeNs) {
countedSteps++;
if ((int) user.get(SessionManager.getKeyCoin()) < (float) user.get(SessionManager.getKEY_BagCapacity())) {
BagBroadcastReceiver.isNotified = false;
coins += 1;
Timber.i("foreground_updatedCoin: coins: %s \n countedSteps: %s \n steps: %s \n bagC: %s",
coins , countedSteps , 1 , bagCapacity);
}
//use content provider
updateContentProvider();
if (coins >= ((float) user.get(SessionManager.getKEY_BagCapacity()))) {
sendBroadcast(new Intent("bag_state"));
Timber.tag("bag_coins").d("%s", coins);
}
}
@Override
public void onLocationUpdate(Location lastLocation) {
if (lastLocation != null) {
originLocation = lastLocation;
try {
if (JSON_locations != null && address != null) {
JSON_locations = dbAdapter.LocationGetAllData().toString();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
@SuppressLint("MissingPermission")
private void activateLocationEngine() {
locationEngine = LocationEngineProvider.getBestLocationEngine(this);
LocationEngineRequest request = new LocationEngineRequest.Builder(DEFAULT_INTERVAL_IN_MILLISECONDS)
.setFastestInterval(DEFAULT_INTERVAL_IN_MILLISECONDS / 5)
.setMaxWaitTime(DEFAULT_MAX_WAIT_TIME)
.setPriority(LocationEngineRequest.PRIORITY_BALANCED_POWER_ACCURACY)
.build();
locationEngine.requestLocationUpdates(request, locationCallback, Looper.getMainLooper());
locationEngine.getLastLocation(locationCallback);
if (!onConnectedFlag) {
locationChecker();
onConnectedFlag = true;
}
}
@Override
public IBinder onBind(@NonNull Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (intent != null &&
ACTION_STOP_SERVICE.equals(intent.getAction())) {
stopSelf();
if (locationEngine != null) {
locationEngine.removeLocationUpdates(locationCallback);
}
} else {
activateLocationEngine();
displaySawTreasures();
updateTreasures();
updateValues(intent);
}
startForegroundService();
Timber.i("onStartCommand Started!");
return START_STICKY;
}
private void updateValues(Intent intent) {
if (intent != null){
coins = intent.getIntExtra(COIN_MAP_FOREGROUND , 0);
bagCapacity = intent.getFloatExtra(BAG_CAPACITY_MAP_FOREGROUND , 0f);
Cursor cursor = getContentResolver().query(MyContentProvider.CONTENT_URI ,
null , null , null , null);
if (cursor != null){
if (cursor.moveToFirst()){
while (!cursor.isAfterLast()){
dailySteps = cursor.getInt(cursor.getColumnIndex(MyContentProvider.STEPS));
}
}
cursor.close();
}
Timber.i("foreground_userUpdated \n coins: %s \n bagCapacity: %s \n dailySteps: %s" ,
coins , bagCapacity , dailySteps);
}
}
private void startForegroundService() {
/*
* Notification for foreground Service
* */
int notification_id = (int) System.currentTimeMillis();
RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.notification_custom);
Intent button_intent = new Intent(this, ForegroundService.class);
button_intent.setAction(ACTION_STOP_SERVICE);
PendingIntent button_pending = PendingIntent.getService(
this,
0,
button_intent,
PendingIntent.FLAG_CANCEL_CURRENT);
remoteViews.setTextViewText(R.id.notif_txt, String.valueOf(dailySteps));
remoteViews.setOnClickPendingIntent(R.id.notif_btn, button_pending);
//action intent
Intent actionIntent = new Intent(this, MapBoxActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(
this,
0,
actionIntent,
PendingIntent.FLAG_UPDATE_CURRENT
);
NotificationCompat.Builder builder =
new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_notification_small)
.setContentTitle(getResources().getString(R.string.notification_title))
.setCustomBigContentView(remoteViews)
.setPriority(NotificationCompat.PRIORITY_LOW)
.addAction(R.id.notif_btn, "Stop", pendingIntent)
.setAutoCancel(false);
if (dailySteps < 2000) {
builder.setContentText("ماجراجویی بیشتر، گنج بیشتر!!");
} else if (dailySteps > 2000 && dailySteps < 4000) {
builder.setContentText("خوبه! امروز خوب فعالیت داشتی!");
} else if (dailySteps >= 4000 && dailySteps < 6000) {
builder.setContentText("ایول! امروز خوب تلاش کردی!");
} else if (dailySteps >= 6000 && dailySteps < 8000) {
builder.setContentText("رفیق امروز میخوای بترکونی؟!");
} else if (dailySteps >= 8000 && dailySteps < 10000) {
builder.setContentText("میبینم کههه خیلی عالی پیش رفتی امروز!");
} else if (dailySteps >= 10000) {
builder.setContentText("رفیق ترکوندی! تو فوق العاده ای!");
}
builder.setContentIntent(pendingIntent);
Notification notification = builder.build();
startForeground(notification_id, notification);
Timber.i("foreground Started!");
}
@Override
public void onDestroy() {
super.onDestroy();
locationEngine.removeLocationUpdates(locationCallback);
unregisterReceiver(receiver);
if (originLocation != null) originLocation = null;
if (JSON_locations != null) JSON_locations = null;
if (JSON_locations_tmp != null) JSON_locations_tmp = null;
if (geocodeAddress != null) geocodeAddress = null;
if (address != null) address = null;
if (dbAdapter != null) dbAdapter = null;
wakeLock.release();
}
@Override
public void onLowMemory() {
super.onLowMemory();
locationEngine.removeLocationUpdates(locationCallback);
stopSelf();
}
private void sendTreasureNotification(MarkerItem markerItem, SparseArray<MarkerItem> updatedList) {
NotificationCompat.Builder builder =
new NotificationCompat.Builder(this, CHANNEL_ID)
.setSmallIcon(R.drawable.ic_stat_notification_small)
.setContentTitle(getResources().getString(R.string.notification_text))
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setVibrate(new long[]{0, 250, 250, 250, 250})
.setLights(Color.BLUE, 1000, 2000)
.setAutoCancel(true);
if (!sessionManager.isLoggedIn())
builder.setContentText("برای بدست آوردنش وارد حسابت شو!");
//creating an action Intent and passing the values to the GoogleMapActivity from Service
Intent actionIntent = new Intent(this, MapBoxActivity.class);
actionIntent.setAction("newTreasureList");
actionIntent.putExtra("list", (Parcelable) updatedList);
PendingIntent actionPendingIntent = PendingIntent.getActivity(this,
0,
actionIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
builder.setContentIntent(actionPendingIntent);
//issue the notification
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
if (notificationManager != null && sawTreasuresList.get(markerItem.getId()) == null) {
//Log.d("markerIds",markerItem.getOwnerId()+"-"+(Integer)user.get(SessionManager.getKeyId()));
if (markerItem.getOwnerId() != (int) user.get(SessionManager.getKeyId())) {
notificationManager.notify(1, builder.build());
}
sawTreasuresList.put(markerItem.getId(), markerItem);
Timber.tag("notification_sent").d(updatedList.toString());
}
}
private void displaySawTreasures() {
final Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
if (originLocation != null) {
for (int i = 0; i < treasuresList.size(); i++) {
MarkerItem markerItem = treasuresList.valueAt(i);
sendTreasureNotification(markerItem, sawTreasuresList);
treasuresList.delete(markerItem.getId());
}
}
handler.postDelayed(this, 12 * 60 * 1000);
}
});
}
private ArrayList<JSONObject> getJsonTreasures(String json) {
ArrayList<JSONObject> jsonObjectArrayList = new ArrayList<>();
if (json != null) {
try {
jsonObject.get("server_response");
JSONArray jsonArray = new JSONArray(json);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject object = (JSONObject) jsonArray.get(i);
jsonObjectArrayList.add(object);
MarkerItem markerItem = new MarkerItem(object.getInt("locationId"),
object.getInt("ownerId"), object.getString("owner"),
object.getDouble("latitude"), object.getDouble("longitude"),
object.getInt("value"), object.getInt("shovelId"), object.getInt("shovel"),
object.getString("charmLink"),
object.getInt("depth"));
treasuresList.put(markerItem.getId(), markerItem);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
return jsonObjectArrayList;
}
private void locationAdder() {
final Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
// Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
if (NetworkUtil.hasNetworkAccess())
if (JSON_locations != null)
if (!JSON_locations.equals(JSON_locations_tmp)) {
// Log.d("LocationsStatus",JSON_locations.equals(JSON_locations_tmp)+"");
JSON_locations_tmp = JSON_locations;
//adding json information to the array list of JSONObject
ArrayList<JSONObject> jsonObjectArrayList = getJsonTreasures(JSON_locations);
treasuresList.clear();
if (jsonObjectArrayList != null) {
for (JSONObject jsonObject : jsonObjectArrayList) {
try {
String latitude = jsonObject.getString("latitude");
String longitude = jsonObject.getString("longitude");
if (!latitude.equals("") && !longitude.equals("")) {
MarkerItem markerItem = new MarkerItem(jsonObject.getInt("locationId"),
jsonObject.getInt("ownerId"), jsonObject.getString("owner"),
jsonObject.getDouble("latitude"), jsonObject.getDouble("longitude"),
jsonObject.getInt("value"), jsonObject.getInt("shovelId"), jsonObject.getInt("shovel"),
jsonObject.getString("charmLink"),
jsonObject.getInt("depth"));
treasuresList.put(markerItem.getId(), markerItem);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
SparseArray<MarkerItem> tmp = new SparseArray<>();
for (int i = 0; i < treasuresList.size(); i++) {
MarkerItem m = treasuresList.valueAt(i);
if (sawTreasuresList.get(m.getId()) != null) {
tmp.put(m.getId(), m);
}
}
sawTreasuresList = tmp;
}
}
handler.postDelayed(this, 11 * 60 * 1000);
}
});
}
private void updateServer() {
Handler handler = new Handler();
handler.post(new Runnable() {
@Override
public void run() {
if (NetworkUtil.hasNetworkAccess()){
if (originLocation != null){
try {
address = new GetAddress(originLocation).execute().get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
if (address != null) {
new LocationTask(ForegroundService.this).execute("updatePoint",
String.valueOf(coins), String.valueOf(1),
String.valueOf(originLocation.getLatitude()), String.valueOf(originLocation.getLongitude()),
address, address);
} else {
new LocationTask(ForegroundService.this).execute("updatePoint", String.valueOf(coins), String.valueOf(1),
String.valueOf(originLocation.getLatitude()), String.valueOf(originLocation.getLongitude()),
"not titled", "not titled");
}
Timber.d("update_server: COINS: %s \n originLocation: %s \n address: %s " ,
coins , originLocation.toString(),address);
}
}
//TODO update server data every 1 hour
handler.postDelayed(this , 30 * 1000);
}
});
}
private void updateTreasures() {
final Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
if (NetworkUtil.hasNetworkAccess()) {
// Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
try {
address = new GetAddress(originLocation).execute().get();
if (address != null) {
new LocationTask(ForegroundService.this).execute("getLocations", address);
JSON_locations = dbAdapter.LocationGetAllData().toString();
}
} catch (Exception e) {
e.printStackTrace();
}
}
//set up to 17 mins
handler.postDelayed(this, 17 * 60 * 1000);
}
});
}
private void locationChecker() {
final Handler handler = new Handler(Looper.getMainLooper());
handler.post(new Runnable() {
@Override
public void run() {
Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
if (originLocation != null && onConnectedFlag && NetworkUtil.hasNetworkAccess()) {
try {
address = new GetAddress(originLocation).execute().get();
if (address != null) {
zone = address;
}
if (zone != null && !zone.equals(currentZone)) {
currentZone = zone;
}
} catch (Exception e) {
e.printStackTrace();
}
}
//set up to 19 mins
handler.postDelayed(this, 19 * 60 * 1000);
}
});
}
@Override
protected void attachBaseContext(Context base) {
super.attachBaseContext(CalligraphyContextWrapper.wrap(base));
}
我根本不明白为什么会发生这种情况,因为我大概 4 小时前就在工作!但目前还不起作用...
更新:大约 9 小时前,我正在使用手机,突然看到我的前台服务已启动的通知!所以我发现系统不会启动我的前台进程(或立即终止它)并在需要时启动它!(也许根据管理内存)那为什么会这样呢?又该如何解决?
最佳答案
我的笨蛋!我的服务未启动并且大多数时候我的应用程序崩溃的原因是 onStartCommand
内部的 updateValues(intent)
方法!它有一个 while 循环,条件不正确,它陷入了无限循环!这就是代码没有进一步完成 onStartCommand
并启动服务的原因!
关于java - Android前台服务onStartCommand不调用,仅onCreate调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56333194/
我在 Android 上开发了一个 GPS 跟踪应用程序。我使用 AlarmManager 每 5 分钟唤醒一次设备。我开发了一个日志文件,显示该应用程序运行良好,直到我收到 public int o
我有一个简单的服务: public class TestService extends Service { final String LOG_TAG = "myLogs"; public void o
当我调用 this.startService(new Intent(this, Some_Service.class)); 我知道 onCreate() 被调用,然后是 onStartCommand(
我在使用实现 onStartCommand() 的服务时有点困惑。 在某些示例中,onStartcommand() 方法已实现,但在某些地方未实现。对于我需要使用此方法的原因,您能否澄清我的疑问。 最
我有一个测试项目,我的简单测试用例扩展了AndroidTestCase类: public class MyTest extends AndroidTestCase{ private Conte
我有一项服务,只要用户使用它,我就会尝试持续运行。问题是该服务使用了大量内存;我猜是因为它会通知用户并不断显示图像。所以我将大部分代码放在另一个 Activity 中。服务只是调用 Activity
我有一个后台服务,我可以使用应用程序菜单启动或停止该服务。该服务也可以在模拟器设备启动时启动。但奇怪的是,我只在设备启动时看到 toast 消息,而 jobThread 没有启动......即使我从菜
我想知道如果两个不同的线程同时调用服务A上的startService,服务是否执行onStartCommand() 两者分开还是一个取消另一个? 我想了解 Android 中的服务。 最佳答案 Ser
我必须确保我的 Service 会运行,直到我显式调用 stopService()。所以我应该从 onStartCommand() 返回 START_STICKY 标志。 我还希望万一我的服务因为内存
我注意到 Service.START_STICKY 不工作,当我仔细观察时,我看到 onCreate() 正在运行但没有调用 onStartCommand。 有什么想法吗? @Override
当我单击播放按钮播放歌曲并将歌曲 mp3 与其 bundle 在一起并在 onStartCommand 中接收时,我就开始了我的服务。问题是当我启动服务的 Activity 结束时,我的服务再次调用
我正在尝试创建一个将在后台处理文件 I/O 的服务。更新数据的 Activity 将绑定(bind)到服务并调用服务的方法来执行 I/O。我正在使用 Android 文档作为指导。 但是,我的服务似乎
我一直在查看文档,有时 onStartCommand() 返回 START_NOT_STICKY,有时返回以下内容: @Override public int onStartCommand(Inten
我有一个服务,我需要从服务 onStartCommand 访问上下文。 我怎么能这样。我是 Android 新手。 最佳答案 可以使用ServiceName.this获取Context,Service
我想从我的 Activity 类(class)中启动一项服务。问题是,onStartCommand 永远不会被调用。我在那里放置了断点,但它从未被击中。我的例子非常简单,我不明白为什么它不起作用。 M
我正在尝试在 android 中创建一个简单的服务。 我检查了“设置”->“应用程序”选项卡,可以看到该服务正在运行。不幸的是 OnStartCommand 函数没有被执行。我什至看不到 toast
我有一个运行两个独立服务的应用程序。其中一个运行平稳,另一个大部分时间都没有问题,但抛出一个 NullPointerException在 onStartCommand() 内在 4.1 和 4.4.2
我目前正在从 Service 类扩展我的自定义服务实现。作为 Android-O 迁移的一部分,我想使用 JobIntentService。 目前我所有的逻辑都在服务的 onStartCommand
我有以下代码 @Override public int onStartCommand(Intent intent, int flags, int startId) { if(intent !=
在 Android 文档中,服务的“onStartCommand()”有一个作为 param 给出的 Intent ,根据文档: “提供给 startService(Intent) 的 Intent,
我是一名优秀的程序员,十分优秀!