简体   繁体   中英

Android Starting Activity via Background Service

My goal is to have UDP packets receiving app continuously running from boot up in the back ground when ever it receives the valid packet it has to process the message and display them.

After some research, I did the following.

  1. Broadcast Receiver class - which start the service on boot UP (mstart.java).
  2. Service Class to monitor for UDP packets (udp.java).
  3. Display Class to display the messages as text (Rmsgs.java).
  4. GlobalState.Java for Global variable.

I wrote a standalone with UDP app with list view it works fine. Hence, I know there is no problem on that.

When I compiled ran the code service start on boot and then crashes. To debug I have taken away the UDP Packet receiving part. The UDP class after receiving the packets it will produce two arrays list and will save it in the Global class and the Display class will obtain it.

    This code is working now, I found mistake I have made and corrected it.

Now I have to modify to receive the udp packets.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>

<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.QUICKBOOT_POWERON"/>
<application
    android:name="com.mmm.rmsg.GlobalState"
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:largeHeap="true"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MsgView"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
           <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <receiver android:enabled="true" android:exported="true"
        android:name=".mstart"
        android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"/>
            <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>
    <service android:name=".udp"
      />
    </application>
<uses-permission android:name="android.permission.INTERNET"/>

Broadcast Receiver Class

 package com.mmm.rmsg;
 import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;

public class mstart extends BroadcastReceiver {

@Override
public void onReceive(Context context, Intent intent) {

    Toast.makeText(context, "Intent detcted.", Toast.LENGTH_LONG).show();

    Intent pushIntent = new Intent(context, udp.class);
    context.startService(pushIntent);
  }

  }

Service Class

  package com.mmm.rmsg;
  import android.app.Service;
  import android.content.Context;
  import android.content.Intent;
  import android.os.IBinder;
  import android.os.PowerManager;
  import android.widget.Toast;
  import java.util.ArrayList;

  import static android.os.PowerManager.PARTIAL_WAKE_LOCK;


  public class udp extends Service {

  private static final String LOG_TAG =udp.class.getSimpleName();


  GlobalState gs = (GlobalState)getApplication();

 @Override
 public IBinder onBind(Intent arg0){

    return  null;
}

@Override public int onStartCommand(Intent intent, int flags, int startId) {

    setWakeLock();
    Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();

    new Thread(new Server()).start();

   return START_STICKY;




}


private void setWakeLock(){


    PowerManager.WakeLock mWakeLock;
    PowerManager powerManager = (PowerManager)getSystemService(Context.POWER_SERVICE);
    mWakeLock=powerManager.newWakeLock(PARTIAL_WAKE_LOCK, LOG_TAG);
}

public class Server implements Runnable {

    @Override
    public void run() {

        ArrayList<String> list = new ArrayList<>();
        ArrayList<String> clist = new ArrayList<>();
        // here udp packets are recvd & processed into 2 list arrays

        list.add(0, "MAIN FAIL");
        list.add(1,"BOILER HEATER 20C");
        list.add(2, "COOLING NEED ATT");

        clist.add(0, "6");
        clist.add(1,"1");
        clist.add(2, "5");

        GlobalState gs = (GlobalState)getApplication();

          gs.setGmlist(list);
          gs.setGclist(clist);

        call();

    }

}

public void call() {


    Intent dialogIntent = new Intent(getBaseContext(), MsgView.class);
    dialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(dialogIntent);

   }

  }

Global Class

   package com.mmm.rmsg;

  import java.util.ArrayList;
  import android.app.Application;

  public class GlobalState extends Application
  {
    private ArrayList<String> Gmlist = new ArrayList<>();
    private ArrayList<String> Gclist = new ArrayList<>();
    private boolean chk = true;
    private boolean cchk = true;



   public ArrayList<String> getGmlist() {

    chk = Gmlist.isEmpty();

    if(chk==true)
    {
        Gmlist.add(0,"No Calls");
    }

     return Gmlist;
  }

   public ArrayList<String> getGclist() {
      cchk = Gclist.isEmpty();

    if(cchk==true)
    {
        Gclist.add(0,"0");
    }

    return Gclist;
}

    public void setGmlist(ArrayList<String> Gmlit) {

        for (int i = 0; i < Gmlit.size(); i++) {
            this.Gmlist.add(i, Gmlit.get(i));
        }


  }

  public void setGclist(ArrayList<String> Gclit) {

    for (int i = 0; i < Gclit.size(); i++) {
        this.Gmlist.add(i, Gclit.get(i));
      }

     }

   }

Display Class

    package com.mmm.rmsg;
    import android.support.v7.app.AppCompatActivity;
    import android.os.Bundle;
    import android.view.Menu;
    import android.view.MenuItem;
    import android.widget.ListView;
    import android.content.Context;
    import android.graphics.Color;
    import android.widget.ArrayAdapter;
    import android.view.View;
    import android.view.ViewGroup;
    import android.widget.TextView;
    import java.util.ArrayList;
    import java.util.Arrays;


    public class MsgView extends AppCompatActivity {

        ListView listView ;
        ArrayList<String> mlist = new ArrayList<>();
        ArrayList<String> plist = new ArrayList<>();

        @Override
        protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_msg_view);

            // Get ListView object from xml
            listView = (ListView) findViewById(R.id.list);

            GlobalState gs = (GlobalState) getApplication();

                mlist= gs.getGmlist();
                plist= gs.getGclist();



                String[] msgArray = mlist.toArray(new String[mlist.size()]);
                Arrays.toString(msgArray);
                String[] clrArray = plist.toArray(new String[plist.size()]);
                Arrays.toString(clrArray);


                listView.setAdapter(new ColorArrayAdapter(this, android.R.layout.simple_list_item_1, msgArray,clrArray));

        }



        public class ColorArrayAdapter extends ArrayAdapter<Object>{
            private String[] list;
            private String[] p;
            public ColorArrayAdapter(Context context, int textViewResourceId,
                             Object[] objects, Object[] obj) {
            super(context, textViewResourceId, objects);
            list = new String[objects.length];
            for (int i = 0; i < list.length; i++)
                list[i] = (String) objects[i];

            p = new String[objects.length];
                for (int i = 0; i < p.length; i++)
                p[i] = (String) obj[i];
    }

    @Override
    public View getView(int position, View convertView, ViewGroup parent) {
        View view = (TextView)super.getView(position, convertView, parent);




        String c;
        for(int x=0; x< list.length; x++)
        {
            c=chk(x,p);

            if("R".equals(c) && position==x ) {
                view.setBackgroundColor(Color.RED);
            }
            else
            if("Y".equals(c) && position==x) {
                view.setBackgroundColor(Color.YELLOW);
            }
            else
            if("G".equals(c) && position==x) {
                view.setBackgroundColor(Color.GREEN);
           }

        }
            return view;
        }

    }


        public  String chk(int idx, String[] table){


    String res;
    if("6".equals(table[idx]) || "7".equals(table[idx])  || "8".equals(table[idx])) {
        res = "R";
    }
    else
    if("4".equals(table[idx])  || "5".equals(table[idx])) {
        res = "Y";
    }
    else
    if("1".equals(table[idx])|| "2".equals(table[idx]) || "3".equals(table[idx]) ) {
        res = "G";
    }
    else{
        res = "W";
    }



        return res;
    }


        @Override
        public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_msg_view, menu);
        return true;
    }

        @Override
        public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
            // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
            }

    return super.onOptionsItemSelected(item);
        }


        @Override
        protected void onDestroy(){
            super.onDestroy();

        }
    }

You haven't started your thread. You can do it like this:

Thread initBkgThread = new Thread(new Runnable() {

        public void run() {
            udp();
        }
    });
initBkgThread .start();

Is this a full code or just some snips? First thing is that your text1 is not initialized.

text1 = findViewById(R.id.<id_of_text_view_in_activity_calls_layout>) ?

To start an activity from your service you should create your intent like:

//Starting Smsgs 
Intent startAct = new Intent(context, Smsgs.class);
startAct.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(startAct);

You need at least two thread for this, one for the receiving of the UDP packets and the other is to compute the data. You need to modify your udp() function like this:

//Warning, I did not test this code, handle it like pseude-code. 
private void udp(){

            // ...
            // Wait to receive a datagram
            dsocket.receive(packet);

            Thread showMsg = new Thread(new Runnable() {

                public void run() {
                   // Convert the contents to a string,
                   String message = new String(buffer, 0, packet.getLength());
                   Intent intent = new Intent(this, Smsgs.class);
                   intent.putExtra("msg",message);
                   intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                   startActivity(intent);

                }

            });
            showMsg.start();
            // ...
}

and also don't forget to start your another thread: initBkgThread.start()

hope it helps.

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