0

I get a android.os.NetworkOnMainThreadException when I run this code the jar is provide by the printer manufacture. The error come right at the StarIOPort.searchPrinter. I don't get the error running the demo code provide from the manufacture.

I'm trying to see if there is any network printers available on the local network.

private void PortDiscovery(String interfaceName)
{
final EditText editPortName;
ArrayList<String> arrayPortName;    
List<PortInfo> BTPortList;
List<PortInfo> TCPPortList; 
final ArrayList<PortInfo> arrayDiscovery;

try {
     if (true == interfaceName.equals("BT")) {
         BTPortList  = StarIOPort.searchPrinter("BT:");   

         for (PortInfo portInfo : BTPortList) {
                arrayDiscovery.add(portInfo);
         }
    }
    if (true == interfaceName.equals("LAN")) {
        TCPPortList = StarIOPort.searchPrinter("TCP:");

        for (PortInfo portInfo : TCPPortList) {
            arrayDiscovery.add(portInfo);
        }
   }

   arrayPortName = new ArrayList<String>();

   for(PortInfo discovery : arrayDiscovery) {
       String portName;
       portName = discovery.getPortName();

  if(discovery.getMacAddress().equals("") == false) {
      portName += "\n - " + discovery.getMacAddress();
          if(discovery.getModelName().equals("") == false) {
         portName += "\n - " + discovery.getModelName();
      }
  }
  arrayPortName.add(portName);
 }

 } catch (StarIOPortException e) {
      e.printStackTrace();
 }

 editPortName = new EditText(this);

 new AlertDialog.Builder(this).setTitle("Please Input Port Name").setView(editPortName).setPositiveButton("OK", new DialogInterface.OnClickListener(){
     public void onClick(DialogInterface dialog, int button){
     EditText portNameField = (EditText)findViewById(R.id.printerName);
         portNameField.setText(editPortName.getText());
}
})
.setNegativeButton("Cancel", new DialogInterface.OnClickListener(){
    public void onClick(DialogInterface dialog, int button) {
}
})
.setItems(arrayPortName.toArray(new String[0]), new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int select) {
EditText portNameField = (EditText)findViewById(R.id.printerName);portNameField.setText(arrayDiscovery.get(select).getPortName());

    }
    })
.show();


}
Kim HJ
  • 1,183
  • 2
  • 11
  • 37

1 Answers1

1

You're getting the NetworkOnMainThreadException because the Android OS does not allow heavy processes (like network related operations) to run on the main thread (also called the UI Thread sometimes) because those operations/process may take a lot of resources and time to operate, and therefore, the application may lag.

A solution is to put your process in an executable thread and instantiate that thread in your onCreate() or where ever you need it, for example, on an onClickListener();. Do is like so:

private class Print extends AsyncTask<String, Void, String> {
    ProgressDialog pDialog;

    @Override
    protected void onPreExecute() {
        super.onPreExecute();
        Log.d("Hi", "Print Commencing");

        pDialog = new ProgressDialog(MainActivity.this);
        pDialog.setMessage("Printing...");


        String message= "Printing";

        SpannableString ss2 =  new SpannableString(message);
        ss2.setSpan(new RelativeSizeSpan(2f), 0, ss2.length(), 0);  
        ss2.setSpan(new ForegroundColorSpan(Color.BLACK), 0, ss2.length(), 0); 

        pDialog.setMessage(ss2);

        pDialog.setCancelable(false);
        pDialog.show();
    }

    @Override
    protected String doInBackground(String... params) {
        Log.d("Hi", "Printing");
        //Toast.makeText(getApplicationContext(), "Printing.", Toast.LENGTH_LONG).show();

        //insert your code here 

        return "Executed!";

    }

    @Override
    protected void onPostExecute(String result) {
        super.onPostExecute(result);
        //Toast.makeText(getApplicationContext(), "Done printing.", Toast.LENGTH_LONG).show();
        Log.d("Hi", "Done Printing.");
        pDialog.dismiss();

    }
}

and call it from a function like so:

new Print().execute("")

In the onPreExecute(), I initialize a progressDialog that is not cancellable to guarantee that your process ends properly. You should insert your code in the doInBackground(); part.

Razgriz
  • 7,179
  • 17
  • 78
  • 150
  • I see how I can put the search for the printer in the doInBackground, but I don't see how I can get back the the arraylist arrayDiscovery so the user can select the printer to use? – Kim HJ May 20 '14 at 20:38