This is for the C/C++ developers out here...
i need to connect a PocketPC to a PC via Bluetooth. Looking at various samples from the Windows Platform SDK and the Windows Mobile SDKs, i came up with the following server (PC) and client (PDA) codes:
Server Code (WinXP):
Code:
WSAData wsaData;
SOCKADDR_BTH sa;
int namelen;
SOCKET sock;
SOCKADDR_BTH sockaddr;
int size = sizeof(sockaddr);
if (WSAStartup(MAKEWORD(2, 2), &wsaData) == SOCKET_ERROR)
return false;
BluetoothHost_Socket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
if (BluetoothHost_Socket == INVALID_SOCKET)
return false;
memset (&sa, 0, sizeof(sa));
sa.addressFamily = AF_BTH;
sa.port = 0;
if (bind(BluetoothHost_Socket, (SOCKADDR *) &sa, sizeof(sa)))
{
closesocket(BluetoothHost_Socket);
return false;
namelen = sizeof(sa);
if (getsockname(BluetoothHost_Socket, (SOCKADDR *)&sa, &namelen))
{
closesocket (BluetoothHost_Socket);
return false;
}
BluetoothHost_ClientListCount = 0;
if (listen(BluetoothHost_Socket, 5))
return false;
sock = accept(BluetoothHost_Socket, (SOCKADDR *) &sockaddr, &size);
}
Client Code (WinCE):
Code:
WSAQUERYSET querySet;
HANDLE hLookup;
char buffer[1000];
DWORD bufferlength;
WSAQUERYSET *results;
SOCKADDR_BTH *btaddr;
if (WSAStartup(MAKEWORD(2, 2), &wsaData) == SOCKET_ERROR)
return false;
memset(&querySet, 0, sizeof(querySet));
querySet.dwSize = sizeof(querySet);
querySet.dwNameSpace = NS_BTH;
BluetoothQuery_DeviceCount = 0;
if (WSALookupServiceBegin(&querySet, LUP_CONTAINERS, &hLookup) == SOCKET_ERROR)
return false;
while (BluetoothQuery_DeviceCount < BLUETOOTHQUERY_MAXDEVICES && !BluetoothQuery_Cancel)
{
bufferlength = sizeof(buffer);
memset(buffer, 0, sizeof(buffer));
results = (WSAQUERYSET *) &buffer;
if (WSALookupServiceNext(hLookup, LUP_RETURN_NAME|LUP_RETURN_ADDR, &bufferlength, results) == SOCKET_ERROR)
{
int result = WSAGetLastError();
break;
}
btaddr = (SOCKADDR_BTH*)results->lpcsaBuffer->RemoteAddr.lpSockaddr;
BluetoothQuery_DeviceAddrList[BluetoothQuery_DeviceCount]=btaddr->btAddr;
if (results->lpszServiceInstanceName != NULL)
wcscpy((TCHAR *)BluetoothQuery_DeviceNameList[BluetoothQuery_DeviceCount],results->lpszServiceInstanceName);
else
wcscpy((TCHAR *)BluetoothQuery_DeviceNameList[BluetoothQuery_DeviceCount],L"<unnamed>");
BluetoothQuery_DeviceCount++;
}
WSALookupServiceEnd(hLookup);
BluetoothClient_Socket = socket (AF_BT, SOCK_STREAM, BTHPROTO_RFCOMM);
if (BluetoothClient_Socket == INVALID_SOCKET)
return false;
SOCKADDR_BTH sa;
memset (&sa, 0, sizeof(sa));
sa.addressFamily = AF_BT;
sa.btAddr = *btaddr;
for (i = 0; i < 30; i++)
{
sa.port = i; //channel & 0xff;
if (connect(BluetoothClient_Socket, (SOCKADDR *) &sa, sizeof(sa)) == 0)
break;
}
if (i >= 30)
{
closesocket(BluetoothClient_Socket);
return false;
}
All calls seems to work out. Sockets are created, all return values look ok. Yet, the client does not connect to the server, so the server never goes beyong that accept() call.
Any comments would be greatly appreciated!
thanks,
Daniel
Related
Hi,
I 'm not able to establish GPRS connection using RasDial on PPC 2005 . It returns always error 633. That means:
"The port is already in use or is not configured for Remote Access dialout.� (See related Microsoft article: ErrMsg: Error 633: The Modem Is Not Installed or Configured...) "
But it works fine in PPC 2003. Does anyone gets RAS API run successfull on WM 5.0 ?
here is my code:
Code:
void ConnectGPRSDlg::connectViaRAS()
{
RASDIALPARAMS rasDialParam;
BOOL bPasswd,bRasEntryFound;
DWORD dwRes, dwSize, dwEntries, dw;
short n_attempts = 5;
HRASCONN g_rasConn = NULL;
CString szError,msg,szResult;
LPRASENTRYNAME lpRasEntry = NULL;
// structure init.
memset(&rasDialParam, 0, sizeof(RASDIALPARAMS));
rasDialParam.dwSize = sizeof (RASDIALPARAMS);
lpRasEntry = new RASENTRYNAME[20];
if(lpRasEntry == NULL)
{
szError.Format( _T("Out of memory") );
msg += szError;
m_editbox.SetWindowTextW(msg);
return;
}
lpRasEntry[0].dwSize = sizeof(RASENTRYNAME);
dwSize = sizeof(RASENTRYNAME) * 20;
dwRes = RasEnumEntries(NULL, NULL, lpRasEntry,
&dwSize, &dwEntries);
if (dwRes != 0)
{
szError.Format( _T("Error getting RAS entries %d"),dwRes );
msg += szError;
}
else
{
szError.Format( _T("got RAS %d entries\r\n "),dwEntries );
msg += szError;
for(dw = 0; dw < dwEntries; dw++)
{
if( 0 == _tcscmp( lpRasEntry[dw].szEntryName, L"T-Mobile Internet" ) )
{
bRasEntryFound = TRUE;
_tcscpy( rasDialParam.szEntryName, lpRasEntry[dw].szEntryName );
szError.Format( _T("found entry: %s\r\n "),lpRasEntry[dw].szEntryName );
msg += szError;
}
}
}
if (!bRasEntryFound) return;
//// connection name
//wcscpy(rasDialParam.szEntryName, _T("T-Mobile Internet") );
//
// parameters from connection structure
dwRes = RasGetEntryDialParams(NULL, &rasDialParam, &bPasswd);
if(dwRes != 0)
{
szResult.Format( _T("getting Dial Params error: %D \r\n") , dwRes );
szResult += szError;
}
else
{
szResult.Format(L"entryname: %s, number: %s \r\n", rasDialParam.szEntryName,rasDialParam.szPhoneNumber);
msg += szResult;
}
// szError.Format( _T("creat new Dial Params...\r\n"));
//msg += szError;
// // Copy in the user credetials.
//_tcscpy( rasDialParam.szEntryName, _T("T-Mobile Internet") );
//_tcscpy( rasDialParam.szUserName, _T("t-mobile") );
//_tcscpy( rasDialParam.szPassword, _T("pwd") );
//_tcscpy( rasDialParam.szPhoneNumber, _T("*99#") );
//_tcscpy( rasDialParam.szCallbackNumber, _T("") );
szResult.Format(L"entryname: %s, number: %s \r\n", rasDialParam.szEntryName,rasDialParam.szPhoneNumber);
msg += szResult;
m_editbox.SetWindowTextW(msg);
do{
// if connection fails, hangup and retry... for 5 attemps
DWORD dwResult = RasDial(NULL,NULL,&rasDialParam,0,NULL,&g_rasConn);
Sleep(2000);
if ( dwResult != 0)
{
szError.Format(L"RAS error: %d \r\n", dwResult);
msg += szError;
m_editbox.SetWindowTextW(msg);
RasHangUp(g_rasConn);
g_rasConn = NULL;
n_attempts--;
}
else {
break;
}
}
while(n_attempts);
if(n_attempts == 0)
{
//AddDebugInfo( L"Can't connect GPRS" );
}
else
{
RASCONNSTATUS rasConStatus;
memset(&rasConStatus, 0, sizeof(RASCONNSTATUS));
rasConStatus.dwSize = sizeof(RASCONNSTATUS);
RasGetConnectStatus(g_rasConn, &rasConStatus);
if(rasConStatus.dwError == 0) {
szResult.Format( L"GPRS connected \r\n" );
msg += szResult;
}
else
{
szResult.Format(L"Ras connect status: %s \r\n", rasConStatus.dwError);
msg += szResult;
}
}
m_editbox.SetWindowTextW(msg);
return;
}
Hi All,
I am developing a VOIP application for Windows Mobile. I want the user to switch the between the Speaker and Earpiece of the Mobile Phone. I have searched the Forum and found the following link
http://teksoftco.com/forum/viewtopic.php?p=1909
As you know we have to use LoadLibrary and GetProcAddress to access the RIL APIs in Windows Mobile. I have written following piece of code for this i.e.
Code:
HRIL hRIL;
bool speakerphone = true; // false;
HRESULT result = RIL_Initialize(1, ResultCallback, NotifyCallback, RIL_NCLASS_MISC, 0, &hRIL);
if (result != S_OK) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not open RIL, error=0x%x", result);
AfxMessageBox(buffer);
return;
}
RILAUDIODEVICEINFO info;
info.cbSize = sizeof(info);
info.dwParams = RIL_PARAM_ADI_ALL; // RIL_PARAM_ADI_TXDEVICE;
info.dwRxDevice = RIL_AUDIO_HANDSET;
info.dwTxDevice = speakerphone ? RIL_AUDIO_NONE : RIL_AUDIO_HANDSET;
result = RIL_SetAudioDevices(hRIL, &info);
if (result != S_OK) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not open RIL, error=0x%x", result);
AfxMessageBox(buffer);
}
RIL_Deinitialize(hRIL);
But this doesn't seems to work, i.e. some time it causes both the audio input and output to halt, sometime audio input is halted (i.e. no voice is heard on the other end).
I have also tried another techniques to accomplish this task, like:
Technique 2
--------------
Code:
#define MM_WOM_FORCESPEAKER (WM_USER+2)
static void SetSpeakerMode(bool speakerphone)
{
MMRESULT result = waveOutMessage((HWAVEOUT)0, MM_WOM_FORCESPEAKER, speakerphone, 0);
if (result != MMSYSERR_NOERROR) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not do speakerphone switch, error=%u", result);
AfxMessageBox(buffer);
}
}
Technique 3
--------------
Code:
/* Stuff from Wavedev.h */
#define IOCTL_WAV_MESSAGE 0x001d000c
typedef struct {
UINT uDeviceId;
UINT uMsg;
DWORD dwUser;
DWORD dwParam1;
DWORD dwParam2;
} MMDRV_MESSAGE_PARAMS;
/* End of Wavedev.h extract */
class WavDevice
{
private:
HANDLE hWavDev;
public:
WavDevice()
{
hWavDev = CreateFile(TEXT("WAV1:"), GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, 0, NULL);
if (hWavDev == INVALID_HANDLE_VALUE) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not open device, error=%u", GetLastError());
AfxMessageBox(buffer);
}
}
~WavDevice()
{
if (hWavDev != INVALID_HANDLE_VALUE)
CloseHandle(hWavDev);
}
bool SendMessage(UINT uMsg, DWORD dwParam1 = 0, DWORD dwParam2 = 0)
{
if (hWavDev == INVALID_HANDLE_VALUE)
return false;
DWORD dwRet = 0, dwOut;
MMDRV_MESSAGE_PARAMS mp;
memset(&mp,0,sizeof(mp));
mp.uMsg = uMsg;
mp.dwParam1 = dwParam1;
mp.dwParam2 = dwParam2;
if (DeviceIoControl(hWavDev, IOCTL_WAV_MESSAGE, &mp, sizeof(mp), &dwOut, sizeof(dwOut), &dwRet, 0))
return true;
wchar_t buffer[200];
wsprintf(buffer, L"Could not do speakerphone switch, error=%u", GetLastError());
AfxMessageBox(buffer);
return false;
}
};
static void SetSpeakerMode(bool speakerphone)
{
WavDevice wd;
if (!wd.SendMessage(1002, speakerphone ? 0 : 2))
return;
if (!wd.SendMessage(1012, speakerphone ? 0 : 1))
return;
if (speakerphone && !wd.SendMessage(1013))
return;
wd.SendMessage(1000, speakerphone ? 2 : 4, speakerphone ? 0 : 7);
}
Technique 4
--------------
Code:
class OsSvcsDll
{
private:
HMODULE hDLL;
typedef HRESULT (* SetSpeakerModeFn)(DWORD mode);
SetSpeakerModeFn pfnSetSpeakerMode;
public:
OsSvcsDll()
{
hDLL = LoadLibrary(L"\\windows\\ossvcs.dll");
if (hDLL == NULL) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not open DLL, error=%u", GetLastError());
AfxMessageBox(buffer);
}
pfnSetSpeakerMode = (SetSpeakerModeFn)GetProcAddress(hDLL, (LPCTSTR)218);
if (pfnSetSpeakerMode == NULL) {
wchar_t buffer[200];
wsprintf(buffer, L"Could not open DLL, error=%u", GetLastError());
AfxMessageBox(buffer);
}
}
~OsSvcsDll()
{
if (hDLL != NULL)
FreeLibrary(hDLL);
}
bool SetSpeakerMode(DWORD speakerphone)
{
if (pfnSetSpeakerMode == NULL)
return false;
HRESULT result = pfnSetSpeakerMode(speakerphone);
if (result == 0)
return true;
wchar_t buffer[200];
wsprintf(buffer, L"Could not do speakerphone switch, error=0x%x", result);
AfxMessageBox(buffer);
return false;
}
};
static void SetSpeakerMode(bool speakerphone)
{
OsSvcsDll dll;
dll.SetSpeakerMode(speakerphone ? 1 : 0);
}
But no procedure seems to work properly.
Can you please guide me where i am going wrong or some other way of achieving this.
I am using
Visual C++ MFC Dialog based Application
Visual Studio 2008
Windows Mobile 6 SDK For PocketPC
I have tested the above mentioned sample on
HTC Touch
Sony Erricsson XPeria
Waiting for response.
Regards,
Ghazanfar Ali
Regards,
Ghazanfar Ali
Hey all
I have the following function to generate the http headers for a GET request on an image file:
Code:
byte [] headersAndImage()
{
StringBuilder s = new StringBuilder();
s.Append("HTTP/1.1 200 OK\r\n");
s.Append("Date: Tue, 17 Aug 2010 11:40:00 GMT\r\n");
s.Append("Vary: *\r\n");
s.Append("Server: Custommade\r\n");
s.Append("Content-Type: image/jpeg\r\n");
Bitmap b = new Bitmap("\\dog.jpg");
MemoryStream ms = new MemoryStream();
b.Save(ms, ImageFormat.Jpeg );
byte[] bitmapData = ms.ToArray();
ms.Close();
s.Append("Content-Length: " + bitmapData.Length + "\r\n\r\n");
byte[] headers = Encoding.ASCII.GetBytes(s.ToString());
return join(headers,bitmapData);
}
however when a browser receives this http packet the image is never displayed, usually just see the red X.
Any ideas why this won't work?
Here is the code that works for me:
Code:
public void TransmitFile(byte[] file, string fileName)
{
MemoryStream fileStream = new MemoryStream();
fileStream.Write(file, 0, file.Length);
fileStream.Position = 0;
var response = HttpContext.Current.Response;
response.Clear();
response.ClearContent();
response.ClearHeaders();
response.ContentType = @"application/force-download\n";
response.AppendHeader(@"Content-Disposition",
String.Format(@"attachment;filename=""{0}""", fileName));
long bytesToGo;
int bytesRead;
Byte[] buffer = new byte[1048576]; //1 MB buffer, you may want to use whatever fits your environment
bytesToGo = fileStream.Length;
while (bytesToGo > 0)
{
if (response.IsClientConnected)
{
bytesRead = fileStream.Read(buffer, 0, 1048576);
response.OutputStream.Write(buffer, 0, bytesRead);
response.Flush();
bytesToGo -= bytesRead;
if (bytesRead == 0)
{
break; ;
}
}
else
{
bytesToGo = -1;
}
}
fileStream.Close();
response.Flush();
response.End();
}
I want to add to HKLM\init an all purpose application launcher (CE 6.0 device has persistent registry):
Code:
[HKEY_LOCAL_MACHINE\Init]
"Depend199"=hex:00,14,00,1e,00,60
[HKEY_LOCAL_MACHINE\Init]
"Launch199"="\NandFlash\CeLaunchAppsAtBootTime.exe"
[HKEY_CURRENT_USER\Startup]
"Process1"="\NandFlash\SetBackLight.exe"
"Process1Delay"=dword:0
The launcher's code is
Code:
#include <Windows.h>
#if defined(OutputDebugString)
#undef OutputDebugString
void OutputDebugString(LPTSTR lpText)
{}
#endif
BOOL IsAPIReady(DWORD hAPI);
void WalkStartupKeys(void);
DWORD WINAPI ProcessThread(LPVOID lpParameter);
#define MAX_APPSTART_KEYNAME 256
typedef struct _ProcessStruct {
WCHAR szName[MAX_APPSTART_KEYNAME];
DWORD dwDelay;
} PROCESS_STRUCT,*LPPROCESS_STRUCT;
int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
int nLaunchCode = -1;
// Quick check to see whether we were called from within HKLM\init -> by default HKLM\init passes the lauch code
if(lpCmdLine && *lpCmdLine)
{
// MessageBox(NULL, lpCmdLine ,NULL,MB_OK);
nLaunchCode = _ttoi( (const TCHAR *) lpCmdLine);
}
else
{
// MessageBox(NULL, _T("No argumets passed"),NULL,MB_OK);
}
//Wait for system has completely initialized
BOOL success = FALSE;
int i = 0;
while((!IsAPIReady(SH_FILESYS_APIS)) && (i++ < 50))
{
Sleep(200);
}
success = (i < 50);
if(success)
{
i = 0;
while((!IsAPIReady(SH_DEVMGR_APIS))&& (i++ < 50))
{
Sleep(200);
}
success = (i < 50);
if(success)
{
i = 0;
while((!IsAPIReady(SH_SHELL))&& (i++ < 50))
{
Sleep(200);
}
success = (i < 50);
if(success)
{
i = 0;
while((!IsAPIReady(SH_WMGR))&& (i++ < 50))
{
Sleep(200);
}
success = (i < 50);
if(success)
{
i = 0;
while((!IsAPIReady(SH_GDI))&& (i++ < 50))
{
Sleep(200);
}
success = (i < 50);
}
}
}
}
if(nLaunchCode != -1)
{
// Since this is application is launched through the registry HKLM\Init we need to call SignalStarted passing in the command line parameter
SignalStarted((DWORD) nLaunchCode);
}
//If system has completely initialized
if( success)
{
WalkStartupKeys();
}
return (0);
}
void WalkStartupKeys(void)
{
HKEY hKey;
WCHAR szName[MAX_APPSTART_KEYNAME];
WCHAR szVal[MAX_APPSTART_KEYNAME];
WCHAR szDelay[MAX_APPSTART_KEYNAME];
DWORD dwType, dwNameSize, dwValSize, i,dwDelay;
DWORD dwMaxTimeout=0;
HANDLE hWaitThread=NULL;
HANDLE ThreadHandles[100];
int iThreadCount=0;
if (RegOpenKeyEx(HKEY_CURRENT_USER, TEXT("Startup"), 0, KEY_READ, &hKey) != ERROR_SUCCESS) {
return;
}
dwNameSize = MAX_APPSTART_KEYNAME;
dwValSize = MAX_APPSTART_KEYNAME * sizeof(WCHAR);
i = 0;
while (RegEnumValue(hKey, i, szName, &dwNameSize, 0, &dwType,(LPBYTE)szVal, &dwValSize) == ERROR_SUCCESS) {
if ((dwType == REG_SZ) && !wcsncmp(szName, TEXT("Process"), 7)) { // 7 for "Process"
// szval
wsprintf(szDelay,L"%sDelay",szName);
dwValSize=sizeof(dwDelay);
if (ERROR_SUCCESS == RegQueryValueEx(hKey,szDelay,0,&dwType,(LPBYTE)&dwDelay,&dwValSize)) {
// we now have the process name and the process delay - spawn a thread to "Sleep" and then create the process.
LPPROCESS_STRUCT ps=(LPPROCESS_STRUCT) LocalAlloc( LMEM_FIXED , sizeof( PROCESS_STRUCT));
ps->dwDelay=dwDelay;
wcscpy(ps->szName,szVal);
DWORD dwThreadID;
OutputDebugString(L"Creating Thread...\n");
HANDLE hThread=CreateThread(NULL,0,ProcessThread,(LPVOID)ps,0,&dwThreadID);
ThreadHandles[iThreadCount++]=hThread;
if (dwDelay > dwMaxTimeout) {
hWaitThread=hThread;
dwMaxTimeout=dwDelay;
}
LocalFree((HLOCAL) ps);
}
}
dwNameSize = MAX_APPSTART_KEYNAME;
dwValSize = MAX_APPSTART_KEYNAME * sizeof(WCHAR);
i++;
}
// wait on the thread with the longest delay.
DWORD dwWait=WaitForSingleObject(hWaitThread,INFINITE);
if (WAIT_FAILED == dwWait) {
OutputDebugString(L"Wait Failed!\n");
}
for(int x=0;x < iThreadCount;x++) {
CloseHandle(ThreadHandles[x]);
}
RegCloseKey(hKey);
}
DWORD WINAPI ProcessThread(LPVOID lpParameter)
{
TCHAR tcModuleName[MAX_APPSTART_KEYNAME];
OutputDebugString(L"Thread Created... Sleeping\n");
LPPROCESS_STRUCT ps=(LPPROCESS_STRUCT)lpParameter;
Sleep(ps->dwDelay); // Wait for delay period
OutputDebugString(L"Done Sleeping...\n");
PROCESS_INFORMATION pi;
STARTUPINFO si;
si.cb=sizeof(si);
OutputDebugString(L"Creating Process ");
OutputDebugString(ps->szName);
OutputDebugString(L"\n");
wcscpy(tcModuleName,ps->szName);
TCHAR *tcPtrSpace=wcsrchr(ps->szName,L' '); // Launch command has a space, assume command line.
if (NULL != tcPtrSpace) {
tcModuleName[lstrlen(ps->szName)-lstrlen(tcPtrSpace)]=0x00; // overwrite the space with null, break the app and cmd line.
tcPtrSpace++; // move past space character.
}
CreateProcess( tcModuleName, // Module Name
tcPtrSpace, // Command line -- NULL or PTR to command line
NULL, // Process handle not inheritable
NULL, // Thread handle not inheritable
FALSE, // Set handle inheritance to FALSE
0, // No creation flags
NULL, // Use parent's environment block
NULL, // Use parent's starting directory
&si, // Pointer to STARTUPINFO structure
&pi ); // Pointer to PROCESS_INFORMATION structure
OutputDebugString(L"Thread Exiting...\n");
return 0;
}
which compiled errorfree
Added the registry entries as shown above, copied the launcher's exe in default location, rebootet device. Nothing happened, means executable defined as
Code:
[HKEY_CURRENT_USER\Startup]
"Process1"="\NandFlash\SetBackLight.exe"
wasn't run at all.
Does anybody have an idea, where the error is? Any help appreciated. Thanks for reading.
I'm implementing a terminal "emulator"/"launcher" in my app. I want to let the user to use all android shell commands. This works great, until I use the "su" command. here is the source code:
Code:
ProcessBuilder processBuilder = new ProcessBuilder(input);
processBuilder.directory(info.currentDirectory);
Process process;
try {
process = processBuilder.start();
} catch (IOException e) {
return 1;
}
process.waitFor();
InputStream i = process.getInputStream();
InputStream e = process.getErrorStream();
BufferedReader ir = new BufferedReader(new InputStreamReader(i));
BufferedReader er = new BufferedReader(new InputStreamReader(e));
String s = null;
output = "";
for(int count = 0; count == 0 || s != null; count++) {
s = ir.readLine();
if(s != null) {
if(count == 0)
output = output.concat(mContext.getString(R.string.output_label) + "\n");
output = output.concat(s + "\n");
}
}
s = null;
for(int count = 0; count == 0 || s != null; count++) {
s = er.readLine();
if(s != null) {
if(count == 0)
output = output.concat(mContext.getString(R.string.error_label) + "\n");
output = output.concat(s + "\n");
}
}
process.destroy();
Main thread is blocked forever in any case: if I call only process.waitFor, and if I use one of the InputStream objects.
What's the problem? SU permissions are granted normally...