For logging purpose, I print out json response string and can see them in android "adb logcat" command. Is there a way to nicely format the json string in adb logcat output so that it looks like this?
{ "code" : "0",
"text" : "hello world"
}
You can use the JSONObject.toString() method to pretty print the JSON on logcat.
Log.d("tag", jsonObject.toString(4));
Output
(29124): {
(29124): "text": "hello world",
(29124): "code": "0"
(29124): }
I don't pretty print the JSON message in code. I just double click on the message in LogRabbit on Mac and it will pretty print it or highlight Base64 to decode it.
Full disclosure, I am the creator of LogRabbit for Mac.
You can format json in log with original form by use code of my logger:
Logger.dd("Section label", json);
Link on Github: https://github.com/scijoker/logger
Source:
import android.os.Build;
import android.util.Log;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
/**
* Created by scijoker on 08.10.15.
*/
public class Logger {
private static boolean DEBUG = true;
public static void d(String tag, String arg) {
if (isEnable()) {
log(tag, arg);
}
}
public static void d(String logMsg) {
if (isEnable()) {
log(getCurrentClassName(), getCurrentMethodName() + "(): " + logMsg);
}
}
public static void dd(String tag, Object source) {
if (isEnable()) {
Object o = getJsonObjFromStr(source);
if (o != null) {
try {
if (o instanceof JSONObject) {
format(tag, ((JSONObject) o).toString(2));
} else if (o instanceof JSONArray) {
format(tag, ((JSONArray) o).toString(2));
} else {
format(tag, source);
}
} catch (JSONException e) {
format(tag, source);
}
} else {
format(tag, source);
}
}
}
private static void log(String tag, String msg) {
Log.d(tag, msg);
}
private static String getSplitter(int length) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < length; i++) {
builder.append("-");
}
return builder.toString();
}
private static void format(String tag, Object source) {
tag = " " + tag + " ";
log(" ", " ");
log(" ", getSplitter(50) + tag + getSplitter(50));
log(" ", "" + source);
log(" ", getSplitter(100 + tag.length()));
log(" ", " ");
}
private static String getCurrentMethodName() {
return Thread.currentThread().getStackTrace()[4].getMethodName();
}
private static String getCurrentClassName() {
String className = Thread.currentThread().getStackTrace()[4].getClassName();
String[] temp = className.split("[\\.]");
className = temp[temp.length - 1];
return className;
}
private static Object getJsonObjFromStr(Object test) {
Object o = null;
try {
o = new JSONObject(test.toString());
} catch (JSONException ex) {
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
o = new JSONArray(test);
}
} catch (JSONException ex1) {
return null;
}
}
return o;
}
public static boolean isEnable() {
return DEBUG;
}
public static void setEnable(boolean flag) {
Logger.DEBUG = flag;
}
}
fastJson provide a method:
//serialize a prettyFormat json string
public static final String toJSONString(Object object, boolean prettyFormat);
eg:Log.d(TAG,JSON.toJSONString(object, true));
Related
I've been building a network requests Queue class for cases where network connectivity may fail temporarily to come back online later. The end goal is every time network connection fails, the request gets queued until the network is available again.
Here's the code done so far for sending data:
import android.app.Activity;
import android.content.Context;
import android.os.AsyncTask;
import android.os.CountDownTimer;
import android.widget.Toast;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import androidx.fragment.app.FragmentTransaction;
import org.json.JSONObject;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import construction.site.logistics.foreman.Encryption.Encryption;
import construction.site.logistics.foreman.Fragments.FragmentJournal;
import construction.site.logistics.foreman.MainActivity;
import construction.site.logistics.foreman.R;
import construction.site.logistics.foreman.abstraction.Functions;
import construction.site.logistics.foreman.data.database.EntityFields;
import construction.site.logistics.foreman.data.database.EntityFiles;
import construction.site.logistics.foreman.data.database.EntityQueue;
import construction.site.logistics.foreman.data.database.LocalDatabaseOperations;
import construction.site.logistics.foreman.data.state;
public class SendData {
private Activity activity=null;
private FragmentActivity fragmentActivity=null;
private EntityQueue queue=null;
private List<EntityFields> fieldsInList=null;
private List<EntityFiles> filesInList=null;
private Boolean encrypt;
private String encryptionType="";
private Boolean waitForCode=false;
private Boolean loadMainPage=false;
private Boolean enableQueue=true;
private Integer retryCount;
private String title;
private static Boolean error;
private String responseMsg;
public ObservableValue DelayedResult;
public SendData (Activity _activity, FragmentActivity _fragmentActivity){
this.activity=_activity;
this.fragmentActivity=_fragmentActivity;
this.DelayedResult = new ObservableValue(getResponse());
this.retryCount=0;
}
public void setWaitForCode(Boolean _wait){ waitForCode=_wait;}
public void setloadMainPage(Boolean _load){ loadMainPage=_load;}
public String getResponse(){ return responseMsg; }
public Boolean getError(){ return error; }
public void addQueue(EntityQueue _queue){ queue=_queue;}
public void addFields(List<EntityFields> _fields){ fieldsInList=_fields;}
public void addfFiles(List<EntityFiles> _files){ filesInList=_files;}
public void setEnableQueue(Boolean _queue){ enableQueue=_queue; }
public void setEncryption(Boolean _encrypt, String _type){
encryptionType= _type;
encrypt=_encrypt;
}
public class ObservableValue extends Observable
{
private String responseMsg = "";
public ObservableValue(String _responseMsg)
{
this.responseMsg = _responseMsg;
}
public void setValue(String _responseMsg)
{
this.responseMsg = _responseMsg;
setChanged();
notifyObservers();
}
public String getValue()
{
return responseMsg;
}
}
public boolean send(){
error=false;
if (waitForCode) {
try{
SendDataAsync sendDataAsync =new SendDataAsync();
sendDataAsync.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR).get();
error=false;
return true;
}catch(Exception e){
Functions.SaveCrash(e, activity);
error=true;
return false;
}
}else{
SendDataAsync sendDataAsync =new SendDataAsync();
sendDataAsync.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
error=false;
return true;
}
}
private class SendDataAsync extends AsyncTask<Void, Void, String> {
#Override
protected String doInBackground(Void... params) {
error=true;
if (queue == null) {
responseMsg = "{'error':true,'message':'" + activity.getResources().getString(R.string.sendData_missing_queue) + "'}";
} else if (fieldsInList == null) {
responseMsg = "{'error':true,'message':'" + activity.getResources().getString(R.string.sendData_missing_fields) + "'}";
} else if (state.getNetworkStatus()) { // send immediately
//Json format var="{'error':true,'message':'some message'}";
String Data2Send = "{";
String temp = "";
JSONObject jObjectData = new JSONObject();
List<String> FileNamesList= new ArrayList<>();
FileNamesList.clear();
Data2Send = "";
EntityFields field = new EntityFields();
field.setRequestVar("tid");
field.setValue(state.serial);
fieldsInList.add(field);
try {
for (int i = 0; i < fieldsInList.size(); i++) {
jObjectData.put(fieldsInList.get(i).getRequestVar(), fieldsInList.get(i).getValue().replace("'", "\'").replace('"', '\"'));
}
if (filesInList != null) {
temp = "";
String temp2 = "";
for (int i = 0; i < filesInList.size(); i++) {
FileNamesList.add(filesInList.get(i).getFilename());
temp2 += filesInList.get(i).getAppendCode() ? "1" : "0";
temp += i == 0 ? temp2 : "," + temp2;
}
jObjectData.put("filecode", temp);
}
} catch (Exception e) {
Functions.SaveCrash(e, activity);
}
Data2Send = jObjectData.toString();
Encryption encryption = new Encryption(activity);
encryption.setSecretKey(state.encryptionKey);
if (encryption.encryptString(Data2Send)) {
HttpComm request = new HttpComm(activity);
request.setType("post");
request.setCharSet("UTF-8");
activity.runOnUiThread(new Runnable() {
public void run() {
Functions.showSimpleProgressDialog(activity, activity.getResources().getString(R.string.commServer_connect_title_msg), activity.getResources().getString(R.string.commServer_connect_msg),false);
}
});
String urlEncoded="";
try{
urlEncoded=URLEncoder.encode(encryption.getEncryptedString(), "UTF-8");
}catch (Exception e){
urlEncoded=encryption.getEncryptedString();
}
error = !request.send(queue.getUrl(), urlEncoded, FileNamesList);
activity.runOnUiThread(new Runnable() {
public void run() {
Functions.removeSimpleProgressDialog();
}
});
if(queue.getMsgError().equals("debug")) {
encryption.decryptString(request.getResponse());
responseMsg = "{'error':true,'message':'DEBUG: " + encryption.getDecryptedString() + "'}";
}else if(error && retryCount< 6){
activity.runOnUiThread(new Runnable() {
public void run() {
new CountDownTimer(20000, 1000) {
public void onTick(long millisUntilFinished) {
activity.setTitle(R.string.commServer_retry+" "+millisUntilFinished / 1000);
}
public void onFinish() {
activity.setTitle(title);
retryCount++;
send();
}
}.start();
}
});
return "retrying";
}else if (error && enableQueue) {
LocalDatabaseOperations localDatabaseOperations = new LocalDatabaseOperations(activity);
error = LocalDatabaseOperations.addQueue(queue, fieldsInList, filesInList);
if (error) {
responseMsg = "{'error':true,'message':'" + request.getMessage() + System.getProperty("line.separator") + localDatabaseOperations.getErrMessage() + "'}";
} else {
responseMsg = "{'error':false,'message':'" + activity.getResources().getString(R.string.sendData_added_queue) + "'}";
}
} else if (error && !enableQueue) {
responseMsg = "{'error':true,'message':'" + request.getMessage() + "'}";
} else { // success sending request
if (encryption.decryptString(request.getResponse())) {
if (encryption.getEncryptedVector().equals(encryption.getDecryptedVector())) {
responseMsg = encryption.getDecryptedString(); // success on retrieving data from server
} else {
String ss=encryption.getEncryptedVector();
String sss=encryption.getDecryptedVector();
String s=encryption.getDecryptedString();
responseMsg = "{'error':true,'message':'" + activity.getResources().getString(R.string.sendData_error_ivector) + "'}";
}
} else { // error decrypting string
responseMsg = "{'error':true,'message':'" + activity.getResources().getString(R.string.sendData_error_decrypt_data) + "'}";
String response= request.getResponse();
String str= "Message:"+encryption.getErrMessage()+" >>>>Encrypt:"+ encryption.getEncryptedVector()+" >>>>Dencrypt:"+ encryption.getDecryptedVector();
Exception e= new Exception(str);
Functions.SaveCrash(e, activity);
}
}
} else { // error encrypting string
responseMsg = "{'error':true,'message':'" + activity.getResources().getString(R.string.sendData_error_encrypt_data) + "'}";
}
}else if(!enableQueue){
responseMsg = "{'error':true,'message':'" + activity.getResources().getString(R.string.error_no_network) + "'}";
} else { // send to queue
LocalDatabaseOperations localDatabaseOperations = new LocalDatabaseOperations(activity);
error = LocalDatabaseOperations.addQueue(queue, fieldsInList, filesInList);
if (error) {
responseMsg = "{'error':true,'message':'" + localDatabaseOperations.getErrMessage() + "'}";
} else {
responseMsg = "{'error':false,'message':'" + activity.getResources().getString(R.string.sendData_added_queue) + "'}";
}
}
return responseMsg;
}
#Override
protected void onPostExecute(String response) {
if(response.equals("retrying")){
return;
}
DelayedResult.setValue(response);
if (queue.getMsgType().equals("toast")) {
if (Functions.isSuccess(response)) {
if (queue.getMsgSuccess().equals("") || queue.getMsgSuccess().equals("response")) {
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, Functions.getErrorCode(activity, response), Toast.LENGTH_SHORT).show();
}
});
} else {
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, queue.getMsgSuccess(), Toast.LENGTH_SHORT).show();
}
});
}
} else {
if (queue.getMsgError().equals("") || queue.getMsgError().equals("response")) {
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, Functions.getErrorCode(activity, response), Toast.LENGTH_SHORT).show();
}
});
} else {
activity.runOnUiThread(new Runnable() {
public void run() {
Toast.makeText(activity, queue.getMsgError(), Toast.LENGTH_SHORT).show();
}
});
}
}
} else if (queue.getMsgType().equals("alertbox")) { // alertbox
if (Functions.isSuccess(response)) {
if (queue.getMsgSuccess().equals("") || queue.getMsgSuccess().equals("response")) {activity.runOnUiThread(new Runnable() {
public void run() {
Functions.alertbox(activity.getResources().getString(R.string.commServer_submit_ok), Functions.getErrorCode(activity, response), activity);
}
});
} else {
activity.runOnUiThread(new Runnable() {
public void run() {
Functions.alertbox(activity.getResources().getString(R.string.commServer_submit_ok), queue.getMsgSuccess(), activity);
}
});
}
} else {
if (queue.getMsgError().equals("") || queue.getMsgError().equals("response") || queue.getMsgError().equals("debug")) {
activity.runOnUiThread(new Runnable() {
public void run() {
Functions.alertbox(activity.getResources().getString(R.string.commServer_submit_error), Functions.getErrorCode(activity, response), activity);
}
});
} else {
activity.runOnUiThread(new Runnable() {
public void run() {
Functions.alertbox(activity.getResources().getString(R.string.commServer_submit_error), queue.getMsgError(), activity);
}
});
}
}
}
// Show messageBox messages
if (Functions.hasMessageBox(response)) {
Functions.getMessageBox(response);
}
if (loadMainPage && !error) {
FragmentTransaction fragmentTransaction = fragmentActivity.getSupportFragmentManager().beginTransaction();
fragmentTransaction.replace(R.id.content_frame, new FragmentJournal());
fragmentTransaction.commit();
}
}
}
}
where the following code
LocalDatabaseOperations localDatabaseOperations = new LocalDatabaseOperations(activity);
error = LocalDatabaseOperations.addQueue(queue, fieldsInList, filesInList);
is for storing data in local device SQL server in a common SQL table using Room database. Next i have a listener listening for networks changes that triggers, on successful network connectivity, sending the data request again.
I created a class for working with subscriptions in the store.
In the beginning I receive from the server the list of subscriptions with the prices
The code is working and on most devices there is no problem.
But some users do not recive prices. It's like there's no response from the server. I've studied examples of implementation in Google documentation, but I can not understand where I can have problems in the code.
Part of my code:
public class BillingActivity extends AppCompatActivity {
RelativeLayout imageLayout;
View payButton;
// WebView payWebView;
// TextView useCodeButton;
ProgressBar progress1;
ProgressBar progress2;
ProgressBar progress3;
IInAppBillingService inAppBillingService;
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_billing_subscription);
price_1monthTextView = (TextView) findViewById(R.id.price_1monthTextView);
relative_1month = (RelativeLayout) findViewById(R.id.relative_1month);
relative_1month.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (MainActivity.myAccount == null) return;
if (MainActivity.myAccount.getUniqid() == null) return;
if (subscription1m != null) {
try {
Log.d("my", "purchase..." + subscription1m.storeName);
purchaseProduct(subscription1m);
} catch (Exception e) {
e.printStackTrace();
Log.d("my", "purchase error = " + e.toString());
}
}
}
});
progress1 = (ProgressBar) findViewById(R.id.progress1);
startGoogleBilling();
}
private void startGoogleBilling() {
if (serviceConnection != null) {
unbindService(serviceConnection);
}
progress1.setVisibility(View.VISIBLE);
serviceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
inAppBillingService = IInAppBillingService.Stub.asInterface(service);
getSubscribtionsList();
}
#Override
public void onServiceDisconnected(ComponentName name) {
inAppBillingService = null;
}
};
Intent serviceIntent =
new Intent("com.android.vending.billing.InAppBillingService.BIND");
serviceIntent.setPackage("com.android.vending");
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
}
private static final int PR_CNT = 3;
List<InAppProduct> subscriptions = null;
InAppProduct subscription1m = null;
InAppProduct subscription3m = null;
InAppProduct subscription1y = null;
String[] productIds = {"eq.subscription.1m", "eq.subscription.3m.2", "eq.subscription.1y"};
private void getSubscribtionsList() {
mSwipeRefreshLayout.setRefreshing(false);
progress1.setVisibility(View.GONE);
try {
subscriptions =
getInAppPurchases("subs", productIds[0], productIds[1], productIds[2]);
if (subscriptions.size() == PR_CNT) {
for (InAppProduct inAppProduct : subscriptions) {
String productId = inAppProduct.productId;
Log.d("my", "productId= " + productId);
if (productId.contains(productIds[0])) subscription1m = inAppProduct;
if (productId.contains(productIds[1])) subscription3m = inAppProduct;
if (productId.contains(productIds[2])) subscription1y = inAppProduct;
}
Log.d("my", "1m= " + subscription1m.storeName + " pr=" + subscription1m.price + "\\n\\r " +
"3m= " + subscription3m.storeName + " pr=" + subscription3m.price + "\\n\\r " +
"1y= " + subscription1y.storeName + " pr=" + subscription1y.price + "\\n\\r ");
///----------------------!!!!
// purchaseProduct(inAppProduct);
}
updatePrices();
} catch (Exception e) {
Log.d("my", "exc = " + e.toString());
if (e.toString().contains("Attempt to invoke interface method 'android.os.Bundle com.android.vending.billing.IInAppBillingService.getSkuDetails")) {
if (attempt < 4) {
//getSubscribtionsList();
// startGoogleBilling();
} else {
}
}
// Toast.makeText(this, "Google inApp connection error", Toast.LENGTH_SHORT).show();
// refreshButton.setVisibility(View.VISIBLE);
startGoogleBilling();
}
}
private int attempt = 0;
#Override
public void onDestroy() {
super.onDestroy();
if (serviceConnection != null) {
unbindService(serviceConnection);
}
}
class InAppProduct {
public String productId;
public String storeName;
public String storeDescription;
public String price;
public boolean isSubscription;
public int priceAmountMicros;
public String currencyIsoCode;
public String getSku() {
return productId;
}
String getType() {
return isSubscription ? "subs" : "inapp";
}
}
List<InAppProduct> getInAppPurchases(String type, String... productIds) throws Exception {
ArrayList<String> skuList = new ArrayList<>(Arrays.asList(productIds));
Bundle query = new Bundle();
query.putStringArrayList("ITEM_ID_LIST", skuList);
Bundle skuDetails = inAppBillingService.getSkuDetails(
3, getPackageName(), type, query);
ArrayList<String> responseList = skuDetails.getStringArrayList("DETAILS_LIST");
List<InAppProduct> result = new ArrayList<>();
for (String responseItem : responseList) {
JSONObject jsonObject = new JSONObject(responseItem);
InAppProduct product = new InAppProduct();
// "com.example.myapp_testing_inapp1"
product.productId = jsonObject.getString("productId");
// Покупка
product.storeName = jsonObject.getString("title");
// Детали покупки
product.storeDescription = jsonObject.getString("description");
// "0.99USD"
product.price = jsonObject.getString("price");
// "true/false"
product.isSubscription = jsonObject.getString("type").equals("subs");
// "990000" = цена x 1000000
product.priceAmountMicros =
Integer.parseInt(jsonObject.getString("price_amount_micros"));
// USD
product.currencyIsoCode = jsonObject.getString("price_currency_code");
result.add(product);
}
return result;
}
private void updatePrices() {
if (subscriptions.size() == PR_CNT) {
price_1monthTextView.setText(subscription1m.price);
price_3monthTextView.setText(subscription3m.price);
price_1yearTextView.setText(subscription1y.price);
}
}
}
my problem was the bit depth of the X variable priceAmountMicros
The price from playmarket is multiplied by a 1000000 , and Kazakh tenge has exchange rate = 1 USD= 331,3 KZT.
And if i have price 18 000 KTZ and * 1000 000.
For price variable I must use long type
I am using data from an Android application, this data is loaded a list after that this information is sending to a MySQL database, these data are points of a chart. I have noticed that these values do not arrive well, because these don’t make the shape of the graph that I need.
Sometimes when I try to access the database, I have this error:
PhpMyAdmin Error
But I don’t understand what this is happing? Has anyone had anything like this?
Is the problem in the server or the application?
I think it is more a server problem because when I check the data of the lists these data that I will send is there.
This is the class where the method is to send the data to the server:
package com.botonmedico.amunet.service;
import com.botonmedico.amunet.Login;
import com.botonmedico.amunet.model.UserModel;
import com.botonmedico.amunet.utils.HttpUtil;
import com.loopj.android.http.AsyncHttpResponseHandler;
import org.json.JSONArray;
import org.json.JSONObject;
public class ServiceManager2
{
public static void onLoginUser(String user,String pw,final Login activity)
{
String url = Globals.baseUrl + "login.php"
+"?user=" + user
+"&pw=" + pw;
HttpUtil.get(url, new AsyncHttpResponseHandler()
{
public void onFailure(Throwable paramThrowable) {
String s = "fail";
}
public void onFinish() {
String s = "finish";
}
public void onSuccess(String paramString)
{ //that is return when success..
System.out.println("Entrando al onSuccess");
try
{
JSONObject localJSONObject1 = new JSONObject(paramString);
if (localJSONObject1.has("response"))
{
String response = localJSONObject1.getString("response");
if (response.equals("200"))
{
JSONArray jsArray = localJSONObject1.getJSONArray("users");
JSONObject model = jsArray.getJSONObject(0);
UserModel mModel = new UserModel();
mModel.mName = model.getString("user");
mModel.mId = model.getString("id");
int state = model.getInt("state");
if (state == 1)//
{
Globals.mAccount = mModel;
activity.iniciaApp();
}
}
}
}
catch (Exception e)
{
e.printStackTrace();
activity.errorIniciarApp();
activity.mDialogLogin.dismiss();
}
}
});
}
//Funcion que envia los datos si las listas de datos no estan vacias
public static void onSendData()
{
String valueECGGraph = "";
String valueContadorECG="";
String valueTiempoMS="";
if(Globals.lstSendECGGraphData.size()>0)
valueECGGraph = Globals.lstSendECGGraphData.get(0);
Globals.lstSendECGGraphData.remove(0);/*********************/
System.out.println("*Valor en lista ECG: "+valueECGGraph);
//final String v_ECGGraphArduino = valueECGGraph;
if(Globals.lstSendContadorECG.size()>0)
valueContadorECG = Globals.lstSendContadorECG.get(0);
Globals.lstSendContadorECG.remove(0);
System.out.println("*Valor en lista Contador: "+valueContadorECG);
if(Globals.lstSendSegundoECG.size()>0)
valueTiempoMS = Globals.lstSendSegundoECG.get(0);
Globals.lstSendSegundoECG.remove(0);
System.out.println("*Valor en lista segundos: "+valueTiempoMS);
//In this section will save the data to Database
String url = Globals.baseUrl + "receiveData.php"
+"?EcgGraphValue="+valueECGGraph
+"&contadorECG="+valueContadorECG
+"&TiempoECG="+valueTiempoMS
+"&uid=" + Globals.mAccount.mId;
HttpUtil.get(url, new AsyncHttpResponseHandler()
{
public void onFailure(Throwable paramThrowable) {
String s = "fail";
}
public void onFinish() {
String s = "finish";
}
//
public void onSuccess(String paramString) { //that is return when success..
try {
JSONObject localJSONObject1 = new JSONObject(paramString);
if (localJSONObject1.has("response")) {
String response = localJSONObject1.getString("response");
if (response.equals("200"))
{
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
This is the part of the class where the data is loaded into the lists:
if (charFinCadena > 0) {
try {
nombreDispositivo = readMessage.substring(charInicioCadena + 1, charInicioTiempo);
switch (nombreDispositivo) {
case "ecg":
cuenta++;
segundo = readMessage.substring(charInicioTiempo + 1, charInicioValor);
valorECG = readMessage.substring(charInicioValor + 1, charFinCadena);
System.out.println("Device: " + nombreDispositivo);
System.out.println("second: " + segundo);
System.out.println("Value: " + valorECG);
System.out.println("dato : " + cuenta);
System.out.println("******************************************************");
//Listas donde se agregan los valores obtenidos de las substrings
Globals.lstSendECGGraphData.add(valorECG);
Globals.lstSendContadorECG.add(String.valueOf(cuenta));
Globals.lstSendSegundoECG.add(segundo);
ServiceManager2.onSendData();
System.out.println("******************************************************");
ServiceManager.onSendData();
break;
default:
break;
}
}catch(NullPointerException|StringIndexOutOfBoundsException ex){}
}
If you have any question or suggestion please let me know,thanks in advice.
I know this kind of questions are maybe too old, but I got stock with this silly thing.
I have an AsyncTask class which is a subclass of an activity class, and right now I want to call it from another class: following codes shows what I mean:
public class STA extends Activity {
public class ListSpdFiles extends AsyncTask<Void, Void, String[]> {
private static final String TAG = "ListSpdFiles: ";
/**
* Status code returned by the SPD on operation success.
*/
private static final int SUCCESS = 4;
private String initiator;
private String path;
private SecureApp pcas;
private boolean isConnected = false; // connected to PCAS service?
private PcasConnection pcasConnection = new PcasConnection() {
#Override
public void onPcasServiceConnected() {
Log.d(TAG, "pcasServiceConnected");
latch.countDown();
}
#Override
public void onPcasServiceDisconnected() {
Log.d(TAG, "pcasServiceDisconnected");
}
};
private CountDownLatch latch = new CountDownLatch(1);
public ListSpdFiles(String initiator, String path) {
this.initiator = initiator;
this.path = path;
}
private void init() {
Log.d(TAG, "starting task");
pcas = new AndroidNode(getApplicationContext(), pcasConnection);
isConnected = pcas.connect();
}
private void term() {
Log.d(TAG, "terminating task");
if (pcas != null) {
pcas.disconnect();
pcas = null;
isConnected = false;
}
}
#Override
protected void onPreExecute() {
super.onPreExecute();
init();
}
#Override
protected String[] doInBackground(Void... params) {
// check if connected to PCAS Service
if (!isConnected) {
Log.v(TAG, "not connected, terminating task");
return null;
}
// wait until connection with SPD is up
try {
if (!latch.await(20, TimeUnit.SECONDS)) {
Log.v(TAG, "unable to connected within allotted time, terminating task");
return null;
}
} catch (InterruptedException e) {
Log.v(TAG, "interrupted while waiting for connection in lsdir task");
return null;
}
// perform operation (this is where the actual operation is called)
try {
return lsdir();
} catch (DeadServiceException e) {
Log.i(TAG, "service boom", e);
return null;
} catch (DeadDeviceException e) {
Log.i(TAG, "device boom", e);
return null;
}
}
#Override
protected void onPostExecute(String[] listOfFiles) {
super.onPostExecute(listOfFiles);
if (listOfFiles == null) {
Log.i(TAG, "task concluded with null list of files");
// tv.setText("task concluded with a null list of files");
} else {
Log.i(TAG, "task concluded with the following list of files: "
+ Arrays.toString(listOfFiles));
//tv.setText("List of files received is:\n" + Arrays.toString(listOfFiles));
}
term();
}
#Override
protected void onCancelled(String[] listOfFiles) {
super.onCancelled(listOfFiles);
Log.i(TAG, "lsdir was canceled");
term();
}
/**
* Returns an array of strings containing the files available at the given path, or
* {#code null} on failure.
*/
private String[] lsdir() throws DeadDeviceException, DeadServiceException {
Result<List<String>> result = pcas.lsdir(initiator, path); // the lsdir call to the
final Global globalVariable = (Global) getApplicationContext();
if (globalVariable.getPasswordButt() == false) {
// Calling Application class (see application tag in AndroidManifest.xml)
// Get name and email from global/application context
final boolean isusername = globalVariable.getIsUsername();
if (isusername == true) {
String username = "/" + getLastAccessedBrowserPage() + ".username" + ".txt";
//String password = "/" + CurrentURL + "password" + ".txt";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pcas.readFile(initiator, username, baos);
Log.i(TAG, "OutputStreampassword: "
+ new String(baos.toByteArray()));
String name = new String(baos.toByteArray());
if (!name.equalsIgnoreCase("")) {
globalVariable.setUsername(name);
// getCurrentInputConnection().setComposingText(name, 1);
// updateCandidates();
}
globalVariable.setIsUsername(false);
} else if (isusername == false)
Log.i(TAG, "Wrong Input Type For Username.");
// globalVariable.setUsernameButt(false);
} else if (globalVariable.getPasswordButt() == true) {
// Calling Application class (see application tag in AndroidManifest.xml)
// final Global globalVariable = (Global) getApplicationContext();
// Get name and email from global/application context
final boolean ispassword = globalVariable.getIsPassword();
if (ispassword == true) {
// String username = "/" + CurrentURL + "username" + ".txt";
String password = "/" + getLastAccessedBrowserPage() + ".password" + ".txt";
ByteArrayOutputStream baos = new ByteArrayOutputStream();
pcas.readFile(initiator, password, baos);
Log.i(TAG, "OutputStreampassword: "
+ new String(baos.toByteArray()));
String name = new String(baos.toByteArray());
if (!name.equalsIgnoreCase("")) {
globalVariable.setPassword(name);
//getCurrentInputConnection().setComposingText(name, 1);
// updateCandidates();
}
globalVariable.setIsPassword(false);
} else if (ispassword == false)
Log.i(TAG, "Wrong Input Type For Password.");
globalVariable.setPasswordButt(false);
// boolpassword=false;
}
//}
if (result.getState() != SUCCESS) {
Log.v(TAG, "operation failed");
return null;
}
if (result.getValue() == null) {
Log.v(TAG, "operation succeeded but operation returned null list");
return null;
}
return result.getValue().toArray(new String[0]);
}
}
public String getLastAccessedBrowserPage() {
String Domain = null;
Cursor webLinksCursor = getContentResolver().query(Browser.BOOKMARKS_URI, Browser.HISTORY_PROJECTION, null, null, Browser.BookmarkColumns.DATE + " DESC");
int row_count = webLinksCursor.getCount();
int title_column_index = webLinksCursor.getColumnIndexOrThrow(Browser.BookmarkColumns.TITLE);
int url_column_index = webLinksCursor.getColumnIndexOrThrow(Browser.BookmarkColumns.URL);
if ((title_column_index > -1) && (url_column_index > -1) && (row_count > 0)) {
webLinksCursor.moveToFirst();
while (webLinksCursor.isAfterLast() == false) {
if (webLinksCursor.getInt(Browser.HISTORY_PROJECTION_BOOKMARK_INDEX) != 1) {
if (!webLinksCursor.isNull(url_column_index)) {
Log.i("History", "Last page browsed " + webLinksCursor.getString(url_column_index));
try {
Domain = getDomainName(webLinksCursor.getString(url_column_index));
Log.i("Domain", "Last page browsed " + Domain);
return Domain;
} catch (URISyntaxException e) {
e.printStackTrace();
}
break;
}
}
webLinksCursor.moveToNext();
}
}
webLinksCursor.close();
return null;
}
public String getDomainName(String url) throws URISyntaxException {
URI uri = new URI(url);
String domain = uri.getHost();
return domain.startsWith("www.") ? domain.substring(4) : domain;
}}
Would you please tell me what should I do to fix this code?
Looking over the code I did not see anywhere you referenced anything from the Activity itself besides the application context so you can move the ListSpdFiles class to its own java file and pass it a context into the constructor when you make a new instance of it.
Put this class in a ListSpdFiles.java file so it is no longer an inner class.
public class ListSpdFiles extends AsyncTask<Void, Void, String[]> {
Context applicationContext;
public ListSpdFiles(Context context, String initiator, String path) {
this.initiator = initiator;
this.path = path;
applicationContext = context.getApplicationContext();
}
// The rest of your code still goes here. Replace other calls to
// getApplicationContext() with the new applicationContext field
}
You can now use this class anywhere a Context is available. You create a new instance by doing:
ListSpdFiles listSpdFilesTask = new ListSpdFiles(context, "someInitiator", "somePath");
listSpdFilesTask.execute();
I am working on an app in Unity3D which can upload tracks to SoundCloud. I have been working on this for a while but i can't get it to work. I am using HttpWebRequest for the request to SoundCloud and this works fine on Unity for Windows. But when i try it on my Android device i get the following message: 'Request entity contains invalid byte sequence. Please transmit valid UTF-8.'.
Below is the part of code that i use (got it from somewhere on the internet).
I made sure i was uploading the same file on Windows as on Android and did the request to RequestBin. Now, when i compared the two, i noticed that the raw data is almost completely identical except for the end:
Ending Windows: ÿàþ³þDþÿýëýÅýÙý
Ending Android: ÿàþ³þDþÿýëýÅýÙý[FF]þÞýþûýCþxþZþ{þ
So as you can see, on Android there is more data. Can someone explain to me what is going on here?
I started with posts on the Unity community, now trying it here. Here you can find my question on the unity website for more information.
public class SoundCloudScript {
//Enter app credentials from here http://soundcloud.com/you/apps
private const string _clientId = "xxx";
private const string _clientSecret = "xxx";
//enter username and password a soundcloud user, e.g. your own credentials
private const string _username = "xxx";
private const string _password = "xxx";
private string soundCloudToken;
//private WebClient _webclient = new WebClient();
public string Status { get; set; }
public IEnumerator GetTokenAndUploadFile(MonoBehaviour mono, FileInfo file)
{
Debug.Log ( "GetTokenAndUploadFile() started");
ServicePointManager.ServerCertificateValidationCallback = (p1, p2, p3, p4) => true;
var form = new WWWForm ();
form.AddField ("client_id", _clientId);
form.AddField ("client_secret", _clientSecret);
form.AddField ("grant_type", "password");
form.AddField ("username", _username);
form.AddField ("password", _password);
//Authentication
string soundCloudTokenRes = "https://api.soundcloud.com/oauth2/token";
Debug.Log ( "Try to get token");
WWW download = new WWW(soundCloudTokenRes, form);
yield return download;
if(!string.IsNullOrEmpty(download.error))
{
Debug.Log ( "Error downloading: " + download.error );
}
else
{
var tokenInfo = download.text;
tokenInfo = tokenInfo.Remove(0, tokenInfo.IndexOf("token\":\"") + 8);
soundCloudToken = tokenInfo.Remove(tokenInfo.IndexOf("\""));
Debug.Log(string.Format("Token set: {0}", soundCloudToken));
UploadFile(file);
}
}
public void UploadFile(FileInfo file)
{
Debug.Log ("Start uploading!");
ServicePointManager.Expect100Continue = false;
var request = WebRequest.Create("https://api.soundcloud.com/tracks/") as HttpWebRequest;
//some default headers
request.Accept = "*/*";
request.Headers.Add("Accept-Charset", "ISO-8859-1,utf-8;q=0.7,*;q=0.3");
request.Headers.Add("Accept-Encoding", "gzip,deflate,sdch");
request.Headers.Add("Accept-Language", "en-US,en;q=0.8,ru;q=0.6");
//file array
var files = new UploadFile[]
{
new UploadFile(file.FullName, "track[asset_data]", "application/octet-stream")
};
//other form data
var form = new System.Collections.Specialized.NameValueCollection();
form.Add("track[title]", "Some title");
form.Add("track[sharing]", "private");
form.Add("oauth_token", soundCloudToken);
form.Add("format", "json");
try
{
using (var response = HttpUploadHelper.Upload(request, files, form))
{
using (var reader = new StreamReader(response.GetResponseStream()))
{
reader.ReadToEnd();
}
}
Debug.Log ("Upload success!");
}
catch (WebException wex) {
if (wex.Response != null) {
using (var errorResponse = (HttpWebResponse)wex.Response) {
using (var reader = new StreamReader(errorResponse.GetResponseStream())) {
string error = reader.ReadToEnd();
Debug.Log ("Error(1/2): Message: " + wex.Message);
Debug.Log ("Error(2/2): " + error);
//TODO: use JSON.net to parse this string and look at the error message
}
}
}
}
//return "Nothing...";
}
}
public class StreamMimePart : MimePart
{
Stream _data;
public void SetStream(Stream stream)
{
_data = stream;
}
public override Stream Data
{
get
{
return _data;
}
}
}
public abstract class MimePart
{
NameValueCollection _headers = new NameValueCollection();
byte[] _header;
public NameValueCollection Headers
{
get { return _headers; }
}
public byte[] Header
{
get { return _header; }
}
public long GenerateHeaderFooterData(string boundary)
{
StringBuilder sb = new StringBuilder();
sb.Append("--");
sb.Append(boundary);
sb.AppendLine();
foreach (string key in _headers.AllKeys)
{
sb.Append(key);
sb.Append(": ");
sb.AppendLine(_headers[key]);
}
sb.AppendLine();
_header = Encoding.UTF8.GetBytes(sb.ToString());
return _header.Length + Data.Length + 2;
}
public abstract Stream Data { get; }
}
public class StringMimePart : MimePart
{
Stream _data;
public string StringData
{
set
{
_data = new MemoryStream(Encoding.UTF8.GetBytes(value));
}
}
public override Stream Data
{
get
{
return _data;
}
}
}
public class HttpUploadHelper
{
private HttpUploadHelper()
{ }
public static string Upload(string url, UploadFile[] files, NameValueCollection form)
{
HttpWebResponse resp = Upload((HttpWebRequest)WebRequest.Create(url), files, form);
using (Stream s = resp.GetResponseStream())
using (StreamReader sr = new StreamReader(s))
{
return sr.ReadToEnd();
}
}
public static HttpWebResponse Upload(HttpWebRequest req, UploadFile[] files, NameValueCollection form)
{
List<MimePart> mimeParts = new List<MimePart>();
try
{
foreach (string key in form.AllKeys)
{
StringMimePart part = new StringMimePart();
part.Headers["Content-Disposition"] = "form-data; name=\"" + key + "\"";
part.StringData = form[key];
mimeParts.Add(part);
}
int nameIndex = 0;
foreach (UploadFile file in files)
{
StreamMimePart part = new StreamMimePart();
if (string.IsNullOrEmpty(file.FieldName))
file.FieldName = "file" + nameIndex++;
part.Headers["Content-Disposition"] = "form-data; name=\"" + file.FieldName + "\"; filename=\"" + file.FileName + "\"";
part.Headers["Content-Type"] = file.ContentType;
part.SetStream(file.Data);
mimeParts.Add(part);
}
string boundary = "----------" + DateTime.Now.Ticks.ToString("x");
req.ContentType = "multipart/form-data; boundary=" + boundary;
req.Method = "POST";
long contentLength = 0;
byte[] _footer = Encoding.UTF8.GetBytes("--" + boundary + "--\r\n");
foreach (MimePart part in mimeParts)
{
contentLength += part.GenerateHeaderFooterData(boundary);
}
req.ContentLength = contentLength + _footer.Length;
Debug.Log ("ContentLength: " + req.ContentLength);
byte[] buffer = new byte[8192];
byte[] afterFile = Encoding.UTF8.GetBytes("\r\n");
int read;
foreach(var header in req.Headers)
{
Debug.Log(header);
}
using (Stream s = req.GetRequestStream())
{
foreach (MimePart part in mimeParts)
{
s.Write(part.Header, 0, part.Header.Length);
while ((read = part.Data.Read(buffer, 0, buffer.Length)) > 0)
{
s.Write(buffer, 0, read);
Debug.Log ("Buffer: >>" + System.Text.Encoding.UTF8.GetString(buffer) + "<<");
}
//Debug.Log ("Buffer: " + System.Text.Encoding.UTF8.GetString(buffer));
part.Data.Dispose();
s.Write(afterFile, 0, afterFile.Length);
Debug.Log ("Buffer-End: >>" + System.Text.Encoding.UTF8.GetString(afterFile) + "<<");
}
s.Write(_footer, 0, _footer.Length);
Debug.Log ("Footer: >>" + System.Text.Encoding.UTF8.GetString(_footer) + "<<");
}
return (HttpWebResponse)req.GetResponse();
}
catch (Exception e)
{
Debug.Log ("Crash! Message: " + e.Message);
foreach (MimePart part in mimeParts)
if (part.Data != null)
part.Data.Dispose();
throw;
}
}
}
public class UploadFile
{
Stream _data;
string _fieldName;
string _fileName;
string _contentType;
public UploadFile(Stream data, string fieldName, string fileName, string contentType)
{
_data = data;
_fieldName = fieldName;
_fileName = fileName;
_contentType = contentType;
}
public UploadFile(string fileName, string fieldName, string contentType)
: this(File.OpenRead(fileName), fieldName, Path.GetFileName(fileName), contentType)
{ }
public UploadFile(string fileName)
: this(fileName, null, "application/octet-stream")
{ }
public Stream Data
{
get { return _data; }
set { _data = value; }
}
public string FieldName
{
get { return _fieldName; }
set { _fieldName = value; }
}
public string FileName
{
get { return _fileName; }
set { _fileName = value; }
}
public string ContentType
{
get { return _contentType; }
set { _contentType = value; }
}
}
It's working!! The problem was that at some point i used StringBuilder.AppendLine() to add a new line. This works fine on Windows, but on Android it didn't work... (i figured it out because the Content-Length was not the same for Windows and Android.)
I fixed it by instead of using 'StringBuilding.AppendLine()', i use 'StringBuilder.Append("\r\n")'