2017-10-01 20 views
2

SMSを受信するたびに、コード(ネットワーク)を実行する必要があるアプリを開発しています。
API25以下では問題ありません。マニフェストファイルに暗黙的にreceiverを登録し、指定されたクラスでサービスを開始します。BroadcastReceiverです。ただし、API26ではandroid.provider.Telephony.SMS_RECEIVEDreceiverに登録することはできません。アンドロイドで受信SMSのサービスを実行するOreo

注:Androidのドキュメントから

アプリケーションがAPIレベル26以上をターゲットにしている場合、あなたは除き、暗黙の放送(特にあなたのアプリケーションをターゲットとしていない放送)のための受信機を宣言するマニフェストを使用することはできませんその制限から免除されるいくつかの暗黙的な放送のために。ほとんどの場合、代わりにスケジュールされたジョブを使用できます。

私はthis one on mediumのようないくつかの記事を読んでいます。 JobSchedulerまたはExplicit Receiverのような解決策がありますが、最初のものはネットワーク状態の変更に使用され、SMS_RECEIVEDイベントでジョブをトリガする方法を見つけることができず、2つ目のアクティビティはアクティビティが起動して実行されるまで有効です。

私のアプリケーションの性質上、受信したSMSがアプリケーションの実行中であるかどうかを聞く必要があります。 API 26+でそれを行うには?

編集

たぶんcode in JobInfoBuilder doc on android websiteは助けることができます。デバイス上の写真の変化を監視し、変更時にジョブを開始します。しかし、私は、私はSMS_RECEIVED_ACTIONは現在免除暗黙の放送listに存在するようになりましたあなたが安全であるためだと思うSMS(それはContentObserver経由でSMSを監視することが可能です場合でもわからない)

+0

私は周期的なチェック方法を備えたジョブスケジューラが正しい解決策かもしれないと思います。 – VVB

+0

@VVB SMSを受信したときに音を鳴らすTTSアプリを開発していますが、受け取ったSMSを検出する時間を短くするとパフォーマンスに悪影響があり、適切な解決策ではないようです。 – szamani20

+2

'SMS_RECEIVED'アクションは、新しい暗黙のブロードキャスト制限から免除されています。 https://developer.android.com/guide/components/broadcast-exceptions.html –

答えて

2

アンドロイドで仕事をする方法がたくさんあるので、私はこの回答を投稿し、問題を解決するための私のアプローチを述べます。明らかに問題によって私は一般的な問題を意味しませんSMS_RECEIVED受信機自体。

Iフォアグラウンドサービスを開始し、そこでは、私は(例えば)着信コールを聞くために、動的または明示的な受信機を登録しますMainActivity.java

CallMonitorService.java S onCreate()方法ここで
String action = "START" 
final Intent intent = new Intent(this, CallMonitorService.class); 
intent.setAction(action); 
startService(intent); 

final IntentFilter intentFilter = new IntentFilter(); 
    intentFilter.setPriority(2147483647); 
    intentFilter.addAction("android.intent.action.PHONE_STATE"); 
    this.callExplicitReceiver = new BroadcastReceiver() { 
     @Override 
     public void onReceive(Context context, Intent intent) { 
      if (intent.getAction().equals(TelephonyManager.ACTION_PHONE_STATE_CHANGED)) { 
       // do the stuff here 
      } 
     } 
    }; 
    registerReceiver(callExplicitReceiver, intentFilter); 

、その後:私はフィールドとしてBroadcastReceiver callExplicitReceiverを持っています:

if (intent.getAction().equals("START")) { 
     Intent callServiceNotificationIntent = new Intent(this, MainActivity.class); 
     callServiceNotificationIntent.setFlags(
      Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); 
     PendingIntent pendingIntent = PendingIntent 
      .getActivity(this, CALL_SERVICE_REQUEST_CODE, 
        callServiceNotificationIntent, CALL_SERVICE_FLAG); 

     Notification notification = new NotificationCompat.Builder(this) 
      .setContentTitle(CALL_NOTIFICATION_CONTENT_TITLE) 
      .setTicker(CALL_NOTIFICATION_TICKER) 
      .setContentText(CALL_NOTIFICATION_CONTENT_TEXT) 
      .setSmallIcon(R.drawable.ic_info_outline_black_24dp) 
      .setContentIntent(pendingIntent) 
      .setOngoing(true) 
      .build(); 
     startForeground(CALL_NOTIFICATION_ID, notification); 
    } 

し、最終的に:

@Override 
public void onDestroy() { 
    super.onDestroy(); 
    unregisterReceiver(callExplicitReceiver); 
} 

ユーザーが原因undismissable通知の実行中のサービスの通知を受け、それはアンドロイドOreoが何を望んだ、しかしを通じてされているので、私は良いアプローチと考えますアプリケーションユーザーのボタンは、サービスを破棄した結果としてサービスと監視受信機を停止することができました(コードのその部分をクリアしました)。

1

と同じことを行うために、適切なURIを見つけることができません。また、システムブロードキャストを受信すると、フォアグラウンドサービスを開始するか、またはジョブをスケジュールすることができます(あなたのケースでネットワーク操作を実行するため)。また、私も同じアクションを使用しており、テストでは正常に動作するようです。

+1

あなたの答えをありがとう。私はまた、そのリストにないいくつかの他の受信者にも必要でした。私のアプローチは、フォアグラウンドサービスを開始し、動的に(明示的な)受信者をプログラムで登録し、起動時にサービスを再起動することでした。私は私のアプローチを答えとして掲示します。 – szamani20

関連する問題