需要的知识点:Notification、Service
第三方开源框架 : android-async-http-master
推送的来源:android项目中,有时会有这样一种需求:客户每隔一段时间,就像服务器发送一个请求,以获取某些重要的、实时更新的消息。比如版本更新,请求是否重新下载等。
关键点在于: 如何让应用实现在后台一直处于运行状态,并且每个一段时间就向服务器发一个请求?
一、在Activity中,通过startService()来启动服务
public void open(View view) {
Intent intent = new Intent(this, PushSmsService.class); //跳转页面
startService(intent); // 启动服务
}
二、自定义一个服务类,去继承android的Service类
/*******************************************************/
//短信推送服务类,在后台长期运行,每个一段时间就向服务器发送一次请求
/*******************************************************/
public class PushSmsService extends Service {
private MyThread myThread; //线程
private NotificationManager manager; //notificationManager
private Notification notification; //notification
private PendingIntent pi; //intent
private AsyncHttpClient client; //异步http客户端
private boolean flag = true; //标志位为true
@Override
public IBinder onBind(Intent intent) {
return null;
}
/****************************************< 加载页面 >******************************************/
@Override
public void onCreate() {
System.out.println("oncreate()");
this.client = new AsyncHttpClient();
this.myThread = new MyThread();
this.myThread.start(); //启动线程
super.onCreate();
}
//销毁页面
public void onDestroy() {
this.flag = false; //标志位为:false
super.onDestroy();
}
/****************************************< notification >******************************************/
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 {
public void run() {
String url = "http://110.65.99.66:8080/jerry/PushSmsServlet"; //定位服务器
while (flag) {//检查并判断标志位
System.out.println("发送请求");
try {
Thread.sleep(10000); // 每个10秒向服务器发送一次请求
} catch (InterruptedException e)
{
e.printStackTrace();
}
// 采用get方式向服务器发送请求
client.get(url, new AsyncHttpResponseHandler() {
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();
}
}
public void onFailure(int statusCode, Header[] headers, byte[] responseBody, Throwable error) {
Toast.makeText(getApplicationContext(), "数据请求失败", 0) .show();
}
});
}
三、清单文件中注册
3.1 service注册:
<service android:name=".PushSmsService"></service>
四、权限配置问题
4.1 由于通知信息使用到了手机的震动功能和网络访问,所以需要配置权限。
<uses-permission android:name="android.permission.VIBRATE"/> <!-震动权限->
<uses-permission android:name="android.permission.INTERNET"/> <!-网络权限->
五、再定义Activity
(用于用户点击下拉通知栏里的某条消息后,跳转到详细的消息界面)
public class ContentActivity extends Activity {
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);
}
}
5.1 在清单文件中注册新的Activity
<activity android:name=".ContentActivity"></activity>
5.2 注意到上边的代码是需要服务器提供支持的,我们去新建一个简单的服务器,里边添加一个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, "2016-08-08", "15208432222");
index++;
// smsList.add(sms);
// sms = new Sms(0, "傻逼", "2016-08-08", "15208432222");
// smsList.add(sms);
// sms = new Sms(1, "傻逼", "2016-08-08", "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();
}
//doPost
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
public class Sms {
this.doGet(request, response);
}
/****************************************< 定义封装用于存放消息的类 >******************************************/
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;
}
}
这部只是分核心代码,其余的就请自行扩充!