Android中的Service模板,通过Service发送通知并修改通知的提示音

         Sercvice作为android中的四大组件之一,主要用来执行后台耗时任务,比如上传大文件、轮询服务器消息、间断向服务器发送数据、应用处于后台运行时向用户推送通知等等,使用场景多样,但是Service跟Activity一样,也有它的代码模板,这里给出通过StartService启动发送通知的方式的Service代码模板,便于快速开发。

       通知已经适配了android8.0版本,这里顺便提一下由于通知在8.0版本android源码改动比较大,提出了一种channel的方式来管理通知,所以当项目的targetVersion>=26的时候需要做版本适配,并手动在设置的通知管理中心内打开通道,才能看到效果,channel通道默认是关闭的。

这里就直接贴上代码了:

public class MessgeService extends Service {
    private static final Class[] mStartForegroundSignature = new Class[]{
            int.class, Notification.class};
    private static final Class[] mStopForegroundSignature = new Class[]{boolean.class};
    private NotificationManager mNM;
    private Method mStartForeground;
    private Method mStopForeground;
    private Object[] mStartForegroundArgs = new Object[2];
    private Object[] mStopForegroundArgs = new Object[1];
    private Uri sound;
    private Uri soundDefault;

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

    @Override
    public void onCreate() {
        super.onCreate();

        mNM = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        sound = Uri.parse("android.resource://" + getPackageName() + "/raw/alarm_voice");
        try {
            mStartForeground = MessgeService.class.getMethod("startForeground",
                    mStartForegroundSignature);
            mStopForeground = MessgeService.class.getMethod("stopForeground",
                    mStopForegroundSignature);
        } catch (NoSuchMethodException e) {
            mStartForeground = mStopForeground = null;
        }
        // 我们并不需要为 notification.flags 设置 FLAG_ONGOING_EVENT,因为
        // 前台服务的 notification.flags 总是默认包含了那个标志位
        Notification notification = new Notification();
        // 注意使用 startForeground ,id 为 0 将不会显示 notification,1显示
        startForegroundCompat(0, notification);
        new Thread(r).start();
    }

    private Runnable r = new Runnable() {
        @Override
        public void run() {
            while (true) {
                handler.sendEmptyMessage(0);
                try {
                    Thread.sleep(30000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    };

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

    // 以兼容性方式开始前台服务
    private void startForegroundCompat(int id, Notification n) {
        if (mStartForeground != null) {
            mStartForegroundArgs[0] = id;
            mStartForegroundArgs[1] = n;
            try {
                mStartForeground.invoke(this, mStartForegroundArgs);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            return;
        }
        mNM.notify(id, n);
    }

    // 以兼容性方式停止前台服务
    private void stopForegroundCompat(int id) {
        if (mStopForeground != null) {
            mStopForegroundArgs[0] = Boolean.TRUE;
            try {
                mStopForeground.invoke(this, mStopForegroundArgs);
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
            return;
        }
        // 在 setForeground 之前调用 cancel,因为我们有可能在取消前台服务之后
        // 的那一瞬间被kill掉。这个时候 notification 便永远不会从通知一栏移除
        mNM.cancel(id);
    }

    Handler handler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            getUnreadMessage();
        }
    };

    /**
     * 读取未读消息的数量.
     */
    private void getUnreadMessage() {
        new OkHttpClientManager()
                .setUrl(MethodConstants.Messge.UNREAD_MESSAGE)
                .setOnNetWorkReponse(onNetworkResponse)
                .setIngnore(false)
                .builder();
    }

    OkHttpClientManager.OnNetworkResponse onNetworkResponse = new OkHttpClientManager.OnNetworkResponse() {
        @Override
        public void onNetworkResponse(String result) {
            try {
                JSONObject json = new JSONObject(result);
                int messgeCount = json.optInt("unreadMessageCount");
                AppApplication.messgeCount = messgeCount;
                AppApplication.getInstance().setSport();
                String unreadMessage = json.optString("unreadMessage");
                if (!TextUtils.isEmpty(unreadMessage) && !"null".equals(unreadMessage)) {
                    List list = GsonUtil.stringToList(unreadMessage, MessgeEntity.class);
                    for (int i = 0; i < list.size() && i < 2; i++) {
                        String taskMessageType = list.get(i).getTaskMessageType();
                        if (TextUtils.isEmpty(taskMessageType)) {
                            showNotifictionIcon(getApplication(), list.get(i), "com.haocang.messge.ui2.MessgeTabLayouFragment", false, null, null);
                        } 
                    }
                }
            } catch (JSONException e) {
                e.printStackTrace();
            }
        }

        @Override
        public void onErrorResponse(Response errorCode) {

        }
    };


    public void showNotifictionIcon(Context context, MessgeEntity entity, String fragmentName, boolean toTaskPage, String type, String taskName) {
        Class clazz = null;
        try {
            clazz = Class.forName("com.haocang.base.ui.CommonActivity");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

        if (clazz != null) {
            Intent intent = new Intent(getApplication(), clazz);//点击之后进入MainActivity
            intent.putExtra("fragmentName", fragmentName);
            intent.putExtra("messageId", entity.getId());
            
            intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, (int) entity.getId(), intent, PendingIntent.FLAG_UPDATE_CURRENT);//第二个参数如果id相同会覆盖之前的所有intent
            NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            String id = "channel_2";//删了会报错 。。。。。
            String id_normal= "channel_1";
            String name = "aaa";
            notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
            Notification notification;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                String channel_id_actural=id_normal;
                if (entity.getMessageCategory() == 2) {
                    channel_id_actural=id;
                }else {
                    channel_id_actural=id_normal;
                }
                NotificationChannel mChannel = new NotificationChannel(channel_id_actural, name, NotificationManager.IMPORTANCE_LOW);

                if(entity.getMessageCategory() == 2){
                    mChannel.setSound(sound, Notification.AUDIO_ATTRIBUTES_DEFAULT);
                }
                notificationManager.createNotificationChannel(mChannel);
                notification = new Notification.Builder(this)
                        .setChannelId(channel_id_actural)
                        .setContentTitle(entity.getTitle())
                        .setContentText(entity.getContent())
                        .setContentIntent(pendingIntent)
                        .setSmallIcon(R.mipmap.ic_mango).build();
            } else {
                NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
                        .setContentTitle(entity.getTitle())
                        .setContentText(entity.getContent())
                        .setSmallIcon(R.mipmap.ic_mango)
                        .setContentIntent(pendingIntent)
//                        .setDefaults(Notification.DEFAULT_SOUND)
                        .setOngoing(false);
//                    .setChannel(id);//无效
                if (entity.getMessageCategory() == 2) {
                    notificationBuilder.setSound(sound, 5);
                } else {
                    notificationBuilder.setDefaults(Notification.DEFAULT_SOUND);
                }
                notification = notificationBuilder.build();
            }
            notificationManager.notify((int) entity.getId(), notification);
        }
    }


    
}

 

你可能感兴趣的:(移动开发)