Android透過接收UDP訊息改寫程式配置

llnnmc發表於2019-08-25

Android程式打包成APK釋出後,如果有引數需要根據不同應用環境作修改,該如何實現呢?

比如這裡有個應用場景,Android程式需要呼叫伺服器端的WebService服務來進行後臺資料庫操作,而WebService的IP地址隨各個生產環境有所不同,如果每次都因為地址的變更而重新編譯打包程式,明顯不便。如果我們能找到一種方式,在不對APK程式做任何改動的情況下,動態修改這個地址引數配置,將是多麼靈活。

還有其它一些場景也需要APK應用程式能隨時改變並且記住我們的設定,如一個安卓電視機大屏,需要實時展示一個HTML網頁報表,那麼我們的Web頁面地址就需要傳送給這個APK應用,讓其記住我們的設定,下次程式開啟後就可以自動顯示到我們的報表頁面了。

要實現這些需求,一個比較簡單的方法就是透過向APP應用程式傳送UDP訊息,將APP需要的一些配置引數傳送給它,APP接收到訊息取到引數後,將其儲存在手機系統特定的位置,以後程式再開啟後就可以讀取到這些設定。

在Android系統中,每當APP應用程式安裝後,都會在系統的data/data目錄下新建一個以應用程式包名稱命名的資料夾,該資料夾包含了應用程式的檔案資源,稱之為內部儲存檔案。雖然沒有ROOT的手機看不到該資料夾,但其實質存在。我們可以在該資料夾中建立自己的儲存檔案,比如建立一個配置文字,存放應用的一些引數配置資料。應用解除安裝後,這些檔案內容自然消失。因此,我們可以在這個路徑下建立自己的配置檔案,將透過UDP接收到的引數儲存在該檔案中。

接收UDP訊息是阻塞式的,也就是說直到收到UDP訊息後才會繼續下一步,因此我們把這個過程放在一個獨立的執行緒中。以下建立一個執行緒類專門用於接收固定埠的UDP訊息,並將接收到的訊息文字寫入data/data下指定的文字檔案中。

public class UdpReceiveThread extends Thread {
    private final String TAG = "UdpReceiveThread";
    private Context context;
 
    // 該建構函式用於將主活動執行緒的上下文環境傳遞進來
    public UdpReceiveThread(Context c)
    {
        context = c;
    }
 
    @Override
    public void run() {
        while (isAlive()) try {
            sleep(1000);
            DatagramSocket socket = new DatagramSocket(8808); // 埠固定為8808
            byte data[] = new byte[1024];
            DatagramPacket packet = new DatagramPacket(data, data.length);
            socket.receive(packet); // 阻塞式,接收傳送方的packet
            String result = new String(packet.getData(), packet.getOffset(), packet.getLength());
 
            // 將從UDP埠接收到的訊息寫入Android內部儲存檔案中做為程式配置引數
            try {
                FileOutputStream fos = context.openFileOutput("MyScan.txt", Context.MODE_PRIVATE);
                OutputStreamWriter osw = new OutputStreamWriter(fos,"UTF-8");
                osw.write(result);
                osw.flush();
                fos.flush();
                osw.close();
                fos.close();
            } catch (Exception e) {
                Log.d(TAG, "run: " + e.getMessage());
                break;
            }
        } catch (Exception e) {
            Log.d(TAG, "run: " + e.getMessage());
            break;
        }
    }
}

在主Activity活動的onCreate函式中新增以下程式碼,從手機系統的data/data路徑中讀取程式配置,呼叫接收UDP訊息的子執行緒,並將活動的上下文環境傳遞給子執行緒。

public void onCreate(Bundle savedInstanceState) {
    ...
    // 從Android內部儲存檔案中讀取配置
    try {
        FileInputStream fis = openFileInput("MyScan.txt");
        InputStreamReader isr = new InputStreamReader(fis,"UTF-8");
        char[] input = new char[fis.available()];  // available()用於獲取檔案內容的長度
        isr.read(input);
        isr.close();
        fis.close();
        String str = new String(input);
        ws_url = str;
    } catch (Exception e){
        Log.d(TAG, "onCreate: " + e.getMessage());
    }
    ...
    // 呼叫UDP接收執行緒迴圈監聽埠訊息
    UdpReceiveThread udpThread = new UdpReceiveThread(getApplicationContext());
    udpThread.start();
    ...
}

由此,程式在執行過程中,一旦接收到固定埠發來的UDP訊息後,將改寫配置,並在下次啟動時,以新的配置引數執行。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/28974745/viewspace-2654898/,如需轉載,請註明出處,否則將追究法律責任。

相關文章