Search code examples
androidbroadcastreceiverandroid-launcher

BroadcastReceiver when no LAUNCHER is present, on Kitkat


I have a project in wich I must create an application with the following properties:

  • No LAUNCHER: category android:name="android.intent.category.LAUNCHER"
  • It must read SMSs sent from an specific number, and when it does, launch an Activity
  • Work on most Android versions (my target now is from [Froyo, 2.2] to [Kitkat, 4.4])

So far, my issue is that, on Kitkat, my BoradcastReceiver does not work when the app is just installed, however, if the app is run once, then it performs correctly. On prior versions, it behaves correctly. I have read that on version [HoneyComb 3.1] there were changes in the broadcast system, this question for instance, shows that my issue is know.

My question is: Is there a way to install an APP, and keep it silent, until needed. Such as the way they work on versions below [Honeycomb]?

  • If so, can someone point a direction.
  • if not, would starting the app once during boot, then closing it would be a reasonable approach?
  • In any case: What I am building "feels" wrong, as in is what I am doing considered bad practice? My system needs the user to actively install the APP, and the APP has the purpose of triggering additional sounds/movement when a message is given, to indicate that the user is in physical danger. The system is used to indicdate that the user, his home, or some of his/hers property is in direct danger, so it must awake and notify him/her under most circunstances.

MANIFEST:

<?xml version="1.0" encoding="utf-8"?>

<!--<uses-sdk android:minSdkVersion="8" /> -->

<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
    android:allowBackup="true"
    android:icon="@drawable/ic_iconedesktop"
    android:label="@string/app_name"
    android:theme="@style/AppTheme">

    <activity
        android:name=".MainActivity"
        android:label="@string/app_name">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

    <receiver android:name=".SMSbroadcastReceptor">
        <intent-filter>
            <action android:name="android.provider.Telephony.SMS_RECEIVED" />
        </intent-filter>
    </receiver>

</application>

RECEIVER

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.SmsManager;
import android.telephony.SmsMessage;
import android.util.Log;
import android.widget.Toast;

public class SMSbroadcastReceptor extends BroadcastReceiver {
final SmsManager sms = SmsManager.getDefault();
public void onReceive(Context contexto, Intent intencao) {
    final Bundle bundle = intencao.getExtras();
    try {
        if (bundle != null) {
            final Object[] pdusObj = (Object[]) bundle.get("pdus");
            String quem = "";
            String mensagem = "";
            for (int i = 0; i < pdusObj.length; i++) {
                SmsMessage smsRecebido = SmsMessage.createFromPdu((byte[]) pdusObj[i]);
                quem = smsRecebido.getDisplayOriginatingAddress();
                mensagem = smsRecebido.getDisplayMessageBody();
                Log.i("SMSbroadcastReceptor", "Quem: " + quem + "\n, O que: " + mensagem);
                Toast toast = Toast.makeText(contexto, "Quem: " + quem + "\n, O que: " + mensagem, Toast.LENGTH_LONG);
                toast.show();
            }
            if (quem.equals("+MY HIDDEN NUMBER IS HERE")) {// 
                // abortBroadcast();
                Intent comecarAMain = new Intent(contexto, MainActivity.class);
                comecarAMain.putExtra("MY PACKAGE", "A COMMAND");
                comecarAMain.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                contexto.startActivity(comecarAMain);
            }
        }
    } catch (Exception e) {
        Log.e("SMSbroadcastReceptor", "Excecao SMSbroadcastReceptor" + e);
    }
}

}


Solution

  • Is there a way to install an APP, and keep it silent, until needed

    Not really. Something has to use an explicit Intent to start up one of your app components before any manifest-registered receivers will work. If you will not have a home screen launcher, I do not know what else would start up one of your app components using an explicit Intent.

    would starting the app once during boot, then closing it would be a reasonable approach?

    No, because you have no way to get control at boot time, except via a manifest-registered BroadcastReceiver, which puts you in the same position that you are now.

    My system needs the user to actively install the APP

    Then there should be no particular problem in having a launcher activity, at least for a one-time launch. You are welcome to then disable that activity, though if the user force-stops your app, you will once again be in the stopped state and will no longer respond to broadcasts.

    and the APP has the purpose of triggering additional sounds/movement when a message is given, to indicate that the user is in physical danger

    Then there should be no problem in just leaving the launcher activity alone. After all, the user needs to be able to configure the behavior of your app.