Ishmael Chibvuri Ishmael Chibvuri - 4 months ago 23
Android Question

java.lang.RuntimeException: Unable to start receiver xx.xx.ImediateSMSReceiver: java.lang.IllegalArgumentException: Context must not be null

I looked around for this question first before this post and figured I am not getting an answer that applies to me. So here I go :

I am developing an Android App which should receive SMS messages and uses the SMSes to do various things. The app is working fine in General, however each time a user closes the App or Reboots their phone and receive a relevant SMS before opening the app, it crashes giving a message "Unfortunately, Appname has stopped". Please help - below is my Receiver Class, Logcat and a Portion of my Manifest File.

PREFS CLASS

public class Prefs {

static Prefs singleton = null;

static SharedPreferences preferences;

static SharedPreferences.Editor editor;

Prefs(Context context) {
preferences = PreferenceManager.getDefaultSharedPreferences(context);
editor = preferences.edit();
}

Prefs(Context context, String name, int mode) {
preferences = context.getSharedPreferences(name, mode);
editor = preferences.edit();
}

public static Prefs with(Context context) {
if (singleton == null) {
singleton = new Builder(context, null, -1).build();
}
return singleton;
}

public static Prefs with(Context context, String name, int mode) {
if (singleton == null) {
singleton = new Builder(context, name, mode).build();
}
return singleton;
}

public void save(String key, boolean value) {
editor.putBoolean(key, value).apply();
}

public void save(String key, String value) {
editor.putString(key, value).apply();
}

public void save(String key, int value) {
editor.putInt(key, value).apply();
}

public void save(String key, float value) {
editor.putFloat(key, value).apply();
}

public void save(String key, long value) {
editor.putLong(key, value).apply();
}

public void save(String key, Set<String> value) {
editor.putStringSet(key, value).apply();
}

public boolean getBoolean(String key, boolean defValue) {
return preferences.getBoolean(key, defValue);
}

public String getString(String key, String defValue) {
return preferences.getString(key, defValue);
}

public int getInt(String key, int defValue) {
return preferences.getInt(key, defValue);
}

public float getFloat(String key, float defValue) {
return preferences.getFloat(key, defValue);
}

public long getLong(String key, long defValue) {
return preferences.getLong(key, defValue);
}

public Set<String> getStringSet(String key, Set<String> defValue) {
return preferences.getStringSet(key, defValue);
}

public Map<String, ?> getAll() {
return preferences.getAll();
}

public void remove(String key) {
editor.remove(key).apply();
}

public void removeAll(){
editor.clear().apply();
}

public void contains(String key){
preferences.contains(key);
}

private static class Builder {

private final Context context;
private final int mode;
private final String name;

public Builder(Context context, String name, int mode) {
if (context == null) {
throw new IllegalArgumentException("Context must not be null.");
}
this.context = context.getApplicationContext();
this.name = name;
this.mode = mode;
}

/**
* Method that creates an instance of Prefs
*
* @return an instance of Prefs
*/
public Prefs build() {
if (mode == -1 || name == null) {
return new Prefs(context);
}
return new Prefs(context, name, mode);
}
}
}


SMS RECEIVER CLASS

public class ImediateSMSReceiver extends BroadcastReceiver {
private static final String TAG = ImediateSMSReceiver.class.getSimpleName();

String amount = "";
String merch = "";
String ref = "";
String date = "";
String time = "";
String account = "";
String balance = "";

@Override
public void onReceive(Context context, Intent intent) {
Log.e(TAG, "Running onReceive from " + TAG);

if (intent.hasExtra("pdus")) {
Bundle bundle = intent.getExtras();
Object messages[] = (Object[]) bundle.get("pdus");
if (messages != null && !messages.equals("")) {
SmsMessage smsMessage[] = new SmsMessage[messages.length];
for (int n = 0; n < messages.length; n++) {
smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
}

Log.e(TAG, "Current Number of Messages Length " + messages.length);

TemplateReader reader = new TemplateReader(context);
String message = smsMessage[0].getMessageBody();

long id = reader.read(message, new Date());
if (id != 0) {
NotificationManager notificationManager = new NotificationManager();
notificationManager.SendTransactionNotification(context, (int) id,
TransactionFragment.class.getName(), message);
}
Log.e(TAG, "Message is " + messages);

} else {
Log.e(TAG, "Message is NULL");
}
}
}
}


LOGCAT

10-29 12:11:24.747: D/AssetManager(25433): addAssetPath path =/data/app/xx.xx.appname-1/base.apkmapset is 0
10-29 12:11:24.747: D/AssetManager(25433): addAssetPath path =/data/app/xx.xx.appname-1/base.apk, mapOffset =0
10-29 12:11:24.747: D/AssetManager(25433): addAssetPath path =/data/app/xx.xx.appname-1/base.apk,elasticAppCookieOffset ={3=0}
10-29 12:11:24.837: D/InjectionManager(25433): fillFeatureStoreMap xx.xx.appname
10-29 12:11:24.837: I/InjectionManager(25433): Constructor xx.xx.appname, Feature store :{}
10-29 12:11:24.837: I/LoadedApk(25433): getClassLoader :dalvik.system.PathClassLoader[DexPathList[[zip file "/data/app/xx.xx.appname/base.apk"],nativeLibraryDirectories=[/vendor/lib64, /system/lib64]]]
10-29 12:11:24.887: E/AndroidRuntime(25433): Process: xx.xx.appname, PID: 25433
10-29 12:11:24.887: E/AndroidRuntime(25433): java.lang.RuntimeException: Unable to start receiver xx.xx.appname.util.ImediateSMSReceiver: java.lang.IllegalArgumentException: Context must not be null.
10-29 12:11:24.887: E/AndroidRuntime(25433): at xx.xx.appname.xtras.Prefs$Builder.<init>(Prefs.java:115)
10-29 12:11:24.887: E/AndroidRuntime(25433): at xx.xx.appname.xtras.Prefs.with(Prefs.java:31)
10-29 12:11:24.887: E/AndroidRuntime(25433): at xx.xx.appname.util.TemplateReader.createAccountInDB(TemplateReader.java:676)
10-29 12:11:24.887: E/AndroidRuntime(25433): at xx.xx.appname.util.TemplateReader.createTransactionInDB(TemplateReader.java:522)
10-29 12:11:24.887: E/AndroidRuntime(25433): at xx.xx.appname.util.TemplateReader.createTransaction(TemplateReader.java:500)
10-29 12:11:24.887: E/AndroidRuntime(25433): at xx.xx.appname.util.TemplateReader.read(TemplateReader.java:441)
10-29 12:11:24.887: E/AndroidRuntime(25433): at xx.xx.appname.util.ImediateSMSReceiver.onReceive(ImediateSMSReceiver.java:56)


MANIFEST

<receiver
android:name=".util.ImediateSMSReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<action android:name="android.intent.action.USER_PRESENT" />
</intent-filter>
</receiver>

Answer

Line 115 of Prefs.java is attempting to use a context object that has not been initialised.Seems to be in an inner class called Builder

The code posted is not really relevant as the problem lies is code somewhere in TemplateReader or Prefs where you appear to be using the wrong context (using a null context instead of one that is passed in)