-3

I want to make post on network whenever i receive sms the broadcastreciever call IntentService method but it give me following error

Activity stop timeout for ActivityRecord{420eec20 u0 com.example.myapp/.LoginActivity}

11-29 00:03:23.486   W/System.err﹕ android.os.NetworkOnMainThreadException

11-29 00:03:23.591   W/System.err﹕ at
 android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1118)

11-29 00:03:23.596   I/dalvikvm﹕ Wrote stack traces to '/data/anr/traces.txt'

11-29 00:03:23.596   W/System.err﹕ at libcore.io.BlockGuardOs.connect(BlockGuardOs.java:84)

11-29 00:03:23.601   W/System.err﹕ at libcore.io.IoBridge.connectErrno(IoBridge.java:127)

11-29 00:03:23.606   W/System.err﹕ at libcore.io.IoBridge.connect(IoBridge.java:112)

11-29 00:03:23.611   W/System.err﹕ at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:192)

11-29 00:03:23.616   W/System.err﹕ at java.net.PlainSocketImpl.connect(PlainSocketImpl.java:459)

I know that in service we cannot use internet long processes because of mainthread but intentservice is independant let me show the code

MAIN ACTIVITY

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

    requestWindowFeature(Window.FEATURE_NO_TITLE);

    setContentView(R.layout.activity_main);

    final Intent intent = new Intent(this,AndroService.class);

    this.startService(intent);

}

Service Class

            import org.json.JSONException;
            import org.json.JSONObject;

            public class AndroService extends IntentService
            {

                UsrAction upPayload;
                private String smsURL = "exampleurl";
                private HttpClientClass usrpayloader;

                public AndroService() {
                    super("MyApp");
                }

                public AndroService(String name) {
                    super("MyApp");
                }

                @Override
                protected void onHandleIntent(Intent intent) {
                    Toast.makeText(this, "Service started", Toast.LENGTH_SHORT).show();
                }

                @Override
                public int onStartCommand(Intent intent, int flags, int startId) {
                    onHandleIntent(intent);
                    return 1;
                }


                public enum RequestMethod
                {
                 GET,POST
                }

                public void smspayload(Context context, String strBody)
                {
                    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
                    String cookievalue = sharedPreferences.getString("androsession", null);

                    usrpayloader.AddParam("smsbody", strBody);
                    usrpayloader.AddHeader(cookievalue,"value");


                    try {
                        usrpayloader.Execute(RequestMethod.POST);
                    }
                    catch (Exception e) {
                        e.printStackTrace();
                    }
                    String fetchdata = usrpayloader.getResponse();
                    try {
                        JSONObject json = new JSONObject(fetchdata);
                    } catch (JSONException e) {
                        e.printStackTrace();
                    }
                }
            }

BroadcastReceiver class

                import android.content.BroadcastReceiver;
                import android.content.Context;
                import android.content.Intent;
                import android.os.Bundle;
                import android.telephony.SmsMessage;
                import android.util.Log;
                import android.widget.Toast;

                public class broadcaster extends BroadcastReceiver
                {
                    private final String TAG = "Hello";
                    private HttpClientClass usrpayloader;
                    private AndroService servusr;

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

                        String strMessage = "";
                        String strSrc="";
                        String strBody ="";
                        long time = 0;

                        if ( extras != null )
                        {
                            Object[] smsextras = (Object[]) extras.get( "pdus" );

                            for ( int i = 0; i < smsextras.length; i++ )
                            {
                                SmsMessage smsmsg = SmsMessage.createFromPdu((byte[])smsextras[i]);

                                String strMsgBody = smsmsg.getMessageBody().toString();
                                String strMsgSrc = smsmsg.getOriginatingAddress();

                                strSrc = strMsgSrc;
                                strBody = strMsgBody;
                                time = smsmsg.getTimestampMillis();
                                strMessage += "SMS from " + strMsgSrc + " : " + strMsgBody;

                                Log.i(TAG, strMessage);
                            }

                            Toast.makeText(context,strMessage,Toast.LENGTH_SHORT).show();
                            servusr = new AndroService();
                            servusr.smspayload(context,strBody,strSrc,time);

                        }

                    }

                }

The question is how can i pass android.os.NetworkOnMainThreadException error and i want to use intentservice methods so is that a good practice to declare object into broadcastreceiver?

Shayan
  • 73
  • 1
  • 5
  • And what did you learn when you Googled for this(very common) error or searched here before posting? – Simon Nov 28 '13 at 19:55
  • `NetworkOnMainThreadException`. Google it. – Ahmad Nov 28 '13 at 19:55
  • I googled and saw similar post in sof but i dont get it how to remove this error.. I dont want to use ASYNC i just want to use intentservice and broadcastreceiver And my friend told me that the following code is not a good practice StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); StrictMode.setThreadPolicy(policy); – Shayan Nov 28 '13 at 20:01

1 Answers1

2

You are not using an IntentService properly.

First, never create an instance of a Service yourself via a constructor. You start services via startService() or bindService(). In the case of an IntentService, startService() is the typical approach.

Second, smspayload() needs to be called by onHandleIntent() in order for it to be processed on the background thread supplied by the IntentService. To pass the data over to it, package your strBody as an extra on the Intent you use with startService(). onHandleIntent() can then call getStringExtra() on the Intent to retrieve the parameter and pass it to smspayload(). You can get rid of the Context parameter on smspayload() and replace context with this, as a Service is a Context.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • can you tell me if this is a good way to call intent service when receive a message ? public class ResponseReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { //my code Intent i = new Intent(context,SimpleIntentService.class); i.putExtra("string",string); context.startService(i); } } – Shayan Nov 29 '13 at 14:18
  • @Shayan: Off the cuff, that seems fine. – CommonsWare Nov 29 '13 at 14:25
  • actually i am new to android and working hard to understand intents services and context .. thanks for the guide. – Shayan Nov 29 '13 at 14:37