【问题标题】:Android - send sms/email - IntentAndroid - 发送短信/电子邮件 - 意图
【发布时间】:2018-08-21 19:47:31
【问题描述】:

我正在尝试通过调用 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'
}

堆栈跟踪:

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。 所以我猜这个问题与我作为上下文传递的内容有关,但我无法弄清楚它是什么。

【问题讨论】:

  • 顺便说一下,在调用 startActivity 之前检查是否存在能够处理此意图的活动。 (可能会发生用户在他的设备上没有电子邮件客户端应用程序)。使用此检查:intent.resolveActivity(getContext().getPackageManager()){ startActivity(intent); }
  • 您不能用new 自己实例化Service,并让它正常工作。这就是最终调用startActivity()Context 为空的原因。
  • 哦,谢谢@MikeM。就是这样。如果您发表评论作为答案,我会选择它作为最佳答案。
  • 哦,我很好。我只是指出了这个问题;并没有真正给你解决方案。我们称之为免费赠品。 :-) 随时发布您自己的答案,并附上实际问题的注释,以及您为解决问题所做的更改。不过,谢谢。我很感激这个提议。很高兴你弄明白了。干杯!

标签: android android-intent android-service


【解决方案1】:

正如Mike M. 所说,我正在用new 实例化服务。 所以我将它添加到我的 AndroidManifest.xml 并在我调用 new FallNotificationService() 的地方调用了 startActivity。

【讨论】:

    【解决方案2】:

    正如我们在您的堆栈跟踪中看到的那样,崩溃来自函数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中捕获它所以它抛出null指针异常,如果您将在具有电子邮件应用程序的设备中测试您的代码,它将起作用。 所以最好使用函数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..
         }
    

    【讨论】:

    • 这不完全是问题,但无论如何感谢您的提示。我会把它添加到代码中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-31
    • 1970-01-01
    • 2014-01-22
    相关资源
    最近更新 更多