我在运行服务和通知时遇到问题。
我想在用户清除应用,服务停止和通知删除时。 但我无法检查服务关闭删除通知。 我检查通知删除以关闭服务成功。 服务不能调用onTaskRemoved。请帮帮我,这是mp3应用程序的服务。
package vn.top12.app;
import android.app.ActivityManager;
import android.app.IntentService;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ServiceInfo;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Build;
import android.support.annotation.Nullable;
import android.support.annotation.StringDef;
import android.support.v4.app.NotificationCompat;
import android.support.v4.content.ContextCompat;
import android.widget.RemoteViews;
import com.bumptech.glide.Glide;
import com.bumptech.glide.request.target.NotificationTarget;
import com.google.android.exoplayer2.ControlDispatcher;
import com.google.android.exoplayer2.DefaultControlDispatcher;
import com.google.android.exoplayer2.SimpleExoPlayer;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.List;
import vn.top12.app.interfaces.IResultListener;
import vn.top12.app.models.Mp3Model;
import vn.top12.app.utils.CommonUtils;
import vn.top12.app.utils.YanNewsCommons;
import static vn.top12.app.MyReceiver.ID_NOTIFICATION;
/**
* An {@link IntentService} subclass for handling asynchronous task requests in
* a service on a separate handler thread.
* <p>
* helper methods.
*/
public class MyIntentService
extends IntentService {
private SimpleExoPlayer mSimpleExoPlayer;
private List<Mp3Model> mp3Models;
private int mPositionCurrent;
private ControlDispatcher controlDispatcher;
public MyIntentService() {
super("MyIntentService");
mSimpleExoPlayer = YanNewsCommons.instance()
.getSimpleExPlayer();
mp3Models = new ArrayList<>();
mPositionCurrent = 0;
controlDispatcher = new DefaultControlDispatcher();
CommonUtils.showLogDebug("abc" + mSimpleExoPlayer);
}
@Override
public void onTaskRemoved(Intent rootIntent) {
//unregister listeners
//do any other cleanup if required
NotificationManager
manager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) {
manager.cancel(ID_NOTIFICATION);
}
//stop service
stopSelf();
}
/**
* You should not override this method for your IntentService. Instead,
* override {@link #onHandleIntent}, which the system calls when the IntentService
* receives a start request.
*
* @param intent
* @param flags
* @param startId
* @see Service#onStartCommand
*/
@Override
public int onStartCommand(@Nullable final Intent intent,
final int flags,
final int startId) {
System.out.println(">>>>"+flags);
return super.onStartCommand(intent,
flags,
startId);
}
@Override
public void onDestroy() {
System.out.println(">>>>> onDestroy");
super.onDestroy();
}
@Override
protected void onHandleIntent(Intent intent) {
CommonUtils.showLogDebug("onHandleIntent");
if (intent != null) {
if (intent.getExtras() != null) {
// get data put to notification.
String strModel = intent.getExtras()
.getString(MyReceiver.KEY_PARAM_DATA_MODEL_PARSE_STR_RECEIVER);
if (CommonUtils.isStringDataValid(strModel)) {
Mp3Model model = new Gson().fromJson(strModel,
Mp3Model.class);
handlerDataForNotification(model);
} else {
//Parse error.
CommonUtils.showLogDebug("error parse:");
}
}
}
}
public void intListDataModelToService(List<Mp3Model> models,
int position) {
if (models == null) {
return;
}
mp3Models = models;
mPositionCurrent = position;
}
public void initListMp3ForPlayer() {
if (mp3Models != null) {
String[] strLinkMp3 =
new String[mp3Models.size()];
for (int i =
0; i < mp3Models.size(); i++) {
strLinkMp3[i] = mp3Models.get(i)
.getUrlMp3();
}
initListMp3ToPlayer(strLinkMp3);
}
}
public void seekTo(int windowIndex,
long positionMs) {
if ((mSimpleExoPlayer != null) && (controlDispatcher != null)) {
boolean dispatched = controlDispatcher.dispatchSeekTo(mSimpleExoPlayer,
windowIndex,
positionMs);
if (!dispatched) {
// The seek wasn't dispatched. If the progress bar was dragged by the user to perform the
// seek then it'll now be in the wrong position. Trigger a progress update to snap it back.
// updateProgress();
CommonUtils.showLogDebug("updateProgress not dispatched");
}
}
}
public void nextOrPreviousClicked(boolean isRightToLeft,
Context context) {
//seek to position new, and update model with current.
if (mSimpleExoPlayer != null) {
if (isRightToLeft) {
if (mSimpleExoPlayer.getNextWindowIndex() >= 0) {
seekTo(mSimpleExoPlayer.getNextWindowIndex(),
0);
}
} else {
if ((mSimpleExoPlayer.getPreviousWindowIndex() >= 0)) {
seekTo(mSimpleExoPlayer.getPreviousWindowIndex(),
0);
}
}
// get current when next have finish.
mPositionCurrent = mSimpleExoPlayer.getCurrentWindowIndex() <= 0 ?
0 :
mSimpleExoPlayer.getCurrentWindowIndex();
if ((mSimpleExoPlayer != null) && (mp3Models != null) && (mp3Models.size() > 0)) {
updateUiToService(context,
mp3Models.get(mPositionCurrent),
MyReceiver.KEY_ACTION_RECEIVER.KEY_ACTION_PREVIOUS_MP3_RECEIVER);
}
CommonUtils.showLogDebug("nextOrPreviousClicked" + mSimpleExoPlayer + "+" + mPositionCurrent);
}
}
public void updatePlayOrPauseForPlayer(boolean isPlay,
Context context) {
if (mSimpleExoPlayer != null) {
mSimpleExoPlayer.setPlayWhenReady(isPlay);
}
if ((mp3Models != null) && (mp3Models.size() > 0) && (mPositionCurrent <= mp3Models.size() - 1)) {
updateUiToService(context,
mp3Models.get(mPositionCurrent),
isPlay ?
MyReceiver.KEY_ACTION_RECEIVER.KEY_ACTION_PLAY_MP3_RECEIVER :
MyReceiver.KEY_ACTION_RECEIVER.KEY_ACTION_PAUSE_MP3_RECEIVER);
}
CommonUtils.showLogDebug("update player");
}
private void initListMp3ToPlayer(String... linkMp3) {
if ((mSimpleExoPlayer != null)) {
YanNewsCommons.instance()
.initializePlayer(mSimpleExoPlayer,
new IResultListener<Boolean>() {
@Override
public void onSuccess(final Boolean result) {
if (mSimpleExoPlayer != null) {
mSimpleExoPlayer.setVolume(10f);
}
}
@Override
public void onFail(final String message) {
CommonUtils.showLogDebug("message:" + message);
}
},
linkMp3);
CommonUtils.showLogDebug("initListMp3ToPlayer" + mSimpleExoPlayer);
}
}
public void stopServiceAndClearFromOut(Context context) {
if ((context == null)) {
return;
}
if (mSimpleExoPlayer != null) {
mSimpleExoPlayer.stop();
mSimpleExoPlayer = null;
}
if (mp3Models != null) {
mp3Models.clear();
mp3Models = null;
}
Intent intent = new Intent(context,
MyIntentService.class);
context.stopService(intent);
}
private void updateUiToService(Context context,
Mp3Model model,
MyReceiver.KEY_ACTION_RECEIVER keyActionReceiver) {
/*save list mp3 to receiver.
* play or pause next.
* */
if ((context == null) || (model == null)) {
return;
}
Intent intent = new Intent(context,
MyIntentService.class);
intent.putExtra(MyReceiver.KEY_PARAM_DATA_MODEL_PARSE_STR_RECEIVER,
new Gson().toJson(model));
if (keyActionReceiver != null) {
intent.setAction(keyActionReceiver.getValue());
}
CommonUtils.showLogDebug("show data:");
context.startService(intent);
}
void handlerDataForNotification(Mp3Model model) {
if (model == null) {
return;
}
//send pending
PendingIntent deletePendingIntent = PendingIntent.getBroadcast(this,
1 /* Request code */,
new Intent(this,
MyReceiver.class).setAction(MyReceiver.KEY_ACTION_RECEIVER.KEY_ACTION_DELETE_RECEIVER.getValue()),
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent previousPendingIntent = PendingIntent.getBroadcast(this,
3 /* Request code */,
new Intent(this,
MyReceiver.class).setAction(MyReceiver.KEY_ACTION_RECEIVER.KEY_ACTION_PREVIOUS_MP3_RECEIVER.getValue()),
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent nextPendingIntent = PendingIntent.getBroadcast(this,
4 /* Request code */,
new Intent(this,
MyReceiver.class).setAction(MyReceiver.KEY_ACTION_RECEIVER.KEY_ACTION_NEXT_MP3_RECEIVER.getValue()),
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent pauseOrPausePendingIntent = PendingIntent.getBroadcast(this,
5 /* Request code */,
new Intent(this,
MyReceiver.class).setAction(model.isPlay() ?
MyReceiver.KEY_ACTION_RECEIVER.KEY_ACTION_PLAY_MP3_RECEIVER.getValue() :
MyReceiver.KEY_ACTION_RECEIVER.KEY_ACTION_PAUSE_MP3_RECEIVER.getValue()),
PendingIntent.FLAG_UPDATE_CURRENT);
PendingIntent openViewPendingIntent = PendingIntent.getBroadcast(this,
5 /* Request code */,
new Intent(this,
MyReceiver.class).setAction(MyReceiver.KEY_ACTION_RECEIVER.KEY_ACTION_OPEN_VIEW_MP3_RECEIVER.getValue()),
PendingIntent.FLAG_UPDATE_CURRENT);
String CHANNEL_ID = MyApplication.getInstance()
.getPackageName();
RemoteViews remoteViews = new RemoteViews(MyApplication.getInstance()
.getPackageName(),
R.layout.view_mp3_notification_small);
remoteViews.setImageViewBitmap(R.id.ivAlbumOfNotification,
CommonUtils.getImageBitmapWithScaleDefault(CommonUtils.isStringDataValid(model.getThumbMp3()) ?
model.getThumbMp3() :
"https://static.zerochan.net/Fukuhara.Mikoto.full.2201488.png"));
remoteViews.setImageViewResource(R.id.ivPreviousOfNotification,
R.drawable.ic_previous);
remoteViews.setImageViewResource(R.id.ivNextOfNotification,
R.drawable.ic_next);
remoteViews.setImageViewResource(R.id.ivPlayOrPauseOfNotification,
model.isPlay() ?
R.drawable.ic_play :
R.drawable.ic_pause);
remoteViews.setTextViewText(R.id.tvTitleOfNotification,
CommonUtils.isStringDataValid(model.getTitleMp3()) ?
model.getTitleMp3() :
MyApplication.getInstance()
.getString(R.string.app_name));
// set clicked.
remoteViews.setOnClickPendingIntent(R.id.ivPreviousOfNotification,
previousPendingIntent);
remoteViews.setOnClickPendingIntent(R.id.ivNextOfNotification,
nextPendingIntent);
remoteViews.setOnClickPendingIntent(R.id.ivPlayOrPauseOfNotification,
pauseOrPausePendingIntent);
remoteViews.setOnClickPendingIntent(R.id.rlParentNotification,
openViewPendingIntent);
NotificationCompat.Builder builder = new NotificationCompat.Builder(this,
CHANNEL_ID)
.setVisibility(NotificationCompat.VISIBILITY_PUBLIC)
.setSmallIcon(R.drawable.ic_headphone)
.setCustomBigContentView(remoteViews)//todo big content.
.setCustomContentView(remoteViews)
.setLargeIcon(BitmapFactory.decodeResource(this.getResources(),
R.mipmap.ic_launcher))
.setOngoing(false)//ko cho xoa notification.
.setDeleteIntent(deletePendingIntent)
.setStyle(new android.support.v4.media.app.NotificationCompat.MediaStyle())
.setAutoCancel(true);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
if (notificationManager != null) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel mChannel = new NotificationChannel(CHANNEL_ID,
CommonUtils.stripAccents(MyApplication.getInstance()
.getString(R.string.app_name)),
NotificationManager.IMPORTANCE_LOW);// set importance notification status
notificationManager.createNotificationChannel(mChannel);
}
int idNotification = ID_NOTIFICATION;
// avoid more notification set id default not change.
notificationManager.notify(idNotification /* ID of notification */,
builder.build());
}
}
}
我的接收器
package vn.top12.app;
import android.app.ActivityManager;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.util.List;
import vn.top12.app.models.Mp3Model;
import vn.top12.app.utils.CommonUtils;
public class MyReceiver
extends BroadcastReceiver {
public static String KEY_PARAM_LIST_DATA_MODEL_PARSE_STR_FROM_ACTIVITY = "mp3ListParse";
public static String KEY_PARAM_DATA_MODEL_PARSE_STR_RECEIVER = "mp3ModelParse";
public static String KEY_PARAM_POSITION_CURRENT_RECEIVER = "current";
private static MyIntentService myIntentService;
public static int ID_NOTIFICATION = 7;
public enum KEY_ACTION_RECEIVER {
// use name same with manifest
KEY_ACTION_OPEN_VIEW_MP3_RECEIVER(MyApplication.getInstance()
.getPackageName() + "_OPEN_L"),
KEY_ACTION_NEXT_MP3_RECEIVER(MyApplication.getInstance()
.getPackageName() + "_NEXT_L"),
KEY_ACTION_PREVIOUS_MP3_RECEIVER(MyApplication.getInstance()
.getPackageName() + "_PREVIOUS_L"),
KEY_ACTION_PLAY_MP3_RECEIVER(MyApplication.getInstance()
.getPackageName() + "_PLAY_L"),
KEY_ACTION_PAUSE_MP3_RECEIVER(MyApplication.getInstance()
.getPackageName() + "_PAUSE_L"),
KEY_ACTION_SEND_DATA_FROM_ACTIVITY_MP3_RECEIVER(MyApplication.getInstance()
.getPackageName() + "_FROM_ACTIVITY_L"),
KEY_ACTION_DELETE_RECEIVER(MyApplication.getInstance()
.getPackageName() + "_DELETE_L");
private String value;
KEY_ACTION_RECEIVER(String value) {
this.value = value;
}
public String getValue() {
return value;
}
}
public MyReceiver() {
CommonUtils.showLogDebug("myre" + myIntentService);
if (myIntentService == null) {
myIntentService = new MyIntentService();
}
}
@Override
public IBinder peekService(final Context myContext,
final Intent service) {
System.out.println(">>>>> peekService");
return super.peekService(myContext,
service);
}
@Override
public void onReceive(Context context,
Intent intent) {
CommonUtils.showLogDebug("abc" + isMyServiceRunning(MyIntentService.class,
context));
if (intent != null) {
CommonUtils.showLogDebug("intent" + intent.getAction() + "_" + intent.getExtras());
if (intent.getExtras() != null) {
//get data.
String strConvertMp3 = intent.getExtras()
.getString(KEY_PARAM_LIST_DATA_MODEL_PARSE_STR_FROM_ACTIVITY);
if (CommonUtils.isStringDataValid(strConvertMp3)) {
List<Mp3Model> mp3Models = new Gson().fromJson(strConvertMp3,
new TypeToken<List<Mp3Model>>() {
}.getType());
if (myIntentService != null) {
myIntentService.intListDataModelToService(mp3Models,
intent.getExtras()
.getInt(KEY_PARAM_POSITION_CURRENT_RECEIVER));
}
}
}
if ((intent.getAction() != null)) {
//handler
if (intent.getAction()
.equals(KEY_ACTION_RECEIVER.KEY_ACTION_SEND_DATA_FROM_ACTIVITY_MP3_RECEIVER.getValue())) {
if (myIntentService != null) {
myIntentService.initListMp3ForPlayer();
myIntentService.updatePlayOrPauseForPlayer(true,
context);
}
} else if (intent.getAction()
.equals(KEY_ACTION_RECEIVER.KEY_ACTION_NEXT_MP3_RECEIVER.getValue())) {
//todo next mp3.
if (myIntentService != null) {
myIntentService.nextOrPreviousClicked(true,
context);
}
} else if (intent.getAction()
.equals(KEY_ACTION_RECEIVER.KEY_ACTION_PREVIOUS_MP3_RECEIVER.getValue())) {
//todo previous
CommonUtils.showLogDebug("previous");
if (myIntentService != null) {
myIntentService.nextOrPreviousClicked(false,
context);
}
} else if (intent.getAction()
.equals(KEY_ACTION_RECEIVER.KEY_ACTION_PAUSE_MP3_RECEIVER.getValue())) {
//todo pause
CommonUtils.showLogDebug("pause");
if (myIntentService != null) {
myIntentService.updatePlayOrPauseForPlayer(false,
context);
}
} else if (intent.getAction()
.equals(KEY_ACTION_RECEIVER.KEY_ACTION_PLAY_MP3_RECEIVER.getValue())) {
//todo play. nhan status play se set up pause.
CommonUtils.showLogDebug("play");
if (myIntentService != null) {
myIntentService.updatePlayOrPauseForPlayer(true,
context);
}
} else if (intent.getAction()
.equals(KEY_ACTION_RECEIVER.KEY_ACTION_OPEN_VIEW_MP3_RECEIVER.getValue())) {
CommonUtils.showLogDebug("open view");
} else if (intent.getAction()
.equals(KEY_ACTION_RECEIVER.KEY_ACTION_DELETE_RECEIVER.getValue())) {
CommonUtils.showLogDebug("myIntentService" + myIntentService);
//put data next.
NotificationManager
manager =
(NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
if (manager != null) {
manager.cancel(ID_NOTIFICATION);
}
if (myIntentService != null) {
myIntentService.stopServiceAndClearFromOut(context);
myIntentService = null;
}
}
}
}
}
private boolean isMyServiceRunning(Class<?> serviceClass,
Context context) {
ActivityManager
manager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
if (manager != null) {
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName()
.equals(service.service.getClassName())) {
System.out.println(">>>>>truw");
return true;
}
}
}
return false;
}
}
答案 0 :(得分:0)
我用创建服务检查服务mp3停止
来解决我的问题
package vn.top12.app;import android.app.Service; import android.content.Intent; import android.content.pm.ServiceInfo; import android.os.IBinder;
import vn.top12.app.activities.HomeNewActivity;
public class MyStopMp3Service extends Service { public MyStopMp3Service() { }
@Override public IBinder onBind(Intent intent) { // TODO: Return the communication channel to the service. throw new UnsupportedOperationException("Not yet implemented"); } /** * This is called if the service is currently running and the user has * removed a task that comes from the service's application. If you have * set {@link ServiceInfo#FLAG_STOP_WITH_TASK ServiceInfo.FLAG_STOP_WITH_TASK} * then you will not receive this callback; instead, the service will simply * be stopped. * * @param rootIntent * The original root Intent that was used to launch * the task that is being removed. */ @Override public void onTaskRemoved(final Intent rootIntent) { // close sendBroadcast(new Intent(this, MyReceiver.class).setAction(MyReceiver.KEY_ACTION_RECEIVER.KEY_ACTION_DELETE_RECEIVER.getValue())); stopSelf(); } } </pre>