I am using the below code to get the call log details which is working very fine for single SIM device, but the problem arises when it comes to the DUAL sim. I am trying to find work around for getting logs from dual sim device.
/**
* Get All Call Logs details as JSON
*
* @param context
*/
@SuppressLint("SimpleDateFormat")
private void getInitialCallDetailsAsJSON() {
// Print dates of the current week starting on Monday
DateFormat df = new SimpleDateFormat("dd-MMM-yyyy hh:mm aa",
Locale.getDefault());
final Uri contacts = CallLog.Calls.CONTENT_URI;
final Cursor managedCursor = getContentResolver().query(contacts, null,
null, null, null);
final int name = managedCursor
.getColumnIndex(CallLog.Calls.CACHED_NAME);
final int number = managedCursor.getColumnIndex(CallLog.Calls.NUMBER);
final int type = managedCursor.getColumnIndex(CallLog.Calls.TYPE);
final int date = managedCursor.getColumnIndex(CallLog.Calls.DATE);
final int durationOfCall = managedCursor
.getColumnIndex(CallLog.Calls.DURATION);
final JSONObject allDetailsJsonObject = new JSONObject();
final JSONArray array = new JSONArray();
if (managedCursor != null && managedCursor.getCount() > 0) {
while (managedCursor.moveToNext()) {
String contactName = managedCursor.getString(name);
final String phoneNumber = managedCursor.getString(number);
final String callTypeIndex = managedCursor.getString(type);
final String callDate = managedCursor.getString(date);
final String callDurationSeconds = managedCursor
.getString(durationOfCall);
final int totalTime = Integer.parseInt(callDurationSeconds);
int day = (int) TimeUnit.SECONDS.toDays(totalTime);
long hours = TimeUnit.SECONDS.toHours(totalTime) - (day * 24);
long minute = TimeUnit.SECONDS.toMinutes(totalTime)
- (TimeUnit.SECONDS.toHours(totalTime) * 60);
long second = TimeUnit.SECONDS.toSeconds(totalTime)
- (TimeUnit.SECONDS.toMinutes(totalTime) * 60);
String callDurationFormatted = "";
if (hours < 10) {
callDurationFormatted += "0" + hours + "h ";
} else {
callDurationFormatted += hours + "h ";
}
if (minute < 10) {
callDurationFormatted += "0" + minute + "m ";
} else {
callDurationFormatted += minute + "m ";
}
if (second < 10) {
callDurationFormatted += "0" + second + "s";
} else {
callDurationFormatted += second + "s";
}
String callType = null;
final int dircode = Integer.parseInt(callTypeIndex);
switch (dircode) {
case CallLog.Calls.OUTGOING_TYPE:
callType = CallAnalyticsConstant.OUTGOING;
break;
case CallLog.Calls.INCOMING_TYPE:
callType = CallAnalyticsConstant.INCOMING;
break;
case CallLog.Calls.MISSED_TYPE:
callType = CallAnalyticsConstant.MISSED;
break;
}
if (contactName == null || contactName.equalsIgnoreCase("")) {
contactName = "UNKNOWN";
}
}
managedCursor.close();
}
If anyone having any idea please kindly help me to get call related details for dual sim phones.
APP which is working fine for dual sim phone as well - CALL LOG MONITOR
Related
As IE, MSN, when it launches, it creates a GPRS connection to Internet automaticly.
How can I do such thing in my own program in eVC 4.0 ?
Thanks.
All right.
No one answers my question, so I do it by myself. :evil:
Code:
#include <windows.h>
#include <winsock.h>
#if (WIN32_PLATFORM_PSPC>300 || WIN32_PLATFORM_WFSP )
#include <objbase.h>
#include <initguid.h>
#include <connmgr.h>
typedef HRESULT(*CONNMGRCONNECTIONSTATUS) (HANDLE hConnection,
DWORD * pdwStatus);
typedef HRESULT(*CONNMGRRELEASECONNECTION) (HANDLE hConnection,
LONG lCache);
typedef HRESULT(*CONNMGRESTABLISHCONNECTION) (CONNMGR_CONNECTIONINFO *
pConnInfo,
HANDLE * phConnection,
DWORD dwTimeout,
DWORD * pdwStatus);
#endif
HANDLE phWebConnection;
BOOL EstablishDatacall(TCHAR * IPout);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
// TODO: Place code here.
TCHAR MyIP[20];
if (EstablishDatacall(MyIP) == TRUE) {
TCHAR Message[255];
wsprintf(Message, L"IP: %s", MyIP);
MessageBox(NULL, Message, L"Success", MB_OK);
} else {
MessageBox(NULL,
L"Data call could not be established or has been established",
L"Information", MB_OK);
}
return 0;
}
BOOL EstablishDatacall(TCHAR * IPout)
{
CHAR szHostname[255];
TCHAR IP[17];
HOSTENT *pHostEnt = NULL;
int nAdapter = 0;
IN_ADDR *tsim = NULL;
BOOL tried2Connect = FALSE;
IP[0] = 0; // Clear the IP Address
if (IPout != NULL) {
IPout[0] = 0;
}
tryagain:
nAdapter = 0;
gethostname(szHostname, sizeof(szHostname));
pHostEnt = gethostbyname(szHostname);
while (pHostEnt != NULL && pHostEnt->h_addr_list[nAdapter]) {
// in case a device has multiple ethernet cards
// i.e. 802.11, Bluetooth, USB-Cradle
// we need to go though all pHostEnt->h_addr_list[nAdapter]
tsim = (IN_ADDR *) pHostEnt->h_addr_list[nAdapter];
if (IPout != NULL) {
wsprintf(IPout, TEXT("%d.%d.%d.%d"),
tsim->S_un.S_un_b.s_b1,
tsim->S_un.S_un_b.s_b2,
tsim->S_un.S_un_b.s_b3, tsim->S_un.S_un_b.s_b4);
}
if (tsim->S_un.S_un_b.s_b1 == 192 ||
tsim->S_un.S_un_b.s_b1 == 169 ||
tsim->S_un.S_un_b.s_b1 == 127 || tsim->S_un.S_un_b.s_b1 == 255) {
// If you want to make sure you have a real Internet
// connection you cannot bet on IpAddresses starting with
// 127 and 255. 192 and 169 are local IP addresses and
// might be routed or proxied
nAdapter++;
} else {
wsprintf(IP, TEXT("%d.%d.%d.%d"),
tsim->S_un.S_un_b.s_b1,
tsim->S_un.S_un_b.s_b2,
tsim->S_un.S_un_b.s_b3, tsim->S_un.S_un_b.s_b4);
break;
}
}
// the next lines only work with Pocket PC Phone
// and Smartphone
#if (WIN32_PLATFORM_PSPC>300 || WIN32_PLATFORM_WFSP )
// Pocket PC Phone Edition has set WIN32_PLATFORM_PSPC to 310
if (IP[0] == 0 && tried2Connect == FALSE) {
CONNMGRCONNECTIONSTATUS g_hConnMgrConnectionStatus = NULL;
CONNMGRESTABLISHCONNECTION g_hConnMgrEstablishConnectionSync =
NULL;
// It is good practice to load the cellcore.dll
// dynamically to be able to compile the code even for
// older platforms
HINSTANCE hcellDll = LoadLibrary(TEXT("cellcore.dll"));
if (hcellDll) {
// We need the Status and a call to establish the
// connection
g_hConnMgrConnectionStatus =
(CONNMGRCONNECTIONSTATUS) GetProcAddress(hcellDll,
TEXT
("ConnMgrConnectionStatus"));
// The next line is just for debugging. You will have
// to decide what you want to do if this call fails
DWORD a = GetLastError();
g_hConnMgrEstablishConnectionSync =
(CONNMGRESTABLISHCONNECTION) GetProcAddress(hcellDll,
TEXT
("ConnMgrEstablishConnectionSync"));
//a = GetLastError();
// Here comes the main code:
// First we check if we might have a connection
DWORD pdwStatus;
(*g_hConnMgrConnectionStatus) (&phWebConnection, &pdwStatus);
if (pdwStatus == CONNMGR_STATUS_CONNECTED) {
//We are already connected!
//This code should never run since we should
//have a valid IP already.
//If you still get here, you probably have
//stale connection.
return TRUE;
} else {
//We are not connected, so lets try:
//The CONNECTIONINFO is the structure that
//tells Connection Manager how we want
//to connect
CONNMGR_CONNECTIONINFO sConInfo;
memset(&sConInfo, 0, sizeof(CONNMGR_CONNECTIONINFO));
sConInfo.cbSize = sizeof(CONNMGR_CONNECTIONINFO);
// We want to use the guidDestNet parameter
sConInfo.dwParams = CONNMGR_PARAM_GUIDDESTNET;
// This is the highest data priority.
sConInfo.dwPriority = CONNMGR_PRIORITY_USERINTERACTIVE;
sConInfo.dwFlags = 0;
// Lets be nice and share the connection with
// other applications
sConInfo.bExclusive = FALSE;
sConInfo.bDisabled = FALSE;
sConInfo.guidDestNet = IID_DestNetInternet;
// We want to wait until the connection was
// established successful but not longer then
// 60 seconds. You can use
// ConnMgrEstablishConnection to establish
// an asynchronous connection.
if ((*g_hConnMgrEstablishConnectionSync)
(&sConInfo, &phWebConnection, 60000,
&pdwStatus) == S_OK) {
//We are successfully connected!
//Now lets try to get the new IP address
tried2Connect = TRUE;
goto tryagain;
} else {
tried2Connect = FALSE;
//Doh! Connection failed!
}
}
}
}
#endif
return tried2Connect;
}
Hey guys,
I have spent at least 24 hours trying to figure this out by myself and still havn't been able to...so I broke down and came here.
This code works...it does not (9/10s sure here...) run asyn and receives the same number of bytes as the picture should have
Code:
class ClientThread implements Runnable {
@TargetApi(Build.VERSION_CODES.GINGERBREAD)
public void run() {
while(true){
try {
int bytesRead;
int totalBytes = 0;
byte[] pic = new byte[1024];
byte[] inputPic_bytes = new byte[5000000];
DataInputStream dis;
DataOutputStream dos;
try {
dis = new DataInputStream(socket.getInputStream());
dos = new DataOutputStream(socket.getOutputStream());
dos.writeBytes("snapshot" + '\n');
int pic_size = Integer.parseInt(dis.readLine());
Log.e("TCP", "Pic size: " + pic_size);
while (totalBytes < pic_size){
bytesRead = dis.read(pic);
System.arraycopy(pic, 0, inputPic_bytes, totalBytes, bytesRead);
totalBytes += bytesRead;
pic[0] = (byte) (pic[0]&0xFF);
Log.e("TCP", "Read bytes: " + bytesRead + " Total bytes: " + totalBytes + " Bytes: " + pic[0] + " " + pic[1] + " " + pic[2]);
}
this code runs async and receives ~5k more bytes than the picture size which does not even seem possible to me (read_mode = 2 gets the pic)
Code:
protected Boolean doInBackground(Void... params) { //This runs on a different thread
boolean result = false;
try {
//create a new socket instance
SocketAddress sockaddr = new InetSocketAddress("192.168.0.5", 50007);
nsocket = new Socket();
nsocket.connect(sockaddr, 5000);//connect and set a 10 second connection timeout
if (nsocket.isConnected()) {//when connected
nis = new DataInputStream(nsocket.getInputStream());
nos = nsocket.getOutputStream();//and output stream from the socket
Log.e("Buffer Size", "Size: " + nsocket.getReceiveBufferSize());
networktask.SendDataToNetwork("sensors");
while(true){//while connected
if(read_mode == 0){
String getPicLength = nis.readLine();//read the lines coming from the socket
byte[] array_getPicLength = getPicLength.getBytes();
publishProgress(array_getPicLength);//update the publishProgress
Log.e("While_Count_0", "Count");
read_mode = 0;
}
else if(read_mode == 1){
String getPicLength = nis.readLine();//read the lines coming from the socket
byte[] array_getPicLength = getPicLength.getBytes();
publishProgress(array_getPicLength);//update the publishProgress
Log.e("While_Count_1", "Count");
read_mode = 2;
}
else if(read_mode == 2){
nis.read(pic);
publishProgress(pic);//update the publishProgress
}
}
}
Not sure if I have included enough info here...but this is seriously troubling me as I used to have it working.
What is so different about async that it is causing to receive so many extra bytes of "picture" data?
Thanks all...this is really bothering me.
hi, its killing me i can't fix it i made this thing because i was learning Canvas and drawing on android !
i included moving animations (smooth) but i removed it
Code:
package com.example.graphics;
import android.content.Context;
import android.view.KeyEvent;
import android.view.MotionEvent;
import java.util.Formatter;
import android.graphics.Typeface;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.view.View;
public class BouncingBallView extends View {
private int xMin = 0; // This view's bounds
private int xMax;
private int yMin = 0;
private int yMax;
private float ballRadius = 80; // Ball's radius
private float ballX = ballRadius + 20; // Ball's center (x,y)
private float ballY = ballRadius + 40;
private float ballSpeedX = 11; // Ball's speed (x,y)
private float ballSpeedY = 7;
//private RectF ballBounds; // Needed for Canvas.drawOval
private Paint paint; // The paint (e.g. style, color) used for drawing
// Status message to show Ball's (x,y) position and speed.
private StringBuilder statusMsg = new StringBuilder();
private Formatter formatter = new Formatter(statusMsg); // Formatting the statusMsg
private float previousX;
private float previousY;
private float currentX;
private float currentY;
private float scale;
private int ifdrawcount = 0;
// Constructor
public BouncingBallView(Context context) {
super(context);
//ballBounds = new RectF();
paint = new Paint();
paint.setTypeface(Typeface.MONOSPACE);
paint.setTextSize(25);
setFocusableInTouchMode(true);
//setFocusable(true);
requestFocus();
}
/*public boolean onKeyUp(int keyCode, KeyEvent event) {
switch (keyCode) {
case KeyEvent.KEYCODE_DPAD_RIGHT: // Increase rightward speed
ballSpeedX++;
break;
case KeyEvent.KEYCODE_DPAD_LEFT: // Increase leftward speed
ballSpeedX--;
break;
case KeyEvent.KEYCODE_DPAD_UP: // Increase upward speed
ballSpeedY--;
break;
case KeyEvent.KEYCODE_DPAD_DOWN: // Increase downward speed
ballSpeedY++;
break;
case KeyEvent.KEYCODE_DPAD_CENTER: // Stop
ballSpeedX = 0;
ballSpeedY = 0;
break;
case KeyEvent.KEYCODE_A: // Zoom in
// Max radius is about 90% of half of the smaller dimension
float maxRadius = (xMax > yMax) ? yMax / 2 * 0.9f : xMax / 2 * 0.9f;
if (ballRadius < maxRadius) {
ballRadius *= 1.05; // Increase radius by 5%
}
break;
case KeyEvent.KEYCODE_Z: // Zoom out
if (ballRadius > 20) { // Minimum radius
ballRadius *= 0.95; // Decrease radius by 5%
}
break;
}
return true; // Event handled
}*/
// Called back to draw the view. Also called by invalidate().
@Override
protected void onDraw(Canvas canvas) {
// Draw the ball
//ballBounds.set(ballX-ballRadius, ballY-ballRadius, ballX+ballRadius, ballY+ballRadius);
//paint.setColor(Color.GRAY);
//canvas.drawOval(ballBounds, paint);
//canvas.drawCircle(70, yMax -70, 60, paint);
//canvas.drawCircle(xMax -70, yMax -60, 60, paint);
paint.setColor(Color.GREEN);
canvas.drawCircle(ballX, ballY, ballRadius, paint);
// Draw the status message
paint.setColor(Color.WHITE);
paint.setStrokeWidth(2);
canvas.drawText(statusMsg.toString(), 10, 30, paint);
if(ifdrawcount > 0){
canvas.drawLine(previousX, previousY, currentX, currentY, paint);
paint.setStrokeWidth(10);
paint.setColor(Color.BLACK);
canvas.drawPoint(previousX,previousY,paint);
ifdrawcount--;
}
// Update the position of the ball, including collision detection and reaction.
update();
// Delay
try {
Thread.sleep(16);
} catch (InterruptedException e) { }
invalidate(); // Force a re-draw
}
// Touch-input handler
@Override
public boolean onTouchEvent(MotionEvent event) {
currentX = event.getX();
currentY = event.getY();
ifdrawcount = 10;
//float deltaX, deltaY;
scale = 20.0f / ((xMax > yMax) ? yMax : xMax);
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
previousX = currentX;
previousY = currentY;
case MotionEvent.ACTION_MOVE:
ballSpeedY = (currentY - previousY) * scale;
ballSpeedX = (currentX - previousX) * scale;
case MotionEvent.ACTION_UP:
ballSpeedX = 0;
ballSpeedY = 0;
}
return true; // Event handled
}
// Detect collision and update the position of the ball.
private void update() {
// Get new (x,y) position
ballX += ballSpeedX;
ballY += ballSpeedY;
/*if(ifdrawcount == 0)
ballSpeedX = 0; ballSpeedY = 0;*/
// Detect collision and react
if (ballX + ballRadius > xMax) {
ballSpeedX = -ballSpeedX;
ballX = xMax-ballRadius;
} else if (ballX - ballRadius < xMin) {
ballSpeedX = -ballSpeedX;
ballX = xMin+ballRadius;
}
if (ballY + ballRadius > yMax) {
ballSpeedY = -ballSpeedY;
ballY = yMax - ballRadius;
} else if (ballY - ballRadius < yMin) {
ballSpeedY = -ballSpeedY;
ballY = yMin + ballRadius;
}
// Build status message
statusMsg.delete(0, statusMsg.length()); // Empty buffer
formatter.format("%3.0f %3.0f || %3.0f %3.0f", ballSpeedX, ballSpeedY,ballX,ballY);
}
// Called back when the view is first created or its size changes.
@Override
public void onSizeChanged(int w, int h, int oldW, int oldH) {
// Set the movement bounds for the ball
xMax = w-1;
yMax = h-1;
}
}
the problem is my ball doesn't move at all, but i see the line, once i remove the line:
Code:
case MotionEvent.ACTION_UP:
ballSpeedX = 0;
ballSpeedY = 0;
it works, but you know, after release it continues with same speed :! its like the ACTION_UP is always the case, !!! any idea why it doesn't work, how to stop the ball once the user releases the screen?
also sorry if this is not the right place. i searched the forums, i got confused i didn't find anyplace to ask this question so i tough this is the best place!
I love Android. I want to learn to develop apps. I keep reading tutorials. I got dissapointed and read about HTML frameworks (phonegap, etc). I came back to Android Native Java. I want to learn from the roots. However, some things discourages me....
All this part of the code is just for making a request to the Openweather API and get the json data (plus a little debugging stuff); which in Python or similar languages you only have to care about
- importing the library that handles http requests
- make the request in one function and save it into a json object
Code:
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String forecastJsonStr = null;
String format = "json";
String units = "metric";
int numDays = 7;
try {
final String FORECAST_BASE_URL =
"<the-domain>/data/2.5/forecast/daily?";
final String QUERY_PARAM = "q";
final String FORMAT_PARAM = "mode";
final String UNITS_PARAM = "units";
final String DAYS_PARAM = "cnt";
Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon()
.appendQueryParameter(QUERY_PARAM, params[0])
.appendQueryParameter(FORMAT_PARAM, format)
.appendQueryParameter(UNITS_PARAM, units)
.appendQueryParameter(DAYS_PARAM, Integer.toString(numDays))
.build();
URL url = new URL(builtUri.toString());
Log.v(LOG_TAG, "Built URI " + builtUri.toString());
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
forecastJsonStr = buffer.toString();
Log.v(LOG_TAG, "Forecast string: " + forecastJsonStr);
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
This is the complete Class:
Code:
public class FetchWeatherTask extends AsyncTask<String, Void, String[]> {
private final String LOG_TAG = FetchWeatherTask.class.getSimpleName();
/* The date/time conversion code is going to be moved outside the asynctask later,
* so for convenience we're breaking it out into its own method now.
*/
private String getReadableDateString(long time){
// Because the API returns a unix timestamp (measured in seconds),
// it must be converted to milliseconds in order to be converted to valid date.
Date date = new Date(time * 1000);
SimpleDateFormat format = new SimpleDateFormat("E, MMM d");
return format.format(date).toString();
}
/**
* Prepare the weather high/lows for presentation.
*/
private String formatHighLows(double high, double low) {
// For presentation, assume the user doesn't care about tenths of a degree.
long roundedHigh = Math.round(high);
long roundedLow = Math.round(low);
String highLowStr = roundedHigh + "/" + roundedLow;
return highLowStr;
}
/**
* Take the String representing the complete forecast in JSON Format and
* pull out the data we need to construct the Strings needed for the wireframes.
*
* Fortunately parsing is easy: constructor takes the JSON string and converts it
* into an Object hierarchy for us.
*/
private String[] getWeatherDataFromJson(String forecastJsonStr, int numDays)
throws JSONException {
// These are the names of the JSON objects that need to be extracted.
final String OWM_LIST = "list";
final String OWM_WEATHER = "weather";
final String OWM_TEMPERATURE = "temp";
final String OWM_MAX = "max";
final String OWM_MIN = "min";
final String OWM_DATETIME = "dt";
final String OWM_DESCRIPTION = "main";
JSONObject forecastJson = new JSONObject(forecastJsonStr);
JSONArray weatherArray = forecastJson.getJSONArray(OWM_LIST);
String[] resultStrs = new String[numDays];
for(int i = 0; i < weatherArray.length(); i++) {
// For now, using the format "Day, description, hi/low"
String day;
String description;
String highAndLow;
// Get the JSON object representing the day
JSONObject dayForecast = weatherArray.getJSONObject(i);
// The date/time is returned as a long. We need to convert that
// into something human-readable, since most people won't read "1400356800" as
// "this saturday".
long dateTime = dayForecast.getLong(OWM_DATETIME);
day = getReadableDateString(dateTime);
// description is in a child array called "weather", which is 1 element long.
JSONObject weatherObject = dayForecast.getJSONArray(OWM_WEATHER).getJSONObject(0);
description = weatherObject.getString(OWM_DESCRIPTION);
// Temperatures are in a child object called "temp". Try not to name variables
// "temp" when working with temperature. It confuses everybody.
JSONObject temperatureObject = dayForecast.getJSONObject(OWM_TEMPERATURE);
double high = temperatureObject.getDouble(OWM_MAX);
double low = temperatureObject.getDouble(OWM_MIN);
highAndLow = formatHighLows(high, low);
resultStrs[i] = day + " - " + description + " - " + highAndLow;
}
for (String s : resultStrs) {
Log.v(LOG_TAG, "Forecast entry: " + s);
}
return resultStrs;
}
@Override
protected String[] doInBackground(String... params) {
// If there's no zip code, there's nothing to look up. Verify size of params.
if (params.length == 0) {
return null;
}
// These two need to be declared outside the try/catch
// so that they can be closed in the finally block.
HttpURLConnection urlConnection = null;
BufferedReader reader = null;
// Will contain the raw JSON response as a string.
String forecastJsonStr = null;
String format = "json";
String units = "metric";
int numDays = 7;
try {
// Construct the URL for the OpenWeatherMap query
// Possible parameters are avaiable at OWM's forecast API page
final String FORECAST_BASE_URL =
"<the-domain>/data/2.5/forecast/daily?";
final String QUERY_PARAM = "q";
final String FORMAT_PARAM = "mode";
final String UNITS_PARAM = "units";
final String DAYS_PARAM = "cnt";
Uri builtUri = Uri.parse(FORECAST_BASE_URL).buildUpon()
.appendQueryParameter(QUERY_PARAM, params[0])
.appendQueryParameter(FORMAT_PARAM, format)
.appendQueryParameter(UNITS_PARAM, units)
.appendQueryParameter(DAYS_PARAM, Integer.toString(numDays))
.build();
URL url = new URL(builtUri.toString());
Log.v(LOG_TAG, "Built URI " + builtUri.toString());
// Create the request to OpenWeatherMap, and open the connection
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setRequestMethod("GET");
urlConnection.connect();
// Read the input stream into a String
InputStream inputStream = urlConnection.getInputStream();
StringBuffer buffer = new StringBuffer();
if (inputStream == null) {
// Nothing to do.
return null;
}
reader = new BufferedReader(new InputStreamReader(inputStream));
String line;
while ((line = reader.readLine()) != null) {
// Since it's JSON, adding a newline isn't necessary (it won't affect parsing)
// But it does make debugging a *lot* easier if you print out the completed
// buffer for debugging.
buffer.append(line + "\n");
}
if (buffer.length() == 0) {
// Stream was empty. No point in parsing.
return null;
}
forecastJsonStr = buffer.toString();
Log.v(LOG_TAG, "Forecast string: " + forecastJsonStr);
} catch (IOException e) {
Log.e(LOG_TAG, "Error ", e);
// If the code didn't successfully get the weather data, there's no point in attemping
// to parse it.
return null;
} finally {
if (urlConnection != null) {
urlConnection.disconnect();
}
if (reader != null) {
try {
reader.close();
} catch (final IOException e) {
Log.e(LOG_TAG, "Error closing stream", e);
}
}
}
try {
return getWeatherDataFromJson(forecastJsonStr, numDays);
} catch (JSONException e) {
Log.e(LOG_TAG, e.getMessage(), e);
e.printStackTrace();
}
// This will only happen if there was an error getting or parsing the forecast.
return null;
}
}
I mean, I know this code can be reduced, but I'm angry about the way it works. Everything needs to be passed to another object! And even rembember all those castings! Castings everywhere!
- The builded URI to the URL.
- The URL to the HttpConection variable.
- Once you connect, save that into the InputStream.
- Make a StringBuffer because we are going to send line by line everything.
- Then create the reader = new BufferedReader(new InputStreamReader(inputStream)).
- Append the lines to the buffer and return if it's ok.
- Else catch all the errors and be sure to close all the connections.
Damn Java !
Forgive me. You'll hate me.
Java is readable, that's the truth... but don't tell me that it is easy for a normal person.
Am I the only one?
If you are a beginner and will straight move to these classes. You will obviously find Java difficult. But Java is very easy if you move step by step from start
Sent from my XT1033 using XDA Premium 4 mobile app
---------- Post added at 04:18 PM ---------- Previous post was at 04:16 PM ----------
And that library also does the same thing inside. Only difference is, your work is already done by author of the library.
Sent from my XT1033 using XDA Premium 4 mobile app
Java is definitely a very verbose language but it's also widely used and so you will find many libraries that do tasks like grab JSON data from a service that have already been implemented for you
manwoman said:
Damn Java !
Forgive me. You'll hate me.
Java is readable, that's the truth... but don't tell me that it is easy for a normal person.
Am I the only one?
Click to expand...
Click to collapse
I don't think you're the only one. It's easy to get scared away by the many too verbose examples available, the key is to look at what you're trying to achieve and then break it up into those parts.
Your code listing is (I think) an attempt to show all steps to get the forecast data, but if that would have been broken up into smaller steps I don't think you'd look at it as quite as bad.
You would then have methods like
Code:
URL getForecastUrl(String parameter);
Code:
BufferedReader getUrl(URL url) { }
Code:
String readAll(BufferedReader reader) {}
Each of which would have had something like 6-7 lines of simple, cohesive code.
I understand your point, but in this particular scenario I think you're the victim of a poorly structured code sample rather than a too verbose language.
If you think the default implementation is too complicated, here are also many java libraries which will make your life easier.
I have an android application that is receiving a string from an arduino via Bluetooth, names the string "data" and displays it by setting a TextView to the string "data". I want a chronometer to start when the incoming string matches a predefined string.
For example:
Code:
if data.equals(startChrono)){
chronometerLeft.setBase(SystemClock.elapsedRealtime());
chronometerLeft.start();
I actually have the arduino sending a "g" and am setting my string goL to be "g" but cannot get the chronometer to start when the g is received. My TextView shows the g. Code is below. I've tried several things and at a loss. Using same code for chronometer.start() with onClickListener with a button works great. I just need it to start the chronometer when i receive a specific string from the arduino.
Code:
beginListenForData();
// text.setText("Bluetooth Opened");
}
void beginListenForData() {
final Handler handler = new Handler();
final byte delimiter = 10; // This is the ASCII code for a newline
// character
stopWorker = false;
readBufferPosition = 0;
readBuffer = new byte[1024];
workerThread = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted() && !stopWorker) {
try {
int bytesAvailable = mmInputStream.available();
if (bytesAvailable > 0) {
byte[] packetBytes = new byte[bytesAvailable];
mmInputStream.read(packetBytes);
for (int i = 0; i < bytesAvailable; i++) {
byte b = packetBytes[i];
if (b == delimiter) {
byte[] encodedBytes = new byte[readBufferPosition];
System.arraycopy(readBuffer, 0,
encodedBytes, 0,
encodedBytes.length);
final String data = new String(
encodedBytes, "US-ASCII");
readBufferPosition = 0;
handler.post(new Runnable() {
public void run() {
text.setText(data);
String goL = "g";
String goR = "f";
chronometerLeft = (Chronometer)findViewById(R.id.chronometerLeft);
chronometerRight = (Chronometer)findViewById(R.id.chronometerRight);
if(data.equals(goL)){
chronometerLeft.setBase(SystemClock.elapsedRealtime());
chronometerLeft.start();
if(data.equals(goR))
chronometerRight.setBase(SystemClock.elapsedRealtime());
chronometerRight.start();
}
}
});
} else {
readBuffer[readBufferPosition++] = b;
}
}
}
} catch (IOException ex) {
stopWorker = true;
}
}
}
});
workerThread.start();
}
Sorry to bother, but in your while loop condition, what does the '!' before Thread do?