0

Android 4.0.3 を搭載したタブレットがここで停止し、2.2.3 を搭載した携帯電話がこのコードで動作していることがわかりましたが、その理由はわかりません。

タブレットと電話のコーディングの違いが思い浮かびません。

/* Store this device macaddress within the server. */
    static void storeMacAddress(final Context context, final String macAddr) { 
        Log.i(TAG, "Store device on Server (macAddress = " + macAddr + ")");
        String serverUrl = SERVER_URLL;
        Map<String, String> params = new HashMap<String, String>();
        params.put("macaddress", macAddr);

        long backoff = BACKOFF_MILLI_SECONDS + random.nextInt(1000);
        // As the server might be down, we will retry it a couple times.
        for (int i = 1; i <= MAX_ATTEMPTS; i++) {
            Log.d(TAG, "Attempt #" + i + " to store");
            try {
                post(serverUrl, params);
                Log.d(TAG, "Store op Server gelukt!");
                return;
            } catch (IOException e) {
                // Here we are simplifying and retrying on any error
                Log.e(TAG, "Failed to store on attempt " + i + ":" + e);
                if (i == MAX_ATTEMPTS) {
                    break;
                }
                try {
                    Log.d(TAG, "Sleeping for " + backoff + " ms before retry");
                    Thread.sleep(backoff);
                } catch (InterruptedException e1) {
                    // Activity finished before we complete - exit.
                    Log.d(TAG, "Thread interrupted: abort remaining retries!");
                    Thread.currentThread().interrupt();
                    return;
                }
                // increase backoff exponentially
                backoff *= 2;
            } 
        }

        Log.d(TAG, "Error tijdens store op Server procedure!");        
    }

private static void post(String endpoint, Map<String, String> params)
            throws IOException {    

        URL url;
        try {
            url = new URL(endpoint);
        } catch (MalformedURLException e) {
            throw new IllegalArgumentException("invalid url: " + endpoint);
        }
        StringBuilder bodyBuilder = new StringBuilder();
        Iterator<Entry<String, String>> iterator = params.entrySet().iterator();
        // constructs the POST body using the parameters
        while (iterator.hasNext()) {
            Entry<String, String> param = iterator.next();
            bodyBuilder.append(param.getKey()).append('=')
                    .append(param.getValue());
            if (iterator.hasNext()) {
                bodyBuilder.append('&');
            }
        }
        String body = bodyBuilder.toString();
        Log.v(TAG, "Posting '" + body + "' to " + url);
        byte[] bytes = body.getBytes();
        HttpURLConnection conn = null;
        try {
            Log.e("URL", "> " + url);
            conn = (HttpURLConnection) url.openConnection();
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setFixedLengthStreamingMode(bytes.length);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded;charset=UTF-8");
            // post the request
            OutputStream out = conn.getOutputStream();
            out.write(bytes);
            out.close();
            // handle the response
            int status = conn.getResponseCode();
            if (status != 200) {
              throw new IOException("Post failed with error code " + status);
            }
        } finally {
            if (conn != null) {
                conn.disconnect();
            }
        }
      }

編集: からの呼び出し:

...    
setContentView(R.layout.activity_main);

            final SharedPreferences prefs = this.getSharedPreferences("nl.easy.winkel", Context.MODE_PRIVATE);

            if(!prefs.getString("macaddress","").equals("send")) { // Send MacAddress once
                prefs.edit().putString("macaddress","send").commit();
                obtainMacAddress();
            }

and 

    private void obtainMacAddress() {
            WifiManager wifiMan = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
            WifiInfo wifiInf = wifiMan.getConnectionInfo();
            String macAddr = wifiInf.getMacAddress();
            final Context context = this;
            ServerUtilities.storeMacAddress(context, macAddr + "|" + getLocalIpAddress());
    }

        public String getLocalIpAddress() {
            try {
                for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
                    NetworkInterface intf = en.nextElement();
                    for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
                        InetAddress inetAddress = enumIpAddr.nextElement();
                        if (!inetAddress.isLoopbackAddress()) {
                            return inetAddress.getHostAddress().toString();
                        }
                    }
                }
            } catch (SocketException ex) {
                Log.e(TAG, ex.toString());
            }
            return null;
        }

EDIT2: AsyncTask の使用

AsyncTask<Void, Void, Void> mStoreTask;

private void obtainMacAddress() {
        WifiManager wifiMan = (WifiManager) this.getSystemService(Context.WIFI_SERVICE);
        WifiInfo wifiInf = wifiMan.getConnectionInfo();
        final String macAddr = wifiInf.getMacAddress();
        final Context context = this;

        mStoreTask = new AsyncTask<Void, Void, Void>() {

            @Override
            protected Void doInBackground(Void... params) {
                // Store on our server
                // On server creates a new user
                ServerUtilities.storeMacAddress(context, macAddr + "|" + getLocalIpAddress());
                return null;
            }

            @Override
            protected void onPostExecute(Void result) {
                mStoreTask = null;
            }

        };
        mStoreTask.execute(null, null, null);
    }
4

1 に答える 1

4

この問題には 2 つの解決策がありますが、最初の解決策は素晴らしい解決策です。

1) メイン UI スレッドにネットワーク呼び出しを記述しないでください。そのために非同期タスクを使用します。

2) setContentView(R.layout.activity_main); の後に MainActivity ファイルに以下のコードを記述します。しかし、これは適切な方法ではありません。

if (android.os.Build.VERSION.SDK_INT > 9) {
    StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
    StrictMode.setThreadPolicy(policy);
}

以下の import ステートメントを Java ファイルに挿入します。

import android.os.StrictMode;

詳細については、以下のリンクを参照してください。

原因: android.os.NetworkOnMainThreadException

于 2012-11-29T11:02:50.987 に答える