0
私はWebSocketイベントを処理するサービスを持っていますが、UIが閉じられたときにはリッスンを停止しますが、メッセージ(例:ロケーションデータなど)は引き続き送信できます。起動時にイベントを待ち受けるように、またはメインのUIスレッドが閉じられたときに、バックグラウンドでWebソケットを実行し続けるにはどうすればよいですか?バックグラウンドサービスとしてリッスンするWebソケットを維持するには?
public class HomeActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener {
public static final String TAG = HomeActivity.class.getSimpleName();
public static final String PREFS_NAME = "MyPrefsFile";
String userName = "init";
String token = "init";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
String macAddress = wInfo.getMacAddress();
TextView textView = (TextView) findViewById(R.id.txtMac);
textView.setText(macAddress);
startService(new Intent(getBaseContext(), wsService.class));
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
userName = settings.getString("username","does not exist");
token = settings.getString("token","does not exist");
textView = (TextView) findViewById(R.id.txtEmail);
textView.setText(userName);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
getSupportActionBar().setTitle("Beacon");
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
}
@Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.home, 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);
}
@SuppressWarnings("StatementWithEmptyBody")
@Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
int id = item.getItemId();
if (id == R.id.nav_camera) {
// Handle the camera action
} else if (id == R.id.nav_gallery) {
} else if (id == R.id.nav_slideshow) {
} else if (id == R.id.nav_manage) {
} else if (id == R.id.nav_share) {
} else if (id == R.id.nav_send) {
} else if (id == R.id.nav_logout) {
Log.i(TAG, "<<<<---- LOGOUT ---->>> ");
Intent i = new Intent(getApplicationContext(), HomeActivity.class);
startActivity(i);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
}
これは、上記の活動から開始されたサービスです。
public class wsService extends Service implements OnPreparedListener {
public static final String PREFS_NAME = "MyPrefsFile";
double longitude = 0;
double latitude = 0;
long time = 0;
float speed = 0;
float accuracy = 0;
float bearing = 0;
boolean sound_stopped = true;
String userName = "init";
String token = "init";
public static final String TAG = wsService.class.getSimpleName();
private LocationRequest mLocationRequest;
MediaPlayer mp;
/** indicates how to behave if the service is killed */
int mStartMode;
/** interface for clients that bind */
IBinder mBinder;
/** indicates whether onRebind should be used */
boolean mAllowRebind;
private Socket mSocket;
{
try {
mSocket = IO.socket("http://192.168.0.2:5000");
} catch (URISyntaxException e) {}
}
/** Called when the service is being created. */
@Override
public void onCreate() {
Log.d(TAG, "-- Starting wsService --");
new LongOperation().execute("test");
mp = MediaPlayer.create(this, R.raw.led);
String locationProvider = LocationManager.NETWORK_PROVIDER;
mLocationRequest = LocationRequest.create() // Create the LocationRequest object
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10 * 1000) // 10 seconds, in milliseconds
.setFastestInterval(1 * 1000); // 1 second, in milliseconds
// Acquire a reference to the system Location Manager
LocationManager locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
locationManager.requestLocationUpdates(locationProvider, 0, 0, locationListener);
}
private class LongOperation extends AsyncTask<String, Void, String> {
@Override
protected String doInBackground(String... params) {
Log.d(TAG, "-- Starting BACKGROUND wsService --");
mSocket.connect();
mSocket.on("to_mobile", onCommand);
return "Executed";
}
@Override
protected void onPostExecute(String result) {
}
@Override
protected void onPreExecute() {}
@Override
protected void onProgressUpdate(Void... values) {}
}
//Listening new message event to receive message
private Emitter.Listener onCommand = new Emitter.Listener() {
@Override
public void call(final Object... args) {
JSONObject data = (JSONObject)args[0];
String command = null;
try {
command = data.getString("command");
} catch (JSONException e) {
e.printStackTrace();
}
Log.i(TAG, "<<<<---- RECEIVING COMMAND ----->>> " + command);
if (command.equals("ping_audio_start")) {
start_sound();
}
if (command.equals("ping_audio_stop")) {
stop_sound();
}
if (command.equals("ping_gps")) {
Log.i(TAG, "<<<<---- RESPONDING GPS REQUEST ----->>> ");
mSocket.emit("from_mobile", gps_string);
}
}
};
String gps_string = "HELLO FROM DROID";
private void handleNewLocation(Location location) {
WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE);
WifiInfo wInfo = wifiManager.getConnectionInfo();
String macAddress = wInfo.getMacAddress();
longitude = location.getLongitude();
latitude = location.getLatitude();
time = location.getTime();
speed = location.getSpeed();
accuracy = location.getAccuracy();
bearing = location.getBearing();
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
userName = settings.getString("username","does not exist");
token = settings.getString("token","does not exist");
gps_string = "{ \"mac\":\"" + macAddress
+ "\", \"userName\":\"" + userName
+ "\", \"token\":\"" + token
+ "\", \"time\":\"" + time
+ "\", \"longitude\":\"" + longitude
+ "\", \"latitude\":\"" + latitude
+ "\", \"speed\":\"" + speed
+ "\", \"accuracy\":\"" + accuracy
+ "\", \"bearing\":\"" + bearing
+ "\"}";
mSocket.emit("from_mobile", gps_string);
Log.i(TAG, "<<<<---- SENDING GPS DATA ---->>> ");
}
// Define a listener that responds to location updates
LocationListener locationListener = new LocationListener() {
public void onLocationChanged(Location location) {
handleNewLocation(location);
}
public void onStatusChanged(String provider, int status, Bundle extras) {}
public void onProviderEnabled(String provider) {}
public void onProviderDisabled(String provider) {}
};
public void start_sound() {
Log.i(TAG, "<<<<---- START PING ----->>>");
mp.release();
mp = MediaPlayer.create(this, R.raw.led);
mp.setLooping(true);
mp.start();
mp.setVolume(1, 1);
sound_stopped = false;
}
public void stop_sound() {
Log.i(TAG, "<<<<---- STOP PING ----->>> ");
mp.stop();
sound_stopped = true;
}
public void onPrepared(MediaPlayer player) {
player.start();
}
/** The service is starting, due to a call to startService() */
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return mStartMode;
}
/** A client is binding to the service with bindService() */
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
/** Called when all clients have unbound with unbindService() */
@Override
public boolean onUnbind(Intent intent) {
return mAllowRebind;
}
/** Called when a client is binding to the service with bindService()*/
@Override
public void onRebind(Intent intent) {
}
/** Called when The service is no longer used and is being destroyed */
@Override
public void onDestroy() {
}
}
私は同じ結果を得ました...私はUIが閉じられるまでメッセージを受け取ることができます。私はまだメッセージ(例えば、位置データ)を出すことができます。 – physiii
サービスはUIに依存しないため、実装上の何かが間違っています。ドキュメントを読んで、間違っている場所を確認してください。 http://developer.android.com/guide/components/services.html UIコードを投稿していないので、間違っていることを伝えることは不可能です。サービスを継続して実行するのではなく、単にサービスを停止しているのかもしれません。 – Kuffs
さて、はい、私はそれを読んだが、私はまだそれがなぜ止まっているのか分からない。私は上記のUIコードを追加します – physiii