Allgemeine Fragen und Anregungen zum SMS abfangen und Sound abspielen

  • 11 Antworten
  • Letztes Antwortdatum
S

Septura

Neues Mitglied
0
Hallo liebe Community,
bin relativ neu auf dem Gebiet der Appentwicklung und bräruchte mal nen Rat, bzw. möchte wissen ob mein Vorhaben Prinzipell möglich ist:

Es geht um folgendes:
Bei unserer Freiwilligen Feuerwehr bekommen wir per SMS Alarmierungen (nicht nur aber ist billiger Piepserersatz).
Diese SMS sind immer von einer Nummer und haben auch den selben Aufbau (werden automatisch gesendet).

Meine Vorhaben ist jetzt mein Handy zum Piepser umfunktionieren, sodass es sozusagen wenn von dieser Nummer eine SMS kommt einen Ton sendet.

Da stehe ich vor folgenden Problemen und wollte mal fragen ob man es umsetzten kann:
a) SMS abfangen und parsen
b) Lautstärkereglung ignorieren (so wie z. B. beim Wecker, soll intern dann abgestellt werden)
c) per Knopfdruck auf die SMS antworten können

denke mal es wenn es umsetzbar ist eher als dienst aufgebaut werden.
Hab auch keine richtige Ahnung, wonach ich überhaupt suchen soll...
Wäre um ein paar Suchbegriffe bzw. Stichwörter sehr dankbar.

einen schönen Sonntag
Septura
 
Hallöchen, ich habe mal eine SMS-Vorlese App geschrieben, so just for fun. Wenn Du willst, kann ich gerne mal ein paar Snipets posten. Ansonsten google mal nach Intent_SMS_RECEIVED auslesen, oder Ton abspielen Android java, wenn Du einen eigenen Sound abspielen möchtest. Zudem hat Android verschiedene "Sound Kanäle" über die Du den Ton abspielen kannst. Empfehlen würde ich Dir jedoch den Telefonkanal zu nehmen und dessen Lautstärke hoch zu regeln. Entsprechende Berechtigungen werden nat. benötigt.

Edit: Das Vorhaben ist meiner Meinung super machbar und ideal als "Einsteigerprojekt" ;-)

Es gibt sehr einfache Möglichkeiten einen festen Text (oder durch Auslesen eines EditText) zu versenden. Man kann es aber auch über 2 Buttons machen à la "Komme" oder "Komme nicht"

Gesendet von meinem GT-I8150 mit der Android-Hilfe.de App
 
Zuletzt bearbeitet:
Super danke für die Antwort. Ja so ähnlich läuft das mit dem "komme" ein automatisches system von der Leitstellen Seite erfasst die Antworten, so weiß man schon früh, ob nachalarmiert werden muss.

dann mach ich mich mal schlau :) danke für den Hinweis mit Intent_SMS_RECEIVED.

Meinst du mit dem Telefonkanal hochregeln, dass ich automatisch bevor ich den Ton sende es lauter mache, und nachher wieder auf den Ursprung setzte, oder gibts die Möglichkeit trotz Stummschaltung des Telefonkanals den Ton zu senden?
 
Mit der Klasse "AudioManager" kannst Du viel regeln... Schau mal nach unter AudioManager | Android Developers

Grüße und viel Erfolg,
L4E

PS:
Septura schrieb:
Meinst du mit dem Telefonkanal hochregeln, dass ich automatisch bevor ich den Ton sende es lauter mache, und nachher wieder auf den Ursprung setzte, oder gibts die Möglichkeit trotz Stummschaltung des Telefonkanals den Ton zu senden?

So wohl als auch. Es geht beides. Du kannst über folgende "Kanäle" senden: Alarm, DTMF, Music, Notification, Ring, System, Voice_call & Default. Du könntest z.B. "Ring" nehmen, dann ist es als ob es klingelt. Dazu die Methode
Code:
public void adjustStreamVolume (int streamType, int direction, int flags)
die Lautstärke verändern, dessen Max. Lautstärke Du mit
Code:
public int getStreamMaxVolume (int streamType)
und die Lautstärke zum zurückstellen mit
Code:
public int getStreamVolume (int streamType)
(natürlich bevor Du es hochstellst) bekommst.
 
Zuletzt bearbeitet:
So hab jetzt mit deiner Hilfe ein bisschen recherchiert und stoße nun an das Problem, dass ich noch einen Art Einstiegspunkt brauche.

Denke mal es als Service geht in die richtige Richtung, nur hab ich da Probleme... schick mal ein bisschen Quellcode:

Code:
    <application
        android:allowBackup="true"
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        
        <service
            android:name="MyService"
            android:icon="@drawable/ic_launcher"
            android:label="@string/service_name"
            >
        </service>
        
        <receiver android:name="MyScheduleReceiver" >
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
            </intent-filter>
        </receiver>
        <receiver android:name="MyStartServiceReceiver" >
        </receiver>
    </application>
Code:
package cus.service;

import android.app.Service;
import android.content.Intent;
import android.os.IBinder;

public class MainService extends Service {

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        
        
        
        //Das ist sozusagen meien MAIN, aber wie komme ich hier hin...
        
        
        
        return Service.START_NOT_STICKY;
    }

    @Override
    public IBinder onBind(Intent intent) {
        // TODO for communication return IBinder implementation
        return null;
    }
}
 
ja mit

startService(..)

vermutlich
 
swordi schrieb:
ja mit

startService(..)

vermutlich

jo hab ich mir auch gedacht, ein bisschen code wäre hilfreich...

Code:
public class MyStartServiceReceiver extends BroadcastReceiver {

  @Override
  public void onReceive(Context context, Intent intent) {
    Intent service = new Intent(context, MainService.class);
    context.startService(service);
  }
}
und hier mit sollte doch der Service jede Sekunde zur ausführung gebracht werden:
Code:
public class MyScheduleReceiver extends BroadcastReceiver {

    // Restart service every 1 seconds
    private static final long REPEAT_TIME = 1000 * 1;

    @Override
    public void onReceive(Context context, Intent intent) {
        AlarmManager service = (AlarmManager) context
                .getSystemService(Context.ALARM_SERVICE);
        Intent i = new Intent(context, MyStartServiceReceiver.class);
        PendingIntent pending = PendingIntent.getBroadcast(context, 0, i,
                PendingIntent.FLAG_CANCEL_CURRENT);
        Calendar cal = Calendar.getInstance();
        // Start 15 seconds after boot completed
        cal.add(Calendar.SECOND, 15);

        // Fetch every 1 seconds
        // InexactRepeating allows Android to optimize the energy consumption
        service.setInexactRepeating(AlarmManager.RTC_WAKEUP,
                cal.getTimeInMillis(), REPEAT_TIME, pending);

        // service.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(),
        // REPEAT_TIME, pending);
    }
}
in diesem Sinne ist es überhaupt nötig jede Sekunde den Service aufzurufen oder kann man das ans empfangen eine SMS binden, dass nur wenn eine SMS im Eingang ist geprüft wird...
 
Ich verstehe Dein Problem noch nicht ganz. Du willst Doch nur, dass beim Eintreffen einer bestimmten SMS ein lauter Alarm ausgelöst wird, bei dem man einfach zurück antworten kann.

Manifest:
Code:
    <uses-permission android:name="android.permission.RECEIVE_SMS"/>
    
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    
    <application blabla> 
        <receiver android:name="PSRActivity"> 
            <intent-filter> 
                <action android:name=
                    "android.provider.Telephony.SMS_RECEIVED" /> 
            </intent-filter> 
        </receiver>
    </application>
PSRActivity.java
Code:
public class PSRActivity extends BroadcastReceiver
{
    @Override
    public void onReceive(Context context, Intent intent) 
    {
        Bundle bundle = intent.getExtras();        
        SmsMessage[] msgs = null;
        if (bundle != null)
        {
            Object[] pdus = (Object[]) bundle.get("pdus");
            msgs = new SmsMessage[pdus.length];            
            for (int i=0; i<msgs.length; i++)
            {
                msgs[i] = SmsMessage.createFromPdu((byte[])pdus[i]);                
                String absenderNummer = msgs[i].getOriginatingAddress();   //Nummer des Absenders                   
                String nachricht = msgs[i].getMessageBody().toString();    //Inhalt der Nachricht
             }
        } 
    }
}
So und durch einfache String-Vergleiche kannst Du nun herausfinden, ob die SMS von der Leitstelle ist und welchen Inhalt sie hat. Danach einfach den Alarm auslösen und Wasser marsch! :thumbup:

EDIT: Diese Methode kann natürlich Probleme mit 4.4 machen, aber wer hat das schon :flapper:
 
danke für den Beispieltext, und dass du so einen Anfänger wie mir hilfst :)
aber so weit bin ich ja noch gar nicht^^

Da ich kaum Ahnung mit der Programmierung auf Mobilgeräten hab, hab ich keinerlei Vorstellung wie ich den Dienst im Hintergrund starte, ob überhaupt ein Dienst laufen muss, und wenn ja wie er periodisch immer wieder ausgeführt wird.

gibt ja keine Benutzeroberfläche, während er die SMS liest...
 
Septura schrieb:
danke für den Beispieltext, und dass du so einen Anfänger wie mir hilfst :)
aber so weit bin ich ja noch gar nicht^^

Kein Ding, hab ja auch mal klein angefangen und war froh über jede Hilfe...

____________________________________________________________________________

Zur Theorie: Intents musst Du Dir vorstellen wie Unterbrechungen à la "Hey, hört mir mal alle zu!" Das gesamte Androidsystem wird also benachrichtigt. Bzw. nur die Anwendungen, die für diese Art von Unterbrechungen ausgestattet sind (Listener). Wenn also so ein Schreihals durchs gesamte System schreit, was passiert, wachen alle Anwendungen auf, die diese Benachrichtigung "hören" dürfen. Sie starten sich selber und führen den Code aus, der in der onReceive-Methode angegeben ist.
Es wird z.B. auch ein Intent gesendet, wenn Du eine App über den Launcher startest. Nur halt nicht SMS-RECEIVED sondern ACTION_MAIN. Weitere Infos unter: Intent | Android Developers
____________________________________________________________________________

Zurück zu Deiner App:

Du brauchst also keine periodische Überprüfung, sondern das Androidsystem weckt Deine App von ganz alleine, wenn eine neue SMS eintrifft! Probiers aus: Kopiere die Methode unten in einer neue .java-Datei, löse die Abhängikeiten mit STRG+UMSCHALT+O auf, erweitere die Manifest.xml um die angegebenen Werte und setze das unter die onReceive-Methode:

Code:
Toast.makeText(context, absenderNummer + ": " + nachricht, Toast.LENGTH_LONG).show();
 
super danke :) funktioniert soweit.
:thumbsup:
wenn ich Fragen hab melde ich mich :)
 
Zurück
Oben Unten