我的应用程序应该检查传入的SMS并阅读第一个单词以查看其是否为911。如果确实以“ 911”开头,则该应用程序应以最大音量播放用户选择的音调。一旦切换按钮变为打开状态,该应用就会继续停止,这将启动服务以在后台检查传入的消息并通知所有“ 911”文本。
我试图将其设置为默认助手处理程序和默认SMS,但是它没有显示为设备的选项。我正在使用Galaxy S9 +通过USB调试对其进行测试。我似乎无法始终运行它,但是我尝试了几种不同的方法。
我什至不知道该如何解决。这是运行输出:
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.urgentnotifications, PID: 6082
java.lang.RuntimeException: Unable to instantiate service com.example.urgentnotifications.UrgentNotifications: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3715)
at android.app.ActivityThread.access$1400(ActivityThread.java:235)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1784)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6981)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.Object android.content.Context.getSystemService(java.lang.String)' on a null object reference
at android.content.ContextWrapper.getSystemService(ContextWrapper.java:741)
at com.example.urgentnotifications.UrgentNotifications.<init>(UrgentNotifications.java:28)
at java.lang.Class.newInstance(Native Method)
at android.app.AppComponentFactory.instantiateService(AppComponentFactory.java:103)
at androidx.core.app.CoreComponentFactory.instantiateService(CoreComponentFactory.java:68)
at android.app.ActivityThread.handleCreateService(ActivityThread.java:3710)
at android.app.ActivityThread.access$1400(ActivityThread.java:235)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1784)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:6981)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1445)
I/Process: Sending signal. PID: 6082 SIG: 9
Application terminated.
有人知道我可以尝试什么或应该看什么来解决该问题吗?
我的代码:
清单:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.urgentnotifications">
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-feature android:name="android.hardware.camera.flash" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<service
android:name=".UrgentNotifications"
android:enabled="true" />
<service
android:name=".OnUnlockService"
android:enabled="true"></service>
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
MainActivity.java:
package com.example.urgentnotifications;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.widget.CompoundButton;
import android.widget.RadioGroup;
import android.widget.Switch;
import java.io.File;
import static android.app.Service.START_STICKY;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final Intent notify911 = new Intent(this, UrgentNotifications.class);
Switch OnOff = (Switch) findViewById(R.id.OnOffSwitch);
OnOff.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if(isChecked){
//what to do if switch is on
startService(notify911);
}else{
//what to do if switch is off
stopService(notify911);
}
}
});
final File ring1 = new File("raw/alarm_car.mp3");
final File ring2 = new File("raw/alarm_ring.mp3");
final File ring3 = new File("raw/alarms.mp3");
final File ring4 = new File("raw/best_htc_alarm_2013.mp3");
final File ring5 = new File("raw/car_alarm.mp3");
final File ring6 = new File("raw/clock_alarm_samsung.mp3");
final File ring7 = new File("raw/emergency_alarm_tone.mp3");
final File ring8 = new File("raw/extreme_loud_ringer.mp3");
final File ring9 = new File("raw/fire_alarm.mp3");
final File ring10 = new File("raw/fire_smoke_alarm.mp3");
final File ring11 = new File("raw/loud.mp3");
final File ring12 = new File("raw/loud2.mp3");
final File ring13 = new File("raw/loud_alarm.mp3");
final File ring14 = new File("raw/loud_alarm_clock.mp3");
final File ring15 = new File("raw/loud_continuous_beep.mp3");
final File ring16 = new File("raw/loud_sound__effect.mp3");
final File ring17 = new File("raw/loud_sounds.mp3");
final File ring18 = new File("raw/loud_train_horn.mp3");
final File ring19 = new File("raw/new_loud_ringtone.mp3");
final File ring20 = new File("raw/shrill9532.mp3");
final File ring21 = new File("raw/siren.mp3");
final File ring22 = new File("raw/siren_loud.mp3");
RadioGroup rg = (RadioGroup) findViewById(com.example.urgentnotifications.R.id.toneChoices);
int checkedRadioButtonID = rg.getCheckedRadioButtonId();
rg.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener(){
public void onCheckedChanged(RadioGroup arg0, int id) {
Uri path;
Ringtone selectedRingtone;
switch (id) {
case -1:
//ring5
path = MediaStore.Audio.Media.getContentUriForPath(ring5.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.alarm_car:
//ring5
path = MediaStore.Audio.Media.getContentUriForPath(ring5.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.alarm_ring:
//ring2
path = MediaStore.Audio.Media.getContentUriForPath(ring2.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.alarms:
//ring3
path = MediaStore.Audio.Media.getContentUriForPath(ring3.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.htc_alarm:
//ring4
path = MediaStore.Audio.Media.getContentUriForPath(ring4.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.car_alarm:
//ring1
path = MediaStore.Audio.Media.getContentUriForPath(ring1.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.clock_alarm_samsung:
//ring6
path = MediaStore.Audio.Media.getContentUriForPath(ring6.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.emergency_alarm_tone:
//ring7
path = MediaStore.Audio.Media.getContentUriForPath(ring7.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.extreme_loud_ringer:
//ring8
path = MediaStore.Audio.Media.getContentUriForPath(ring8.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.fire_alarm:
//ring9
path = MediaStore.Audio.Media.getContentUriForPath(ring9.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.fire_smoke_alarm:
//ring10
path = MediaStore.Audio.Media.getContentUriForPath(ring10.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.loud:
//ring11
path = MediaStore.Audio.Media.getContentUriForPath(ring11.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.loud2:
//ring12
path = MediaStore.Audio.Media.getContentUriForPath(ring12.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.loud_alarm:
//ring13
path = MediaStore.Audio.Media.getContentUriForPath(ring13.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.loud_alarm_clock:
//ring14
path = MediaStore.Audio.Media.getContentUriForPath(ring14.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.loud_continuous_beep:
//ring15
path = MediaStore.Audio.Media.getContentUriForPath(ring15.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.loud_sound_effect:
//ring16
path = MediaStore.Audio.Media.getContentUriForPath(ring16.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.loud_sounds:
//ring17
path = MediaStore.Audio.Media.getContentUriForPath(ring17.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.loud_train_horn:
//ring18
path = MediaStore.Audio.Media.getContentUriForPath(ring18.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.new_loud_ringtone:
//ring19
path = MediaStore.Audio.Media.getContentUriForPath(ring19.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.shrill:
//ring20
path = MediaStore.Audio.Media.getContentUriForPath(ring20.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.siren:
//ring21
path = MediaStore.Audio.Media.getContentUriForPath(ring21.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
case R.id.siren_loud:
//ring22
path = MediaStore.Audio.Media.getContentUriForPath(ring22.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
default:
//ring5
path = MediaStore.Audio.Media.getContentUriForPath(ring5.getAbsolutePath());
selectedRingtone = RingtoneManager.getRingtone(getApplicationContext(), path);
selectedRingtone.play();
notify911.putExtra("wakingTone", path);
break;
}
//notify911.putExtra("waking Tone", path);
}
});
}
}
UrgentNotifications.java(应该一直运行的第一个服务):
package com.example.urgentnotifications;
import java.lang.String;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import android.provider.Telephony;
import android.telephony.SmsMessage;
import static android.content.Intent.ACTION_USER_PRESENT;
import static android.media.AudioManager.STREAM_NOTIFICATION;
public class UrgentNotifications extends Service {
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
int originalVolume;
Uri urgentTone;
Ringtone newTone;
final int maxVolume = audioManager.getStreamMaxVolume(STREAM_NOTIFICATION);
Uri originalSoundUri = RingtoneManager.getActualDefaultRingtoneUri(getApplicationContext(), RingtoneManager.TYPE_NOTIFICATION);
public UrgentNotifications(){
}
@Override
public int onStartCommand(Intent intent, int flags, int startId){
originalVolume = audioManager.getStreamVolume(STREAM_NOTIFICATION);
//get current tone
urgentTone = intent.getParcelableExtra("wakingTone");
final BroadcastReceiver receiver = new BroadcastReceiver(){
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals("android.provider.Telephony.SMS_RECEIVED")){
//action for sms received
if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
String messageBody = smsMessage.getMessageBody();
if(messageBody.startsWith("911",0)){
wakeUpTheBeast();
}
}
}
}
}
};
return START_STICKY;
}
public void wakeUpTheBeast(){
//turn volume to max
audioManager.setStreamVolume(STREAM_NOTIFICATION, maxVolume, 0);
//use loud tone
setNewTone();
//listen for unlock; call onUnlock when unlocked
Intent youAwake = new Intent (this, OnUnlockService.class);
IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_USER_PRESENT);
youAwake.putExtra("stopThis", urgentTone);
youAwake.putExtra("originalUri", originalSoundUri);
youAwake.putExtra("originalVolume", originalVolume);
startService(youAwake);
}
public void setNewTone(){
//set notification tone to the chosen tone
RingtoneManager.setActualDefaultRingtoneUri(UrgentNotifications.this, RingtoneManager.TYPE_NOTIFICATION, urgentTone);
//loop until woken
Ringtone loopingTone = RingtoneManager.getRingtone(getApplicationContext(), urgentTone);
loopingTone.setLooping(true);
loopingTone.play();
}
@Override
public IBinder onBind(Intent arg0) { return null; }
}
OnUnlockService.java(当用户解锁手机时,UrgentNotification服务开始监视和处理的服务。)
package com.example.urgentnotifications;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.media.AudioManager;
import android.media.Ringtone;
import android.media.RingtoneManager;
import android.net.Uri;
import android.os.IBinder;
import static android.media.AudioManager.STREAM_NOTIFICATION;
public class OnUnlockService extends Service {
public OnUnlockService() {
}
AudioManager audioManager = (AudioManager) getSystemService(AUDIO_SERVICE);
public int onStartCommand(Context context, Intent intent){
final Uri stopThis = intent.getParcelableExtra("stopThis");
final Uri originalSoundUri = intent.getParcelableExtra("originalSoundUri");
final int originalVolume = intent.getParcelableExtra("originalVolume");
final BroadcastReceiver br = new BroadcastReceiver(){
@Override
public void onReceive(Context context1, Intent intent1){
String action = intent1.getAction();
if(intent1.getAction().equals(Intent.ACTION_USER_PRESENT)){
hesAlive(stopThis, originalSoundUri, originalVolume);
stopSelf();
}
}
};
return START_NOT_STICKY;
}
public void hesAlive(Uri stopThis, Uri originalSoundUri, int originalVolume){
Ringtone tone = RingtoneManager.getRingtone(getBaseContext(), stopThis);
tone.stop();
audioManager.setStreamVolume(STREAM_NOTIFICATION, originalVolume, 0);
RingtoneManager.setActualDefaultRingtoneUri(OnUnlockService.this, RingtoneManager.TYPE_NOTIFICATION, originalSoundUri);
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
}
注意:我正在使用Android Pie。