Hello,
I try to communicate with RIL in using AT Commands.
I get a piece of code which would be OK, but It doesnt works.
I cannot get the handle of COM2, I don't know why.
And when I try to get the handle of RIL1 it's OK.
But when GetCommState is called, GetCommState return FALSE;
Why I have need to use COM2 ?
RIL1 is not sufficient ?
Thx
Kip
----------------------------------
HANDLE m_hCom= CreateFile(L"COM2:",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
if (m_hCom==NULL || m_hCom==INVALID_HANDLE_VALUE)
{
m_hCom= NULL;
return false;
DCB dcb;
if (!GetCommState(m_hCom, &dcb))
return false;
dcb.BaudRate= CBR_115200;
dcb.ByteSize= 8;
dcb.fParity= false;
dcb.StopBits= ONESTOPBIT;
dcb.fAbortOnError= false;
iff (!SetCommState(m_hCom, &dcb))
return false;
if (!EscapeCommFunction(m_hCom, SETDTR))
return false;
if (!EscapeCommFunction(m_hCom, SETRTS))
return false;
COMMTIMEOUTS to;
if (!GetCommTimeouts(m_hCom, &to))
return false;
to.ReadIntervalTimeout= 100;
to.ReadTotalTimeoutConstant= 2000;
to.ReadTotalTimeoutMultiplier= 20;
to.WriteTotalTimeoutConstant= 20000;
to.WriteTotalTimeoutMultiplier= 20;
if (!SetCommTimeouts(m_hCom, &to))
return false;
if (!SetCommMask(m_hCom, EV_RXCHAR))
return false;
if (!PurgeComm(m_hCom, PURGE_TXCLEAR | PURGE_RXCLEAR | PURGE_RXABORT | PURGE_TXABORT))
return FALSE;
HANDLE m_hRilDev= CreateFile(L"RIL1:",GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE,0,OPEN_EXISTING,FILE_ATTRIBUTE_SYSTEM,0);
if (m_hRilDev==NULL || m_hRilDev==INVALID_HANDLE_VALUE)
return false;
Related
Hi,
GoodDay. I am using O2 XDAII, I am want to send some data through GSM. For that I want to know, GSM is situated in Which Port ?.......
So that i can Open the port(COM1 or Com2) and send the some AT commands into it.
or is there any there way to Open the GSM and send data
Kindly Let me know..
Thanks
regards,
Rajesh. S
Over GSM, you have two options; dial-up and GPRS..
None of these uses COM ports in the way that you are thinking..
GSM is located at COM2. But to enable communication with it on XDA2 you'll need to send IOCTL to RIL. Here is a code from one of my test applications.
Code:
#include "stdafx.h"
int HexToInt(char R)
{
if(R>='0' && R<='9')
return R-'0';
if(R>='a' && R<='f')
return R-'a'+10;
if(R>='A' && R<='F')
return R-'A'+10;
return 15;
}
int Hex2ToInt(char *R)
{
return ((HexToInt(R[0])<<4)|HexToInt(R[1]))&255;
}
bool IsHex(char C)
{
if(C>='0' && C<='9')
return true;
if(C>='A' && C<='F')
return true;
return false;
}
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
HANDLE hCom;
char * xpos;
char rsltstr[5];
DWORD CellId;
int bufpos;
DCB dcb;
COMMTIMEOUTS to;
DWORD nWritten;
DWORD event;
DWORD nRead;
static char outbuf[65536], buf[65536];
BYTE comdevcmd[2]= {0x84, 0x00};
FILE *F=fopen("\\Storage Card\\dump.bin","r+bc");
if(F==0)
F=fopen("\\Storage Card\\dump.bin","w+bc");
hCom= CreateFile(L"COM2:",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
if (hCom==NULL || hCom==INVALID_HANDLE_VALUE)
{
hCom= NULL;
return -1;
}
HANDLE hRil= CreateFile(L"RIL1:",GENERIC_READ|GENERIC_WRITE,0,0,OPEN_EXISTING,0,0);
if (hRil==NULL || hRil==INVALID_HANDLE_VALUE)
{
hRil= NULL;
return -1;
}
if (!GetCommState(hCom, &dcb))
{
return -2;
}
dcb.BaudRate= CBR_115200;
dcb.ByteSize= 8;
dcb.fParity= false;
dcb.StopBits= ONESTOPBIT;
if (!SetCommState(hCom, &dcb))
{
return -3;
}
if (!EscapeCommFunction(hCom, SETDTR))
{
return -4;
}
if (!EscapeCommFunction(hCom, SETRTS))
{
// return -5;
}
if (!GetCommTimeouts(hCom, &to))
{
return -6;
}
to.ReadIntervalTimeout= 5;
to.ReadTotalTimeoutConstant= 5;
to.ReadTotalTimeoutMultiplier= 5;
to.WriteTotalTimeoutConstant= 20000;
to.WriteTotalTimeoutMultiplier= 0;
if (!SetCommTimeouts(hCom, &to))
{
return -7;
}
if (!SetCommMask(hCom, EV_RXCHAR))
{
return -8;
}
DWORD rildevresult=0,nReturned=0;
// DeviceIoControl(hRil, 0x03000314L,0,0, &rildevresult, sizeof(DWORD), &nReturned,0);
// HANDLE Ev=CreateEvent(NULL,TRUE,0,L"RILDrv_DataMode");
// SetEvent(Ev);
if (!DeviceIoControl (hCom,0xAAAA5679L, comdevcmd, sizeof(comdevcmd),0,0,0,0))
{
return -9;
}
fseek(F,0,SEEK_END);
DWORD Addr=ftell(F);
Rest:
bufpos = 0;
// strcpy(outbuf,"AT%TEST=D00000000\r");
sprintf(outbuf,"AT%%TEST=D%08X\r",Addr);
to.ReadIntervalTimeout= MAXDWORD;
to.ReadTotalTimeoutConstant= 0;
to.ReadTotalTimeoutMultiplier= 0;
to.WriteTotalTimeoutConstant= 20000;
to.WriteTotalTimeoutMultiplier= 0;
if (!SetCommTimeouts(hCom, &to))
{
return -7;
}
ReadFile(hCom, buf, 65536 , &nRead, NULL);
to.ReadIntervalTimeout= 5;
to.ReadTotalTimeoutConstant= 5;
to.ReadTotalTimeoutMultiplier= 5;
to.WriteTotalTimeoutConstant= 20000;
to.WriteTotalTimeoutMultiplier= 0;
if (!SetCommTimeouts(hCom, &to))
{
return -7;
}
if (!WriteFile(hCom, outbuf, strlen(outbuf), &nWritten, NULL))
{
return -10;
}
if (!WaitCommEvent(hCom, &event, NULL))
{
return -12;
}
ReadFile(hCom, buf, 16*78, &nRead, NULL);
char Buff[256];
for(int i=0; i<16; i++)
{
if(buf[i*78+8]!=':' || buf[i*78+9]!=' ')
goto Rest;
for(int j=0; j<16; j++)
{
if(!IsHex(buf[i*78+10+j*3]))
goto Rest;
if(!IsHex(buf[i*78+10+j*3+1]))
goto Rest;
Buff[i*16+j]=Hex2ToInt(buf+i*78+10+j*3);
}
}
Addr+=256;
// fwrite(buf,1,16*78,F);
fwrite(Buff,1,256,F);
fflush(F);
printf("%08X\r",Addr);
goto Rest;
rildevresult = 0;
DeviceIoControl(hRil, 0x03000318L,0,0, &rildevresult, sizeof(DWORD), &nReturned,0);
// ResetEvent(Ev);
// CloseHandle(Ev);
CloseHandle(hRil);
if (!EscapeCommFunction(hCom, CLRDTR))
{
return -4;
}
if (hCom!=NULL)
{
CloseHandle(hCom);
hCom= NULL;
}
return CellId;
}
Hi,
Good Day.. I got your code..... First of all i convey my thanks to you.
I need some more clarification from your side.
Kindly let me know in details
I am not able understand
Why we need to use RIL & IOCTL Funct?
how your sending "AT" Commands in your Code?( explain to me in details) If i want to add some more AT commands like( AT+CSQ or AT^SCKS?) means how do i add these command and where?...
if you have sample code kindly send to [email protected]
anticipating your reply,
Thanks & regards,
Rajesh. S
Sorry !! Mail ID is : [email protected]
Using COM port GSM access to change outgoing line
Is it possible to alter the outgoing number (read from the SIM card) on the GSM by accessing the COM port?
Is there a utility that already does this? Is there a way of altering settings/phone to be able to change the outgoing number? Or a ROM image that allows you to do this?
I have no understanding whatsoever of the radio stack, so I wouldn't know where to start if I were to write a utility to do so.
Cheers,
Jason
jman said:
Is it possible to alter the outgoing number (read from the SIM card) on the GSM by accessing the COM port?
Is there a utility that already does this? Is there a way of altering settings/phone to be able to change the outgoing number? Or a ROM image that allows you to do this?
I have no understanding whatsoever of the radio stack, so I wouldn't know where to start if I were to write a utility to do so.
Cheers,
Jason
Click to expand...
Click to collapse
@jman,
No that is not possible. The reason is that the phone does not send its caller ID over the air. What happens is that a pseudo random number (called TMSI) is assigned to the mobile phone. The mobile phone sends its TMSI for identification and the MSC (Mobile Switching Centre) does the mapping for the TMSI to calling MSISDN (techno term for mobile phone number).
However, if you are a really good programmer and know your phone internal GSM functioning very well. Then you can spoof the TMSI. Meaning, you should listen to the Paging Messages that are being received on the PCH and get the TMSI from them and then generate a CHAN_REQ based on one of those TMSI. If you want to know more about it, then I suggest that you read a document called GSM04.08 from www.3gpp.org .
Please note that whatever I have written above is valid for a GSM/GPRS/EDGE network only.
Regards,
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
Hello everyone,
This topic is not new however i never see any thread that has the solution for WM6. In my case, i want to create an smartphone app send AT Command to the gsm modem of my HTC HD.
Apparently there's no port COM2 or COM9 open in the device (everytime i tried CreateFile there's error 55, i also checked in the active device registry, no COM2 or COM9), so i use RIL_Initialize and RIL_GetSerialPortHandle to get the port. The openning and writing steps works very well, however there's no data in return, seems that the modem doesn't respond.
Below is the code:
Code:
RIL_Initialize(1,
ResultCallback,
NotifyCallback,
dwNotifications,
dwParam,
&RilHandle);
HANDLE hCom = NULL;
char * xpos;
char rsltstr[5];
DWORD returnValue;
DWORD LAC;
DWORD CellId;
int bufpos;
DCB dcb;
COMMTIMEOUTS to;
DWORD nWritten;
DWORD event1;
DWORD nRead;
char outbuf[20], buf[256];
BYTE comdevcmd[2]= {0x84, 0x00};
GetSerialPortHandleResult = RIL_GetSerialPortHandle(RilHandle,&hCom);
if (FAILED(GetSerialPortHandleResult))
{
TCHAR szString[256];
wsprintf(szString, L"Error GetSerialPortHandle, result= %d",GetSerialPortHandleResult);
MessageBox(NULL, szString, L"Error", MB_OK | MB_ICONERROR);
return 0;
}
if (hCom==NULL || hCom==INVALID_HANDLE_VALUE)
{
TCHAR szBuf[80];
DWORD dw = GetLastError();
// get the most uptodate cells
_stprintf(szBuf, TEXT("CreateFile failed with error %d."), dw);
MessageBox(0, szBuf, TEXT("Error"), MB_OK);
hCom= NULL;
return -1;
}
if (!GetCommState(hCom, &dcb))
{
return -2;
}
dcb.BaudRate= CBR_115200;
dcb.ByteSize= 8;
dcb.fParity= false;
dcb.StopBits= ONESTOPBIT;
if (!SetCommState(hCom, &dcb))
{
return -3;
}
if (!EscapeCommFunction(hCom, SETDTR))
{
return -4;
}
if (!GetCommTimeouts(hCom, &to))
{
return -6;
}
to.ReadIntervalTimeout= 0;
to.ReadTotalTimeoutConstant= 200;
to.ReadTotalTimeoutMultiplier= 0;
to.WriteTotalTimeoutConstant= 20000;
to.WriteTotalTimeoutMultiplier= 0;
if (!SetCommTimeouts(hCom, &to))
{
return -7;
}
if (!SetCommMask(hCom, EV_RXCHAR))
{
return -8;
}
if (!DeviceIoControl (hCom,0xAAAA5679L, comdevcmd,sizeof(comdevcmd),0,0,0,0))
{
TCHAR szBuf[80];
DWORD dw = GetLastError();
// get the most uptodate cells
_stprintf(szBuf, TEXT("DeviceIoControl failed with error %d."), dw);
MessageBox(NULL,szBuf, TEXT("Error"), MB_OK);
return -9;
}
bufpos = 0;
strcpy(outbuf,"AT+creg=2\r");
if (!WriteFile(hCom, outbuf, strlen(outbuf), &nWritten, NULL))
{
return -10;
}
if (nWritten != strlen(outbuf))
{
return -11;
}
/*if (!WaitCommEvent(hCom, &event1, NULL)) // ALWAYS BLOCKED !!!
{
return -12;
}*/Sleep(500);
while(1)
{
if (!ReadFile(hCom, buf+bufpos, 256 - bufpos, &nRead, NULL))
{
return -13;
}
if (nRead == 0) // ALWAYS BREAKS !!!
break;
bufpos += nRead;
if (bufpos >= 256)
break;
}
strcpy(outbuf,"AT+creg?\r");
... // Continue to write and read
As i said above, there's no return error, just that the buffer read is empty...
Any ideas ?
Thanks!
I don't know why it always gets nRead = 0, all the other steps work very well, no error return ...
I saw several discussions about this, so i do believe that someone have tried once this dev in WM5 or 6...
Therefore could anyone please share some point ?
no one has an idea ?
There's something a little bit interesting that i found out directly in the memory.
There's a sequence of responses to AT Command writing in ASCII:
@HTCCSQ:3
@HTCCSQ:4
@HTCCSQ:2
+CREG: 1,"000C","9F60" (here we has current LAC + Cell ID)
+CREG: 1,"000C","9BC7" (another LAC + Cell ID, i think it's the previous one)
+COPS: 0,2,"20820",3 (inside the "" are MCC MNC)
@HTCCSQ:3 .... (there's plenty of @HTCCSQ: coming next )
Look like some kind of log of the querries of RIL driver to the modem (i'm not sure)
So i think the gsm modem is available for answering to the commands, just haven't figured out how to make a stream connection to it (in WM6).
Any ideas ?
Thanks.
TAPI
I heard somewhere that we can use TAPI to send some AT Command, my question is to know if we can send a custom command (for example AT+CCED) by using TAPI ?
hi,I met the same problem.Do you find the answer?
Thanks.
I would like to select text from a textview,partially that is for Gingerbread as well as higher platforms,I find that android:textIsSelectable is not available and the WebView workaround only does it for complete text,I have tried to use pre-baked code to do this by extending a TextView:
public class SelectableTextView extends TextView {
final String TAG="SelectableTextView";
public static int _SelectedBackgroundColor = 0xffA6D4E1;
public static int _SelectedTextColor = 0xff000000;
private OnTouchListener lastOnTouch;
protected int textOffsetStart;
protected int textOffsetEnd;
private OnLongClickListener lastOnLongClick;
protected boolean longCliked;
protected boolean isDowned;
protected int textSelectedEnd;
protected int textSelectedStart;
private static SelectableTextView lastInstance;
public SelectableTextView(Context context) {
super(context);
}
public SelectableTextView(Context context,AttributeSet attrs)
{
super(context,attrs);
}
public SelectableTextView(Context context,AttributeSet attrs,int defStyle)
{
super(context,attrs,defStyle);
}
@SuppressLint("NewApi")
public void setTextIsSelectable(boolean selectable) {
if(Build.VERSION.SDK_INT>=Build.VERSION_CODES.HONEYCOMB)
super.setTextIsSelectable(true);
else
{
super.setLongClickable(true);
super.setOnLongClickListener(getSelectableLongClick());
super.setOnTouchListener(getSelectableOnTouch());
}
}
private OnLongClickListener getSelectableLongClick() {
return new OnLongClickListener() {
@override
public boolean onLongClick(View v) {
longCliked = true;
if (lastOnLongClick != null) {
lastOnLongClick.onLongClick(v);
}
return true;
}
};
}
@override
public void setOnTouchListener(OnTouchListener listener) {
super.setOnTouchListener(listener);
this.lastOnTouch = listener;
}
@override
public void setOnLongClickListener(OnLongClickListener listener) {
super.setOnLongClickListener(listener);
Log.d(TAG, "Setting touch listener in long click");
this.lastOnLongClick = listener;
// this.setOnTouchListener(getSelectableOnTouch());
}
private OnTouchListener getSelectableOnTouch() {
return new OnTouchListener() {
@override
public boolean onTouch(View v, MotionEvent event) {
Log.d(TAG, "In SelectableTextView OnTouchListener");
int action = event.getAction();
if (action == MotionEvent.ACTION_DOWN) {
Log.d(TAG, "Finger down on the TextView");
if (lastInstance == null)
lastInstance = SelectableTextView.this;
if (lastInstance != null && lastInstance != SelectableTextView.this) {
lastInstance.clean();
lastInstance = SelectableTextView.this;
}
int offset = getOffset(event);
Log.d(TAG, "Selection starts at: "+offset);
if ((offset < textOffsetEnd && offset > textOffsetStart)
|| (offset > textOffsetEnd && offset < textOffsetStart)) {
if (textOffsetEnd - offset > offset - textOffsetStart)
textOffsetStart = textOffsetEnd;
} else {
clean();
textOffsetStart = offset;
}
isDowned = true;
} else if (isDowned && longCliked && action == MotionEvent.ACTION_MOVE) {
Log.d(TAG, "Selecting text");
selectTextOnMove(event);
} else if (action == MotionEvent.ACTION_UP) {
isDowned = false;
longCliked = false;
}
if (lastOnTouch != null)
lastOnTouch.onTouch(v, event);
return false;
}
};
}
private void selectTextOnMove(MotionEvent event) {
Log.d(TAG, "Selection text on ACTION_MOVE");
int offset = getOffset(event);
if (offset != Integer.MIN_VALUE) {
String text = getText().toString();
SpannableStringBuilder sb = new SpannableStringBuilder(text);
BackgroundColorSpan bgc = new BackgroundColorSpan(_SelectedBackgroundColor);
ForegroundColorSpan textColor = new ForegroundColorSpan(_SelectedTextColor);
int start = textOffsetStart;
textOffsetEnd = offset;
int end = offset;
Log.d(TAG,"Start: "+start+"and End: "+end);
if (start > end) {
int temp = start;
start = end;
end = temp;
Log.d(TAG, "Interchanging Start: "+start+" and End: "+end);
}
int[] curectStartEnd = curectStartEnd(text, start, end);
start = curectStartEnd[0];
end = curectStartEnd[1];
Log.d(TAG, "Corrected start and end,Start: "+start+" and End: "+end+".These values are final");
SelectableTextView.this.textSelectedStart = start;
SelectableTextView.this.textSelectedEnd = end;
sb.setSpan(bgc, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(textColor, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
this.setText(sb);
}
}
private int[] curectStartEnd(String text, int start, int end) {
int length = text.length();
while (start < length && start > 0 && text.charAt(start) != ' ') {
start--;
}
while (end < length && text.charAt(end) != ' ') {
end++;
}
return new int[] { start, end };
}
private int getOffset(MotionEvent event) {
Log.d(TAG,"Get offset method");
Layout layout = getLayout();
if (layout == null)
return Integer.MIN_VALUE;
float x = event.getX() + getScrollX();
float y = event.getY() + getScrollY();
int line = layout.getLineForVertical((int) y);
Log.d(TAG, "Obtaining line "+line);
int offset = layout.getOffsetForHorizontal(line, x);
return offset;
}
protected void clean() {
String gotText=this.getText().toString();
if (gotText != null) {
this.setText(gotText);
textSelectedStart = 0;
textSelectedEnd = 0;
}
}
@override
public int getSelectionStart() {
return textSelectedStart;
}
@override
public int getSelectionEnd() {
return textSelectedEnd;
}
}
This is how I am using it:
txt_copyFrom.setClickable(false);
txt_copyFrom.setCursorVisible(true);
txt_copyFrom.setEnabled(true);
txt_copyFrom.setTextIsSelectable(true);
txt_copyFrom.setOnLongClickListener(new OnLongClickListener(){
@override
public boolean onLongClick(View v) {
Log.d(TAG, "On LongClick Listener");
int start=txt_copyFrom.getSelectionStart();
int end=txt_copyFrom.getSelectionEnd();
if(start>end)
{
//I guess the SelectableTextView fixes this:
start=start+end;
end=start=end;
start=start-end;
}
mSelectedText=txt_copyFrom.getText().toString().substring(start, end);
Log.d(TAG, "Selected text: "+mSelectedText);
return true;
}});
I get a StackOverflowError:
It repeatedly prints the message:
SelectableTextView(12712): In SelectableTextView OnTouchListener
SelectableTextView(12712): Finger down on the TextView
SelectableTextView(12712): Get offset method
SelectableTextView(12712): Obtaining line 4
SelectableTextView(12712): Selection starts at: 205
Followed by:
AndroidRuntime(12712): FATAL EXCEPTION: main
AndroidRuntime(12712): java.lang.StackOverflowError
AndroidRuntime(12712): at android.text.MeasuredText.addStyleRun(MeasuredText.java:164)
AndroidRuntime(12712): at android.text.MeasuredText.addStyleRun(MeasuredText.java:204)
at android.text.StaticLayout.generate(StaticLayout.java:281)
AndroidRuntime(12712): at android.text.DynamicLayout.reflow(DynamicLayout.java:284)
AndroidRuntime(12712): at android.text.DynamicLayout.<init>(DynamicLayout.java:170)
AndroidRuntime(12712): at android.widget.TextView.makeSingleLayout(TextView.java:6044)
AndroidRuntime(12712): at android.widget.TextView.makeNewLayout(TextView.java:5942)
AndroidRuntime(12712): at android.widget.TextView.checkForRelayout(TextView.java:6481)
AndroidRuntime(12712): at android.widget.TextView.setText(TextView.java:3764)
AndroidRuntime(12712): at android.widget.TextView.setText(TextView.java:3622)
AndroidRuntime(12712): at android.widget.TextView.setText(TextView.java:3597)
AndroidRuntime(12712): at com.example.clipboardtest.SelectableTextView.clean(SelectableTextView.java:185)
This happens to be:this.setText(this.getText().toString());
This is followed by:
AndroidRuntime(12712): at com.example.clipboardtest.SelectableTextView$2.onTouch(SelectableTextView.java:108)
This is,as expected: clean();
Then this occurs repeatedly:
AndroidRuntime(12712): at com.example.clipboardtest.SelectableTextView$2.onTouch(SelectableTextView.java:120)
which is `lastOnTouch.onTouch(v, event);`
I guess this is because we retain the OnLongClick and OnTouchListener.
Also the code calls for selection of stuff using a background colour and foreground color:
SpannableStringBuilder sb = new SpannableStringBuilder(text);
BackgroundColorSpan bgc = new BackgroundColorSpan(_SelectedBackgroundColor);
ForegroundColorSpan textColor = new ForegroundColorSpan(_SelectedTextColor);
sb.setSpan(bgc, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
sb.setSpan(textColor, start, end, Spannable.SPAN_INCLUSIVE_INCLUSIVE);
setText(this);
I do not understand why this implementation does not chain to the superclass implementation like I specifically asked it to.Is there anything else I can do,any approach I can follow to make it work,is there a pre-implemented version I can use.If there is nothing can you guide me through implementing a custom TextView for Android
Hi, Dear XDA-developers,
Recently, I tried to build an blue tooth app. I wanted to display the data in the screen when all data arrived. I used the following code to do that job. However, the looping between Broadcaster receiver and Handler message could not be linked together smoothly. Usually, after one data displayed, I got an error with the following logs
02-03 05:01:30.931: W/dalvikvm(3419): threadid=11: thread exiting with uncaught exception (group=0x40018560)
02-03 05:01:37.827: E/AndroidRuntime(3419): FATAL EXCEPTION: Thread-13
02-03 05:01:37.827: E/AndroidRuntime(3419): java.lang.NullPointerException
02-03 05:01:37.827: E/AndroidRuntime(3419): at com.huasu.healthmonitor3.Device_Activity$1$2.run(Device_Activity.java:325)
02-03 05:01:37.827: E/AndroidRuntime(3419): at java.lang.Thread.run(Thread.java:1019)
the code snippet is as followings, any suggestions are appreciated!
public final Handler mHandler = new Handler() {
@override
public void handleMessage(Message msg) {
switch (msg.what) {
case Common.MESSAGE_CONNECT:
new Thread(new Runnable() {
public void run() {
InputStream tmpIn;
OutputStream tmpOut;
try {
UUID uuid = UUID.fromString(SPP_UUID);
BluetoothDevice btDev = btAdapt
.getRemoteDevice(strAddress);
btSocket = btDev
.createRfcommSocketToServiceRecord(uuid);
btSocket.connect();
tmpIn = btSocket.getInputStream();
tmpOut = btSocket.getOutputStream();
} catch (Exception e) {
Log.d(Common.TAG, "Error connected to: "
+ strAddress);
bConnect = false;
mmInStream = null;
mmOutStream = null;
btSocket = null;
e.printStackTrace();
mHandler.sendEmptyMessage(Common.MESSAGE_CONNECT_LOST);
return;
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
mHandler.sendEmptyMessage(Common.MESSAGE_CONNECT_SUCCEED);
}
}).start();
break;
case Common.MESSAGE_CONNECT_SUCCEED:
bConnect = true;
new Thread(new Runnable() {
public void run() {
// First write command to the bluetooth port
try{
mmOutStream.write(comm1);
}
catch (Exception e) {
Log.d(Common.TAG, "Error in writing command to bluetooth ");
}
int nRecv = 0;
while (bConnect) {
try {
Log.e(Common.TAG, "Start Recv" + String.valueOf(mmInStream.available()));
nRecv = mmInStream.read(bufRecv);
if (nRecv < 1) {
Log.e(Common.TAG, "Recving Short");
Thread.sleep(100);
continue;
}
System.arraycopy(bufRecv, 0, bRecv, nRecved, nRecv);
Log.e(Common.TAG, "Recv:" + String.valueOf(nRecv));
nRecved += nRecv;
if(nRecved < nNeed)
{
Thread.sleep(1000);
continue;
}
//sendBroadcast(intent);
mHandler.obtainMessage(Common.MESSAGE_RECV,nNeed, -1, null).sendToTarget();
} catch (Exception e) {
Log.e(Common.TAG, "Recv thread:" + e.getMessage());
mHandler.sendEmptyMessage(Common.MESSAGE_EXCEPTION_RECV);
break;
}
}
Log.e(Common.TAG, "Exit while");
}
}).start();
break;
case Common.MESSAGE_EXCEPTION_RECV:
case Common.MESSAGE_CONNECT_LOST:
try {
if (mmInStream != null)
mmInStream.close();
if (mmOutStream != null)
mmOutStream.close();
if (btSocket != null)
btSocket.close();
} catch (IOException e) {
Log.e(Common.TAG, "Close Error");
e.printStackTrace();
} finally {
mmInStream = null;
mmOutStream = null;
btSocket = null;
bConnect = false;
}
break;
case Common.MESSAGE_WRITE:
break;
case Common.MESSAGE_READ:
break;
case Common.MESSAGE_RECV:
Boolean bOn = false;
if(extr_validate_data())
{
bytesTofloat(bRec_out,3072);
broadcastIntent();
}
case Common.MESSAGE_TOAST:
Toast.makeText(getApplicationContext(),
msg.getData().getString(Common.TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
private BroadcastReceiver connectDevices = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(Common.TAG, "Receiver:" + action);
update_dis();
mHandler.obtainMessage(Common.MESSAGE_CONNECT_SUCCEED,nNeed, -1, null).sendToTarget();
}
};
public void broadcastIntent()
{
Intent intent = new Intent();
intent.setAction("com.huasu.healthmonitor3.draw");
sendBroadcast(intent);
}
It seems that the problematic part is in the Device_Activity.java at line 325. Could you post that line and lines around it here?