Covert a code to class - java

Can any one help me to learn how to convert a code to a class so I can use it every where?
for example I have this code
How can I convert it to a separate class and use it in my diffrent activities?
I am new with java and really have problem with this..Thanks for your helps
public String getInformationData(String mySQL){
String information_text=null;
try{
db = SQLiteDatabase.openDatabase(ClubCP.DbPath,null,SQLiteDatabase.CREATE_IF_NECESSARY);
Cursor information = mDb.rawQuery(mySQL,null);
int information1 = information.getColumnIndex("description");
while (information.moveToNext()) {
String columns = (String) information.getString(information1);
information_text = "<head><style>#font-face {font-family: 'verdana';src: url('file://"+ ClubCP.SDcardPath+ "Homa.ttf');}body {font-family: 'verdana';color:#ffffff;font-size:18px;padding:10px 10px 0 10px;}</style></head>"+"<html Content-Type: text/html charset=UTF-8;dir=\"rtl\"><body>"
+ "<p dir=\"rtl\" align=\"justify\">"
+ columns
+ "</p> "
+ "</body></html>";
}
} catch (Exception e) {
Toast.makeText(callingActivity, e.getMessage(), 1).show();
}
return information_text;
}
Finally I created my class..I added another method to it but when I call it I get FC ..Where is my mistake?
package co.tosca.persianpoem;
import java.io.File;
import android.app.Activity;
import android.content.Context;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
public class persian_poem_class {
private Context c = null;
private SQLiteDatabase Db=null;
private Activity callingActivity;
//private Resources res =null ;
public persian_poem_class(Context c,Activity a)
{
// Constructor
this.c = c;
Db = SQLiteDatabase.openDatabase(ClubCP.DbPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
callingActivity=a;
}
public String getInformationData(String mySQL)
{
String information_text = null;
try
{
Cursor information = Db.rawQuery(mySQL,null);
int information1 = information.getColumnIndex("description");
while (information.moveToNext())
{
String columns = (String) information.getString(information1);
information_text = "<head><style>#font-face {font-family: 'verdana';src: url('file://"+ ClubCP.SDcardPath+ "Homa.ttf');}body {font-family: 'verdana';color:#ffffff;font-size:18px;padding:10px 10px 0 10px;}</style></head>"+"<html Content-Type: text/html charset=UTF-8;dir=\"rtl\"><body>"
+ "<p dir=\"rtl\" align=\"justify\">"
+ columns
+ "</p> "
+ "</body></html>";
}
}
catch (Exception e)
{
Toast.makeText(c, e.getMessage(), Toast.LENGTH_SHORT).show();
}
return information_text;
}
public void Change_header(View v,String id){
String path = ClubCP.SDcardPath + "/temp/"+id+"-header.jpg";
Log.i("view binder", path);
File imgFile = new File(path);
ImageView img=(ImageView)v;
if(imgFile.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
img.setImageBitmap(myBitmap);
}
else {
img.setImageDrawable(callingActivity.getDrawable(R.drawable.music_album_header_vinyl));
}
}
public Cursor getData(String mySQL){
Cursor c = Db.rawQuery(mySQL, null);
return c;
}
public void closeMyDb()
{
if (Db != null)
Db.close();
else
throw new NullPointerException("No database selected!");
}
}
I call secound method by this code
persian_poem_class main = new persian_poem_class(Book_list.this);
ImageView header=(ImageView)findViewById(R.id.img_header_book_list_activity);
main.Change_header(header, Peot_ID_for_db);
Again thanks for your time..
I fixed my class but now I have another problem with Change_header method..I get this error for getDrawable(R.drawable.music_album_header_vinyl) "getdrawable is undifined" I searched and I found problem is with scope but Cant fix it..I tried c.getDrawable but still have problementer code here

Okay I made a simple class according your request but some section of your code is unclear to me like ClubCP.DbPath or ClubCP.SDcardPath that I think these are static variables.
Anyway to use this class you need to make new instance from myClass:
myClass mMyClass = new myClass(youractivity.this);
mMyClass.getInformationData("your query");
mMyClass.closeMyDb() // To close your current database
Edited as per comment:
import java.io.File;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.Toast;
public class myClass
{
private Context c = null;
private SQLiteDatabase mDb;
public myClass(Context c)
{
// Constructor
this.c = c;
mDb = SQLiteDatabase.openDatabase(ClubCP.DbPath, null, SQLiteDatabase.CREATE_IF_NECESSARY);
}
public String getInformationData(String mySQL)
{
String information_text = null;
try
{
Cursor information = mDb.rawQuery(mySQL,null);
int information1 = information.getColumnIndex("description");
while (information.moveToNext())
{
String columns = (String) information.getString(information1);
information_text = "<head><style>#font-face {font-family: 'verdana';src: url('file://"+ ClubCP.SDcardPath+ "Homa.ttf');}body {font-family: 'verdana';color:#ffffff;font-size:18px;padding:10px 10px 0 10px;}</style></head>"+"<html Content-Type: text/html charset=UTF-8;dir=\"rtl\"><body>"
+ "<p dir=\"rtl\" align=\"justify\">"
+ columns
+ "</p> "
+ "</body></html>";
}
}
catch (Exception e)
{
Toast.makeText(c, e.getMessage(), Toast.LENGTH_SHORT).show();
}
return information_text;
}
public void Change_header(View v, String id)
{
String path = ClubCP.SDcardPath + "/temp/"+id+"-header.jpg";
Log.i("view binder", path);
File imgFile = new File(path);
ImageView img = (ImageView) v;
if(imgFile.exists())
{
Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath());
img.setImageBitmap(myBitmap);
}
else
img.setImageDrawable(c.getResources().getDrawable(R.drawable.music_album_header_vinyl));
}
public void closeMyDb()
{
if (mDb != null)
mDb.close();
else
throw new NullPointerException("No database selected!");
}
}

First, create a new class with a name that is descriptive of what it does (i.e. replace myClass with the name). Then, you create a constructor for this class by calling public myClass() WITHOUT a return type (this is how Java identifies it as a constructor. The constructor is what gets called every time the class runs, so simply paste your code in the body of the constructor, and it will get called every time you create a new object of the class.
Class myClass {
...
public myClass(){
public String getInformationData(String mySQL){
String information_text=null;
try{
db = SQLiteDatabase.openDatabase ...
... rest of code...
return information_text;
}
}
}
Welcome to object-oriented programming :)

Simple create a new class by right clicking on your src folder and clicking create new class.
Once you've gone the through the process of naming your class, go and paste your current code into that class, which would be your public String getInformationData(String mySQL) method.
Once this has been done, create a reference to this class, be creating an object of this class in every class/activity you want to call String getInformationData(String mySQL) from.
YourClass foo = new YourClass();
foo.getInformationData(string);
I hope this helps.

Related

Android SQLite, onCreate() not being called

I've been struggling to create a SQLite DB within my Android application.
I've looked at numerous tutorials, and quite a few existing questions on stack overflow and other sites.
Here is my DatabaseHelper class
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.util.Log;
public class DatabaseHelper extends SQLiteOpenHelper {
public SQLiteDatabase db;
public static final String DATABASE_NAME = "user.db";
//Module table
public static final String MODULE_TABLE = "modules_table";
public static final String MODULE_COL_1 = "ID";
public static final String MODULE_COL_2 = "CODE";
public static final String MODULE_COL_3 = "TITLE";
public DatabaseHelper(Context context) {
super(context, DATABASE_NAME, null, 1);
Log.d("SQL", "SQLite dbhelper");
db = getWritableDatabase();
}
#Override
public void onCreate(SQLiteDatabase db) {
//db.execSQL("create table " + MODULE_TABLE + "(" + MODULE_COL_1 + " INTEGER PRIMARY KEY AUTOINCREMENT, " + MODULE_COL_2 + " TEXT, " + MODULE_COL_3 + " TEXT " +")");
db.execSQL("create table modules_table (ID INTEGER PRIMARY KEY
AUTOINCREMENT, CODE TEXT, TITLE TEXT)");
Log.d("SQL", "SQLite onCreate");
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS " + MODULE_TABLE);
onCreate(db);
}
}
I've managed to get SQLite dbhelper to appear in logcat, but cannot get SQLite onCreate to appear, and cannot find the db anywhere in the file explorer or the device itself, both emulated and real device.
Any help would be greatly appreciated, and apologies for the formatting of the code!
I'd suggest using the following (temporarily) in the activity :-
DatabaseHelper myDBHelper = new DatabaseHelper(this); //<<<<<<<<< you appear to already have the equivalent of this line (if so use whatever variable name you have given to the DatabaseHelper object)
Cursor csr = myDBHelper.getWritableDatabase().query("sqlite_master",null,null,null,null,null,null);
DatabaseUtils.dumpCursor(csr);
csr.close();
Run and then check the log. You should see output for your modules_table and also sqlite_sequence (the latter because you have coded autoincrement.
sqlite_master is a system table that stores system information, such as table and index names i.e. the schema.
Additional - access to the database file
On a device that isn't rooted each applications data (data/data) is protected so you won't be able to see the database file.
On an emulator, it depends upon the emulator. I believe later versions of Android studio do now allow access e.g. :-
Note the above is Android 10.1 Pie (API 28) and hence the database has Write-Ahead Logging (WAL) and thus the -shm and -wal files also exist.
The package is mjt.pvcheck. The full path is data/data/mjt.pvcheck/databases.
As you can see cache directory, then I'd suggest that for some reason, perhaps a failure, the database doesn't exist, but you do appear to have access as per however upon checking through the virtual device file explorer the only sub folder I have within my package is the cache.
Perhaps, try rerunning on the device (note in device explorer re-select the device as it doesn't refresh), which may be another reason why you didn't see the database.
I don't use SQL query like
db.execSQL("create table modules_table (ID INTEGER PRIMARY KEY
AUTOINCREMENT, CODE TEXT, TITLE TEXT)");
Log.d("SQL", "SQLite onCreate");
instead, I'm using my own implementation of SQLiteOpenHelper class
import android.content.Context;
import android.content.res.AssetManager;
import android.database.SQLException;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Environment;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.util.Log;
import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.zip.GZIPOutputStream;
public class DbProvider extends SQLiteOpenHelper {
private static final ReentrantReadWriteLock LOCK = new ReentrantReadWriteLock(true);
private static final int VERSION = 0;
private final String DB_NAME = "mydb";
private final AssetManager assets;
private DbProvider(Context context) {
super(context, DB_NAME, null, VERSION);
assets = context.getAssets();
}
#NonNull
public static DbProvider getInstance() {
return new DbProvider(App.getContext());
}
#NonNull
public static ReentrantReadWriteLock.WriteLock writeLock() {
return LOCK.writeLock();
}
#NonNull
public static ReentrantReadWriteLock.ReadLock readLock() {
return LOCK.readLock();
}
#NonNull
public static ReentrantReadWriteLock getLock() {
return LOCK;
}
public static void close(DbProvider instance) {
try {
instance.close();
} catch (Exception ex) {
}
}
#Override
public void onCreate(SQLiteDatabase db) {
executeQuery(db, "db-scripts/database.sql", false);
Log.w("database", "database create");
executeQuery(db, "db-scripts/database_updates.sql", true);
Log.w("database", "database update");
}
private void executeQuery(SQLiteDatabase db, String sql, boolean shouldHandleExceptions) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(new InputStreamReader(assets.open(sql)));
String line;
File tempDbScript = new File(Environment.getExternalStorageDirectory(), "iErunt/dbBackup");
tempDbScript.getParentFile().mkdirs();
tempDbScript.createNewFile();
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(tempDbScript));
while ((line = bufferedReader.readLine()) != null) {
line = line.replaceAll("\t+", " ").replaceAll("\n+", " ").replaceAll(" +", " ").replaceAll(";", ";\n");
if (line.startsWith("--") || line.isEmpty()) {
continue;
}
bufferedWriter.write(line);
bufferedWriter.flush();
}
bufferedWriter.close();
bufferedReader.close();
bufferedReader = new BufferedReader(new FileReader(tempDbScript));
db.beginTransaction();
while ((line = bufferedReader.readLine()) != null) {
if (!(line = line.trim().replace(";", "")).isEmpty()) {
if (shouldHandleExceptions) {
try {
db.execSQL(line);
} catch (SQLException ex) {
Log.e("database", ex.getMessage(), ex);
}
} else {
db.execSQL(line);
}
}
}
db.setTransactionSuccessful();
db.endTransaction();
tempDbScript.delete();
} catch (IOException ex) {
Log.e("database", ex.getMessage(), ex);
} finally {
if (bufferedReader != null) {
try {
bufferedReader.close();
} catch (IOException e) {
}
}
}
}
#Override
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
executeQuery(db, "db-scripts/database_updates.sql", true);
}
}
and put initial DB schema of your database in assets/db-scripts/database.sql
and whenever you make DB modifications put your alter queries in assets/db-scripts/database_updates.sql. Be sure to increase VERSION of the database when updating the database.
What this class does is read your entire SQL script and executes one by one. which significantly reduces development time.
Note: You'll need android.permission.WRITE_EXTERNAL_STORAGE permission, as this creates a temp file and deletes it at the end
Hope this helps!

How to use Java classes in Talend

I have the following three classes :
I tried making the routine of 1 & 2 and used tjava to call the main class and the method from 1 & 2 but I am unable to fetch those methods.
1)
package page_scraper;
import com.gargoylesoftware.htmlunit.Page;
import com.gargoylesoftware.htmlunit.WebClient;
import com.gargoylesoftware.htmlunit.WebClientOptions;
import com.gargoylesoftware.htmlunit.html.FrameWindow;
import com.gargoylesoftware.htmlunit.html.HtmlButtonInput;
import com.gargoylesoftware.htmlunit.html.HtmlElement;
import com.gargoylesoftware.htmlunit.html.HtmlOption;
import com.gargoylesoftware.htmlunit.html.HtmlPage;
import com.gargoylesoftware.htmlunit.html.HtmlSelect;
import com.gargoylesoftware.htmlunit.html.HtmlTextInput;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintStream;
import java.io.Writer;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import page_scraper.UnitArray;
public class PageScraper {
public void Scrape() throws IOException {
try {
UnitArray object = new UnitArray();
ArrayList<String> unitList = object.getUnitArray();
WebClient webClient = new WebClient();
webClient.getOptions().setThrowExceptionOnScriptError(false);
webClient.getOptions().setThrowExceptionOnFailingStatusCode(false);
HtmlPage page = (HtmlPage)webClient.getPage("http://www.bmreports.com/servlet/com.logica.neta.bwp_PanBMUData");
List frames = page.getFrames();
HtmlPage page1 = (HtmlPage)((FrameWindow)frames.get(0)).getEnclosedPage();
HtmlTextInput settlementDay = (HtmlTextInput)page1.getHtmlElementById("param5");
HtmlSelect period = (HtmlSelect)page1.getHtmlElementById("param6");
HtmlOption periodOption = period.getOption(1);
HtmlTextInput unitId = (HtmlTextInput)page1.getHtmlElementById("param1");
HtmlButtonInput button = (HtmlButtonInput)page1.getHtmlElementById("go_button");
String outputLocation = String.valueOf(System.getProperty("user.home")) + "/Documents/output.csv";
FileWriter fileWriter = new FileWriter(outputLocation);
String errorLocation = String.valueOf(System.getProperty("user.home")) + "/Documents/error.csv";
FileWriter errorWriter = new FileWriter(errorLocation);
int i = 0;
while (i < unitList.size()) {
int x = 0;
while (x < 365) {
String errorData;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Calendar cal = Calendar.getInstance();
cal.add(5, - x);
String dateValue = dateFormat.format(cal.getTime());
System.out.println(dateValue);
settlementDay.setValueAttribute(dateValue);
period.setSelectedAttribute(periodOption, true);
unitId.setValueAttribute(unitList.get(i));
System.out.println(unitList.get(i));
try {
button.click();
HtmlPage page2 = (HtmlPage)((FrameWindow)frames.get(1)).getEnclosedPage();
String pageSource = page2.asXml();
int firstIndex = pageSource.indexOf("csv=") + 38;
int secondIndex = pageSource.indexOf("n\"") + 1;
String csvData = pageSource.substring(firstIndex, secondIndex);
fileWriter.append(csvData);
}
catch (ClassCastException e) {
errorData = String.valueOf(dateValue) + " " + unitList.get(i) + System.getProperty("line.separator");
System.out.println(errorData);
errorWriter.append(errorData);
continue;
}
catch (StringIndexOutOfBoundsException e) {
errorData = String.valueOf(dateValue) + " " + unitList.get(i) + System.getProperty("line.separator");
System.out.println(errorData);
errorWriter.append(errorData);
continue;
}
++x;
}
++i;
}
webClient.close();
fileWriter.close();
errorWriter.close();
}
catch (IOException e) {
e.printStackTrace();
}
}
}
2)
package page_scraper;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
public class UnitArray {
public ArrayList<String> getUnitArray() {
String csvList = "abc,xyz";
ArrayList<String> list = new ArrayList<String>(Arrays.asList(csvList.split(",")));
return list;
}
}
3)
package page_scraper;
import page_scraper.PageScraper;
public class main {
public static void main(String[] args) throws Exception {
PageScraper test = new PageScraper();
test.Scrape();
}
}
I made the routines for the above code(1) & 2)) in Talend and then used tjava to call the method but unable to do so..I also tried using tjava for all and did a onSubjob ok on each of the tjava.
How can I call these classes in talend and call the method ?
Firstly, routines classes in Talend need to be in routines package
package routines;
public class PageScraper {
public void Scrape() {
System.out.println("PageScraper.Scrape");
}
}
Secondly, to use it in Job you need to drag'n'drop routine to opened job area.
Then you can use your class in that way
You can easily make a jar file that contains the three classes then load the jar using tLibraryLoad or include the jar in your routine if you want to get more reusability.
As suggested in the other answers, you need to define classes under routines package.
in case you are using Takend 7.3 & above, Right click on your routine and add it as Dependent package
Get routines as a jar and in case using in bigData jobs, you may need to use tLibraryLoad to package it together with other dependencies..

how to get a list of values?

Below is the code which i want to get the output of the names of the particular administrator number , administrator Emailid , but insted of that i am getting the output as : List of ---> com.demo.model.Administrator#91e143 with different numbers , basically i am new to java .Would you please help me in the Loop Iteration .
package com.demo.action;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.struts.action.Action;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionForward;
import org.apache.struts.action.ActionMapping;
import org.apache.struts.actions.DispatchAction;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import com.demo.model.Administrator;
import com.demo.model.AdministratorDAO;
import com.demo.model.AdministratorDemo;
import com.demo.model.JQueryDataTableParam;
import com.demo.model.JqueryDatatablesParamUtil;
public class AdministratorAction extends Action {
public ActionForward execute(ActionMapping mapping, ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
System.out.println("in execute..");
JQueryDataTableParam param = JqueryDatatablesParamUtil
.getParam(request);
String txt2=request.getParameter("txt1");
//String select2=request.getParameter("select1");
//request.setAttribute("e", "select2");
//String select3=request.getParameter("select2");
//System.out.println("txtValue->"+e);
//System.out.println("txtValue->"+select2);
System.out.println("txtValue->"+txt2);
//String var = Administrator.isValidname(sData);
String sEcho = param.sEcho;
int iTotalRecords;
int iTotalDisplayRecords;
int start = param.iDisplayStart;
System.out.println("start" + start);
int last = param.iDisplayLength +param.iDisplayStart;
System.out.println("last" + last);
int sortColumnIndex = param.iSortColumnIndex;
System.out.println("sortColumnIndex" + sortColumnIndex);
String sortDirection = param.sSortDirection;
System.out.println("sortDirection" + sortDirection);
JSONArray data = new JSONArray();
iTotalRecords = AdministratorDemo.getAdminCount();
List<Administrator> Administrators = new LinkedList<Administrator>();
for (Administrator a : AdministratorDemo.getAdimistrators()) {
if (a.getAdministrator_nm() != null
&& a.getAdministrator_nm().toLowerCase()
.contains(param.sSearch.toLowerCase())
|| a.getAdmin_Email_ID() != null
&& a.getAdmin_Email_ID().toLowerCase()
.contains(param.sSearch.toLowerCase())
|| a.getAdmin_Fax_Phone_Num_Tx() != null
&& a.getAdmin_Fax_Phone_Num_Tx().toLowerCase()
.contains(param.sSearch.toLowerCase())) {
Administrators.add(a);
}
}
iTotalDisplayRecords = iTotalRecords;
if (Administrators.size() < param.iDisplayStart + param.iDisplayLength)
Administrators = Administrators.subList(param.iDisplayLength,
Administrators.size());
else
Administrators = Administrators.subList(param.iDisplayStart,
param.iDisplayStart + param.iDisplayLength);
System.out.println("End of the operations");
try {
JSONObject jsonresponse = new JSONObject();
jsonresponse.put("sEcho", sEcho);
jsonresponse.put("iTotalRecords", iTotalRecords);
jsonresponse.put("iTotalDisplayRecords", iTotalDisplayRecords);
JSONArray row = new JSONArray();
for(Iterator<Administrator> i = AdministratorDemo.getAdimistrators().iterator();i.hasNext();)
{
System.out.println(i.next());
}
jsonresponse.put("aaData", data);
response.setContentType("application/json");
response.getWriter().print(jsonresponse.toString());
} catch (JSONException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
response.setContentType("text/html");
response.getWriter().print(e1.getMessage());
}
System.out.println("In execute method.");
return null;
}
public String getXMLObject(HttpServletRequest request) {
return new java.util.Date().toString()
+ " sent by vasu from Date Action";
}
}
The result that you are seeing (com.demo.model.Administrator#91e143) is the default string representation of the Administrator object, more specifically, it's what is returned by the default toString() method inherited from Object
To print useful information, override public String toString() of Administrator
You need to override Object#toString() in your Administrator class.
This method can return any meaningful representation of the object you want, e.g:
#Override
public String toString() {
return "id = " + id + "email = " + email;
}
You're making a list of Administrators, where you want to make a list of Strings.
Alternatively (and probably better), if you can change the Administrator class, just implement the toString method in it, that will return the string you want to see on the screen.

On Android simple-xml serial.read() throws StackOverflowError

I'm trying to learn to use xml in Java (Android platform, using Eclipse and simple-xml-2.5.2).
I keep getting a weird java.lang.StackOverflowError in the "serial.read" line in "Training.java".
Can you help fixing the problem? Is it an xml definition error?
I include the source below:
File beacons.java:
package com.marcos.training;
import java.util.List;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.ElementList;
#Element
public class Beacons {
#ElementList(inline=true)
private List<Beacon> list;
#Element
private String id;
public String getId() {
return id;
}
public Integer getSize() {
return list.size();
}
public List<Beacon> getList() {
return list;
}
}
File Beacon.java:
package com.marcos.training;
import org.simpleframework.xml.Attribute;
import org.simpleframework.xml.Element;
import org.simpleframework.xml.Root;
#Root
public class Beacon {
#Attribute
protected String ssid;
#Element
protected String bssid;
public String getSsid() {
return ssid;
}
public String getBssid() {
return bssid;
}
}
File Training.java:
package com.marcos.training;
import org.simpleframework.xml.Serializer;
import org.simpleframework.xml.core.Persister;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;
import android.content.res.Resources.NotFoundException;
public class Training extends Activity {
private final static String TAG = Training.class.getCanonicalName();
TextView textStatus;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
textStatus = (TextView) findViewById(R.id.textStatus);
Serializer serial = new Persister();
try {
Beacons myBeacons;
try {
myBeacons = serial.read(Beacons.class, getResources().openRawResource(R.xml.beacons));
Log.i(TAG, "Number of Beacons: " + myBeacons.getSize());
} catch (NotFoundException e) {
Log.d(TAG, "Uncaught exception", e);
return;
} catch (Exception e) {
Log.d(TAG, "Uncaught exception", e);
return;
}
int len = myBeacons.getSize();
for (int i = 0; i < len; i++) {
Beacon b = myBeacons.getList().get(i);
textStatus.append("Beacon " + (i+1) + "\n");
textStatus.append(" SSID : " + b.getSsid() + "\n");
textStatus.append(" BSSID : " + b.getBssid() + "\n");
textStatus.append("\n");;
}
} catch (Exception e) {
Log.d(TAG, "Uncaught exception", e);
}
}
}
File beacons.xml:
<?xml version="1.0" encoding="utf-8"?>
<beacons id="1">
<beacon ssid="north">
<bssid>01:02:03:04:05:06</bssid>
</beacon>
<beacon ssid="east">
<bssid>02:03:04:05:06:07</bssid>
</beacon>
<beacon ssid="south">
<bssid>03:04:05:06:07:08</bssid>
</beacon>
<beacon ssid="west">
<bssid>04:05:06:07:08:09</bssid>
</beacon>
</beacons>
By putting your XML file into the XML directory of the resources, the Android build system is assuming you want that compiled down into a binary format and it obliges you. Therefore, when you access that input stream and then try to treat it as a textual XML representation it just doesn't work. You have 2 choices.
Move your XML file into the res\raw directory.
Leave it where it is and use the getResources().getXml(R.xml.beacons) API and create a pull parser for your particular XML.
See this link for more details.

How to read MP3 file tags

I want to have a program that reads metadata from an MP3 file. My program should also able to edit these metadata. What can I do?
I got to search out for some open source code. But they have code; but not simplified idea for my job they are going to do.
When I read further I found the metadata is stored in the MP3 file itself. But I am yet not able to make a full idea of my baby program.
Any help will be appreciated; with a program or very idea (like an algorithm). :)
The last 128 bytes of a mp3 file contains meta data about the mp3 file., You can write a program to read the last 128 bytes...
UPDATE:
ID3v1 Implementation
The Information is stored in the last 128 bytes of an MP3. The Tag
has got the following fields, and the offsets given here, are from
0-127.
Field Length Offsets
Tag 3 0-2
Songname 30 3-32
Artist 30 33-62
Album 30 63-92
Year 4 93-96
Comment 30 97-126
Genre 1 127
WARINING- This is just an ugly way of getting metadata and it might not actually be there because the world has moved to id3v2. id3v1 is actually obsolete. Id3v2 is more complex than this, so ideally you should use existing libraries to read id3v2 data from mp3s . Just putting this out there.
You can use apache tika Java API for meta-data parsing from MP3 such as title, album, genre, duraion, composer, artist and etc.. required jars are tika-parsers-1.4, tika-core-1.4.
Sample Program:
package com.parse.mp3;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.apache.tika.exception.TikaException;
import org.apache.tika.metadata.Metadata;
import org.apache.tika.parser.ParseContext;
import org.apache.tika.parser.Parser;
import org.apache.tika.parser.mp3.Mp3Parser;
import org.xml.sax.ContentHandler;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.DefaultHandler;
public class AudioParser {
/**
* #param args
*/
public static void main(String[] args) {
String fileLocation = "G:/asas/album/song.mp3";
try {
InputStream input = new FileInputStream(new File(fileLocation));
ContentHandler handler = new DefaultHandler();
Metadata metadata = new Metadata();
Parser parser = new Mp3Parser();
ParseContext parseCtx = new ParseContext();
parser.parse(input, handler, metadata, parseCtx);
input.close();
// List all metadata
String[] metadataNames = metadata.names();
for(String name : metadataNames){
System.out.println(name + ": " + metadata.get(name));
}
// Retrieve the necessary info from metadata
// Names - title, xmpDM:artist etc. - mentioned below may differ based
System.out.println("----------------------------------------------");
System.out.println("Title: " + metadata.get("title"));
System.out.println("Artists: " + metadata.get("xmpDM:artist"));
System.out.println("Composer : "+metadata.get("xmpDM:composer"));
System.out.println("Genre : "+metadata.get("xmpDM:genre"));
System.out.println("Album : "+metadata.get("xmpDM:album"));
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
} catch (TikaException e) {
e.printStackTrace();
}
}
}
For J2ME(which is what I was struggling with), here's the code that worked for me..
import java.io.InputStream;
import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;
import javax.microedition.lcdui.*;
import javax.microedition.media.Manager;
import javax.microedition.media.Player;
import javax.microedition.media.control.MetaDataControl;
import javax.microedition.midlet.MIDlet;
public class MetaDataControlMIDlet extends MIDlet implements CommandListener {
private Display display = null;
private List list = new List("Message", List.IMPLICIT);
private Command exitCommand = new Command("Exit", Command.EXIT, 1);
private Alert alert = new Alert("Message");
private Player player = null;
public MetaDataControlMIDlet() {
display = Display.getDisplay(this);
alert.addCommand(exitCommand);
alert.setCommandListener(this);
list.addCommand(exitCommand);
list.setCommandListener(this);
//display.setCurrent(list);
}
public void startApp() {
try {
FileConnection connection = (FileConnection) Connector.open("file:///e:/breathe.mp3");
InputStream is = null;
is = connection.openInputStream();
player = Manager.createPlayer(is, "audio/mp3");
player.prefetch();
player.realize();
} catch (Exception e) {
alert.setString(e.getMessage());
display.setCurrent(alert);
e.printStackTrace();
}
if (player != null) {
MetaDataControl mControl = (MetaDataControl) player.getControl("javax.microedition.media.control.MetaDataControl");
if (mControl == null) {
alert.setString("No Meta Information");
display.setCurrent(alert);
} else {
String[] keys = mControl.getKeys();
for (int i = 0; i < keys.length; i++) {
list.append(keys[i] + " -- " + mControl.getKeyValue(keys[i]), null);
}
display.setCurrent(list);
}
}
}
public void commandAction(Command cmd, Displayable disp) {
if (cmd == exitCommand) {
notifyDestroyed();
}
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
}
}

Categories