Android短链接方式实现消息推送

       最近学习了Android的消息推送。一开始一直以为很复杂,没想到消息推送也分为两种方式一种是长链接,比如现在的即时通讯,基于XMPP、MQTT协议的消息推送。一种是短链接方式,实现的原理是android开机启动服务,定时调戏(就是访问的意思)服务器,服务器json形式返回数据,客户端再解析数据,把内容显示在通知栏栏,点击通知栏跳到指定的html页面上。上面总结下来就是短链接的Android端消息推送方式。接下来看怎么做!

       1,建立一个web项目,作为练习的服务器。如下图所示

      

     2,创建一个Servlet,定义以Json的形式返回。

public class UserServelt extends HttpServlet {

    public UserServelt() {
        super();
    }
    public void destroy() {
        super.destroy();
    }
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        this.doPost(request, response);        
    }

    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        
        System.out.println("hahha");
        
        response.setContentType("text/html");
        response.setCharacterEncoding("utf-8");
        String title = "标题";
        String content ="内容";
        String http = "http://www.baidu.com";
        PrintWriter out = response.getWriter();
        JSONObject json = new JSONObject();
        json.put("title", title);
        json.put("content",content);
        json.put("http",http);        
        out.println(json);        
        out.flush();
        out.close();
    }


  3,做完web端,回到android,建立一个android项目

  4,因为作为消息推送,当手机APP没有运行,手机是开启状态时,也可以接收到服务器推送的消息。所以,我们在设置一个开机广播,当手机开机后,启动一个定时服务,访问服务器指定的地址。开机广播代码如下。特别注意的是,需要在清单文件中注册开机广播,并且添加权限<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

public class BootReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        System.out.println("------------------看看你有木有动静-----------------");
        Intent service = new Intent(context,RunningService.class);
        context.startService(service);
    }
}

5,后台服务是通过定时器来完成,每隔1分钟访问服务器拿到数据。通过Timer、TimerTask和handler来完成。

    private void timerTask() {
        Timer timer = new Timer();
        TimerTask task = new TimerTask() {            
            @Override
            public void run() {
                Message msg = new Message();                
                //访问http操作
                try {    
                    String path = "http://192.168.1.110:8080/APP/servlet/UserServelt";
                    String result = HttpToServier.connect2(path); //获取json数据,把数据传给显示在通知栏的类中。
                    System.out.println("----------------------------result--------------------"+result);
                    msg.obj = result;                    
                    handler.sendMessage(msg);//发送数据                    
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };        
        timer.schedule(task, systemDate, 60000);//每隔一分钟访问
    }

6.服务器返回的数据通过JSON解析,发送给通知栏

try {
                json = new JSONObject((String) msg.obj);
                title = json.getString("title");
                content = json.getString("content");
                url = json.getString("http");
            } catch (JSONException e1) {
                e1.printStackTrace();
            }

7,定义一个通知栏,显示服务器返回的数据

//获取状态通知栏管理
        NotificationManager mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        //获取通知栏构造器Builder
        NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(this);
        
        //初始化通知栏
        mBuilder.setContentTitle(title)
            .setContentText(content)
            .setContentIntent(getDefalutIntent(Notification.FLAG_AUTO_CANCEL,url))
            .setNumber(5)//显示数量
            .setTicker(url)//通知首次出现在通知栏,带上升动画效果的
            .setWhen(System.currentTimeMillis())//通知产生的时间,会在通知信息里显示
            .setPriority(Notification.PRIORITY_DEFAULT)//设置该通知优先级
            .setAutoCancel(true)//设置这个标志当用户单击面板就可以让通知将自动取消  
            .setOngoing(false)//ture,设置他为一个正在进行的通知。他们通常是用来表示一个后台任务,用户积极参与(如播放音乐)或以某种方式正在等待,因此占用设备(如一个文件下载,同步操作,主动网络连接)
            .setDefaults(Notification.DEFAULT_VIBRATE)//向通知添加声音、闪灯和振动效果的最简单、最一致的方式是使用当前的用户默认设置,使用defaults属性,可以组合:
            //Notification.DEFAULT_ALL  Notification.DEFAULT_SOUND 添加声音 // requires VIBRATE permission
            .setSmallIcon(R.drawable.ic_launcher);
        mNotificationManager.notify(1,mBuilder.build());    //显示

8,访问服务器我用了两种方式一种是httpclient方式,一种是post的方式,你可以根据自己的喜爱挑一种

public static String connect2(String url) throws Exception{
        HttpClient httpClient = new DefaultHttpClient();
        HttpPost post = new HttpPost(new URI(url));
        HttpResponse httpResponse = httpClient.execute(post);        
        //如果服务器成功返回响应
        if(httpResponse.getStatusLine().getStatusCode() == 200){
            HttpEntity entity = httpResponse.getEntity();
            if(entity != null){
                //获取服务器返回的数据
                result = EntityUtils.toString(entity,"UTF-8");
                
                System.out.print("服务器返回的代码"+result);
            }
        }else{
            System.out.println("连接超时");
        }
        return result;
    }


public static String connect(URL url){
        InputStream inputStream = null;
        HttpURLConnection connection = null;
        StringBuffer sb = null;
        System.out.println("--------------------------准备----------------------");
        try {
            connection = (HttpURLConnection) url.openConnection();//打开链接
            System.out.println("--------------------------开始----------------------");
            connection.setConnectTimeout(3000);    //连接超时
            connection.setRequestMethod("POST");//连接请求方式
            
            connection.setDoInput(true);//设置是否从httpUrlConnection读入
            connection.setDoOutput(true);//设置是否向httpUrlConnection输出
            
//            connection.setRequestProperty("Connection", "Keep-Alive");//请求属性
            connection.connect();//连接
            System.out.println("--------------------------马上了----------------------");
            if(connection.getResponseCode() == 200){
                System.out.println("--------------------------hhaha----------------------");
                inputStream = connection.getInputStream();
                
                Reader reader = new InputStreamReader(inputStream,"UTF-8");//获取流
                BufferedReader bufferedReader = new BufferedReader(reader);
                String str = null;
                sb = new StringBuffer();
                while((str = bufferedReader.readLine()) != null){//读取流
                    sb.append(str);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally{
            if(inputStream != null){
                try {
                    inputStream.close();
                    inputStream = null;
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }        
        if(sb != null){
            return new String(sb);
        }
        return null;        
    }

9,需要注意的是需要在清单文件中添加访问网络的权限<uses-permission android:name="android.permission.INTERNET"/>,真机上运行必须在同一个局域网内

10,程序运行后的效果图如下,程序主界面和收到服务器返回的数据通过通知栏显示效果图



点击通知栏访问指定页面效果图:

服务端收到android端的请求,打印在控制台的信息如图


最后希望对大家有用

源码下载地址:http://download.csdn.net/detail/hong15007046964/8668677

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值