본문 바로가기

Android/Service with Socket

안드로이드 예제 Service with Socket

BroadcastReceiver에서 시스템 부팅을 감지하여 Service를 실행하고 Service에서는 Socket을 이용하여 특정 서버로부터 데이터를 수신하여 모바일 기기의 제목 표시줄에 Notification을 표시해주고 이용자가 해당 Notification을 선택하면 웹브라우저가 실행되면서 지정한 웹사이트로 접속하는 예제


서버측 메인 클래스 ( NotificationServer )

 0: package com.nms.server;
 1: 
 2: import java.io.IOException;
 3: import java.net.*;
 4: 
 5: public class NotificationServer {
 6: 	
 7: 	public static void main(String[] args) {
 8: 		
 9: 		ServerSocket server = null;
10: 		Socket client = null;
11: 		try{
12: 			server = new ServerSocket(8888);
13: 			System.out.println("서버 작동중....");
14: 			while(true) {
15: 				System.out.println("클라이언트 접속");
16: 				client = server.accept();
17: 				new ServerThread(client).start();
18: 			}
19: 		}catch(IOException ie) {
20: 			ie.printStackTrace();
21: 		}
22: 	}
23: }




다중이용자를 처리하기 위한 서버측 쓰레드 클래스(ServerThread)

 0: package com.nms.server;
 1: 
 2: import java.io.DataOutputStream;
 3: import java.io.IOException;
 4: import java.net.Socket;
 5: 
 6: public class ServerThread extends Thread {
 7: 
 8: 	Socket client;
 9: 	DataOutputStream dout;
10: 	
11: 	public ServerThread(Socket client) throws IOException {
12: 		this.client = client;
13: 		dout = new DataOutputStream(client.getOutputStream());
14: 	}
15: 
16: 	@Override
17: 	public void run() {
18: 		try {
19: 			dout.writeBoolean(true);
20: 			dout.flush();
21: 		} catch (IOException e) {
22: 			try {
23: 				if(client!=null) client.close();
24: 			} catch (IOException e1) {
25: 				e1.printStackTrace();
26: 			}
27: 			e.printStackTrace();
28: 		}
29: 	}
30: 
31: }





안드로이드 모바일 AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="test.android.hello" android:versionCode="1" android:versionName="1.0" > <uses-sdk android:minSdkVersion="10" /> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.CALL_PHONE"/> <uses-permission android:name="android.permission.SEND_SMS"/> <uses-permission android:name="android.permission.CAMERA" /> <uses-feature android:name="android.hardware.camera" /> <uses-feature android:name="android.hardware.camera.autofocus" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/> <application android:icon="@drawable/ic_launcher" android:label="@string/app_name" > <activity android:name=".ServiceStarterActivity" android:label="@string/app_name" > <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".ClientSocketService" /> <receiver android:name=".BootBroadcastReceiver" android:label="@string/app_name"> <intent-filter> <action android:name="android.intent.action.BOOT_COMPLETED" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </receiver> </application> </manifest>





모바일측의 시스템이 부팅될 때 실행되는 BroadcastReceiver

 0: package test.android.hello;
 1: 
 2: import java.util.Calendar;
 3: 
 4: import android.app.AlarmManager;
 5: import android.app.PendingIntent;
 6: import android.content.BroadcastReceiver;
 7: import android.content.Context;
 8: import android.content.Intent;
 9: 
10: public class BootBroadcastReceiver extends BroadcastReceiver {
11: 
12: 	@Override
13: 	public void onReceive(Context context, Intent intent) {
14: 		 if(intent.getAction().equals("android.intent.action.BOOT_COMPLETED")){
15: 			 int SECS = 1000;
16: 			 int MINS = 60 * SECS;
17: 			 Calendar cal = Calendar.getInstance();
18: 			 Intent in = new Intent(context, ClientSocketService.class);
19: 			 PendingIntent pi = PendingIntent.getService(context, 0, in, PendingIntent.FLAG_UPDATE_CURRENT);
20: 			 AlarmManager alarms = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
21: 			 alarms.setRepeating(AlarmManager.RTC_WAKEUP, cal.getTimeInMillis(), MINS, pi);
22: 		}
23: 	}
24: }





모바일 측에서 주기적으로 서버에 접속하여 데이터를 수신하는 Service 클래스 (ClientSocketService) 

 0: package test.android.hello;
 1: 
 2: import java.io.DataInputStream;
 3: import java.io.IOException;
 4: import java.net.Socket;
 5: 
 6: import android.app.Service;
 7: import android.content.Intent;
 8: import android.os.IBinder;
 9: import android.util.Log;
10: 
11: import android.app.Notification;
12: import android.app.NotificationManager;
13: import android.app.PendingIntent;
14: import android.content.BroadcastReceiver;
15: import android.content.Context;
16: import android.content.IntentFilter;
17: import android.net.Uri;
18: 
19: public class ClientSocketService extends Service {
20: 
21: 	private static final int MY_NOTIFICATION_ID=1;
22: 	private NotificationManager notificationManager;
23: 	private Notification myNotification;
24: 	private final String myBlog = "http://micropilot.tistory.com/";
25: 	
26: 	@Override
27: 	public void onCreate() {
28: 		super.onCreate();
29: 	}
30: 	
31: 	@Override
32: 	public int onStartCommand(Intent intent, int flags, int startId) {
33: 
34: 		Log.i("서비스호출", "onStartCommand()실행됨");
35: 		Socket socket = null;
36: 		try{ 
37: 			socket = new Socket("211.183.3.170", 8888);
38: 			socket.setSoTimeout(10000);
39: 			DataInputStream din = new DataInputStream(socket.getInputStream());
40: 			int n = din.read();
41: 			if(n!=1) {
42: 				return super.onStartCommand(intent, flags, startId);
43: 			}
44: 		}catch(Exception e) {
45: 			Log.e("소켓접속상태", e.getMessage());
46: 			if(socket!=null)
47: 				try {
48: 					socket.close();
49: 				} catch (IOException e1) {
50: 				}
51: 			return super.onStartCommand(intent, flags, startId);
52: 		}
53: 		// Send Notification
54: 		notificationManager =
55: 		 (NotificationManager)getSystemService(Context.NOTIFICATION_SERVICE);
56: 		myNotification = new Notification(R.drawable.ic_launcher,
57: 		  "Notification!",
58: 		  System.currentTimeMillis());
59: 		Context context = getApplicationContext();
60: 		String notificationTitle = "새로운 글 등록알림";
61: 		String notificationText = "http://micropilot.tistory.com 접속";
62: 		Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(myBlog));
63: 		PendingIntent pendingIntent
64: 		  = PendingIntent.getActivity(getBaseContext(),
65: 		    0, myIntent,
66: 		    Intent.FLAG_ACTIVITY_NEW_TASK);
67: 		myNotification.defaults |= Notification.DEFAULT_SOUND;
68: 		myNotification.flags |= Notification.FLAG_AUTO_CANCEL;
69: 		myNotification.setLatestEventInfo(context,
70: 		   notificationTitle,
71: 		   notificationText,
72: 		   pendingIntent);
73: 		notificationManager.notify(MY_NOTIFICATION_ID, myNotification);
74: 		
75: 		return super.onStartCommand(intent, flags, startId);
76: 	}
77: 	
78: 	@Override
79: 	public void onDestroy() {
80: 		super.onDestroy();
81: 	}
82: 	
83: 	@Override
84: 	public IBinder onBind(Intent arg0) {
85: 		return null;
86: 	}
87: }