简体   繁体   中英

Send Intent from Broadcast Receiver with Extras to Activity (Problems with a Service)

I have been looking for that so much and I haven't found the solution.

My applications calls a number all time, and when it receives an incoming call with an exactly number it stops (dies). My idea is that:

  1. Activity launches Service that does the job of calling
  2. A BroadcastReceiver that is expecting for the incoming call

So, I want to use the BroadcastReceiver to kill the Activity, but I haven't found any solution to this. To try another thing, I tried to send an Intent with Extras but the Extras have become null.

I'm open to use any other solution that solve it!

Thank-you very very much!

UPDATED CODE TO DO THE RECOMMENDATION OF Kurtis Nusbaum I see that the problem is in the Service when it makes the call, so I put all my code

Here my code:

package com.comunicacio;

import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;

public class Comunicacio extends Activity {

    IntentFilter filter;

    private BroadcastReceiver receiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            Log.i("BYE", "OOOOOOOOOOOOK");
            finish();
        }
    };

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        filter = new IntentFilter();
        filter.addAction("com.comunicacio.FINALITZAR");

        startService(new Intent(this, Servicio.class));
    }

    @Override
    protected void onResume() {
        super.onResume();
        registerReceiver(receiver, filter);
    }

    @Override
    protected void onPause() {
        super.onPause();
        unregisterReceiver(receiver);
    }

}

The BroadcastReceiver: package com.comunicacio;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.telephony.TelephonyManager;
import android.util.Log;

public class DetectarCridada extends BroadcastReceiver {
    public static final String CUSTOM_INTENT = "com.comunicacio.FINALITZAR";

    @Override
    public void onReceive(Context context, Intent intent) {
        Bundle bundle = intent.getExtras();

        if (bundle == null)
            return;

        String state = bundle.getString(TelephonyManager.EXTRA_STATE);

        if (state.equalsIgnoreCase(TelephonyManager.EXTRA_STATE_RINGING)) {
            String phonenumber = bundle
                    .getString(TelephonyManager.EXTRA_INCOMING_NUMBER);

            Log.i("BYE", "UUUUUUUUUUUUUUUUL");

            // if (es_acceptat(phonenumber)) {
            Intent i = new Intent();
            i.setAction(CUSTOM_INTENT);
            context.sendBroadcast(i);
            // }
        }
    }

    private boolean es_acceptat(String telefono) {
        if (telefono.equals("123"))
            return true;
        return false;
    }
}

And Manifest:

    <uses-sdk android:minSdkVersion="10" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name" >
        <activity
            android:label="@string/app_name"
            android:name="Comunicacio" >
            <intent-filter >
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <receiver android:name=".DetectarCridada" >
            <intent-filter >
                <action android:name="android.intent.action.PHONE_STATE" />
            </intent-filter>
        </receiver>
        <service
            android:enabled="true"
            android:name=".Servicio" />

        <activity android:name=".Call" />
    </application>

    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
</manifest>

The Service Sercivio.java: package com.comunicacio;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;

public class Servicio extends Service {
    private static final String TAG = "MyService";
    boolean hem_cridat = false;
    int telefono = 123;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onCreate() {
        Toast.makeText(this, "My Service Created", Toast.LENGTH_LONG).show();
        Log.d(TAG, "onCreate");
        EndCallListener callListener = new EndCallListener();
        TelephonyManager mTM = (TelephonyManager) this
                .getSystemService(Context.TELEPHONY_SERVICE);
        mTM.listen(callListener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    @Override
    public void onDestroy() {
        Toast.makeText(this, "My Service Stopped", Toast.LENGTH_LONG).show();
    }

    @Override
    public void onStart(Intent intent, int startid) {
        Toast.makeText(this, "My Service Started", Toast.LENGTH_LONG).show();
        call();
    }

    private class EndCallListener extends PhoneStateListener {
        private static final String LOG_TAG = "Comunicacio:";

        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            switch (state) {
            case TelephonyManager.CALL_STATE_RINGING:
                Log.i(LOG_TAG, "RINGING, number: " + incomingNumber);
                break;
            case TelephonyManager.CALL_STATE_OFFHOOK:
                Log.i(LOG_TAG, "OFFHOOK");
                hem_cridat = true;
                break;
            case TelephonyManager.CALL_STATE_IDLE:
                Log.i(LOG_TAG, "IDLE");
                if (hem_cridat) {
                    hem_cridat = false;
                    try {
                        Log.i(LOG_TAG, "Cridant!");
                        call();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                break;
            }
        }
    }

    private void call() {
    /* THE PROBLEM IS THERE !!! If I don't do that, it works! */
    /*  Intent i = new Intent(getBaseContext(), Call.class);
        i.putExtra("NUMERO", telefono);
        i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        getApplication().startActivity(i);
        ++telefono; */
    }
}

And finally Call.java: package com.comunicacio;

import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;

public class Call extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Bundle b = getIntent().getExtras();
        Intent i = new Intent(Intent.ACTION_CALL, Uri.parse("tel:"
                + b.getInt("NUMERO")));
        startActivity(i);
    }
}

Thank-you very very much!

If you want to finish and activity from a broadcast receiver, create another broadcast receiver in your activity that listens for a particular intent. Then in your first broadcaster receiver, when ever you want to kill the activity, broadcast the Intent that the receiver in your activity is listening for. That receiver will then get activated and can all finish on the activity.

Here's some pseudo code:

public class YourActivity extends Activity{

  private class CloseLisntener extends BroadcastReceiver{
    onReceive(Contetxt context, Intent intent){
      YourActivity.this.finish();
    }
  }

  private CloseListener closeListener;

  protected void onCreate(Intent icicle){
     closeListener = new CloseListener();
     // other on create stuff
  }

  protected void onResume(){
     registerReceiver(closeListener, /* Your intent filter goes here */);
  }

  protected void onPause(){
    unregisterReceiver(closeListener);
  }
}

The problem was on:

@Override
protected void onPause() {
    super.onPause();
    unregisterReceiver(receiver);
}

It stopped the Receiver, so I have changed it to:

@Override
protected void onDestroy() {
    super.onDestroy();
    unregisterReceiver(receiver);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM