Грешка при счупена тръба при изпълнение на Android метод повече от веднъж?

Опитвам се да изпълня следния метод за подправяне на MAC адреса на устройство с Android. Методът се изпълнява всеки път, когато потребителят щракне върху бутон:

public void changeMac(View v) throws IOException {
        editText = (EditText)findViewById(R.id.newMacText);
        String mac = editText.getText().toString();
        Log.d("my log", "" + mac);
        String[] cmds = {"ip link set wlan0 address " + mac};

        Log.d("my log", "in method");
        DataOutputStream os = new DataOutputStream(p.getOutputStream());
        for (String tmpCmd : cmds) {
            os.writeBytes(tmpCmd + "\n");
        }
        os.writeBytes("exit\n");
        os.flush();


        BufferedReader bufferedReader = new BufferedReader(
                new InputStreamReader(p.getInputStream()));

        StringBuilder result = new StringBuilder();
        String line = "";
        while ((line = bufferedReader.readLine()) != null) {
            result.append(line);
        }

       Log.d("my log", "new mac " + Utils.getMACAddress("wlan0"));
        Log.d("my log", result.toString());

    }

Сега, когато потребителят щракне върху бутона отново, приложението се срива и получавам грешка „счупена тръба“.

 android.system.ErrnoException: write failed: EPIPE (Broken pipe)

а също и незаконно държавно изключение. Какво мога да направя, за да накарам тази грешка да спре да се случва и да позволя методът да се извиква многократно?


person coder4lyf    schedule 22.06.2015    source източник
comment
Как да създадете процеса, в който пишете (променлива p)? Предполагам, че това е root/su процес?   -  person Robert    schedule 22.06.2015
comment
да, това е su процес, който правя p = Runtime.getRuntime().exec(su); в моя метод onCreate().   -  person coder4lyf    schedule 22.06.2015


Отговори (3)


Когато изпълните командата os.writeBytes("exit\n"); това завършва вашата su сесия. Процесът su завършва сам и каналът, който използвате за писане на команди в su shell, се поврежда.

Следователно, ако искате да изпълните друга команда, трябва да рестартирате нова su сесия или да не затваряте старата, извиквайки exit.

Както и да е, не бих стартирал процеса su във вашия метод onCreate(). Разрешенията за SuperUser трябва да се получават само когато са необходими, а не при стартиране на приложението.

person Robert    schedule 22.06.2015
comment
Когато извадя реда os.writeBytes(exit\n); приложението замръзва :/ Ако създавам нова su сесия всеки път, ще иска ли всеки път от потребителя да му предостави root достъп? - person coder4lyf; 22.06.2015
comment
Разбира се, той замръзва, защото цикълът while, който чете входа, никога не свършва. bufferedReader.readLine() връща null, ако потокът приключи (следователно, ако su е прекратено). Повечето потребители разрешават root разрешения за постоянно за приложение, ако поиска. SuperSu има възможност да ограничи разрешенията до 10-15 минути, преди да поиска отново. Понякога ще се покаже само малък Toast, който казва, че приложението ви е получило root права. - person Robert; 22.06.2015

Съмнявам се, че можете да промените MAC адреса на всяко устройство.

От wikipedia:

MAC адресите най-често се присвояват от производителя на мрежов интерфейсен контролер (NIC) и се съхраняват в неговия хардуер, като паметта само за четене на картата или някакъв друг фърмуерен механизъм

person Gordak    schedule 22.06.2015
comment
Това е по-скоро като MAC spoofing. - person coder4lyf; 22.06.2015

защо изпълнявате един и същ код отново и отново, можете да запазите mac адреса, като изпълните код веднъж, както създаваме сесия, ако промените устройството, тогава в този случай трябва да проверите mac адреса отново.

person Puneet Kumar    schedule 22.06.2015