I am very new to android, as I got a project for maintenance. I completed other part of the project like authentication, token setting etc... In that face recognition is used to identify the person. Previously it was working fine and taken images, trained with it and recognized the person.(Obviously not done by me :)). Now it throws error as
Add Person ActivityCvException [org.opencv.core.CvException:
cv::Exception:
/build/master_pack-android/opencv/modules/core/src/matrix.cpp:1047:
error: (-13) The matrix is not continuous, thus its number of rows can
not be changed in function cv::Mat cv::Mat::reshape(int, int) const
Code sample is as follows
public void training() {
Thread thread;
try{
PreferenceManager.setDefaultValues(getApplicationContext(), R.xml.preferences, false);
}catch (Exception e){
AddPersonActivity.this.runOnUiThread(new Runnable() {
public void run() {
WriteLog("Add Person Activity" +e.fillInStackTrace());
errorAlert("Add Person Activity" +e.fillInStackTrace());
VolleyHelper.progressDialog.dismiss();
}
});
}
WriteLog("training 1 ");
final Handler handler = new Handler(Looper.getMainLooper());
thread = new Thread(new Runnable() {
public void run() {
if (!Thread.currentThread().isInterrupted()) {
try {
WriteLog("training 2 ");
PreProcessorFactory ppF = new PreProcessorFactory(AddPersonActivity.this);
PreferencesHelper preferencesHelper = new PreferencesHelper(AddPersonActivity.this);
String algorithm = preferencesHelper.getClassificationMethod();
FileHelper fileHelper = new FileHelper();
fileHelper.createDataFolderIfNotExsiting();
final File[] persons = fileHelper.getTrainingList();
if (persons.length > 0) {
Recognition rec = RecognitionFactory.getRecognitionAlgorithm(getApplicationContext(), Recognition.TRAINING, algorithm);
for (File person : persons) {
if (person.isDirectory()) {
File[] files = person.listFiles();
int counter = 1;
for (File file : files) {
if (FileHelper.isFileAnImage(file)) {
Mat imgRgb = Imgcodecs.imread(file.getAbsolutePath());
Imgproc.cvtColor(imgRgb, imgRgb, Imgproc.COLOR_BGRA2RGBA);
Mat processedImage = new Mat();
imgRgb.copyTo(processedImage);
List<Mat> images = ppF.getProcessedImage(processedImage, PreProcessorFactory.PreprocessingMode.RECOGNITION);
if (images == null || images.size() > 1) {
continue;
} else {
processedImage = images.get(0);
}
if (processedImage.empty()) {
continue;
}
String[] tokens = file.getParent().split("/");
final String name = tokens[tokens.length - 1];
for (int i = 0; i < files.length; i++) {
File myfile = new File(person +
"\\" + files[i].getName());
String long_file_name = files[i].getName();
System.out.println(long_file_name);
System.out.print(long_file_name);
myfile.renameTo(new File(person +
"\\" + long_file_name + "_101" + ".png"));
}
WriteLog("training 3 ");
MatName m = new MatName("processedImage", processedImage);
fileHelper.saveMatToImage(m, FileHelper.DATA_PATH);
rec.addImage(processedImage, name, false);
counter++;
}
}
}
}
try {
if (rec.train()) {
if (zipFileAtPath("/storage/emulated/0/Pictures/facerecognition/training/" + lcode, "/storage/emulated/0/Pictures/facerecognition/data/SVM/" + lcode + ".zip")) {
WriteLog("training 4 ");
if (zipFileAtPath("/storage/emulated/0/Pictures/facerecognition/data/SVM", "/storage/emulated/0/Pictures/facerecognition/" + "SVM_" + lcode + ".zip")) {
WriteLog("training 5 ");
fileupload(getintent.getStringExtra("lcode"));
} else {
Toast.makeText(getApplicationContext(), "No Face Recognised", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(), "No Face Recognised", Toast.LENGTH_SHORT).show();
}
} else {
Toast.makeText(getApplicationContext(), "Try Again", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
WriteLog("Add Person Activity" +e.fillInStackTrace());
errorAlert("Add Person Activity" +e.fillInStackTrace());
}
handler.post(new Runnable() {
#Override
public void run() {
}
});
} else {
Thread.currentThread().interrupt();
}
} catch (Exception e) {
AddPersonActivity.this.runOnUiThread(new Runnable() {
public void run() {
VolleyHelper.progressDialog.dismiss();
WriteLog("Add Person Activity" +e.fillInStackTrace());
errorAlert("Add Person Activity" +e.fillInStackTrace());
}
});
}
}
}
});
thread.start();
}
The input image needs to be stored as a continuous block of bytes in memory. I came to a similar situation, particularly because Android (at least the version I tried) does not seem to store images continuously. 1) Check if the image is continuous using: inputImage.isContinuous(). It returns a bool. It should be true. 2) If the image is not continuous, you can create a copy of the image that it is by creating a clone of the image via inputImage.clone() . Behind the scenes, we are creating a deep copy of the input using the create method, that should guarantee that the new matrix is continuous.
//check image before continuing:
if ( !inputImage.isContinuous() ){
//if the image is not continuous, create a deep copy:
inputImage = inputImage.clone();
}
Hello Guys need a help
This is my requirement:-
I have a folder in my device
there are different types of files in that
wanna load these all files on a recycler view (only display)
Please guide me I am a beginner in android development
Thanks in Advance.
Things get complicated for android 10 and even more so for android 11 in terms of file access. Read up on Scoped Storage and Storage Access Framework (SAF)
This piece of code checks through a folder and looks for directories. I hope this will give some ideas
private void getDir(String dirPath) throws IOException {
fileNames = new ArrayList<>();
strpath = dirPath;
setTitle(strpath);
String rootItem = "";
File f = new File(dirPath);
DocumentFile pickedDir = fio.getDocumentFileIfAllowedToWrite(f, mContext);
if (pickedDir != null) {
DocumentFile dfile[] = pickedDir.listFiles();
if (!dirPath.equals("/")) {
rootItem = dirPath;
}
if (null != dfile) {
for (int i = 0; i < dfile.length; i++) {
DocumentFile file = dfile[i];
if (file.isDirectory()) {
if (file.canRead()) {
String next_part = dfile[i].getName();
try {
fileNames.add(f.getAbsolutePath() + "/" + next_part);
} catch (Exception e) {
e.printStackTrace();
}
}
} else {
if (tracks.checkAndroidAudioFormat(file.getName())) {
fileNames.add(file.getName());
}
}
}// end of loop
Collections.sort(fileNames, new Comparator<String>() {
public int compare(String obj1, String obj2) {
return obj1.compareToIgnoreCase(obj2);
}
});
// now insert root at position1
fileNames.add(0, rootItem);
mAdapter = new browseLocalFoldersAdapter(
browseLocalFoldersActivity.this, fileNames);
mAdapter.initializearray(fileNames.size());
mListView.setAdapter(mAdapter);
invalidateOptionsMenu(); // triggers onPrepareOptionsMenu etc.
progressBar.setVisibility(View.INVISIBLE);
}
}else{
// FragmentManager manager = getParentFragmentManager();
FragmentManager manager = getSupportFragmentManager();
FilePickerDialog dialog = new FilePickerDialog();
Bundle b = new Bundle();
b.putInt("ACTION_CODE", 0);
b.putString("COMMENT", getString(R.string.setpermissions));
b.putString("BUTTON", getString(R.string.set_sdcard_permissions));
b.putInt("OPEN_INTERNAL_STORAGE_REQUEST_CODE", OPEN_STORAGE_REQUEST_CODE);
dialog.setArguments(b);
// dialog.setTargetFragment(this, OPEN_STORAGE_REQUEST_CODE);
dialog.show(manager, "OPEN_INTERNAL_STORAGE_REQUEST_CODE");
}
}
I'm trying to download a list of RemoteFiles in Android using ownCloud. I can download the files perfectly fine but I'd like to notify the user when a file finishes. I'm downloading an entire directory:
#Override
public void onRemoteOperationFinish(RemoteOperation operation, RemoteOperationResult result) {
if (operation instanceof ReadRemoteFolderOperation) {
if (result.isSuccess()) {
Toast.makeText(this, "Finished reading folder", Toast.LENGTH_SHORT).show();
for (Object o : result.getData()) {
RemoteFile remoteFile = (RemoteFile) o;
String remotePath = remoteFile.getRemotePath();
File targetDirectory = new File(Environment.getExternalStorageDirectory().getAbsolutePath() +
"/owncloud_download");
downloadHelper.downloadFile(remoteFile, targetDirectory);
}
}
}
if (operation instanceof DownloadRemoteFileOperation) {
if (result.isSuccess()) {
// Notify the user here that the file finished
}
}
}
I've looked at the ownCloud library source but can't seem to find what a DownloadRemoteFileOperation returns as a result other than a boolean indicating success and an HTTP status code. I thought it might be in result.getLogMessage() but that just gives me an HTTP 200 status. How can I get the name of a file that's finished?
Edit: I also looked at result.getData() but that's null in a DownloadRemoteFileOperation.
Here's my workaround for the time being. I didn't want to modify the ownCloud library source (again) so instead I just do a check in onTransferProgress like so:
#Override
public void onTransferProgress(long rate, long transferred, long total, String fileName) {
if (transferred == total) {
runOnUiThread(new Runnable() {
// do the update here, file name is available
}
}
}
Here's another option. I needed the file being uploaded if the upload failed so I modified the ownCloud library source. This way I could return file names in the RemoteOperationResult.
RemoteOperationResult.java:
private String fileName;
public String getFileName() {
return fileName;
}
public void setFileName(String name) {
fileName = name;
}
DownloadRemoteFileOperation.java
#Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
/// download will be performed to a temporal file, then moved to the final location
File tmpFile = new File(getTmpPath());
/// perform the download
try {
tmpFile.getParentFile().mkdirs();
int status = downloadFile(client, tmpFile);
result = new RemoteOperationResult(isSuccess(status), status,
(mGet != null ? mGet.getResponseHeaders() : null));
Log_OC.i(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " +
result.getLogMessage());
} catch (Exception e) {
result = new RemoteOperationResult(e);
Log_OC.e(TAG, "Download of " + mRemotePath + " to " + getTmpPath() + ": " +
result.getLogMessage(), e);
}
// Added this line
result.setFileName(mRemotePath);
return result;
}
UploadRemoteFileOperation.java:
#Override
protected RemoteOperationResult run(OwnCloudClient client) {
RemoteOperationResult result = null;
try {
// / perform the upload
synchronized (mCancellationRequested) {
if (mCancellationRequested.get()) {
throw new OperationCancelledException();
} else {
mPutMethod = new PutMethod(client.getWebdavUri() +
WebdavUtils.encodePath(mRemotePath));
}
}
int status = uploadFile(client);
if (mForbiddenCharsInServer){
result = new RemoteOperationResult(
RemoteOperationResult.ResultCode.INVALID_CHARACTER_DETECT_IN_SERVER);
} else {
result = new RemoteOperationResult(isSuccess(status), status,
(mPutMethod != null ? mPutMethod.getResponseHeaders() : null));
}
} catch (Exception e) {
// TODO something cleaner with cancellations
if (mCancellationRequested.get()) {
result = new RemoteOperationResult(new OperationCancelledException());
} else {
result = new RemoteOperationResult(e);
}
}
// Added this line
result.setFileName(mLocalPath);
return result;
}
I'm making an Android app that needs to allow client to maintain the resources from their server which would include strings, drawables etc.
I've already created a mechanism for downloading a zip file with all these files, and they're able to change strings pretty easy, I've also created a mechanism that allows the client to change bg color for UI controls, to change width, height etc but I have a feeling that there must be a better way to create all this.
So I believe the real question is:
What's the best practice to create a custom theme, deploy it on server, make the app download it, and apply it to app afterwards?
I know how to create custom theme and how to deploy it with the app, and how to apply it during runtime, but the problem here is that resources are pre-compiled and once you create APK there's no way for developer to change them which would be required in order to add new themes/drawables/styles/strings.
Do I need to create a custom mechanism for all this (loading images, styles, strings etc from the file system) and to apply them during runtime by creating my own controls that would do that in constructor for example or is there a way to do this properly :)? ( how does Swiftkey do this with all the keyboard themes, and how do similar apps do it allowing the users to download theme and apply it after that )?
I'm sorry if I didn't see similar question, I really tried to find an answer myself during past 2 days, but I failed to find anything useful, so this is my last chance to get a constructive answer :).
The closest to solution i need was this answer: Changing app theme at runtime using using external theme file but I've already made that functionality, and i know i can change colors like that, but the problem is that i would like to be able to change things like borders, on button pressed state etc that require resources other than simple color value :(.
Thanks heaps!
P.S. I've also read about the extension files so is that something i need to consider while thinking about this, or do i need to look elsewhere? The problem with obb files is that they must be deployed over PlayStore and that's not "perfect" for the client because they need to pack it by using jobb, and to deploy it to PlayStore which is too technical for them, so they would prefer creating a zip file, putting it on server, and the app should do the rest :).
I've finally decided to solve this by making a custom system for handling drawables, strings etc so now i have a custom class called "ResourceManager" that handles what needs to be loadad and how, and themes are distributed as a zip file which app downloads, extracts and later uses.
I had to compile nine patch images by myself before putting them in zip file, and I did that using "abrc" from here: http://forum.xda-developers.com/showthread.php?t=785012
I've also created a simple bash script that goes recursively through custom folder and compiles all nine patch images with abrc.
I've also created a simple helper in the ResourceManager that checks and tells me the screen density so i can normally support images in hdpi, xhdpi etc densities, and finally i don't re-create the images every time i need them, i save them in a static list of HashMap so i can reuse the ones I've already created and that way i hope to prevent wasting too much phone's memory :).
OK that's all in short lines, if anyone has any questions please let me know, i'll be glad to share this experience with anyone.
Cheers!
============ EDIT ============
Here's the class I ended up writing for this purpose (it downloads the file, checks for it's version, loads strings from JSON file rather than strings.xml etc)
NOTE: This is not a full class so some parts are missing, but I think it's more than enough to get the idea how I solved all this :)
/**
* Created by bojank on 7/28/2014.
* Class that handles custom resources downloaded from server
*/
public class ResourceManager {
// List of ninePatchImages in the application
private static ArrayList<HashMap<String, NinePatchDrawable>> ninePatchHashMaps;
private static ArrayList<HashMap<String, Drawable>> imagesHashMaps;
private static ImageLoader imageLoader;
// Context for methods
public static Context ctx;
// JSONObject with all strings
private static JSONObject joString;
// JSONObject with all styles
private static JSONObject joStyles;
// String with current active lang code
private static String currentLanguage;
private static String sdcardPath;
// Private consturctor to prevent creating a class instance
private ResourceManager() {
}
/**
* Method that returns a translated string for given key
*
* #param key String
* #return String
*/
public static String getString(String module, String key) {
String output = ""; //String.format("[%s - %s]", module, key);
try {
if (getStringsFile() != null && getStringsFile().getJSONObject(module).has(key))
output = getStringsFile().getJSONObject(module).getString(key);
} catch (Exception e) {
// Force some default language if proper json file is missing for newly added language
currentLanguage = "en-US";
Helper.saveLocale(currentLanguage, ctx);
Helper.logError("ErrorFetchingString", e);
}
return output;
}
/**
* Method that returns JSONObject with string resources
* #return JSONObject
* #throws JSONException
*/
public static JSONObject getStringsFile() throws JSONException {
if (joString == null) {
String stringFileName = getResourcesPath() + "languages/" + getCurrentLanguage() + "/values.json";
String languageFile = Helper.readJsonFile(stringFileName);
if (languageFile != null) {
joString = new JSONObject(Helper.readJsonFile(stringFileName));
} else {
return null;
}
}
return joString.getJSONObject("strings");
}
/**
* Method that returns current language ("sr", "en"...)
* #return String
*/
public static String getCurrentLanguage() {
if (currentLanguage == null)
currentLanguage = Helper.getCurrentLanguage(ctx);
return currentLanguage;
}
/**
* Method that resets joString object and currentLanguage on language change
*/
public static void resetLanguage() {
joString = null;
currentLanguage = null;
}
/**
* Method that resets joStyles object on theme change
*/
public static void resetStyle() {
joStyles = null;
}
/**
* Method that deletes a directory from filesystem
* #param path File
* #return boolean
*/
public static boolean deleteDirectory(File path) {
if( path.exists() ) {
File[] files = path.listFiles();
for(int i=0; i<files.length; i++) {
if(files[i].isDirectory()) {
deleteDirectory(files[i]);
}
else {
files[i].delete();
}
}
}
return(path.delete());
}
/**
* Method that get's the version of assets file
* #param url String
*/
public static String getAssetsVersion(String url) throws IOException {
Helper.logInfo("REQUEST URL:", url);
OkHttpClient client = new OkHttpClient();
// set connection timeut to 5min
client.setConnectTimeout(1, TimeUnit.MINUTES);
Request request = new Request.Builder()
.url(url)
.build();
Response response = client.newCall(request).execute();
return response.body().string();
}
/**
* Method that downloads assets file from server
* #param url String
* #return String
* #throws IOException
*/
public static String getAssetsFile(String url) throws IOException {
Helper.logInfo("REQUEST URL:", url);
OkHttpClient client = new OkHttpClient();
// set connection timeut to 5min
client.setConnectTimeout(1, TimeUnit.MINUTES);
Request request = new Request.Builder()
.url(url)
.header("User-Agent", MyApplication.USER_AGENT)
.build();
Response response = client.newCall(request).execute();
InputStream inputStreamFile = response.body().byteStream();
try {
// Output stream
String outputFileName = Environment.getExternalStorageDirectory().toString() + "/assets.zip";
File deleteFile = new File(outputFileName);
deleteFile.delete();
OutputStream output = new FileOutputStream(outputFileName);
byte data[] = new byte[1024];
int count;
// writing data to file
while ((count = inputStreamFile.read(data)) != -1)
output.write(data, 0, count);
// flushing output
output.flush();
// closing streams
output.close();
inputStreamFile.close();
return outputFileName;
} catch (Exception e) {
Helper.logError("Download Resursa", e);
return "ERROR";
}
}
public static void setStyle(View v, String styleName) {
try {
if (styleName == null || styleName.equals("")) {
if (v instanceof EditText)
processStyle(v, getStylesFile().getJSONObject("EditText"));
} else
processStyle(v, getStylesFile().getJSONObject(styleName));
} catch (Exception e) {
Helper.logError("Setting Styles", e);
}
}
private static void setBackground(View v, Drawable d) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
v.setBackgroundDrawable(d);
} else {
v.setBackground(d);
}
}
public static JSONObject getStylesFile() throws JSONException {
if (joStyles == null) {
String stylesFileName = getResourcesPath() + "styles/properties.json";
joStyles = new JSONObject(Helper.readJsonFile(stylesFileName));
}
return joStyles;
}
public static void processStyle(View v, JSONObject joStyle) {
if(joStyle != null) {
try {
// used for layout margins
LinearLayout.LayoutParams layoutParams = null;
if (Helper.isValidParameter(joStyle, "backgroundColor"))
v.setBackgroundColor(Color.parseColor(joStyle.getString("backgroundColor")));
if (Helper.isValidParameter(joStyle, "backgroundImage"))
setBackground(v, loadNinePatchFromFilesystem(getImagesPath() + joStyle.getString("backgroundImage")));
if (v instanceof TextView) {
applyTextViewParameters(v, joStyle);
} else if (v instanceof ListView) {
if (Helper.isValidParameter(joStyle, "dividerColor")) {
((ListView) v).setDivider(new ColorDrawable(Color.parseColor(joStyle.getString("dividerColor"))));
((ListView) v).setDividerHeight(Helper.convertDpToPixel(1));
}
if (Helper.isValidParameter(joStyle, "dividerHeight")) {
((ListView) v).setDividerHeight(Helper.convertDpToPixel(joStyle.getInt("dividerHeight")));
}
} else if (v instanceof UnderlinePageIndicator) {
if (Helper.isValidParameter(joStyle, "backgroundColor")) {
v.setBackgroundColor(Color.parseColor(joStyle.getString("backgroundColor")));
}
if (Helper.isValidParameter(joStyle, "selectedColor")) {
((UnderlinePageIndicator) v).setSelectedColor(Color.parseColor(joStyle.getString("selectedColor")));
}
} else if (v instanceof StyleableBackground) {
if (Helper.isValidParameter(joStyle, "backgroundColor")) {
View background = v.findViewById(R.id.llBackground);
if (background != null) {
background.setBackgroundColor(Color.parseColor(joStyle.getString("backgroundColor")));
}
}
if (Helper.isValidParameter(joStyle, "borderTopColor")) {
View topBorder = v.findViewById(R.id.llTopBorder);
if (topBorder != null) {
topBorder.setBackgroundColor(Color.parseColor(joStyle.getString("borderTopColor")));
if (Helper.isValidParameter(joStyle, "borderTopHeight")) {
topBorder.setMinimumHeight(Helper.convertDpToPixel(joStyle.getInt("borderTopHeight")));
}
}
}
if (Helper.isValidParameter(joStyle, "borderBottomColor")) {
View bottomBorder = v.findViewById(R.id.llBottomBorder);
if (bottomBorder != null) {
bottomBorder.setBackgroundColor(Color.parseColor(joStyle.getString("borderBottomColor")));
if (Helper.isValidParameter(joStyle, "borderBottomHeight")) {
bottomBorder.setMinimumHeight(Helper.convertDpToPixel(joStyle.getInt("borderBottomHeight")));
}
}
}
if (Helper.isValidParameter(joStyle, "backgroundImage")) {
ImageView ivBackgroundImage = (ImageView) v.findViewById(R.id.ivBackgroundImage);
if (ivBackgroundImage != null) {
BitmapDrawable d = (BitmapDrawable) ResourceManager.loadImageFromFilesystem(ResourceManager.getImagesPath() + joStyle.getString("backgroundImage"));
d.setTileModeXY(Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
d.setGravity(Gravity.FILL_HORIZONTAL | Gravity.FILL_VERTICAL);
setBackground(ivBackgroundImage, d);
}
}
}
if(Helper.isValidParameter(joStyle, "width"))
v.setMinimumWidth(joStyle.getInt("width"));
if(Helper.isValidParameter(joStyle, "height"))
v.setMinimumHeight(joStyle.getInt("height"));
if(Helper.isValidParameter(joStyle, "padding"))
v.setPadding(joStyle.getInt("padding"), joStyle.getInt("padding"), joStyle.getInt("padding"), joStyle.getInt("padding"));
if(Helper.isValidParameter(joStyle, "paddingLeft"))
v.setPadding(joStyle.getInt("paddingLeft"), v.getPaddingTop(), v.getPaddingRight(), v.getPaddingBottom());
if(Helper.isValidParameter(joStyle, "paddingTop"))
v.setPadding(v.getPaddingLeft(), joStyle.getInt("paddingTop"), v.getPaddingRight(), v.getPaddingBottom());
if(Helper.isValidParameter(joStyle, "paddingRight"))
v.setPadding(v.getPaddingLeft(), v.getPaddingTop(), joStyle.getInt("paddingRight"), v.getPaddingBottom());
if(Helper.isValidParameter(joStyle, "paddingBottom"))
v.setPadding(v.getPaddingLeft(), v.getPaddingTop(), v.getPaddingRight(), joStyle.getInt("paddingBottom"));
if(Helper.isValidParameter(joStyle, "margin")) {
layoutParams = new LinearLayout.LayoutParams(v.getLayoutParams());
layoutParams.setMargins(joStyle.getInt("margin"), joStyle.getInt("margin"), joStyle.getInt("margin"), joStyle.getInt("margin"));
}
if(Helper.isValidParameter(joStyle, "marginLeft")) {
layoutParams = new LinearLayout.LayoutParams(v.getLayoutParams());
layoutParams.setMargins(joStyle.getInt("marginLeft"), layoutParams.topMargin, layoutParams.rightMargin, layoutParams.bottomMargin);
}
if(Helper.isValidParameter(joStyle, "marginTop")) {
layoutParams = new LinearLayout.LayoutParams(v.getLayoutParams());
layoutParams.setMargins(layoutParams.leftMargin, joStyle.getInt("marginTop"), layoutParams.rightMargin, layoutParams.bottomMargin);
}
if(Helper.isValidParameter(joStyle, "marginRight")) {
layoutParams = new LinearLayout.LayoutParams(v.getLayoutParams());
layoutParams.setMargins(layoutParams.leftMargin, layoutParams.topMargin, joStyle.getInt("marginRight"), layoutParams.bottomMargin);
}
if(layoutParams != null)
v.setLayoutParams(layoutParams);
RelativeLayout.LayoutParams relativeLayoutParams = null;
if (Helper.isValidParameter(joStyle, "alignParentTop") && joStyle.getBoolean("alignParentTop")) {
relativeLayoutParams = new RelativeLayout.LayoutParams(v.getLayoutParams());
relativeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
}
if (Helper.isValidParameter(joStyle, "alignParentLeft") && joStyle.getBoolean("alignParentLeft")) {
relativeLayoutParams = new RelativeLayout.LayoutParams(v.getLayoutParams());
relativeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_LEFT);
}
if (Helper.isValidParameter(joStyle, "alignParentBottom") && joStyle.getBoolean("alignParentBottom")) {
relativeLayoutParams = new RelativeLayout.LayoutParams(v.getLayoutParams());
relativeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
}
if (Helper.isValidParameter(joStyle, "alignParentRight") && joStyle.getBoolean("alignParentRight")) {
relativeLayoutParams = new RelativeLayout.LayoutParams(v.getLayoutParams());
relativeLayoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
}
if(Helper.isValidParameter(joStyle, "marginLeft")) {
relativeLayoutParams = new RelativeLayout.LayoutParams(v.getLayoutParams());
relativeLayoutParams.setMargins(joStyle.getInt("marginLeft"), relativeLayoutParams.topMargin, relativeLayoutParams.rightMargin, relativeLayoutParams.bottomMargin);
}
if(Helper.isValidParameter(joStyle, "marginTop")) {
relativeLayoutParams = new RelativeLayout.LayoutParams(v.getLayoutParams());
relativeLayoutParams.setMargins(relativeLayoutParams.leftMargin, joStyle.getInt("marginTop"), relativeLayoutParams.rightMargin, relativeLayoutParams.bottomMargin);
}
if(Helper.isValidParameter(joStyle, "marginRight")) {
relativeLayoutParams = new RelativeLayout.LayoutParams(v.getLayoutParams());
relativeLayoutParams.setMargins(relativeLayoutParams.leftMargin, relativeLayoutParams.topMargin, joStyle.getInt("marginRight"), relativeLayoutParams.bottomMargin);
}
if (relativeLayoutParams != null) {
v.setLayoutParams(relativeLayoutParams);
}
} catch (Exception e) {
Helper.logError("", e);
}
}
}
public static String getSdcardPath() {
if(sdcardPath == null)
sdcardPath = ctx.getApplicationInfo().dataDir;
return sdcardPath;
}
public static String getResourcesPath() {
return getSdcardPath() + "/resources/";
}
public static String getCSSPath() {
return getResourcesPath() + "default.css";
}
public static String getImagesPath() {
return getResourcesPath() + "images/" + ResourceConstants.getScreenDPI(ctx) + "/";
}
public static String getImagesPathNoDpi() {
return getResourcesPath() + "images/";
}
public static NinePatchDrawable loadNinePatchFromFilesystem(String filename) {
if(ninePatchHashMaps == null)
ninePatchHashMaps = new ArrayList<HashMap<String, NinePatchDrawable>>();
// check if we already have this filename so we can reuse it
for (int i = 0; i < ninePatchHashMaps.size(); i++) {
HashMap<String, NinePatchDrawable> row = ninePatchHashMaps.get(i);
if(row.containsKey(filename))
return row.get(filename);
}
NinePatchDrawable patchy = null;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(filename, options);
byte[] chunk = bitmap.getNinePatchChunk();
boolean result = NinePatch.isNinePatchChunk(chunk);
if (result)
patchy = new NinePatchDrawable(bitmap, chunk, new Rect(), null);
} catch (Exception e){
Helper.logError("NinePatchLoading",e);
}
if(patchy != null) {
HashMap<String, NinePatchDrawable> drawableImage = new HashMap<String, NinePatchDrawable>();
drawableImage.put(filename, patchy);
ninePatchHashMaps.add(drawableImage);
}
return patchy;
}
public static Drawable loadImageFromFilesystem(String filename) {
if(imagesHashMaps == null)
imagesHashMaps = new ArrayList<HashMap<String, Drawable>>();
// check if we already have this filename so we can reuse it
for (int i = 0; i < imagesHashMaps.size(); i++) {
HashMap<String, Drawable> row = imagesHashMaps.get(i);
if(row.containsKey(filename))
return row.get(filename);
}
Drawable image = null;
try {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
Bitmap bitmap = BitmapFactory.decodeFile(filename, options);
if(bitmap == null)
bitmap = BitmapFactory.decodeFile(filename.replace(ResourceConstants.getScreenDPI(ctx) + "/", ""), options);
image = new BitmapDrawable(bitmap);
} catch (Exception e){
Helper.logError("ImageLoadingError",e);
}
if(image != null) {
HashMap<String, Drawable> drawableImage = new HashMap<String, Drawable>();
drawableImage.put(filename, image);
imagesHashMaps.add(drawableImage);
}
return image;
}
}
My application is running fine but when it went in testing,it have some issue somewhere it got crashed and some issue also happens my question is how can i get all logs of my application in testing phase from device when device is not connection to computer because tester not use eclipse.
please help me to resolve this. Thanks in advance for any help.
You should use a crash report library like BugSense or Accra.
This kind of libs mimics the Android market feature of released apps, but during testing phase : you can get complete crash reports, with stack traces and other data (first time/last time of bug occurence, device model, etc.)
If you really want log. You can use the code below:
logcatProc = Runtime.getRuntime().exec(cmds);
mReader = new BufferedReader(new InputStreamReader(logcatProc.getInputStream()), 1024);
String line = null;
while ((line = mReader.readLine()) != null) {
if (line.length() == 0) {
continue;
}
if (out != null && line.contains(mPID)) {
out.write((simpleDateFormat2.format(new Date()) + " " + line + "\n").getBytes());
}
}
cmds = "logcat *:e *:i | grep \"(" + mPID + ")\"";
you can use your own grep format.
Tips: The logcat will be flushed off in a while
so you should put above code in a thread
You should try android-logging-log4j.
By the help of this Api you can record all the crash log in form of Text, Xml format and will be stored in the path you will provide like Phone memory or SD card.
So even if device is in Offline mode all the crash entry will be recorded over there. So you can get from that device and go through it for debugging.
Hope this will help you.
You have to use this code to get your own project logs.
public class LogcatFileManager {
private static LogcatFileManager INSTANCE = null ;
private static String PATH_LOGCAT;
private LogDumper mLogDumper = null ;
private int MPID;
private SimpleDateFormat simpleDateFormat1 = new SimpleDateFormat ( "yyyyMMdd" );
private SimpleDateFormat simpleDateFormat2 = new SimpleDateFormat ( "yyyy-MM-dd HH: mm: SS" );
public static LogcatFileManager getInstance () {
if (INSTANCE == null ) {
INSTANCE = new LogcatFileManager ();
}
return INSTANCE;
}
private LogcatFileManager () {
MPID = android.os.Process.myPid ();
}
private void setFolderPath (String folderPath) {
File folder = new File (folderPath);
if (! folder.exists ()) {
folder.mkdirs ();
}
if (! folder.isDirectory ())
throw new IllegalArgumentException ( "The folder path is Not a logcat Directory:" + folderPath);
PATH_LOGCAT = folderPath.endsWith("/") ? folderPath : folderPath + "/";
}
public void start (String saveDirectoy) {
setFolderPath (saveDirectoy);
if (mLogDumper == null )
mLogDumper = new LogDumper (String.valueOf (MPID), PATH_LOGCAT);
mLogDumper.start ();
}
public void stop () {
if (mLogDumper!=null ) {
mLogDumper.stopLogs();
mLogDumper = null ;
}
}
public class LogDumper extends Thread {
private Process logcatProc;
private BufferedReader MReader = null ;
private boolean mRunning = true ;
String cmds = null ;
private String MPID;
private FileOutputStream out = null ;
public LogDumper (String pid, String dir) {
MPID = pid;
try {
out = new FileOutputStream (new File(dir, "logcat-" + simpleDateFormat1.format (new Date ()) +".log"),true);
} catch (FileNotFoundException e) {
e.printStackTrace ();
}
cmds = "logcat *:e *:i | grep \"(" + MPID + ")\"";
}
public void stopLogs () {
mRunning = false ;
}
#Override
public void run() {
// TODO Auto-generated method stub
try {
logcatProc = Runtime.getRuntime().exec(cmds);
MReader = new BufferedReader ( new InputStreamReader (logcatProc.getInputStream ()), 1024 );
String line = null ;
while (mRunning && (line=MReader.readLine())!=null ) {
if (! mRunning) {
break ;
}
if (line.length () == 0 ) {
continue ;
}
if (out!=null && line.contains (MPID)) {
out.write ((simpleDateFormat2.format(new Date())+""+line+"\n").getBytes());
}
}
} catch (IOException e) {
e.printStackTrace ();
} finally {
if (logcatProc!=null ) {
logcatProc.destroy();
logcatProc = null ;
}
if (MReader!=null) {
try {
MReader.close ();
MReader = null ;
} catch (IOException e) {
e.printStackTrace ();
}
}
if (out!=null) {
try {
out.close ();
} catch (IOException e) {
e.printStackTrace ();
}
out = null ;
}
}
}
}
}
crashlytics is something you need: http://try.crashlytics.com/
You will be informed about errors, version of app that crashed etc...