about broadcast receiver - java

Hi all I want to create an application in which there is an activity say My activity. Now I want to start it with incoming call, if it is not answered within 20 seconds.Please Help me.

You would first need to register your receiver such as..
<receiver android:name=".CustomBroadcastReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
Here you register to listen for the phones state to change.
Next you would want to extend the phonestateListener for your specifications.
public class CustomPhoneStateListener extends PhoneStateListener {
private static final String TAG = "CustomPhoneStateListener";
public void onCallStateChange(int state, String incomingNumber){
//Here you recieve the phone state being changed and are able to get the number and state.
switch(state){
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "RINGING");
//Here you could count with for() for 20 seconds and then create a method to do what you want.
break;
Here you create your BroadCastReceiver...
public class CustomBroadcastReceiver extends BroadcastReceiver {
private static final String TAG = "CustomBroadcastReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, "inside");
TelephonyManager telephony = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
CustomPhoneStateListener customPhoneListener = new CustomPhoneStateListener();
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
Bundle bundle = intent.getExtras();
String phoneNr= bundle.getString("incoming_number");
Log.v(TAG, "phoneNr: "+phoneNr);
}
EDIT:
To count you could create a method such as
public void increment() {
if (count < maxCount) count++;
}

Related

Android Java callback null inside broadcastReceiver

I'm trying to get notification when Android receives a text message, so I wrote a new class for that like this:
public class MyBroadcastReceiver extends BroadcastReceiver {
public MyBroadcastCallback callback;
public MyBroadcastReceiver() {}
public MyBroadcastReceiver(MyBroadcastCallback callback) {
this.callback=callback;
Log.d("myTag", "MyBroadcastReceiver CONSTRUCTOR.... "+this.callback);
this.callback.OnReceiveSMS("phone TEST","message TEST");
}
#Override
public void onReceive(Context context, Intent intent) {
Bundle intentExtras = intent.getExtras();
if (intentExtras != null) {
Object[] sms = (Object[]) intentExtras.get("pdus");
for (int i = 0; i < sms.length; ++i) {
SmsMessage smsMessage = SmsMessage.createFromPdu((byte[]) sms[i]);
String phone = smsMessage.getOriginatingAddress();
String message = smsMessage.getMessageBody().toString();
this.callback.OnReceiveSMS(phone,message);
}
}
}
public interface MyBroadcastCallback {
void OnReceiveSMS(String phone,String message);
}
}
Then in my main activity I instantiate the class like this:
public class MainActivity extends AppCompatActivity implements MyBroadcastReceiver.MyBroadcastCallback {
MyBroadcastReceiver broadcastReceiver=null;
#Override
protected void onCreate(Bundle savedInstanceState) {
....
super.onCreate(savedInstanceState);
broadcastReceiver=new MyBroadcastReceiver(this);
....
}
#Override
public void OnReceiveSMS(String phone, String message) {
Log.d("myTag", "NEW SMS MESSAGE PHONE="+phone + " message="+message);
}
}
The Android manifest looks like this:
<receiver android:name=".MyBroadcastReceiver">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED" />
</intent-filter>
</receiver>
When a text is received, OnReceive is called in the MyBroadCastReceiver class, that works great.
But when I try to call my own callback function inside OnReceive() to notify the main activity of the text message like this:
this.callback.OnReceiveSMS(phone, message);
It crashes with exception that this.callback is null.
I know it's not null in the beginning because in the constructor I pass in the main activity which implements that interface.
To debug I also printed out this.callback in the constructor and even called that function in there to make sure its not null, and all that works, but somehow it BECOMES null when a text comes in and Android OS calls OnReceive.
Does anybody knows why it's null? How to fix?

Android BroadcastReceiver inside service: issues

I am currently trying to create an Activity in Android with the capabilities of communicating with a started BroadcastReceiver inside of a service but I can't manage to do it well. I don't really know what the problem could be since (I think) I have followed all necessary steps.
In addition, I have other Activities which can communicate with this BroadcastReceiver without any problems. The code that I am using for the one I am having problems with is the following:
Registration of the name of the action in file ActivityList.java (Another activity):
public static final String ACTION1 = "com.test.ActionOne";
public static final String ACTION2 = "com.test.ActionTwo";
Registration of the actions with IntentFilter in the file GestTree.java which extends a Service:
Inside onCreate():
IntentFilter filter;
filter = new IntentFilter();
filter.addAction(ActivityList.ACTION1);
filter.addAction(ActivityList.ACTION2);
rec = new Receptor(); // This is a class which extends BroadcastReceiver
registerReceiver(receptor, filter);
Inside the function onReceive() of the private class Receptor of GestTree.java which extends BroadcastReceiver:
public final void onReceive(final Context context, final Intent intent) {
String action = intent.getAction();
if (action.equals(ActivityList.ACTION1)) {
Log.d(tag, "Test Passed!");
}
}
The definition of the service and the Activity State3Activity(the one I want to communicate with the service) in AndroidManifest.xml:
<activity
android:name="State3Activity"
android:label="#string/app_name" >
</activity>
<service
android:name="GestTree"
android:enabled="true"
android:label="#string/app_name" >
</service>
Code inside State3Activity.java:
public class State3Activity extends Activity {
Button mButton;
EditText editText_Name;
EditText editText_Desc;
private final String tag = this.getClass().getSimpleName();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.state3_layout);
mButton = (Button)findViewById(R.id.button_myButton);
editText_Nombre = (EditText)findViewById(R.id.editText_Name);
editText_Descripcion = (EditText)findViewById(R.id.editText_Desc);
mButton.setOnClickListener(
new View.OnClickListener()
{
public void onClick(View view)
{
Intent intent;
intent = new Intent();
intent.setAction(ActivityList.ACTION1);
// I have tried with all this combination of lines
// but none of them works
//intent.addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES);
//intent.setClass(State3Activity.this, GestTree.class);
//intent.addCategory(Intent.CATEGORY_DEFAULT);
sendBroadcast(intent);
}
});
}
There is where the problem comes. The intent never enters on the onReceive() function of the class when I press the button. What am I leaving?
Are you sure your service started? If you have not start the service, the method of onCreate() will not be executed, and the receiver will not be registed.

How to start a timer when a call is get connected?

I need to start a timer when a call get connected, but in my case it is starting when call is ringing, I searched a lot, but did't get proper solution. With the hope again I'm repeating this. At least i need a suggestion to achieve this.
My code:
public void onReceive(Context context, Intent intent) {
String state = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
Log.d("Status", "Phone is Ringing");
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
Log.d("Status", "Phone is on call");
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
// Call Dropped or rejected
System.exit(0);
Log.d("Status", "Phone is dropped");
}
}
You can try this out.
Inside your BroadCastReceiver
static boolean flag = false;
static long start_time, end_time;
And the onReceive function will be something like this,
public void onReceive(Context arg0, Intent intent) {
String action = intent.getAction();
if (action.equalsIgnoreCase("android.intent.action.PHONE_STATE")) {
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_RINGING)) {
start_time = System.currentTimeMillis();
}
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_IDLE)) {
end_time = System.currentTimeMillis();
//Total time talked =
long total_time = end_time - start_time;
//Store total_time somewhere or pass it to an Activity using intent
}
}
Also you need to giver permissions for this in the Manifest.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
Register a receiver in your Manifest like this :
<receiver android:name=".CallDurationReceiver">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>

Service containing BroadCastReceiver not functioning correctly

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"));

Listening for downloads when application is minimized

I am trying to create an application that listens for downloads and performs an action upon hearing it. The key here is that I want the application to do this even when it's minimized (like when a user downloads from the browser). The following code does not seem to be tripping the receiver:
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("did download");
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
String downloadPath = intent.getStringExtra(DownloadManager.COLUMN_URI);
System.out.println(downloadPath);
}
}
};
registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
}
Anyone know what's wrong?
Your almost there just move your BroadcastReceiver to a separate file . Do what you want with the received String downloadPath. In this example I save it to SharedPreferences.
public class MyBroadcastReceiver extends BroadcastReceiver{
#Override
public void onReceive(final Context context, Intent intent) {
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = settings.edit();
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
String downloadPath = intent.getStringExtra(DownloadManager.COLUMN_URI);
editor.putString("downloadPath", downloadPath);
editor.commit();
}
}
}
In your manifest add this and edit the action
<receiver android:name=".MyBroadcastReceiver " >
<intent-filter>
<action android:name="PUT YOUR ACTION HERE DownloadManager.ACTION_DOWNLOAD_COMPLETE" />
</intent-filter>
</receiver>
Just declare the broadcast receiver in manifest. More about the differences between the dynamically register and statically register, please see BroadcastReceiver

Categories

Resources