我正在尝试通过调用Intent发送短信/电子邮件,但是我正在获得NPE,我不知道是什么原因。
我尝试了几种不同的方法,但是显然我在寻找代码错误部分中的问题。
我仍在测试中,我直接从其他类中使用sendSms / sendEmail,该类也扩展了IntentService,但事实并非如此。虽然那不是很重要。 Anyhoo,这是我的代码:
import android.app.IntentService;
import android.content.Intent;
import android.net.Uri;
import android.support.annotation.Nullable;
import android.widget.Toast;
import java.util.Map;
public class FallNotificationService extends IntentService { // FIXME necessário extender IntentService?
public FallNotificationService() {
super(".FallNotificationService");
}
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public FallNotificationService(String name) {
super(name);
}
@Override
protected void onHandleIntent(@Nullable Intent intent) {
}
public boolean sendNotification(Elderly elderly) {
boolean success = false;
String name = elderly.getName();
for (Caregiver caregiver : elderly.getCaregivers()) {
for (Map.Entry<ContactType, String> entry : caregiver.getContacts().entrySet()) {
ContactType contactType = entry.getKey();
String contact = entry.getValue();
switch (contactType) {
case SMS:
success = this.sendSms(name, contact);
break;
case EMAIL:
success = this.sendEmail(name, contact);
break;
case WHATSAPP:
success = this.sendWhatsapp(name, contact);
break;
}
}
}
return success;
}
public boolean sendWhatsapp(String name,
String contact) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
intent.setType("text/plain");
intent.setPackage("com.whatsapp");
try {
super.startActivity(intent);
//finish();
return true;
} catch (Exception e) {
//Toast.makeText(this, "Sms not send", Toast.LENGTH_LONG).show();
e.printStackTrace();
return false;
}
}
public boolean sendSms(String name,
String contact) {
String uriText = "smsto:" + contact +
"?sms_body=" + Uri.encode("caiu");
Intent intent = new Intent(Intent.ACTION_SENDTO);
//intent.setData(Uri.parse("smsto:"));
//intent.setData(Uri.parse("smsto:" + contact));
intent.setData(Uri.parse(uriText));
intent.setType("vnd.android-dir/mms-sendSms");
//intent.putExtra("address", contact);
try {
super.startActivity(intent);
//finish();
return true;
} catch (Exception e) {
//Toast.makeText(this, "Sms not send", Toast.LENGTH_LONG).show();
e.printStackTrace();
return false;
}
}
public boolean sendEmail(String name,
String contact) {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:" + contact));
//intent.putExtra("address", contact);
intent.putExtra("message_body", "caiu");
try {
startActivity(intent);
//finish();
return true;
} catch (Exception e) {
// Toast.makeText(this, "Email not send", Toast.LENGTH_LONG).show();
e.printStackTrace();
return false;
}
}
}
这是我的AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.cam.myapplication">
<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">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".FallDetectionService" android:exported="false"/>
</application>
<uses-feature android:name="android.hardware.sensor.accelerometer" android:required="true" />
<uses-feature android:name="android.hardware.sensor.gyroscope" android:required="false"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
</manifest>
这是app / build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 27
defaultConfig {
applicationId "com.example.cam.myapplication"
minSdkVersion 15
targetSdkVersion 27
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:27.1.1'
implementation 'com.android.support.constraint:constraint-layout:1.1.2'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
compileOnly "org.projectlombok:lombok:1.18.2"
annotationProcessor 'org.projectlombok:lombok:1.18.2'
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
}
Stacktrace:
java.lang.NullPointerException: Attempt to invoke virtual method 'void android.content.Context.startActivity(android.content.Intent)' on a null object reference
at android.content.ContextWrapper.startActivity(ContextWrapper.java:356)
at com.example.cam.myapplication.FallNotificationService.sendEmail(FallNotificationService.java:108)
at com.example.cam.myapplication.FallDetectionService.isFallDetected(FallDetectionService.java:88)
at com.example.cam.myapplication.FallDetectionService.onSensorChanged(FallDetectionService.java:74)
at android.hardware.SystemSensorManager$SensorEventQueue.dispatchSensorEvent(SystemSensorManager.java:699)
at android.os.MessageQueue.nativePollOnce(Native Method)
at android.os.MessageQueue.next(MessageQueue.java:323)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:6123)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:757)
此外,如果取消注释Toast.makeText所在的行,我也会得到一个NPE。 因此,我猜测问题出在与我作为上下文传递的内容有关,但我无法弄清楚是什么。
答案 0 :(得分:0)
正如我们在堆栈跟踪中看到的那样,崩溃是由函数sendEmail()
引起的,并且像在手机中那样生成,没有应用程序具有任何可以处理意图约束的活动,您已经在意图中提供了该功能,
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:" + contact));
//intent.putExtra("address", contact);
intent.putExtra("message_body", "caiu");
try {
startActivity(intent);
//finish();
return true;
} catch (Exception e) {
// Toast.makeText(this, "Email not send", Toast.LENGTH_LONG).show();
e.printStackTrace();
return false;
}
我们可以在这里看到,您在setData(Uri.parse("mailto:" + contact))
中提供了条件,因此如果android手机没有任何可发送电子邮件的应用程序,它将崩溃,但是由于您在try-catch中捕获了它,因此抛出空指针异常,如果您将在具有电子邮件应用程序的设备中测试代码,则它将起作用。
因此,使用功能resolveActivity()
检查意图条件是否满足始终是最佳实践
如下所示。
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:" + contact));
//intent.putExtra("address", contact);
intent.putExtra("message_body", "caiu");
if(intent.resolveActivity(getContext().getPackageManager())){
// Phone has email app to handle this intent.. we can call the
intent
startActivity(intent);
}else{
// Phone does not have email app to handle this intent, handle
accordingly, in this case we can show open default android
share intent..
}
答案 1 :(得分:0)
碰巧,正如Mike M.所说,我正在用new实例化服务。 所以我将其添加到AndroidManifest.xml中,并在我调用新的FallNotificationService()的地方调用了startActivity。