Environment null is coming after executing this method - android

public static String[] getAdbLogCat() {
try {
String line;
ArrayList<String> arrList = new ArrayList<String>();
Process p = Runtime.getRuntime().exec("D:/androidsoftware/android sdk/platform-tools/adb shell logcat");
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
while ((line = br.readLine()) != null) {
System.out.println(line);
Log.e("ADB TEST",line);
}
return (String[])arrList.toArray(new String[0]);
} catch (IOException e) {
System.err.println(e);
e.printStackTrace();
return new String[]{};
}
}
Environment null is coming after executing this method.I am running this in emulator.What if i want to run in mobile then what will be the adb path? My requirement is to read the adb log and save the crash data into a table.My android sdk located in d drive.Or is there any other way to get my application crash log from android system log.

You can't run executable programs on your computer from within an app running on an emulator. You can only run programs that live in the emulator's own space. The emulator is like an actual device, and you would never expect a device to reach outside itself to execute some other process.

You need a bridge to contact the host-environment from your android application.
Sample project: https://github.com/toantran-ea/adb-ci-bridge
You can extend the function with new endpoint in that library. And make call to from your application.
Sample request with curl:
curl -H "Content-Type: application/json" -X POST -d '{"tag":"sample tag value","trace":"TooAwesomeException foo bar"}' http://localhost:9001/screenshot
This is used in some limited contexts, like when you running on a Continuous Sever and you need some utility functions to contact with host (for screenshot, reporting, or something else).

Related

Xamarin SqlServer cant get a connection

I'm building an app with the Entity Framework on Xamarin that lets me compare some data. But when I start my "fetchdata" function, I receive the Error:
System.Data.SqlClient.SqlException (0x80131904): Snix_Connect (provider: SNI_PN7, error: 35 - SNI_ERROR_35)Snix_Connect (provider: SNI_PN7, error: 35 - SNI_ERROR_35)
I see many posts about Xamarin / Android & that it is not possible to get a connection to a SQL Server. Is there any way to fetch data from a SQL Server with .NET Core on Xamarin?
This is the string I put into SQL_Class folder with Sql_Common.cs
Fill up the brace brackets with actual parameters (removing the brace brakets too).
public static string SQL_connection_string = #"data source={server_address};initial catalog={database_name};user id={user_id};password={password};Connect Timeout={seconds}";
Then I access whenever I need it from any xamarin code just like we use in our asp.net c#
This works for me on my app without any issues.
using (SqlConnection Sql_Connection = new SqlConnection(Sql_Common.saralEHR_connection_string))
But as #Jason mentioned in his first reply, I too would get once again check the security part. I fexperienced before publishing Package to Google Play, they encrypt the App files with Hash Key Code and then only it gets upload to server
Yes it is possible (HuurrAYY!):
Im new in .net core, c# and so on and for me it was a hell of a work to get it working..
So here for the other noobs who are seeking for Help:
GuideĀ“s i used:
Building Android Apps with Entity Framework
https://medium.com/#yostane/data-persistence-in-xamarin-using-entity-framework-core-e3a58bdee9d1
https://blog.xamarin.com/building-android-apps-entity-framework/
Scaffolding
https://cmatskas.com/scaffolding-dbcontext-and-models-with-entityframework-core-2-0-and-the-cli/
How i did it:
Build your normal Xamarin app.
create new .net solution like in the tutorials (DONT WRITE YOUR Entity Framework CLASSES)
create a third solution what has to be a .net core console application
Scaffold your DB in your CONSOLE application move all created classes & folders in your "xamarin .net" solution & change the namespaces
Ready to Go!
Side Node: NuGets you need in every solution:
Microsoft.EntityFrameworkCore
Microsoft.EntityFrameworkCore.SqlServer
[EDIT: NuGets you need in every solution]
I am doing this way (working snippet):
string connectionString = #"data source={server};initial catalog={database};user id={user};password={password};Connect Timeout=10";
string databaseTable = "{table name}";
string selectQuery = String.Format("SELECT count(*) as Orders FROM {0}", databaseTable);
try
{
using (SqlConnection connection = new SqlConnection(connectionString))
{
//open connection
connection.Open();
SqlCommand command = new SqlCommand(selectQuery, connection);
command.Connection = connection;
command.CommandText = selectQuery;
var result = command.ExecuteScalar().ToString();
//check if there is result
if(result != null)
{
OrdersLabel.Text = result;
}
}
}
catch (Exception ex)
{
OrdersLabel.Text = ex.Message;
}
It is working fine, but API call more elegant.
I hope it helps.

var exec = require('child_process').exec; callbacks for commands that run continuously

I am trying to write an interface for the adb logcat command with node.js, and need some help having my function do continuous and asynchronous callbacks. This command generates constant output that I want to send to the callback function as it is generated (not after I let it run for awhile and then stop it). Is this possible with node.js, and if so how do I do it?
Here is my code so far
exports.logcat = function(options, callback){
var logcatCmd = "adb logcat" + options;
console.log("sending command: " + logcatCmd);
exec(logcatCmd, function(error, stdout, stderr){
if(error !== null){
console.log("encountered error = " + error);
}
callback(stdout);
});
};
In short, no; you cannot watch shell commands for new outputs, in the same way you can stream data from a changing file or socket.
If it generates constant output, it's more likely it just reads from some log file and prints
it on screen. You should figure out which file it's getting the data from, and use fs.watch with readableStream to continuously get the stream of data.

Challenge with Android communicating to GAE using restlet

I'm using Eclipse to (try to) build an Android client to get reuse a restlet service I developed using GAE and GWT.
My service is running at
http://127.0.0.1:8888/abc/audits
I can test this by going directly to this url, and by using my GWT client - both work.
However, the following code returns a communication error
private AuditsResource resource;
private Audits audits;
ClientResource cr = new ClientResource("http://127.0.0.1:8888/abc/audits");
resource = cr.wrap(AuditsResource.class);
try {
// Get the remote contact
audits = resource.retrieve();
// The task is over, let the parent conclude.
handler.sendEmptyMessage(0);
} catch (Exception e) {
Message msg = Message.obtain(handler, 2);
Bundle data = new Bundle();
data.putString("msg", "Cannot get the contact due to: "
+ e.getMessage());
msg.setData(data);
handler.sendMessage(msg);
}
I have no idea where to look next. I've instrumented the server implementation of AuditsResource, and it is never touched (by the Android application).
The AuditsResource class has one method, to keep things simple for now
#Get
public Audits retrieve();
It appears the problem is that the Andriod Emulator cannot connect to either 127.0.0.1 or 10.0.2.2. The solution is to use your PC's IP address.
I am able to connect from Android to my local Google App Engine through Android/Restlet using 10.0.2.2 instead of localhost.

Programmatically filtering logcat for my application. not working for me

In an android app I am trying to get my application log messages and saving them to file
I am using the code below.
I am using a different TAG for each of my class and there are several of them.
doing logcat -d gives me all irrelevant messages..
putting my package name like
logcat -d myapp.com:I *:S
does not work the results are empty but if I do
logcat -d MYCLASS1TAG:I MYCLASS2TAG *:S
then it works, but I have many classes..
how can I just put my package name and get results ..??
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null)
{
// write to my file here
}
} catch (IOException e) { }
I'm not sure how to do it from the command line, but the ADT plugin for Eclipse lets you filter by application.
edit: I was curious, so I looked through the ADT source to figure out how ADT does it. The long and short of it is that it uses the -v long option to include the PID with each message, and it keeps a Map from a PID to an app name. The relevant source code files are in the package com.android.ddmuilib.logcat.LogCatMessageParser and com.android.ddmuilib.logcat.LogCatPidToNameMapper.
So, one workaround I can think of is to call up a shell (adb shell), figure out your PID using ps, and then pipe the output of adb logcat to grep:
adb logcat -v long | grep <your PID>
It will be a bit of a pain since your PID will change every time you run the app, but that's how you can do it in a pinch.
edit: I just noticed that the long format actually prints the PID on one line and the message on the next line, so you may need to use something like awk instead of grep. I'll test a few things out and post a followup.
So as I understand it you are trying to run logcat on the device to grab and save to file. Unfortunately in the current command line the filterspec only supports the tag:priority format. You will need to run the output through your own line by line filter. You can probably automate this by figuring out your PID and then filtering lines based on that.

Stream android logcat output to an sd card

I want to achieve the following but so far, no luck
Open a file in the SD Card when the android application first started.
Stream the logcat output to the file.
When the application exits, stop the logcat streaming.
In my ApplicationClass extends Application onCreate() method, I do this
wwLogManager.openLogFile();
and here's the code in the openLogFile()
private static final String LOGCAT_COMMAND = "logcat -v time -f ";
String timestamp = Long.toString(System.currentTimeMillis());
String logFileName = BuildConstants.LOG_LOCATION + "_" + timestamp + ".log";
mLogFile = new File(Environment.getExternalStorageDirectory() + logFileName);
mLogFile.createNewFile();
String cmd = LOGCAT_COMMAND + mLogFile.getAbsolutePath();
Runtime.getRuntime().exec(cmd);
I do get log files in the sd card, but the log output in these files do not have any trace of the Log.i() calls that I placed in my activities. Is the logcat command that I used here correct? Thanks!
I apologize if I am misunderstanding your goals, but perhaps you could use the java.util.logging API instead of using Logcat or the Android Logging mechanism.
Like the Android logging API, the java.util.logging API allows you to easily log messages at various levels, such as FINE, FINER, WARN, SEVERE, etc.
But the standard logging API has additional advantages, too. For example, you can easily create a log file by using a FileHandler. In fact, FileHandler has a built-in log rotation mechanism, so you don't have to worry (so much) about cleaning up the log files. You can also create a hierarchy of Loggers; so, for example, if you have two Loggers, com.example.foo and com.example.foo.bar, changing the logging level of the former will also change the logging level of the latter. This will even work if the two Loggers are created in different classes! Moreover, you change logging behavior at runtime by specifying a logging configuration file. Finally, you can customize the format of the log by implementing your own Formatter (or just use the SimpleFormatter to avoid the default XML format).
To use the standard logging API, you might try something like this:
// Logger logger is an instance variable
// FileHandler logHandler is an instance variable
try {
String logDirectory =
Environment.getExternalStorageDirectory() + "/log_directory";
// the %g is the number of the current log in the rotation
String logFileName = logDirectory + "/logfile_base_name_%g.log";
// ...
// make sure that the log directory exists, or the next command will fail
//
// create a log file at the specified location that is capped 100kB. Keep up to 5 logs.
logHandler = new FileHandler(logFileName, 100 * 1024, 5);
// use a text-based format instead of the default XML-based format
logHandler.setFormatter(new SimpleFormatter());
// get the actual Logger
logger = Logger.getLogger("com.example.foo");
// Log to the file by associating the FileHandler with the log
logger.addHandler(logHandler);
}
catch (IOException ioe) {
// do something wise
}
// examples of using the logger
logger.finest("This message is only logged at the finest level (lowest/most-verbose level)");
logger.config("This is an config-level message (middle level)");
logger.severe("This is a severe-level message (highest/least-verbose level)");
The Android logging mechanism is certainly easy and convenient. It isn't very customizable, though, and log filtering must be done with tags, which can easily become unwieldy. By using the java.uitl.logging API, you can avoid dealing with a multitude of tags, yet easily limit the log file to specific parts of your application, gain greater control over the location and appearance of the log, and even customize logging behavior at runtime.
I repost my answer here so #JPM and others can see... The code basically just execute the logcat command and then build the log from the input stream.
final StringBuilder log = new StringBuilder();
try {
ArrayList<String> commandLine = new ArrayList<String>();
commandLine.add("logcat");
commandLine.add("-d");
ArrayList<String> arguments = ((params != null) && (params.length > 0)) ? params[0] : null;
if (null != arguments){
commandLine.addAll(arguments);
}
Process process = Runtime.getRuntime().exec(commandLine.toArray(new String[0]));
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null){
log.append(line);
log.append(LINE_SEPARATOR);
}
}
catch (IOException e){
//
}
return log;
Try manually setting a filter as described here:
http://developer.android.com/guide/developing/debugging/debugging-log.html#filteringOutput
Something like:
logcat ActivityManager:I MyApp:V *:S
If you replace "MyApp" with the log tags that you are using, that should show you all info (and greater) logs from ActivityManager, and all verbose (and greater) logs from your app.
I know this is a late answer to the question but I would highly recommend using Logback to write messages to a log file as well as the logcat.
Copy logback-android-1.0.10-2.jar and slf4j-api-1.7.5.jar to your libs folder.
Right-Click on both libs and from the menu select Build Path -> Add to Build Path.
Create a logback.xml file in your assets folder and enter the following:
%msg
WARN
${LOG_DIR}/log.txt
%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
To write a log:
public class MyActivity extends Activity
{
public static final Logger logger = LoggerFactory.getLogger(MyActivity.class);
protected void onCreate(Bundle b)
{
super(b);
try{
throw new Exception("Test");
}catch(Exception e){
logger.error("Something bad happened",e);
}
}
}

Categories

Resources