標籤:
需要的知識點: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 { 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; } } 這部只是分核心代碼,其餘的就請自行擴充!
Android開發--推送