안드로이드 프레임워크 프로그래밍(6) [Wi-Fi 접속 확인 Toast 만들기]

안드로이드/프레임워크 2015. 1. 30. 23:30

 최근 안드로이드 프레임워크 공부를 해보던 중 한 번 도전하고 싶었던 것이 있었습니다. 바로 갤럭시 S2에서 지원하던 Wi-Fi 접속 알림창이었습니다.


 ※갤럭시 S2 JellyBean 4.1에서의 모습입니다.

 위에서 보는 바와 같이 안드로이드 기기가 Wi-Fi에 접속하면 Framework를 통해 Toast가 이를 알려주는 모습을 보고 이를 Nexus 폰에도 적용해보자는 마음으로 도전하게 되었습니다.


※본 포스팅은 Nexus5 KitKat 4.4.4 환경에서 제작되었음을 알립니다.


1.  아래 굵은 표시로 추가된 소스코드를 안드로이드 소스에 추가합니다.

/frameworks/base/services/java/com/android/server/ConnectivityService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
        @Override
        public void handleMessage(Message msg) {
            NetworkInfo info;
            switch (msg.what) {
                case NetworkStateTracker.EVENT_STATE_CHANGED: {
                    info = (NetworkInfo) msg.obj;
                    NetworkInfo.State state = info.getState();
 
                    if (VDBG || (state == NetworkInfo.State.CONNECTED) ||
                            (state == NetworkInfo.State.DISCONNECTED) ||
                            (state == NetworkInfo.State.SUSPENDED)) {
                        log("ConnectivityChange for " +
                            info.getTypeName() + ": " +
                            state + "/" + info.getDetailedState());
        //APPEND
 
        if ( state == NetworkInfo.State.CONNECTED ){
            Toast.makeText(mContext, info.getExtraInfo().
                substring(1,info.getExtraInfo().length() - 1)
                + "에 연결되었습니다.", Toast.LENGTH_SHORT).show();
        }
 
        //END
                    }
 
                    // Since mobile has the notion of a network/apn that can be used for
                    // provisioning we need to check every time we're connected as
                    // CaptiveProtalTracker won't detected it because DCT doesn't report it
                    // as connected as ACTION_ANY_DATA_CONNECTION_STATE_CHANGED instead its
                    // reported as ACTION_DATA_CONNECTION_CONNECTED_TO_PROVISIONING_APN. Which
                    // is received by MDST and sent here as EVENT_STATE_CHANGED.
                    if (ConnectivityManager.isNetworkTypeMobile(info.getType())
                            && (0 != Settings.Global.getInt(mContext.getContentResolver(),
                                        Settings.Global.DEVICE_PROVISIONED, 0))
                            && (((state == NetworkInfo.State.CONNECTED)
                                    && (info.getType() == ConnectivityManager.TYPE_MOBILE))
                                || info.isConnectedToProvisioningNetwork())) {
                        log("ConnectivityChange checkMobileProvisioning for"
                                + " TYPE_MOBILE or ProvisioningNetwork");
                        checkMobileProvisioning(CheckMp.MAX_TIMEOUT_MS);
                    }
    }
 
 
cs


2. 적용된 소스코드를 빌드하여 이미지를 새로 만듭니다.

$ make -j4


3. 안드로이드 기기에 이미지를 올린 후 동작을 확인합니다.




300x250

Windows XP에서 DOS 파일 실행시 EMS 문제 해결방법

공대생의 팁 2015. 1. 26. 22:11

 오랜만에 추억의 DOS 기반의 게임을 해보려고 XP에 설치한 후 실행을 해 보았더니 다음과 같은 문구가 뜨면서 실행이 중단되 버리더군요.


 "FATAL: Not enough memory. Free more conventional memory or EMS or install EMM386"


 무척대고 경고문을 그대로 검색을 해도 도저히 관련 자료를 찾지 못하고 있는데 뜻밖의 사실을 알게 되었습니다. 바로 XP 부터는 DOS 프로그램에 메모리가 할당되지 않는다는 겁니다. 이전 버전인 95와 98의 경우 DOS에 Extended Memory 가 지원되어 DOS 프로그램이 무난히 실행되나 XP부터는 해당 기능이 사라졌다고 하는군요.


 하지만 전혀 걱정할 필요는 없습니다! XP에서도 실행할 수 있는 방법은 존재합니다. 즉 수동으로 직접 할당하는 방법이지요. 다음 방법대로 진행해주시면 해결하실 수 있습니다.


1. 해당 실행파일(exe)에서 오른쪽 클릭 후 속성(R)을 클릭합니다.



2. '메모리' 탭을 선택하신 후 확인하시면 확장(EMS) 메모리가 '없음'으로 체크되어 있습니다.


3. 해당 영역을 클릭하신 후 '자동'으로 설정하시거나 자신이 직접 적당한 양의 메모리를 할당해 줍니다.


4. '확인' 버튼을 눌러 설정을 저장합니다.




위 설정을 마친 후 DOS 파일을 실행하면 정상적으로 동작되는 것을 확인하실 수 있습니다.

300x250

안드로이드 프레임워크 프로그래밍(5) [Toast 구현하기]

안드로이드/프레임워크 2015. 1. 25. 01:43

 지난 포스팅에서 새로 추가한 System service를 적용하여 Log를 통해 등록한 System service가 제대로 동작하는지에 대해 알아보았습니다. 이번에는 Framework 자체에서 Toast를 구현하는 작업을 해보도록 하겠습니다.


※본 포스팅은 지난 포스팅에서 사용하였던 예제를 수정하여 적용하였습니다. 그러므로 본 포스팅에서는 수정된 코드에 대해서만 다룰 것이며 상세한 코드는 이전 포스팅을 통해 확인해 주시기 바랍니다.


http://elecs.tistory.com/64


1. System service에 Toast 관련 소스를 입력합니다.

frameworks/base/services/java/com/android/server/TestService.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
package com.android.server;
import android.content.Context;
import android.os.Handler;
import android.os.ITestService;
import android.os.Looper;
import android.os.Message;
import android.os.Process;
import android.util.Log;
import android.widget.Toast;
public class TestService extends ITestService.Stub {
    private static final String TAG = "TestService";
    private TestWorkerThread mWorker;
    private TestWorkerHandler mHandler;
    private Context mContext;
    public TestService(Context context) {
        super();
        mContext = context;
        mWorker = new TestWorkerThread("TestServiceWorker");
        mWorker.start();
        Log.i(TAG, "Spawned worker thread");
    }
 
    public void setValue(int val) {
        Log.i(TAG, "setValue " + val);
        Message msg = Message.obtain();
        msg.what = TestWorkerHandler.MESSAGE_SET;
        msg.arg1 = val;
        mHandler.sendMessage(msg);
    }
 
    public void showToast(int val){
        Log.i(TAG, "showToast " + val);
        Message msg = Message.obtain();
        msg.what = 2;
        msg.arg1 = val;
        mHandler.sendMessage(msg);
    }
 
    private class TestWorkerThread extends Thread {
        public TestWorkerThread(String name) {
            super(name);
        }
        public void run() {
            Looper.prepare();
            mHandler = new TestWorkerHandler();
            Looper.loop();
        }
    }
 
    private class TestWorkerHandler extends Handler {
        private static final int MESSAGE_SET = 0;
        @Override
        public void handleMessage(Message msg) {
            try {
                if (msg.what == MESSAGE_SET) {
                    Log.i(TAG, "set message received: " + msg.arg1);
                }
        if (msg.what == 2){
            Log.i(TAG, "Show toast!!");
            Toast.makeText(mContext, "Toast message : "+msg.arg1, Toast.LENGTH_SHORT).show();
        }
        
            } catch (Exception e) {
                // Log, don't crash!
                Log.e(TAG, "Exception in TestWorkerHandler.handleMessage:", e);
            }
        }
    }
}
cs


2. AIDL 또한 변경된 System service 프로그램에 맟게 method를 추가합니다.

frameworks/base/core/java/android/os/ITestService.aidl

1
2
3
4
5
6
7
8
package android.os;
interface ITestService {
/**
* {@hide}
*/
    void setValue(int val);
    void showToast(int val);
}
cs



3. 여기까지 진행하셨다면 작성한 소스를 Build 해줍니다.

$ make -j4


4. 애플리케이션 프로젝트를 통해 Framework에서 Toast를 구현하는 프로그램을 작성합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.example.test;
 
import android.app.Activity;
import android.app.ActivityThread;
import android.os.Bundle;
import android.os.ITestService;
import android.os.ServiceManager;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import android.util.Log;
 
 
public class MainActivity extends Activity {
    private static final String DTAG = "HelloServer";
 
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        ITestService om = ITestService.Stub.asInterface(ServiceManager.getService("Test"));
        try{
            Log.d(DTAG, "Going to call service");
            om.setValue(20);
            om.showToast(30);
            Log.d(DTAG, "Service called successfully");
        }catch(Exception e){
            Log.d(DTAG, "FAILED to call service");
            e.printStackTrace();
        }
        
    }
 
 
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, 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();
        if (id == R.id.action_settings) {
            return true;
        }
        return super.onOptionsItemSelected(item);
    }
 
}
cs



이제 어플리케이션을 실행하면 다음과 같은 결과를 확인하실 수 있습니다.





300x250