android - Passing message from broadcast to activity - android

I was reading some post but none have a good answer for me.
So, which is the best way to pass data from broadcast to activity without restart the activity?
Actually I'm using this.
SMSListener:
public class SmsListener extends BroadcastReceiver {
private OnSmsReceivedListener listener = null;
#Override
public void onReceive(Context context, Intent intent) {
try {
if (Telephony.Sms.Intents.SMS_RECEIVED_ACTION.equals(intent.getAction())) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
for (SmsMessage smsMessage : Telephony.Sms.Intents.getMessagesFromIntent(intent)) {
String messageBody = smsMessage.getMessageBody();
String phoneNumber = smsMessage.getDisplayOriginatingAddress();
if (listener != null) {
listener.onSmsReceived(phoneNumber, messageBody);
}
}
}
}
} catch (Exception e)
{
Log.e("Error", "Some some");
}
}
public void setOnSmsReceivedListener(Context context) {
this.listener = (OnSmsReceivedListener) context;
}
}
OnSmsReceivedListener:
public interface OnSmsReceivedListener {
void onSmsReceived(String sender, String message);
}
Activity:
public class MainActivity extends AppCompatActivity implements OnSmsReceivedListener {
private SmsListener receiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.test);
/***********/
receiver = new SmsListener();
receiver.setOnSmsReceivedListener(this);
}
#Override
public void onSmsReceived(String sender, String message) {
Log.e("Test", "Sender: "+sender+" - Message: "+message);
}
}
Another of my questions is why I never get log "Test" in my activity. Is like listener is always null, why?

You should add at the end of onCreate()
final String SMS_RECEIVED_ACTION = "android.provider.Telephony.SMS_RECEIVED";
IntentFilter intentFilter = new IntentFilter(SMS_RECEIVED_ACTION);
registerReceiver(receiver, intentFilter);
and in the onPause()
unregisterReceiver(receiver);
add also the following permission on AndroidManifest.xml
<uses-permission android:name="android.permission.RECEIVE_SMS"/>

Related

Android : Call a Fragment Method from a service

Have a Firebase Cloud messagin Service running , and i want each time i receive a new message a methode in a specif fragment is called.
public class FirebaseMsgService extends FirebaseMessagingService {
public FirebaseMsgService() {
}
#Override
public void onMessageReceived(RemoteMessage remoteMessage) {
super.onMessageReceived(remoteMessage);
ServiceConnector serviceconnector =null;
JSONObject data;
String json = remoteMessage.getData().toString();
try{
data= new JSONObject(json);
**Fragment.method(data);**
}
catch(Exception e){
}
}
}
You can use LocalBroadcastManager
Service:
private void notifyFragment(String json){
Intent intent = new Intent("nameOfTheAction");
Bundle bundle = new Bundle();
bundle.putString("json", json));
intent.putExtras(bundle);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
Fragment:
LocalBroadcastManager bm;
#Override
public void onAttach(Context context) {
super.onAttach(context);
bm = LocalBroadcastManager.getInstance(this);
IntentFilter actionReceiver = new IntentFilter();
actionReceiver.addAction("nameOfTheAction");
bm.registerReceiver(onJsonReceived , actionReceiver);
}
private BroadcastReceiver onJsonReceived = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null) {
String json = intent.getString("json")
data = new JSONObject(json);
}
}
};
#Override
protected void onDetach() {
super.onDetach();
bm.unregisterReceiver(onJsonReceived);
}

Send service result to activity

I've got a BroadcastReceiver which checks if Internet connection is available then it starts a service which retrieves an ArrayList from the DB:
public class NetworkWatcher extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = cm.getActiveNetworkInfo();
Intent retrieveVehicleList = new Intent(context, RetrieveVehicleListService.class);
if (info != null)
{
if (info.isConnected())
{
context.startService(retrieveVehicleList);
}
else
{
context.stopService(retrieveVehicleList);
}
}
}
}
public class RetrieveVehicleListService extends IntentService
{
private static final int NOTIFICATION_ID = 1;
private NotificationManager mNotificationManager;
private NotificationCompat.Builder builder;
private ArrayList<Vehicle> vehicles;
private void parseVehiclesFromMap(ArrayList vehicles)
{
for (int i = 0; i < vehicles.size(); i++)
{
final Vehicle v = new Vehicle();
HashMap vehicleMap = (HashMap) vehicles.get(i);
v.setPlate(vehicleMap.get("plate").toString());
v.setKm(vehicleMap.get("km") == null ? null : Integer.parseInt(vehicleMap.get("km").toString()));
v.setFuelQuantity(Double.parseDouble(vehicleMap.get("fuel_quantity").toString()));
v.setEffectiveFuelEconomy(Double.parseDouble(vehicleMap.get("fuel_economy").toString()));
v.setInsuranceDate(vehicleMap.get("insurance_date") == null ? null : new LocalDate(vehicleMap.get("insurance_date").toString()));
v.setMatriculationDate(new LocalDate(vehicleMap.get("matriculation_date").toString()));
v.setLatitude(vehicleMap.get("latitude") == null ? null : Double.parseDouble(vehicleMap.get("latitude").toString()));
v.setLongitude(vehicleMap.get("longitude") == null ? null : Double.parseDouble(vehicleMap.get("longitude").toString()));
v.setFuelType(FuelType.fromInt(Integer.parseInt(vehicleMap.get("id_fuel").toString())));
this.vehicles.add(v);
}
}
private void sendRequest(int userID)
{
Response.Listener<String> listener = new Response.Listener<String>()
{
#Override
public void onResponse(String response)
{
try
{
HashMap json = new ObjectMapper().readValue(response, HashMap.class);
String errorCode = json.get("error_code").toString();
switch (errorCode)
{
case "0":
parseVehiclesFromMap((ArrayList) json.get("vehicles"));
break;
default:
// TODO gestire
break;
}
}
catch (IOException e)
{
// TODO gestire
e.printStackTrace();
}
}
};
VehicleListRequest request = new VehicleListRequest(String.valueOf(userID), listener, null);
RequestQueue queue = Volley.newRequestQueue(this);
queue.add(request);
}
#Override
protected void onHandleIntent(Intent intent)
{
SharedPreferences sp = getSharedPreferences(getString(clyky.cartracker.R.string.sharedPreferencesName), Context.MODE_PRIVATE);
int userID = sp.getInt("id_user", SplashActivity.DEFAULT_USER_ID);
if (userID != SplashActivity.DEFAULT_USER_ID)
{
sendRequest(userID);
}
}
public RetrieveVehicleListService()
{
super("RetrieveVehicleList");
vehicles = new ArrayList<>();
}
}
I want my MainActivity gets that ArrayList from RetrieveVehicleListService when the activity is started. How could I do that?
Thanks in advance.
Use LocalBroadcast reciever to send data from service to activity. Add following code to your activty
private BroadcastReceiver BReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
//put here whaterver you want your activity to do with the intent received
ArrayList<String> arrayList=intent.getStringArrayListExtra("arrayList");
}
};
protected void onResume(){
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(bReceiver, new IntentFilter("message"));
}
protected void onPause (){
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(bReceiver);
}
and use following method to send broadcast from service
private void sendBroadcast (boolean success){
Intent intent = new Intent ("message"); //put the same message as in the filter you used in the activity when registering the receiver
intent.putExtra("success", success);
intent.putStringArrayListExtra("arrayList", arrayList);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
Use Local Broadcast Receiver :
send broadcast using below code
Intent intent = new Intent("YourAction");
Bundle bundle = new Bundle();
bundle .putSerializable("ARRAYLIST",(Serializable)vehicles);
intent.putExtra("BUNDLE",bundle);
intent.putExtras(intent)
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
And receive broadcast in your activity:
private MyBroadcastReceiver myReceiver;
#Override
public void onResume(){
myReceiver = new MyReceiver();
final IntentFilter intentFilter = new IntentFilter("YourAction");
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, intentFilter);
}
#Override
public void onPause(){
if(myReceiver != null)
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
myReceiver = null;
}
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// Here you have the received broadcast
// And if you added extras to the intent get them here too
// this needs some null checks
Intent intent = getIntent();
Bundle args = intent.getBundleExtra("BUNDLE");
ArrayList<Object> object = (ArrayList<Object>)args.getSerializable("ARRAYLIST");
}
}

app which will record the ussd or sms

As we know that, when we use any menu in sim toolkit it send command to mobile network in ussd or sms format.
I need that sms or ussd to record and show it to me in android application.
I am calling the library service which i got in main activity like this
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Intent srvIntent = new Intent(this, CDUSSDService.class);
startService(srvIntent);
}
}
USSD Service Class is like that:
public class CDUSSDService extends Service{
private String TAG = CDUSSDService.class.getSimpleName();
private boolean mActive = true;//false //we will only activate this "USSD listener" when we want it
BroadcastReceiver receiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
if(intent.getAction().equals(Intent.ACTION_INSERT))
{
//activity wishes to listen to USSD returns, so activate this
mActive = true;
Log.d(TAG, "activate ussd listener");
showtoast(""+"activate ussd listener");
}
else if(intent.getAction().equals(Intent.ACTION_DELETE))
{
mActive = false;
Log.d(TAG, "deactivate ussd listener");
showtoast(""+"DeActivate ussd listener");
}
}
};
private final IExtendedNetworkService.Stub mBinder = new IExtendedNetworkService.Stub ()
{
public void clearMmiString() throws RemoteException
{
Log.d(TAG, "called clear");
showtoast("called clear.");
}
public void setMmiString(String number) throws RemoteException
{
Log.d (TAG, "setMmiString:" + number);
showtoast("setMmiString:"+number);
}
public CharSequence getMmiRunningText() throws RemoteException
{
if(mActive == true)
{
return null;
}
return "USSD Running";
}
public CharSequence getUserMessage(CharSequence text)
throws RemoteException {
Log.d(TAG, "get user message " + text);
showtoast("GET Usr Message:"+text);
if(mActive == false){
//listener is still inactive, so return whatever we got
Log.d(TAG, "inactive " + text);
showtoast("inactive:"+text);
return text;
}
//listener is active, so broadcast data and suppress it from default behavior
//build data to send with intent for activity, format URI as per RFC 2396
Uri ussdDataUri = new Uri.Builder()
.scheme(getBaseContext().getString(R.string.uri_scheme))
.authority(getBaseContext().getString(R.string.uri_authority))
.path(getBaseContext().getString(R.string.uri_path))
.appendQueryParameter(getBaseContext().getString(R.string.uri_param_name), text.toString())
.build();
sendBroadcast(new Intent(Intent.ACTION_GET_CONTENT, ussdDataUri));
mActive = false;
return null;
}
};
#Override
public IBinder onBind(Intent intent) {
Log.i(TAG, "called onbind");
//the insert/delete intents will be fired by activity to activate/deactivate listener since service cannot be stopped
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_INSERT);
filter.addAction(Intent.ACTION_DELETE);
filter.addDataScheme(getBaseContext().getString(R.string.uri_scheme));
filter.addDataAuthority(getBaseContext().getString(R.string.uri_authority), null);
filter.addDataPath(getBaseContext().getString(R.string.uri_path), PatternMatcher.PATTERN_LITERAL);
registerReceiver(receiver, filter);
return mBinder;
}
public void showtoast(String str)
{
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
}
}
I have created MainActivity inside the UssdLibray structure is like that in the below picture:
you can do this with the help of this library https://github.com/alaasalman/ussdinterceptor

BroadcastReceiver onReceive being called multiple times

I'm writing an app that checks external storage state. For monitoring the state I use BroadcastReceiver and I've noticed, that onReceive is called multiple times (eg.: 3x for unmount and 1x for mount) for one event (eg.: unplug usb).
Here is my code:
public class MainActivity extends ActionBarActivity {
final static String TAG = "BroadcastReceiverDemo";
private IntentFilter filter;
private BroadcastReceiver receiver;
private void registerReceiver() {
filter = new IntentFilter();
filter.addAction(Intent.ACTION_MEDIA_MOUNTED);
filter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
filter.addAction(Intent.ACTION_MEDIA_REMOVED);
filter.addAction(Intent.ACTION_MEDIA_SHARED);
filter.addDataScheme("file");
filter.setPriority(IntentFilter.SYSTEM_HIGH_PRIORITY);
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String broadcast;
String state = Environment.getExternalStorageState();
Log.d(TAG, "State: " + state);
if (Environment.MEDIA_MOUNTED.equals(state) && !Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
broadcast = "External storage aviable";
} else {
broadcast = "External storage NOT aviable";
}
String msg = intent.getAction() + " received broadcast: " + broadcast;
Log.d(TAG, msg);
}
};
this.registerReceiver(receiver, filter);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
registerReceiver();
}
#Override
protected void finalize() throws Throwable {
if (receiver != null) {
this.unregisterReceiver(receiver);
}
super.finalize();
}
}
Q: Why is onReceive called so many times and how to make it call only once?
Thanks for any help.

android Charge intent has no extra data

I am trying to display an alert in a specific Activity when the charging status changes.
this is my receiver class:
public class BatteryChargeReceiver extends BroadcastReceiver {
private String TAG = "receiver";
private ChargeReceiverCallback callback;
public BatteryChargeReceiver(ChargeReceiverCallback callback) {
this.callback =callback;
Log.v(TAG,"Inside Constructor (Callback)");
}
public interface ChargeReceiverCallback {
public void onReceive(Intent intent);
}
#Override
public void onReceive(Context context, Intent intent) {
callback.onReceive(intent);
}
}
And below is how I instantiate it from my MainActivity's onResume. MainActivity implements my interface and overrides onReceive(intent). I found out that at no stage does intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1) return anything else then -1.
BatteryChargeReceiver batteryReceiver = new BatteryChargeReceiver(this);
IntentFilter filterPower = new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED");
registerReceiver(batteryReceiver, filterPower);
Intent.ACTION_POWER_CONNECTED not delivering current plugged-in state - this is probably a change in how API works, but I could not locate any mention of such change in docs.
The broadcast Intent.ACTION_POWER_CONNECTED was never meant to receive current plugged-in type, but it merely lets the receiving end of power connection (ref.). In fact, BatteryService.java broadcasts plain intent without any extra values (lines 410~412 as of this writing):
Intent statusIntent = new Intent(Intent.ACTION_POWER_CONNECTED);
statusIntent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
mContext.sendBroadcastAsUser(statusIntent, UserHandle.ALL);
However, following code with
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="19" />
worked on Nexus 5:
public class MainActivity extends Activity {
private static final String TAG = "PowerReceiver";
private final BroadcastReceiver mPowerReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (Intent.ACTION_POWER_CONNECTED.equals(action)) {
Log.d(TAG, "Power connected");
checkPluggedState(context, intent);
} else if (Intent.ACTION_POWER_DISCONNECTED.equals(action)) {
Toast.makeText(context, "Power disconnected", Toast.LENGTH_SHORT).show();
} else {
Log.wtf(TAG, "Unknown action: " + action);
}
}
};
private void checkPluggedState(Context context, Intent intent) {
Intent chargingIntent = registerReceiver(null, new IntentFilter(
Intent.ACTION_BATTERY_CHANGED));
final int pluggedState = chargingIntent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
final String msg;
switch (pluggedState) {
case 0:
msg = "The device is running on battery";
break;
case BatteryManager.BATTERY_PLUGGED_AC:
msg = "Plugged into AC charger";
break;
case BatteryManager.BATTERY_PLUGGED_USB:
msg = "Plugged into USB charger";
break;
case BatteryManager.BATTERY_PLUGGED_WIRELESS:
msg = "Plugged into wireless charger";
break;
default:
msg = "Unknown state: " + pluggedState;
}
Toast.makeText(context, msg, Toast.LENGTH_SHORT).show();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
protected void onResume() {
super.onResume();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
registerReceiver(mPowerReceiver, filter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mPowerReceiver);
}
}
Hope this helps.
According to The docs, EXTRA_STATUS is for ACTION_BATTERY_CHANGED

Categories

Resources