I would like to know how can I check when mobile data is connected using BroadcastReceiver.
Here's what I have so far:
private BroadcastReceiver MobileDataStateChangedReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
int state = intent.getIntExtra(TelephonyManager.EXTRA_STATE,
TelephonyManager.DATA_DISCONNECTED);
if (state == TelephonyManager.DATA_CONNECTED) {
mobileStatus.setText("Connected");
} else if (state == TelephonyManager.DATA_DISCONNECTED) {
mobileStatus.setText("Disconnected");
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.status_page);
mobileStatus = (TextView) this.findViewById(R.id.textView4);
registerReceiver(MobileDataStateChangedReceiver, new IntentFilter(
TelephonyManager.ACTION_PHONE_STATE_CHANGED));
}
What am I doing wrong in here?
I used the same concept on Wi-Fi checking and it worked great?
I am using the permissions of:
<uses-permission android:name="android.permission.INTERNET"/>
The TelephonyManager.ACTION_PHONE_STATE_CHANGED does not seem to work because as I could read in TelephonyManager class description it only fires with calls, but not with networks or mobile data.
Instead of this, I suggest you try setting a listener. It would be something like this:
1) Get the service with TelephonyManager tm = (TelephonyManager)Context.getSystemService(Context.TELEPHONY_SERVICE)
2) Set a listener with tm.listen(myCustomPhoneStateListener, PhoneStateListener.LISTEN_DATA_CONNECTION_STATE);
3) Once you have the listener you will be able to send custom intents to your BroadcastReceiver, if you still want to do that.
Related
Edit with an update at the bottom with the cause, but still no fix
I am trying to capture a notification and later replay it once I dismiss it. From what I've been able to figure out so far, I can capture a notification, but when I try create a new notification using NotificationManager.notify(), nothing happens. No errors, nothing. Is this even something I should be able to do?
Maybe I am not taking the right approach and someone can suggest a better approach. Like I stated above, I want to be able to know when a user receives a notification and to capture the notification in its entirety, so even when it's dismissed, I can restore it. Maybe there is a way to restore things from the notification history but I haven't been able to figure out fully how that works yet. Here's the code I have so far. I can successfully listen to when a notification is posted or removed. The goal is to send a broadcast when a notification is posted with the notification id and the actual Notification itself (this part works I think), and when the button is pressed, recreate the notification. When I press the button, nothing happens.
public class MainActivity extends AppCompatActivity {
private int notification_id = -1;
private Notification myNotify;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main3);
final Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Bundle extras = myNotify.extras;
String title = extras.getString("android.title");
String text = extras.getString("android.text");
NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nManager.notify(notification_id, myNotify);
}
});
}
private MyBroadcastReceiver myReceiver;
#Override
public void onResume() {
super.onResume();
myReceiver = new MyBroadcastReceiver();
final IntentFilter intentFilter = new IntentFilter("notification_restore");
LocalBroadcastManager.getInstance(this).registerReceiver(myReceiver, intentFilter);
}
#Override
public void onDestroy() {
super.onDestroy();
if (myReceiver != null)
LocalBroadcastManager.getInstance(this).unregisterReceiver(myReceiver);
myReceiver = null;
}
public class MyBroadcastReceiver extends BroadcastReceiver {
#Override
#Nullable
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
Bundle b = intent.getExtras();
notification_id = b.getInt("notification_id");
myNotify = b.getParcelable("notification");
}
}
}
public class MyNotificationListenerService extends NotificationListenerService {
private int notification_id;
private Notification myNotify;
#Override
public void onNotificationPosted(StatusBarNotification sbn) {
if ((sbn.getNotification().flags & Notification.FLAG_GROUP_SUMMARY) != 0) {
//Ignore the notification
return;
}
notification_id = sbn.getId();
myNotify = sbn.getNotification();
Intent intent = new Intent("notification_restore");
Bundle b = new Bundle();
b.putInt("notification_id", notification_id);
b.putParcelable("notification", myNotify);
intent.putExtras(b);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
#Override
public void onNotificationRemoved(StatusBarNotification sbn) {
if ((sbn.getNotification().flags & Notification.FLAG_GROUP_SUMMARY) != 0) {
//Ignore the notification
return;
}
}
}
Edit:
So it looks like the reason my notification isn't showing up is because it complains about not finding a channel, even though the notification I am trying to replay has one. The exact error is:
E/NotificationService: No Channel found for pkg=com.gevdev.notify, channelId=bugle_default_channel, id=0, tag=null, opPkg=com.gevdev.notify, callingUid=10086, userId=0, incomingUserId=0, notificationUid=10086, notification=Notification(channel=bugle_default_channel pri=1 contentView=null vibrate=null sound=null tick defaults=0x0 flags=0x10 color=0xff2a56c6 category=msg groupKey=bugle_notification_group_key sortKey=00 actions=2 vis=PRIVATE)
I am still new to android, but my initial guess is that the channelId found bugle_default_channel isn't found under my package name, but I don't know how to fix this yet.
Figured it out
Even though the notification that I am grabbing to replay has a channel ID, the NotificationManager doesn't have that notification channel registered. I figured it based off the code found here. This is how to register it.
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = nManager.getNotificationChannel(myNotify.getChannelId());
if (notificationChannel == null) {
int importance = NotificationManager.IMPORTANCE_HIGH;
notificationChannel = new NotificationChannel(myNotify.getChannelId(), "Description Goes Here", importance);
notificationChannel.setLightColor(Color.GREEN);
notificationChannel.enableVibration(true);
nManager.createNotificationChannel(notificationChannel);\
}
}
I am trying to code APK to identify the received calls are in sim 1 or sim 2. I have tried below solutions but in all devices, it is not working. Samsung and MI devices the below solution is not working. can you please suggest universal solutions. thanks
I tried below solutions
URL1
URL2
public class IncomingCallInterceptor extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String callingSIM = "";
Bundle bundle = intent.getExtras();
callingSIM =String.valueOf(bundle.getInt("simId", -1));
if(callingSIM == "0"){
// Incoming call from SIM1
}
else if(callingSIM =="1"){
// Incoming call from SIM2
}
}
}
I want to pause the MediaPlayer when the user unplugs his headphones. I found out that I can use the "ACTION_AUDIO_BECOMING_NOISY" broadcast , so I tried it out !
Theoretically it works , BUT the time of receiving takes too long. The music is still playing for 3-5 seconds before it really pauses.This wouldnt be acceptable for an user.
How are other devolopers able to pause it in milliseconds ? Are there better Soloutions ?
My BroadcastReceiver which is actually for Notifications :
public class NotificationBroadcast extends BroadcastReceiver {
...
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
Intent iPause = new Intent(context , SongService.class);
iPause.putExtra("com.Hohos.mplay.Services.SongService.MEDIA_ACTION", NOTIFY_EXTRA_PAUSE);
context.startService(iPause);
}
...
}
I also added <uses-permission android:name="android.permission.ACTION_HEADSET_PLUG"/>
, which really didnt any difference
Thanks for your help guys !
To know when the user unplugs his headphones you need to listen the action ACTION_HEADSET_PLUG and check the state extra:
Broadcast Action: Wired Headset plugged in or unplugged.
The intent will have the following extra values:
state - 0 for unplugged, 1 for plugged.
name - Headset type, human
readable string
microphone - 1 if headset has a microphone, 0
otherwise
This is an example:
public class MainActivity extends Activity {
private HeadsetBroadcastReceiver mHeadsetBroadcastReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver = new HeadsetBroadcastReceiver();
}
#Override
protected void onResume() {
IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
registerReceiver(mHeadsetBroadcastReceiver, filter);
super.onResume();
}
#Override
protected void onPause() {
unregisterReceiver(mHeadsetBroadcastReceiver);
super.onPause();
}
private class HeadsetBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
int state = intent.getIntExtra("state", -1);
if (state == 0) {
//Headset is unplugged
} else if(state == 1) {
//Headset is plugged
}
}
}
}
}
Please see edits before answering!
I have an app which contains a BackgroundService class:
public class BackgroundService extends Service {
#Override
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction("com.spotify.music.playbackstatechanged");
filter.addAction("com.spotify.music.metadatachanged");
filter.addAction("com.spotify.music.queuechanged");
registerReceiver(receiver, filter);
Log.e("Playing:", "APP IS PLAYING");
Notification notification = new Notification();
startForeground(1, notification);
}
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
long timeSentInMs = intent.getLongExtra("timeSent", 0L);
String action = intent.getAction();
if (action.equals(BroadcastTypes.METADATA_CHANGED)) {
String trackId = intent.getStringExtra("id");
String artistName = intent.getStringExtra("artist");
String albumName = intent.getStringExtra("album");
String trackName = intent.getStringExtra("track");
int trackLengthInSec = intent.getIntExtra("length", 0);
// Do something with extracted information...
} else if (action.equals(BroadcastTypes.PLAYBACK_STATE_CHANGED)) {
boolean playing = intent.getBooleanExtra("playing", false);
Log.e("Playing:","TRUE");
}
}
};
#Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
}
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
static final class BroadcastTypes {
static final String SPOTIFY_PACKAGE = "com.spotify.music";
static final String PLAYBACK_STATE_CHANGED = SPOTIFY_PACKAGE + ".playbackstatechanged";
static final String METADATA_CHANGED = SPOTIFY_PACKAGE + ".metadatachanged";
}
}
and this is declared in my manifest:
<service
android:name=".BackgroundService"
android:enabled="true" >
<intent-filter>
<action android:name="com.spotify.music.playbackstatechanged" />
<action android:name="com.spotify.music.metadatachanged" />
<action android:name="com.spotify.music.queuechanged" />
</intent-filter>
</service>
So essentially my objective is to have my BackgroundService initialized when my app is opened, and to have it continue to run in the Background doing whatever I need it to do. As of now, I am using logs to determine whether my "setup" is working, but when I run my app, I am unable to see an logs even after I tested all actions that should have triggered my BroadCastReceiver. Furthermore, my persistent notification should have changed had my service been running, but it does not...
Edit::
So, I added logs to my BackgroundService's onCreate() and onReceive() methods, however, neither seem to be appearing. Im wondering, do I need to do something in my launcher activity to initialize the service? Furthermore, no notification is shown so I assume the Service is not being started for some reason...
Latest Edit:
So I added the following code to my Main activity to see if it would make a difference:
startService(new Intent(this,BackgroundService.class));
And after debugging my app, I began to see the following error:
java.lang.RuntimeException: Unable to create service com.aurum.mutify.BackgroundService: java.lang.SecurityException: Isolated process not allowed to call registerReceiver
pointing to my BroadCast Receiver class.
Intent services are designed for short tasks. And your intent handling method is empty.
If you need long running task in the background use standard service and call start foreground. This will minimize chance of system destroying your service.
To learn more go here
EDIT
Try overriding onStartCommand method. this method is called when service is started and usually you do all stuff here. Remember that there are 3 options to return.
Edit 2:
try something like this
in on create
PendingIntent pi;
BroadcastReceiver br;
Intent myIntent;
#Override
public void onCreate()
{
super.onCreate();
myIntent = new Intent("something")
if(Build.Version.SDK_INT >= 16) //The flag we used here was only added at API 16
myIntent.setFlags(Intent.FLAG_RECEIVER_FOREGROUND);
//use myIntent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND); if you want to add more than one flag to this intent;
pi = PendingIntent.getBroadcast(context, 1, myIntent, 0);
br = new BroadcastReceiver ()
{
public void onReceive (Context context, Intent i) {
new thread(new Runnable()
{
public void run()
{
//do something
}
}).start();
}
};
And then in on start command
this.registerReceiver(br, new IntentFilter("something"));
I need to locate my current location in a building by scanning the strongest available Wifi to launch an activity. I want to locate only 3 places in that building. So if I am currently near any of those locations, I will click a button to scan the strongest available Wifi to launch an activity.
I need to scan available Wifi in a building.
Get the 3 strongest signal.
Then detect whether any of those 3 strongest signal's SSID is the same with the specific SSID that I want to locate.
If my SSID is one of the strongest 3 signals, then the application will launch a xml layout activity,
So far I already have the coding to scan strongest available Wifi. But I don't know how to launch an activity when the strongest specific Wifi SSID detected. I do not need the information about the Wifi, just to launch my activity layout that has my information.
At the moment I'm using the following bit of code to scan the strongest Wifi signal that I got from here:
WiFiDemo.java
public class WiFiDemo extends Activity implements OnClickListener {
private static final String TAG = "WiFiDemo";
WifiManager wifi;
BroadcastReceiver receiver;
TextView textStatus;
Button buttonScan;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Setup UI
textStatus = (TextView) findViewById(R.id.textStatus);
buttonScan = (Button) findViewById(R.id.buttonScan);
buttonScan.setOnClickListener(this);
// Setup WiFi
wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
// Get WiFi status
WifiInfo info = wifi.getConnectionInfo();
textStatus.append("\n\nWiFi Status: " + info.toString());
// List available networks
List<WifiConfiguration> configs = wifi.getConfiguredNetworks();
for (WifiConfiguration config : configs) {
textStatus.append("\n\n" + config.toString());
}
// Register Broadcast Receiver
if (receiver == null)
receiver = new WiFiScanReceiver(this);
registerReceiver(receiver, new IntentFilter(
WifiManager.SCAN_RESULTS_AVAILABLE_ACTION));
Log.d(TAG, "onCreate()");
}
#Override
public void onStop() {
unregisterReceiver(receiver);
}
public void onClick(View view) {
Toast.makeText(this, "On Click Clicked. Toast to that!!!",
Toast.LENGTH_LONG).show();
if (view.getId() == R.id.buttonScan) {
Log.d(TAG, "onClick() wifi.startScan()");
wifi.startScan();
}
} }
WiFiScanReceiver.java
public class WiFiScanReceiver extends BroadcastReceiver {
private static final String TAG = "WiFiScanReceiver";
WiFiDemo wifiDemo;
public WiFiScanReceiver(WiFiDemo wifiDemo) {
super();
this.wifiDemo = wifiDemo;
}
#Override
public void onReceive(Context c, Intent intent) {
List<ScanResult> results = wifiDemo.wifi.getScanResults();
ScanResult bestSignal = null;
for (ScanResult result : results) {
if (bestSignal == null
|| WifiManager.compareSignalLevel(bestSignal.level, result.level) < 0)
bestSignal = result;
}
String message = String.format("%s networks found. %s is the strongest.",
results.size(), bestSignal.SSID);
Toast.makeText(wifiDemo, message, Toast.LENGTH_LONG).show();
Log.d(TAG, "onReceive() message: " + message);
}
}
You just need to start your activity from onReceive. Unless I'm not understanding your question, you just need to fire off your activity.
Since you have the context on your receiver's onReceive you just need to startActivity()
Start Activity inside onReceive BroadcastReceiver
#Override
public void onReceive(Context context, Intent intent) {
//start activity
Intent i = new Intent();
i.setClassName("com.test", "com.test.MainActivity");
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
Don't forget to define a proper filter for it in your manifest.
http://developer.android.com/reference/android/content/BroadcastReceiver.html