- Em đang viết 1 app hiện thị notification bằng service, nhưng khi kill app thì service cũng dừng luôn.
Khi app kill thì service gọi hàm onTaskRemoved(), e đã thử dùng broadcast mở lại service nhưng k đc? - Khi hiện thị notification e dùng remoteView (tự xây dựng layout) nhưng button hiện thị k giống như trong layout,
Mong a/c giúp đỡ!
Cách chạy service ngay cả khi app killed?
- Service sẽ hồi sinh khi app kill khi bạn return START_STICKY ở onCreateCommand(). Khi đó app bị kill khoảng vài s sau service sẽ tự hồi sinh
- Bạn có thể cho code cụ thể hơn k?
Tìm hiểu thằng startForeground().
A foreground service is a service that should have the same priority as an active activity and therefore should not be killed by the Android system, even if the system is low on memory. A foreground service must provide a notification for the status bar, which is placed under the “Ongoing” heading, which means that the notification cannot be dismissed unless the service is either stopped or removed from the foreground.
1)Vẫn không dc a ak.
2)Layout của e tạo button dạng mặc định ( hình chữ nhật) vào máy lại nhận dạng bo tròn các cạnh như này a.Với cả các button và text k đặt dc ở giữa trong thanh à ( hơi lệch lên trên)
Đã làm được những gì mà không được? Sao không đưa code lên luôn 
E đã có startForeground() trong phần hàm hiện thông báo r a nhưng khi kill vẫn tắt
public class VolumeControl extends Service {
String mode="Music";
int heightNoti;
BroadcastReceiver checkChange;
int valueMusic=0,valueBell=0,valueAlarm=0;
Bitmap p1,p2,p3;
Notification noti;
RemoteViews views;
AudioManager myAudioManager;
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if(intent.getAction().equals("StartVolumeControl")) {
heightNoti=intent.getIntExtra("height",60);
Bitmap p = BitmapFactory.decodeResource(getResources(),R.drawable.bell);
p1=Bitmap.createScaledBitmap(p,heightNoti,heightNoti,true);
p = BitmapFactory.decodeResource(getResources(),R.drawable.alarm);
p2=Bitmap.createScaledBitmap(p,heightNoti,heightNoti,true);
p = BitmapFactory.decodeResource(getResources(),R.drawable.music);
p3=Bitmap.createScaledBitmap(p,heightNoti,heightNoti,true);
myAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
showNotification();
}
switch (intent.getAction()){
case "IconVolume":
if(mode.equals("Music")){
mode = "Bell";
views.setImageViewBitmap(R.id.mode,p1);
valueBell=myAudioManager.getStreamVolume(AudioManager.STREAM_RING);
views.setTextViewText(R.id.text,"Bell: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_RING))+"%");
}
else{
if(mode.equals("Bell")){
mode = "Alarm";
Bitmap p = BitmapFactory.decodeResource(getResources(),R.drawable.alarm);
views.setImageViewBitmap(R.id.mode,p2);
valueAlarm=myAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
views.setTextViewText(R.id.text,"Alarm: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_ALARM))+"%");
}
else {
mode = "Music";
views.setImageViewBitmap(R.id.mode,p3);
valueMusic=myAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
views.setTextViewText(R.id.text,"Music: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))+"%");
}
}
break;
case "UpVolume":
if(mode.equals("Music")){
valueMusic = Math.min(valueMusic+1,15);
myAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,valueMusic,0);
views.setTextViewText(R.id.text,"Music: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))+"%");
}
if(mode.equals("Alarm")){
valueAlarm = Math.min(valueAlarm+1,15);
myAudioManager.setStreamVolume(AudioManager.STREAM_ALARM,valueAlarm,0);
views.setTextViewText(R.id.text,"Alarm: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_ALARM))+"%");
}
if(mode.equals("Bell")){
valueBell = Math.min(valueBell+1,15);
myAudioManager.setStreamVolume(AudioManager.STREAM_RING,valueBell,0);
views.setTextViewText(R.id.text,"Bell: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_RING))+"%");
}
break;
case "DownVolume":
if(mode.equals("Music")){
valueMusic = Math.max(valueMusic-1,0);
myAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC,valueMusic,0);
views.setTextViewText(R.id.text,"Music: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))+"%");
}
if(mode.equals("Alarm")){
valueAlarm = Math.max(valueAlarm-1,0);
myAudioManager.setStreamVolume(AudioManager.STREAM_ALARM,valueAlarm,0);
views.setTextViewText(R.id.text,"Alarm: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_ALARM))+"%");
}
if(mode.equals("Bell")){
valueBell = Math.max(valueBell-1,0);
myAudioManager.setStreamVolume(AudioManager.STREAM_RING,valueBell,0);
views.setTextViewText(R.id.text,"Bell: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_RING))+"%");
} break;
}
return START_STICKY;
}
public void showNotification(){
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction("Demo");
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
views = new RemoteViews(getPackageName(),R.layout.services_volumecontrol);
//image
Intent intentIcon = new Intent(this, VolumeControl.class);
intentIcon.setAction("IconVolume");
PendingIntent pIntentIcon = PendingIntent.getService(this, 0,
intentIcon, 0);
//up
Intent intentUp = new Intent(this, VolumeControl.class);
intentUp.setAction("UpVolume");
PendingIntent pIntentUp = PendingIntent.getService(this, 0,
intentUp, 0);
//down
Intent intentDown = new Intent(this, VolumeControl.class);
intentDown.setAction("DownVolume");
PendingIntent pIntentDown = PendingIntent.getService(this, 0,
intentDown, 0);
//Text
Intent intentText = new Intent(this, VolumeControl.class);
intentText.setAction("IconVolume");
PendingIntent pIntentText = PendingIntent.getService(this, 0,
intentText, 0);
views.setOnClickPendingIntent(R.id.mode, pIntentIcon);
views.setOnClickPendingIntent(R.id.Up, pIntentUp);
views.setOnClickPendingIntent(R.id.Down, pIntentDown);
valueMusic=myAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
views.setTextViewText(R.id.text,"Music: "+valueVolume(valueMusic)+"%");
views.setImageViewBitmap(R.id.mode,p3);
noti = new Notification.Builder(this).build();
noti.contentView = views;
noti.flags = Notification.FLAG_ONGOING_EVENT;
noti.icon = R.mipmap.ic_launcher;
noti.contentIntent = pendingIntent;
startForeground(10, noti);
//bat sk tang giam am luong
IntentFilter filter = new IntentFilter("android.media.VOLUME_CHANGED_ACTION");
checkChange = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
valueMusic=myAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC);
if(mode.equals("Music"))
views.setTextViewText(R.id.text,"Music: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC))+"%");
valueAlarm=myAudioManager.getStreamVolume(AudioManager.STREAM_ALARM);
if(mode.equals("Alarm"))
views.setTextViewText(R.id.text,"Alarm: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_ALARM))+"%");
valueBell=myAudioManager.getStreamVolume(AudioManager.STREAM_RING);
if(mode.equals("Bell"))
views.setTextViewText(R.id.text,"Bell: "+valueVolume(myAudioManager.getStreamVolume(AudioManager.STREAM_RING))+"%");
startForeground(10, noti);
}
};
registerReceiver(checkChange,filter);
}
public int valueVolume(int value){
return (int) ((value*1.0/15.0)*100.0);
}
}
E mới code demo thử ạ
Doccument của android có chỉ rõ mà hình như bạn không thèm đọc hay sao ấy, start foreground chỉ có tác dụng giành quyền ưu tiên đối với system khỏi bị kill khi thiếu bộ nhớ, tuy nhiên không có gì đảm bảo là service sẽ không bị kill cả, hành động kill với tư cách là user sẽ có quyền quyết định cao nhất, bỏ qua mọi config mà không cần biết service đang chạy, đang ưu tiên hay không.
Vâng e cảm ơn. E sẽ chú ý hơn 

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?