zoukankan      html  css  js  c++  java
  • android通过服务实现消息推送

    这里运用到的andorid知识模块主要有Notification和Service,和一个android-async-http-master开源框架

    android项目中,有时会有这样一种需求:客户每隔一段时间,就像服务器发送一个请求,以获取某些重要的、实时更新的消息。比如天气预报。

    如何让应用实现在后台一直处于运行状态,并且每个一段时间就向服务器发一个请求?android里的四大组件之一:服务,就为我们提供了这种功能。

    因此,我们可以尝试在服务里边定义一个线程,只要服务不停止,线程就一直在运行,让它每隔一段时间,就向服务器发送一个请求。

    我们来看一下核心代码

    1.在Activity中,我们可以通过startService()来启动服务

    public void open(View view) {
    		Intent intent = new Intent(this, PushSmsService.class);
    		// 启动服务
    		startService(intent);
    	}


    2.这是我们需要自定义一个服务类,去继承android的Service类

    /**
     * 
     * 短信推送服务类,在后台长期运行,每个一段时间就向服务器发送一次请求
     * 
     * @author jerry
     * 
     */
    public class PushSmsService extends Service {
    	private MyThread myThread;
    	private NotificationManager manager;
    	private Notification notification;
    	private PendingIntent pi;
    	private AsyncHttpClient client;
    	private boolean flag = true;
    
    	@Override
    	public IBinder onBind(Intent intent) {
    		// TODO Auto-generated method stub
    		return null;
    	}
    
    	@Override
    	public void onCreate() {
    		System.out.println("oncreate()");
    		this.client = new AsyncHttpClient();
    		this.myThread = new MyThread();
    		this.myThread.start();
    		super.onCreate();
    	}
    
    	@Override
    	public void onDestroy() {
    		this.flag = false;
    		super.onDestroy();
    	}
    
    	private void notification(String content, String number, String date) {
    		// 获取系统的通知管理器
    		manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
    		notification = new Notification(R.drawable.ic_menu_compose, content,
    				System.currentTimeMillis());
    		notification.defaults = Notification.DEFAULT_ALL; // 使用默认设置,比如铃声、震动、闪灯
    		notification.flags = Notification.FLAG_AUTO_CANCEL; // 但用户点击消息后,消息自动在通知栏自动消失
    		notification.flags |= Notification.FLAG_NO_CLEAR;// 点击通知栏的删除,消息不会依然不会被删除
    
    		Intent intent = new Intent(getApplicationContext(),
    				ContentActivity.class);
    		intent.putExtra("content", content);
    		intent.putExtra("number", number);
    		intent.putExtra("date", date);
    
    		pi = PendingIntent.getActivity(getApplicationContext(), 0, intent, 0);
    		
    		notification.setLatestEventInfo(getApplicationContext(), number
    				+ "发来短信", content, pi);
    
    		// 将消息推送到状态栏
    		manager.notify(0, notification);
    
    	}
    
    	private class MyThread extends Thread {
    		@Override
    		public void run() {
    			String url = "http://110.65.99.66:8080/jerry/PushSmsServlet";
    			while (flag) {
    				System.out.println("发送请求");
    				try {
    					// 每个10秒向服务器发送一次请求
    					Thread.sleep(10000);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    
    				// 采用get方式向服务器发送请求
    				client.get(url, new AsyncHttpResponseHandler() {
    					@Override
    					public void onSuccess(int statusCode, Header[] headers,
    							byte[] responseBody) {
    						try {
    							JSONObject result = new JSONObject(new String(
    									responseBody, "utf-8"));
    							int state = result.getInt("state");
    							// 假设偶数为未读消息
    							if (state % 2 == 0) {
    								String content = result.getString("content");
    								String date = result.getString("date");
    								String number = result.getString("number");
    								notification(content, number, date);
    							}
    						} catch (Exception e) {
    							e.printStackTrace();
    						}
    
    					}
    
    					@Override
    					public void onFailure(int statusCode, Header[] headers,
    							byte[] responseBody, Throwable error) {
    						Toast.makeText(getApplicationContext(), "数据请求失败", 0)
    								.show();
    					}
    				});
    
    			}
    		}
    	}
    
    }
    


    注意我们要在清单文件中注册Service

     <service android:name=".PushSmsService"></service>


    由于通知信息使用到了手机的震动功能和网络访问,所以需要配置权限

        <uses-permission android:name="android.permission.VIBRATE"/>
        <uses-permission android:name="android.permission.INTERNET"/>


    我们在定义一个Activity,用于用户点击下拉通知栏里的某条消息后,跳转到详细的消息界面

    public class ContentActivity extends Activity {
    
    	@Override
    	protected void onCreate(Bundle savedInstanceState) {
    		super.onCreate(savedInstanceState);
    		setContentView(R.layout.activity_content);
    		Intent intent = getIntent();
    		TextView tv_content = (TextView) this.findViewById(R.id.tv_content);
    		TextView tv_number = (TextView) this.findViewById(R.id.tv_number);
    		TextView tv_date = (TextView) this.findViewById(R.id.tv_date);
    		if (intent != null) {
    			String content = intent.getStringExtra("content");
    			String number = intent.getStringExtra("number");
    			String date = intent.getStringExtra("date");
    			tv_content.setText("内容:" + content);
    			tv_number.setText("号码:" + number);
    			tv_date.setText("日期:" + date);
    
    		}
    
    	}
    
    }


    同样,我们需要在清单文件中注册新的Activity

    <activity android:name=".ContentActivity"></activity>


    主要到上边的代码是需要服务器提供支持的,我们去新建一个简单的服务器,里边添加一个Servlet就可以了

    public class PushSmsServlet extends HttpServlet {
    	private static int index = 1;
    
    	public void doGet(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    		System.out.println(index);
    		// List<Sms> smsList = new ArrayList<Sms>();
    		Sms sms = new Sms(index,
    				"我爱你我爱你我爱你我爱你我爱你我爱你我爱你我爱你我爱你我爱你我爱你我爱你" + index, "2013-03-03",
    				"13522224444");
    		index++;
    		// smsList.add(sms);
    		// sms = new Sms(0, "我真的爱你", "2013-04-04", "13522224444");
    		// smsList.add(sms);
    		// sms = new Sms(1, "我真的真的爱你", "2013-05-05", "13522224444");
    		// smsList.add(sms);
    
    		response.setContentType("text/html");
    		request.setCharacterEncoding("UTF-8");
    		response.setCharacterEncoding("utf-8");
    		PrintWriter out = response.getWriter();
    		Gson gson = new Gson();
    		// 将Sms类的数据转换为json数据格式
    		String json = gson.toJson(sms);
    		out.write(json);
    		out.flush();
    		out.close();
    
    	}
    
    	public void doPost(HttpServletRequest request, HttpServletResponse response)
    			throws ServletException, IOException {
    
    		this.doGet(request, response);
    	}
    
    }
    


    在定义封装用于存放消息的类

    public class Sms {
    	private int state;
    	private String content;
    	private String date;
    	private String number;
    
    	public Sms(int state, String content, String date, String number) {
    		super();
    		this.state = state;
    		this.content = content;
    		this.date = date;
    		this.number = number;
    	}
    
    }


    这里只贴出核心代码

    源码下载请点击。。。。。


  • 相关阅读:
    流处理 —— Spark Streaming中的Window操作
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.8 提供带注解的限定符元数据
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.7 为自动检测组件提供作用域
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.6 给自动检测组件命名
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.5 在组件中定义bean的元数据
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.4 使用过滤器自定义扫描
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.3 自动检测类和注册bean的定义
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.2 元注解
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10.1 @Component和深层的构造型注解
    Spring框架参考手册(4.2.6版本)翻译——第三部分 核心技术 6.10 类路径扫描和被管理的组件
  • 原文地址:https://www.cnblogs.com/riasky/p/3435760.html
Copyright © 2011-2022 走看看