使用Android服務,實現報警管理器和廣播接收器

来源:https://www.cnblogs.com/langda/archive/2018/12/20/10152221.html
-Advertisement-
Play Games

介紹 幾乎在所有平臺上都有很多進程運行背景,它們被稱為服務。可能在Android平臺中有一些服務可以執行長時間運行的操作,這些操作在處理時不需要用戶交互。 在本文中,藉助預定義的Android警報服務,我們將創建一個應用程式,在所需的時間間隔內將電話模式更改為振動模式。除此之外,我們將編寫自己的Se ...


介紹

幾乎在所有平臺上都有很多進程運行背景,它們被稱為服務。可能在Android平臺中有一些服務可以執行長時間運行的操作,這些操作在處理時不需要用戶交互。  

在本文中,藉助預定義的Android警報服務,我們將創建一個應用程式,在所需的時間間隔內將電話模式更改為振動模式。除此之外,我們將編寫自己的Service類併在特定時間調用它。此外,此演示應用程式將回答以下問題:

  • 如何使用Alarm Manager?
  • 如何通過Alarm Manager啟動Intent?
  • 如何使用BroadcastReceiver?
  • 如何使用服務?
  • 如何在AndroidManifest.xml中註冊服務和接收器?
  • 如何更改手機鈴聲模式?

背景

要理解本文,讀者應該瞭解Java和Android平臺。

使用代碼

在開始編碼之前,應用程式的結構應該在編碼器的腦海中清楚。對於此演示應用程式,我們可以按照以下簡單步驟操作:

  1. 獲取用戶的時間間隔 MainActivity
  2. 根據時間間隔,設置鬧鐘以廣播它
  3. 寫入BroadcastReceivers以接收警報並執行操作或呼叫服務。

在這個演示中,有4個類:

隱藏   複製代碼
MainActivity             // main calss

FromHourAlarmReceiver    //BroadcastReceiver

ToHourAlarmReceiver      //BroadcastReceiver

MyService                //Service Class

1-在MainActivity中獲取用戶的時間間隔

a)MainActivity.class

public class MainActivity extends Activity {

 private EditText editText1;    //create the objects
 private EditText editText2;
 private Button btn1;
 private int hourFrom;
 private int hourTo;
             
       @Override
       protected void onCreate(Bundle savedInstanceState) {
          super.onCreate(savedInstanceState);
          setContentView(R.layout.activity_main);
         
          editText1 = (EditText) findViewById(R.id.editText1); //bind the object
          editText2 = (EditText) findViewById(R.id.editText2);
          btn1 = (Button) findViewById(R.id.btn1);
                      
          btn1.setOnClickListener(new OnClickListener() { //click listener for btn
                
                 @Override
                 public void onClick(View v) {
          });
       }
 
       @Override
       public boolean onCreateOptionsMenu(Menu menu) {
          // Inflate the menu; this adds items to the action bar if it is present.
          getMenuInflater().inflate(R.menu.main, menu);
          return true;
       }
 
}

b)main_activity.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    xmlns:tools="http://schemas.android.com/tools"

    android:layout_width="match_parent"

    android:layout_height="match_parent"

    android:paddingBottom="@dimen/activity_vertical_margin"

    android:paddingLeft="@dimen/activity_horizontal_margin"

    android:paddingRight="@dimen/activity_horizontal_margin"

    android:paddingTop="@dimen/activity_vertical_margin"

    android:orientation="vertical"

    tools:context=".MainActivity" >
    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Enter The Desired Time Interval For To Changed In Vibrate Mode" />
    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="From (24 Hour Format)" />
    <EditText

        android:id="@+id/editText1"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:numeric="integer"

        />
    <TextView

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="To (24 Hour Format)" />
    <EditText

        android:id="@+id/editText2"

        android:layout_width="fill_parent"

        android:layout_height="wrap_content"

        android:numeric="integer"

        />
    <Button

        android:id="@+id/btn1"

        android:layout_width="wrap_content"

        android:layout_height="wrap_content"

        android:text="Set the Service"/>
 
</LinearLayout>

2 - 根據間隔設置警報管理器

在創建Alarm Manager之前,我們需要創建我們的意圖來通過AlarmManager以下方式調用它們

Intent intent1 = new Intent(getBaseContext(), FromHourAlarmReceiver.class);
final PendingIntent sender1 = PendingIntent.getBroadcast(this, 192837, intent1, PendingIntent.FLAG_UPDATE_CURRENT);

Intent intent2 = new Intent(getBaseContext(), ToHourAlarmReceiver.class);
final PendingIntent sender2 = PendingIntent.getBroadcast(this, 192837, intent2, PendingIntent.FLAG_UPDATE_CURRENT);

在這裡,Intent是要執行的操作的名稱。由於我們將調用一個類,FromHourAlarmReceiver該類需要知道發生了什麼,為什麼調用它,誰是調用者等等。因此我們需要通過Intent對象[1]發送上下文。

這裡有另一個術語PendingIntent,這有兩點重要。第一個表明我們寫的意圖將在稍後開始。第二個是通過使用PendingIntent我們告訴我們正與3通信Android平臺研發 Android平臺的第三方應用程式或服務。在這個演示中,它是AlarmManager服務。

我們創建了兩個意圖,因為我們將設置2個警報,第一個將手機狀態更改為振動模式,另一個將其更改為正常模式。所以我們需要2個日曆對象來設置時間。

Calendar cal1 = Calendar.getInstance();
cal1.set(Calendar.HOUR,hourFrom);
                                  
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.HOUR,hourTo);

在我們擁有所有設置警報的對象和信息之後:

AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);am.set(AlarmManager.RTC_WAKEUP,
cal1.getTimeInMillis(), sender1);am.set(AlarmManager.RTC_WAKEUP,
cal2.getTimeInMillis(), sender2);

最後我們MainActivity將看起來像這樣:

public class MainActivity extends Activity {

 private EditText editText1;
 private EditText editText2;
 private Button btn1;
 private int hourFrom;
 private int hourTo;
             
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
     
      editText1 = (EditText) findViewById(R.id.editText1);
      editText2 = (EditText) findViewById(R.id.editText2);
      btn1 = (Button) findViewById(R.id.btn1);
     
       Intent intent1 = new Intent(getBaseContext(), FromHourAlarmReceiver.class);
       final PendingIntent sender1 = PendingIntent.getBroadcast(
         this, 192837, intent1, PendingIntent.FLAG_UPDATE_CURRENT);
       
       Intent intent2 = new Intent(getBaseContext(), ToHourAlarmReceiver.class);
       final PendingIntent sender2 = PendingIntent.getBroadcast(
         this, 192837, intent2, PendingIntent.FLAG_UPDATE_CURRENT);
     
      btn1.setOnClickListener(new OnClickListener() {
            
             @Override
             public void onClick(View v) {
                  
             try{
                   hourFrom = Integer.parseInt(editText1.getText().toString());
                   hourTo = Integer.parseInt(editText2.getText().toString());
             } catch(Exception e){}
                   if((0<hourFrom&&hourFrom<24)&&
                             (0<hourTo&&hourTo<24)){
                         
                       Calendar cal1 = Calendar.getInstance();
                       cal1.set(Calendar.HOUR,hourFrom);
                       
                       Calendar cal2 = Calendar.getInstance();
                       cal2.set(Calendar.HOUR,hourTo);
                       
                       AlarmManager am = (AlarmManager) getSystemService(ALARM_SERVICE);
                       am.set(AlarmManager.RTC_WAKEUP, cal1.getTimeInMillis(), sender1);
                        am.set(AlarmManager.RTC_WAKEUP, cal2.getTimeInMillis(), sender2);

                       Toast.makeText(getBaseContext(), 
                         "Phone Mode Will Be Changed Automatically !",Toast.LENGTH_LONG).show();
                   }
                   else{
                      Toast.makeText(getBaseContext(), 
                        "Please enter hour in between 1-23 !",Toast.LENGTH_LONG).show();
                   }     
             }
      });
   }
 
   @Override
   public boolean onCreateOptionsMenu(Menu menu) {
      // Inflate the menu; this adds items to the action bar if it is present.
      getMenuInflater().inflate(R.menu.main, menu);
      return true;
   }
}

3實現BroadcastReceivers

android源碼平臺中,幾乎所有在設備中執行的動作都被廣播。它可以想象成一個游泳池。無論操作是什麼,都會將信息發送到該池。這樣,您可以檢查設備中發生的情況並根據它們執行操作。

在我們的演示中,AlarmManager將廣播已發生警報並捕獲此警報,我們需要編寫BroadcastReceiver如下所示:

public class FromHourAlarmReceiver extends BroadcastReceiver{
   @Override
   public void onReceive(Context context, Intent intent) {
      }
}

可以用tie onReceive()方法執行期望的操作

註意:當a BroadcastReceiver添加到項目時,需要將其註冊到AndroidManifest.xml中以下代碼適用於此:

<receiverandroid:process=":remote" android:name="FromHourAlarmReceiver"></receiver>
<receiverandroid:process=":remote" android:name="ToHourAlarmReceiver"></receiver>

所以我們有2個BroadcastReceivers:

  1. FromHourAlarmReceiver 負責將手機狀態更改為振動模式。
  2. ToHourAlarmReceiver 負責將手機狀態更改為正常模式。

FromHourAlarmReceiver.class

public class FromHourAlarmReceiver extends BroadcastReceiver{

   @Override
   public void onReceive(Context context, Intent intent) {
      AudioManager am= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
      am.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
      Toast.makeText(context, "Phone Mode Is Changed to Vibrate Mode", Toast.LENGTH_LONG).show();
   }
}

ToHourAlarmManager.class

public class ToHourAlarmReceiver extends BroadcastReceiver{

   @Override
   public void onReceive(Context context, Intent intent) {
      AudioManager am= (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
      am.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
      Toast.makeText(context, "Phone Mode Is Changed to Normal Mode", Toast.LENGTH_LONG).show();
      Log.d("warnning", "something is happend...");
   }
}

註意2:當a收到警報提醒時BroadCastReceiver,您可以調用自己的服務類,如下所示:

Intent myServiceIntent = new
Intent(context,MyService.class);
context.startService(myServiceIntent);

註3:不要忘記將Service類註冊到AndroidManifest.xml

<service class=".MyService" android:name="MyService">
 <intent-filter>
   <action android:value="com.javaorigin.android.sample.service.MY_SERVICE"

           android:name=".MyService" />       
 </intent-filter>
</service>

MyService.class

public class MyService extends Service{

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

    }

    @Override
       public int onStartCommand(Intent intent, int flags, int startId) {
           Toast.makeText(getApplicationContext(), 
            "*** I am called by BroadcastReceiver ***", Toast.LENGTH_LONG).show();
                 return startId;
    }
     @Override
      public void onDestroy() {
          super.onDestroy();  
      }
   @Override
   public IBinder onBind(Intent arg0) {
          // TODO Auto-generated method stub
          return null;
   }
}

2.服務類的註冊

眾所周知,AndroidManifest.xml負責所有許可權,服務,意圖等。所以我們編寫的服務必須由AndroidManifest.xml知道為此,應將以下代碼添加到AndroidManifes.xml

<service class=".MyService" android:name="MyService">
 <intent-filter>
   <action android:value="com.javaorigin.android.sample.service.MY_SERVICE"

           android:name=".MyService" />       
   </intent-filter>
</service>

註意4:如果服務在運行時被調用,可能會崩潰。要防止出現此類錯誤,請檢查方法的標誌類型onStartCommand

節點5:大多數系統應用程式服務對用戶不可見。如果你想編寫一個不可見的服務,你應該使你的“apk”好像它是一個系統應用程式。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 1,某條數據放首位,其他倒序並分頁 select * from Student order by( case when id='2' then 1 ELSE 4 END),id desc limit 0,5; 2,給查詢的每條記錄添加編號 select (@i:=@i+1) no , s.* fro ...
  • Ubuntu 12.04上安裝Hadoop並運行 作者:凱魯嘎吉 - 博客園 http://www.cnblogs.com/kailugaji/ 在官網上下載好四個文件 在Ubuntu的/home/wrr/下創建一個文件夾java,將這四個文件拷到Ubuntu的/home/wrr/java/下,將e ...
  • 本文由雲+社區發表 本文作者:孫旭,騰訊資料庫開發工程師,9年資料庫內核開發經驗;熟悉資料庫查詢處理,併發控制,日誌以及存儲系統;熟悉PostgreSQL(Greenplum,PGXC等)、Teradata等資料庫內核實現機制。 CynosDB 是騰訊資料庫研發團隊推出的自研資料庫,有Postgre ...
  • 關於oracle database link,使用database link相關的查詢語句是否會開啟事務呢?我們知道,在資料庫中一個簡單的SELECT查詢語句不會產生事務(select for update會產生事務)。如下測試所示: 我們首先準備測試環境,創建了一個database link: L... ...
  • http://www.cnblogs.com/yijiaming/p/9684601.html 方法一: 1、需要安裝pymssql pip install pymssql 2、使用方法: 方法二: 1、安裝必要的組件: pip install django-sqlserver django-pyt ...
  • 公眾號:SAP Technical 本文作者:matinal 原文出處:http://www.cnblogs.com/SAPmatinal/ 原文鏈接:【HANA系列】SAP HANA XS使用Data Services查詢CDS實體【一】 前言部分 使用SAP HANA XS數據服務(XSDS)庫 ...
  • 今天不瘦給大家分享一下redis第二個基本數據類型:列表。如果大家瞭解基本數據結構,相信大家對列表不會陌生,比如在C語言中我們可以使用數組實現一個列表,也可以使用鏈表實現一個列表(列錶鏈表傻傻分不清楚,列表是一種抽象數據類型,鏈表為一種實現方式)。 言歸正傳,那redis是怎麼實現列表的呢?答案是: ...
  • 本文簡述在Android開發中Intent的常見應用,僅供學習分享使用。 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...