Receive MMS in my android application [closed] - java

It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
i am developing an android application that will receive MMS from specific number and show it in my application, I found this code but when i run it, Nothing Happened
public class MMSActivity extends Activity {
ImageView imageView1;
TextView t;
MMSMonitor myMonitor = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
t= (TextView) findViewById(R.id.t);
imageView1= (ImageView) findViewById(R.id.imageView1);
startMMSMonitor();
}
#Override
public void onDestroy()
{
super.onDestroy();
if(myMonitor != null)
myMonitor.stopMMSMonitoring();
}
protected void startMMSMonitor()
{
Context ctx = this;
ContentResolver cr = this.getContentResolver();
myMonitor = new MMSMonitor(cr, ctx);
myMonitor.startMMSMonitoring();
}
public void setMMSText(String text)
{
//Do whatever you want
}
public void setMMSImageData(byte[] data, String fileType)
{
//Do whatever you want
}
public class MMSMonitor {
private ContentResolver contentResolver = null;
private Handler mmshandler = null;
private ContentObserver mmsObserver = null;
public String mmsNumber = "";
public boolean monitorStatus = false;
public String activationCode;
int mmsCount = 0;
String lastMMSTxId = null;
String code;
public MMSMonitor(final ContentResolver contentResolver, final Context mainContext) {
this.contentResolver = contentResolver;
mmshandler = new MMSHandler();
mmsObserver = new MMSObserver(mmshandler);
System.out.println( "MMSMonitor :: ***** Start MMS Monitor *****");
}
public void startMMSMonitoring() {
try {
monitorStatus = false;
if (!monitorStatus) {//do not get it
//it is observe anychange like delete or incoming MMS etc...
//ContentObserver is used to get notified if the data residing in the data set has changed.
//So it is used to observe the data source for changes.
//Content providers manage access to a structured set of data
//Content providers are the standard interface that connects data
//in one process with code running in another process.
//When you want to access data in a content provider, you use the ContentResolver object
contentResolver.registerContentObserver(Uri.parse("content://mms-sms"), true, mmsObserver);
Uri uriMMSURI = Uri.parse("content://mms");
Cursor mmsCur = contentResolver.query(uriMMSURI, null, "msg_box = 4", null, "_id");
if (mmsCur != null && mmsCur.getCount() > 0) {
//Number of MMS
mmsCount = mmsCur.getCount();
System.out.println( "MMSMonitor :: Init MMSCount ==" + mmsCount);
}
}
} catch (Exception e) {
System.out.println( "MMSMonitor :: startMMSMonitoring Exception== "+ e.getMessage());
}
}
public void stopMMSMonitoring() {
try {
monitorStatus = false;
if (!monitorStatus){
contentResolver.unregisterContentObserver(mmsObserver);
}
} catch (Exception e) {
System.out.println( "MMSMonitor :: stopMMSMonitoring Exception == "+ e.getMessage());
}
}
//A Handler allows you to send and process Message and Runnable objects associated with a thread's MessageQueue.
class MMSHandler extends Handler {
public void handleMessage(final Message msg) {
//Log("MMS", "MMSMonitor :: Handler");
}
}
class MMSObserver extends ContentObserver {
private Handler mms_handle = null;
public MMSObserver(final Handler mmshandle) {
super(mmshandle);
mms_handle = mmshandle;
}
public void onChange(final boolean bSelfChange) {
super.onChange(bSelfChange);
//Log("MMS", "MMSMonitor :: Onchange");
Thread thread = new Thread() {
public void run() {
try {
monitorStatus = true;
// Send message to Activity
Message msg = new Message();
mms_handle.sendMessage(msg);
// Getting the mms count
Uri uriMMSURI = Uri.parse("content://mms/");
Cursor mmsCur = contentResolver.query(uriMMSURI, null, "msg_box = 4 or msg_box = 1", null,"_id");
int currMMSCount = 0;
if (mmsCur != null && mmsCur.getCount() > 0) {
currMMSCount = mmsCur.getCount();
}
if (currMMSCount > mmsCount) {
mmsCount = currMMSCount;
mmsCur.moveToLast();
// get id , subject
//String subject = mmsCur.getString(6);
//int id = Integer.parseInt(mmsCur.getString(0));
String subject = mmsCur.getString(mmsCur.getColumnIndex("sub"));
int id = Integer.parseInt(mmsCur.getString(mmsCur.getColumnIndex("_id")));
System.out.println( "MMSMonitor :: _id == " + id);
System.out.println( "MMSMonitor :: Subject == " + subject);
byte[] imgData = null;
String message = "";
String address = "";
String fileName = "";
String fileType = "";
String direction = "";
// GET DIRECTION
boolean isIncoming = false;
//int type = Integer.parseInt(mmsCur.getString(12));
int type = Integer.parseInt(mmsCur.getString(mmsCur.getColumnIndex("m_type")));
if (type == 128) {
direction = "0";
System.out.println( "MMSMonitor :: Type == Outgoing MMS");
} else {
isIncoming = true;
direction = "1";
System.out.println( "MMSMonitor :: Type == Incoming MMS");
}
// Get Parts
Uri uriMMSPart = Uri.parse("content://mms/part");
Cursor curPart = contentResolver
.query(uriMMSPart, null, "mid = " + id, null, "_id");
System.out.println( "MMSMonitor :: parts records length == "+ curPart.getCount());
curPart.moveToLast();
do {
//String contentType = curPart.getString(3);
//String partId = curPart.getString(0);
String contentType = curPart.getString(curPart.getColumnIndex("ct"));
String partId = curPart.getString(curPart.getColumnIndex("_id"));
System.out.println( "MMSMonitor :: partId == " + partId);
System.out.println( "MMSMonitor :: part mime type == "+ contentType);
// Get the message
if (contentType.equalsIgnoreCase("text/plain"))
{
System.out.println("MMSMonitor :: ==== Get the message start ====");
byte[] messageData = readMMSPart(partId);
if (messageData != null && messageData.length > 0)
message = new String(messageData);
if(message == ""){
Cursor curPart1 = contentResolver
.query(uriMMSPart, null, "mid = " + id +
" and _id =" + partId,null, "_id");
for (int i = 0; i < curPart1.getColumnCount(); i++)
{
System.out.println("MMSMonitor :: Column Name : " +
curPart1.getColumnName(i));
}
curPart1.moveToLast();
message = curPart1.getString(13);
}
System.out.println("MMSMonitor :: Txt Message == " + message);
//SEND DATA TO ACTIVITY
setMMSText(message);
}
// Get Image
else if (isImageType(contentType) == true) {
System.out.println("MMSMonitor :: ==== Get the Image start ====");
fileName = "mms_" + partId;
fileType = contentType;
imgData = readMMSPart(partId);
System.out.println( "MMSMonitor :: Iimage data length == "+ imgData.length);
//SEND DATA TO ACTIVITY
setMMSImageData(imgData, fileType);
}
} while (curPart.moveToPrevious());
}
} catch (Exception e) {
System.out.println( "MMSMonitor Exception:: "+ e.getMessage());
}
}
};
thread.start();
}
}
private byte[] readMMSPart(String partId) {
byte[] partData = null;
Uri partURI = Uri.parse("content://mms/part/" + partId);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
InputStream is = null;
try {
System.out.println("MMSMonitor :: Entered into readMMSPart try..");
ContentResolver mContentResolver = contentResolver;
is = mContentResolver.openInputStream(partURI);
byte[] buffer = new byte[256];
int len = is.read(buffer);
while (len >= 0) {
baos.write(buffer, 0, len);
len = is.read(buffer);
}
partData = baos.toByteArray();
//Log.i("", "Text Msg :: " + new String(partData));
} catch (IOException e) {
System.out.println( "MMSMonitor :: Exception == Failed to load part data");
} finally {
if (is != null) {
try {
is.close();
} catch (IOException e) {
System.out.println("Exception :: Failed to close stream");
}
}
}
return partData;
}
private boolean isImageType(String mime) {
boolean result = false;
if (mime.equalsIgnoreCase("image/jpg")
|| mime.equalsIgnoreCase("image/jpeg")
|| mime.equalsIgnoreCase("image/png")
|| mime.equalsIgnoreCase("image/gif")
|| mime.equalsIgnoreCase("image/bmp")) {
result = true;
}
return result;
}
}
}
//=====================
}
any answer i will appreciate it,
also
what this statement suppose be to do ?
Cursor mmsCur = contentResolver.query(uriMMSURI, null, "msg_box = 4 or msg_box = 1", null,"_id");

I think your approach isn't even the right one.
Afaik you have to register a broadcastreceiver and handle/implement this in your app in order to achieve what you want.
See
Android MMS Broadcast receiver
Detecting new MMS (Android 2.1)
Detecting MMS messages on Android
There are all infos u need ;)

Related

How to run Asynctask for show "data is reading" dialog in running thread

I have a thread which is continuously running ,when i will send the command to get the data, data starts to come. I wanna to show this process to the Asynctask show that user can understand data is reading . How can i achieve this please help me . For now i am using timer. but timer will work for fixed time. but if my data is less, that time, timer will take the same time that i don't want . If anyone have any idea please let me know.... Thanks in advance for help
I had use this but because of running thread message getting continuously.
public static class Test extends AsyncTask<String, String, String> {
ProgressDialog progressDialog;
DataBaseController dataBaseController;
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog( context);
progressDialog.setTitle( "Sync Data" );
progressDialog.setMessage( "Syncing..." );
progressDialog.setCancelable( false );
progressDialog.setIcon( android.R.drawable.ic_dialog_info );
progressDialog.show();
super.onPreExecute();
}
#Override
protected String doInBackground(String... strings) {
dataBaseController = DataBaseController.getnstance( context );
// seperating the data which is getting from getResponse method
if (strings[0] != null) {
String ok = strings[0].replace( "OK", "" ).replace( "Scale id,Rec.No,Date,Time,Bill No.,Item No.,Plu,Name,Qty,Rate,Amount,Void", "" );
String[] data = ok.split( "," );
Log.i( "TEST", strings[0] );
for (int i = 0; i < data.length; i++) {
char c = strings[0].charAt( i );
if (c == ',') {
int id = Integer.parseInt( data[0] );
int rec_no = Integer.parseInt( (data[1]) );
String Date = data[2];
if (Date != null)
Date = custom_date_format( Date );
String Time = data[3];
int Bill_No = Integer.parseInt( data[4] );
int Item_No = Integer.parseInt( data[5] );
int Plu = Integer.parseInt( data[6] );
String Name = data[7];
String weight_type = data[8];
int Unit;
if (weight_type=="Kg"){
Unit=0;
}else{
Unit=1;
}
float Qty = Float.parseFloat( data[9] );
float Rate = Float.parseFloat( data[10] );
float Amount = Float.parseFloat( data[11] );
String Void = data[12];
PLU plu = new PLU( id, rec_no, Date, Time, Bill_No, Item_No, Plu, Name, Unit, Qty, Rate, Amount );
boolean check = dataBaseController.isBillExist( plu.getRec_no() );
if (!check) {
dataBaseController.Trasaction(plu);
}
}
}
}
return String.valueOf( strings );
}
#Override
protected void onPostExecute(String result) {
if (progressDialog.isShowing()) {
progressDialog.dismiss();
}
if (result != null) {
Toast.makeText( context, "Mission successfully", Toast.LENGTH_SHORT ).show();
}else{
Toast.makeText( context, "Mission failed", Toast.LENGTH_SHORT ).show();
}
}
}
*******Thread which is connected*****************
private class ConnectedThread extends Thread {
private final BluetoothSocket mmSocket;
private final InputStream mmInStream;
private final OutputStream mmOutStream;
boolean get_actualdata = false;
private boolean stop = false;
private boolean hasReadAnything = false;
public ConnectedThread(BluetoothSocket socket) {
Log.d( TAG, "create ConnectedThread" );
mmSocket = socket;
InputStream tmpIn = null;
OutputStream tmpOut = null;
// Get the BluetoothSocket input and output streams
try {
tmpIn = socket.getInputStream();
// tmpIn.skip( 22 );
tmpOut = socket.getOutputStream();
} catch (IOException e) {
Log.e( TAG, "temp sockets not created", e );
}
mmInStream = tmpIn;
mmOutStream = tmpOut;
}
public void shutdown() {
stop = true;
if (!hasReadAnything) return;
if (mmInStream != null) {
try {
mmInStream.close();
} catch (IOException e) {
Log.e( TAG, "close() of InputStream failed." );
}
}
}
public void run() {
boolean send_validation = true;
int version;
while (true) {
try {
version = readfunction(); // reading the version response after sending command on bluetooth
} catch (Exception e) {
e.printStackTrace();
connectionLost();
break;
}
if (version == 0) {
if (send_validation && !get_actualdata) {
StringParsing( str.toString() );// it will seperate the version
get_actualdata = true;
}
} else {
try {
readfunction();
} catch (IOException e) {
e.printStackTrace();
}
}
if (get_actualdata && send_validation) {
try {
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
int ok = Handle_OK();//if getting ok
String status;
if (ok == 1) {
status = "OK";
mHandler.readLine( status );
} else {
status = "Not Recognised with device";
mHandler.readLine( status );
}
getReportResponse();
}
} catch (IOException e) {
connectionLost();
e.printStackTrace();
break;
}
}
}
}
//this method calling in running thread , it will response when command send by click on button
public void getReportResponse() throws IOException {
boolean with_header = false;
try {
BufferedReader bufferedReader = new BufferedReader( new InputStreamReader( mmInStream ) );
String line = null;
while ((line = bufferedReader.readLine()) != null) {
// String finalLine = line;
if (reset_the_reader_flag) { //if reset_the_header will true
with_header = false;
}
String f_line = custom_filter(line);
if (!f_line.isEmpty()){
if (with_header) { // if with_header flag will false then it will jump in else
// dataparse.ReportData( f_line);
new Handler( Looper.getMainLooper()).post( new Runnable() {
#Override
public void run() {
//Asynctask when command send this method will run
TabularFragment.Test data = new TabularFragment.Test();
data.execute( f_line );
}
} );
} else {
// if header matches set the with_header flag true, then exist from else part and again check with_heaer flag
// if header will not match, will jump in else and read the data that is without header.
if (f_line.matches( "Scale(.*)" )) {
with_header = true;
} else {//
dataparse.Data( f_line );
}
reset_the_reader_flag = false;
}
}
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
mmInStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}

JVMTI_ERROR_THREAD_NOT_ALIVE error using multiple activites and OpenWeatherMap API

I am making an weather app, on the main screen app shows current weather for a city that is chosen and on the second activity screen you can find weather for next 3 days. I have WeatherInfoTask.java that is used to get JSON for MainActivity and MultipleWeatherTask.java that is used to get JSON for MultipleDays (activity)
so the MainActivity works fine and I get JSON and all of the info is shown on the screen just as it should be, but when I click on the button that should redirect me to the screen of the MultipleDays, I am redirected and just a plain screen is shown without data and this error is shown:
E/StudioProfiler: JVMTI error: 15(JVMTI_ERROR_THREAD_NOT_ALIVE)
These are my files:
public class MainActivity extends AppCompatActivity {
public static String cityName;
Handler handler;
TextView titleText;
TextView temperatureText;
TextView descriptionText;
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(!isNetworkAvailable()){
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Closing the App")
.setMessage("No Internet Connection, check your settings")
.setPositiveButton("Close", new DialogInterface.OnClickListener()
{
#Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
})
.show();
}
handler = new Handler();
titleText = (TextView) findViewById(R.id.titleText);
temperatureText = (TextView) findViewById(R.id.temperatureText);
descriptionText = (TextView) findViewById(R.id.descriptionText);
PlaceAutocompleteFragment autocompleteFragment = (PlaceAutocompleteFragment)
getFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
autocompleteFragment.setHint("Find City");
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
cityName = place.getName().toString();
updateWeather(cityName);
/*Log.i(TAG, "Place: " + place.getName());*/
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.i("MainActivity", "An error occurred: " + status);
}
});
}
private void updateWeather(final String city){
new Thread(){
public void run(){
final JSONObject json = WeatherInfoTask.getJSON(MainActivity.this, city);
if(json == null){
Toast.makeText(MainActivity.this, "Error loading weather", Toast.LENGTH_LONG).show();
} else {
handler.post(new Runnable(){
public void run(){
SetWeather(json);
}
});
}
}
}.start();
}
private void SetWeather(JSONObject json){
try {
/*cityField.setText(json.getString("name").toUpperCase(Locale.US) +
", " +
json.getJSONObject("sys").getString("country"));*/
JSONObject details = json.getJSONArray("weather").getJSONObject(0);
JSONObject main = json.getJSONObject("main"); /*"main":{"temp":280.32,"pressure":1012,"humidity":81,"temp_min":279.15,"temp_max":281.15}*/
titleText.setText(R.string.title + cityName);
descriptionText.setText( /*"description":"light intensity drizzle"*/
details.getString("description") +
"\n" + "Humidity: " + main.getString("humidity") + "%" +
"\n" + "Pressure: " + main.getString("pressure") + " hPa");
temperatureText.setText(
String.format("%.2f", main.getDouble("temp"))+ " ℃");
}catch(Exception e){
Log.e("SimpleWeather", "One or more fields not found in the JSON data");
}
}
public void MultipleDays(View view){
Intent intent = new Intent(this, MultipleDays.class);
startActivity(intent);
}
}
Next one:
public class WeatherInfoTask {
private static final String OpenWeatherAPI =
"http://api.openweathermap.org/data/2.5/weather?q=%s&units=metric";
public static JSONObject getJSON(Context context, String city) {
try {
URL url = new URL(String.format(OpenWeatherAPI, city));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.addRequestProperty("x-api-key", context.getString(R.string.apikey));
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer json = new StringBuffer(1024);
String tmp = ""; /*tmp = temporary*/
while ((tmp = reader.readLine()) != null)
json.append(tmp).append("\n");
reader.close();
JSONObject data = new JSONObject(json.toString());
/*This value will be 404 if the request was not successful*/
if (data.getInt("cod") != 200) {
/*greska*/
return null;
}
return data;
} catch (Exception e) {
return null;
}
Next one:
public class MultipleDays extends AppCompatActivity {
Handler handler;
TextView day1;
TextView day2;
TextView day3;
Integer dayCounter = 1;
Date comparisonDate;
Date currentDate;
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Float dailyMin;
Float dailyMax;
Float currMin;
Float currMax;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_multiple_days);
handler = new Handler();
day1 = (TextView) findViewById(R.id.day1);
day2 = (TextView) findViewById(R.id.day2);
day3 = (TextView) findViewById(R.id.day3);
updateMultipleWeather(MainActivity.cityName);
}
private void updateMultipleWeather(final String city){
new Thread(){
public void run(){
final JSONObject json = MultipleWeatherTask.getJSON(MultipleDays.this, city);
if(json == null){
Toast.makeText(MultipleDays.this, "Error loading weather", Toast.LENGTH_LONG).show();
} else {
handler.post(new Runnable(){
public void run(){
setWeather(json);
}
});
}
}
}.start();
}
private void setWeather(JSONObject json){
try {
JSONArray list = json.getJSONArray("list");
for (int i=0; i < list.length() ; i++){
if(i == 0) {
String string = list.getJSONObject(i).getString("dt_txt");
string = convertDate(string);
comparisonDate = formatter.parse(string.replace("",""));
dailyMin = Float.parseFloat(list.getJSONObject(i).getString("temp_min"));
dailyMax = Float.parseFloat(list.getJSONObject(i).getString("temp_max"));
}
else if ( dayCounter <=3 ){
String string = list.getJSONObject(i).getString("dt_txt");
string = convertDate(string);
currentDate = formatter.parse(string.replace("","")); //datum u obliku "yy-MM-dd"
if ( comparisonDate == currentDate ){ //ako smo i dalje na istom danu
currMin = Float.parseFloat(list.getJSONObject(i).getString("temp_min"));
currMax = Float.parseFloat(list.getJSONObject(i).getString("temp_max"));
if( dailyMin > currMin ) dailyMin = currMin;
if( dailyMax < currMax ) dailyMax = currMax;
}
else {
switch (dayCounter){
case 1: day1.setText("Minimum temperature: " + String.format("%.2f", dailyMin) + "\n" +
"Maximum temperature: " + String.format("%.2f", dailyMax) + "\n" +
"Weather: " + list.getJSONObject(i-1).getString("description"));
dayCounter++;
break;
case 2: day2.setText("Minimum temperature: " + String.format("%.2f", dailyMin) + "\n" +
"Maximum temperature: " + String.format("%.2f", dailyMax) + "\n" +
"Weather: " + list.getJSONObject(i-1).getString("description"));
dayCounter++;
break;
case 3: day3.setText("Minimum temperature: " + String.format("%.2f", dailyMin) + "\n" +
"Maximum temperature: " + String.format("%.2f", dailyMax) + "\n" +
"Weather: " + list.getJSONObject(i-1).getString("description"));
dayCounter++;
break;
}
}
}
}
Next one:
public class MultipleWeatherTask {
private static final String OpenWeatherAPI =
"api.openweathermap.org/data/2.5/forecast?q=%s&units=metric";
public static JSONObject getJSON(Context context, String city) {
try {
URL url = new URL(String.format(OpenWeatherAPI, city));
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.addRequestProperty("x-api-key", context.getString(R.string.apikey));
BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
StringBuffer json = new StringBuffer(1024);
String tmp = ""; /*tmp = temporary*/
while ((tmp = reader.readLine()) != null)
json.append(tmp).append("\n");
reader.close();
JSONObject data = new JSONObject(json.toString());
/*This value will be 404 if the request was not successful*/
if (data.getInt("cod") != 200) {
/*greska*/
return null;
}
return data;
} catch (Exception e) {
return null;
}
}
}
File ---> Invalidate Caches / Restart will help you.

Android/Java - Out of Memory Exception with Dream Service

I have developed an application that uses the Android's Dream Service as a screen saver of sorts - it displays a slideshow of images. These images are housed in binary format within a database and decoded. I realize this is not the best way, but given the particular structure and purpose of this application, it is the most realistic. Additionally, the class does not make constant trips to database nor continuously decode image - it does this when it starts and then closes the resources.
With that being said, after the screen saver has run for a while, I occasionally receive an "Application has Stopped Working" message which I believe is related to an out of memory error. I find this a little odd because, far as I am aware, the bitmaps are only decoded once - when the service is attached to window. I do not see why there would be issues with memory when the only repetitive action is loading a bitmap into an ImageView container, certainly not something I believe requires a great deal of resources. I have looked over my code and have been unable to locate the issue.
What am I doing wrong; how can I stop these errors from occurring?
public class screenSaver extends DreamService {
XmlPullParser parser;
String storeImages = "";
// creates messages
public Bitmap drawText(Context c, int resource, String text) {
Resources resources = c.getResources();
Bitmap bitmap = BitmapFactory.decodeResource(resources, resource);
android.graphics.Bitmap.Config config = bitmap.getConfig();
if (config == null) {
config = android.graphics.Bitmap.Config.ARGB_8888;
}
bitmap = bitmap.copy(config, true);
Canvas canvas = new Canvas(bitmap);
TextPaint paint = new TextPaint(Paint.ANTI_ALIAS_FLAG);
float scale = resources.getDisplayMetrics().density;
paint.setColor(Color.BLACK);
paint.setTextSize(48 * scale);
int textWidth = canvas.getWidth() - (int) (16 * scale);
StaticLayout textLayout = new StaticLayout(text, paint, textWidth, Layout.Alignment.ALIGN_CENTER, 1f, 0f, false);
int textHeight = textLayout.getHeight();
float x = (bitmap.getWidth() - textWidth) / 2;
float y = (bitmap.getHeight() - textHeight) / 2;
canvas.save();
canvas.translate(x, y);
textLayout.draw(canvas);
canvas.restore();
return bitmap;
}
ArrayList<Bitmap> imageList = new ArrayList<Bitmap>();
int slideCounter = 0;
ImageView slide;
Cursor images;
Cursor corpImages;
final Handler handler = new Handler(Looper.getMainLooper());
private int counter = 0;
private Runnable runnable = new Runnable() {
#Override
public void run() {
slide.setImageBitmap(imageList.get(counter));
if (counter == (imageList.size() - 1)) {
counter = 0;
} else {
counter++;
}
}
};
public screenSaver() {
}
#Override
public void onAttachedToWindow() {
super.onAttachedToWindow();
setInteractive(false);
setFullscreen(true);
setContentView(R.layout.screen_saver);
databaseHelper dbHelper = new databaseHelper(this);
Intent testIntent = new Intent(this, lockActivity.class);
testIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(testIntent); // unpin screen so screen saver can load
SQLiteDatabase db = dbHelper.getReadableDatabase();
SharedPreferences preferences = getSharedPreferences("config", MODE_PRIVATE);
final String store = preferences.getString("store", "");
String managerMessageText = "";
String mainMessageText = "";
String districtMessageText = "";
try {
FileInputStream input = new FileInputStream(new File(this.getFilesDir(), "stores.xml"));
parser = Xml.newPullParser();
parser.setInput(input, null);
// begin search for correct 'store' tag
boolean elementsRemain = true;
while (elementsRemain) {
parser.next();
int event = parser.getEventType();
switch (event) {
case XmlPullParser.START_TAG:
String name = parser.getName();
if (name.equals("store")) {
Log.i("Screen Saver", "entering if store");
String number = parser.getAttributeValue(null, "number");
if (number.equals(store)) {
// located corresponding store, beginning parsing to find associate images and messages
boolean withinStore = true;
while (withinStore) {
parser.next();
if (parser.getEventType() == XmlPullParser.START_TAG) {
String tag = parser.getName();
if (tag.equals("images")) {
parser.nextTag();
while (parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("image")) {
if (parser.getAttributeValue(null, "id") != null && (!parser.getAttributeValue(null, "id").equals(""))) {
storeImages += parser.getAttributeValue(null, "id") + ",";
}
parser.nextTag();
if (parser.getEventType() == XmlPullParser.END_TAG) {
parser.nextTag();
}
}
}
parser.next();
if (parser.getEventType() == XmlPullParser.TEXT) {
switch (tag) {
case "message":
managerMessageText += parser.getText();
break;
case "district":
districtMessageText += parser.getText();
break;
case "corporate":
mainMessageText += parser.getText();
break;
default:
break;
}
}
} else if (parser.getEventType() == XmlPullParser.END_TAG && parser.getName().equals("store")) {
withinStore = false;
}
}
parser.next();
}
} else {
}
break;
case XmlPullParser.END_DOCUMENT:
elementsRemain = false;
break;
}
}
} catch (Exception e) {
Log.e("Error reading XML ", " " + e.getMessage());
}
/* LTO images
try {
File managerFile = new File(this.getFilesDir(), store + ".txt");
File universalFile = new File(this.getFilesDir(), "universal.txt");
File districtFile = new File(this.getFilesDir(), "district.txt");
BufferedReader reader = new BufferedReader(new FileReader(managerFile));
managerMessageText = reader.readLine();
reader = new BufferedReader(new FileReader(universalFile));
mainMessageText = reader.readLine();
reader = new BufferedReader(new FileReader(districtFile));
districtMessageText = reader.readLine();
} catch (Exception e) {
Log.e("Error opening file: ", e.getMessage());
}*/
/* images = db.rawQuery("SELECT " + databaseHelper.IMAGE + " FROM " + databaseHelper.TABLE_NAME + " where " + databaseHelper.LTO + " = 1", null);
images.moveToFirst();
while(!images.isAfterLast()) {
imageList.add(BitmapFactory.decodeByteArray(images.getBlob(images.getColumnIndex(databaseHelper.IMAGE)), 0, images.getBlob(images.getColumnIndex(databaseHelper.IMAGE)).length ));
images.moveToNext();
}
images.close(); */
if (storeImages.length() > 1) {
storeImages = storeImages.substring(0, storeImages.length() - 1); // remove trailing comma
}
// get all images that are associated with store
corpImages = db.rawQuery("SELECT " + databaseHelper.SLIDE_IMAGE + " FROM " + databaseHelper.SLIDE_TABLE + " WHERE " + databaseHelper.SLIDE_ID + " IN (" + storeImages + ")", null);
corpImages.moveToFirst();
while (!corpImages.isAfterLast()) {
imageList.add(BitmapFactory.decodeByteArray(corpImages.getBlob(corpImages.getColumnIndex(databaseHelper.SLIDE_IMAGE)), 0, corpImages.getBlob(corpImages.getColumnIndex(databaseHelper.SLIDE_IMAGE)).length));
corpImages.moveToNext();
}
corpImages.close();
db.close();
// begin drawing message bitmaps
if (managerMessageText != "") {
imageList.add(drawText(this, R.drawable.message_background, "Manager Message: \n" + managerMessageText));
}
if (mainMessageText != "") {
imageList.add(drawText(this, R.drawable.message_background, "Corporate Message: \n" + mainMessageText));
}
if (districtMessageText != "") {
imageList.add(drawText(this, R.drawable.message_background, "District Manager Message: \n" + districtMessageText));
}
slide = (ImageView) findViewById(R.id.slider);
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TimerTask() {
#Override
public void run() {
updateGUI();
}
}, 0, 8000);
}
;
#Override
public void onDetachedFromWindow() {
super.onDetachedFromWindow();
// unpin screen so it can update
Intent testIntent = new Intent(this, lockActivity.class);
testIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.startActivity(testIntent); // unpin screen so it can update
}
private void updateGUI() {
if (reminder.running || hourlyReminder.running) {
this.finish();
} else {
handler.post(runnable);
}
}
}
Thanks so much for any guidance.
Using the decodeResource() method directly attempts to allocate memory for the constructed bitmap & can result OutOfMemory. There are several options to decode bitmaps efficiently.
Setting inJustDecodeBounds of BitmapFactory.Options to true avoids memory allocation in decoding step. It seems you are not using this option.
You don't need to load a full image/bitmap into memory when you just need to show a scaled down/smaller version of it. You can control this by setting inSampleSize of BitmapFactory.Options. It seems you are not using this option as well.
Try using:
options.inJustDecodeBounds = true;
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
etc. options while decoding bitmaps to efficiently handle the memory.
You can find a whole tutorial here: https://developer.android.com/training/displaying-bitmaps/load-bitmap.html

Multi-Thread on ArrayList java

I'm developing an application in JavaFX who "scan" Mp3 files to get ID3tag.
Actually my program works, but the application is slow when there is a lot of songs (mp3).
I use a thread who scan every files from an list of mp3files (path).
I'm wondering if it's possible to use more threads to scan every files 4 by 4 rather than 1 by 1 ?
I'm low with multi-threading from java so I ask for your help. Any advice would be great.
Here is my function :
private ArrayList checkMp3files(String sDir)
{
this.currentData = 0;
this.filesCorrupted.clear();
ArrayList<DataSong> newLs = new ArrayList<>(); // ArrayList with Data from all Songs scanned
Task taskScan = new Task<ArrayList<DataSong>>() {
#Override
protected ArrayList<DataSong> call() throws InterruptedException, IOException, UnsupportedTagException
{
String absoluteLoc;
String location;
for(String mp3file : Mp3FileData)
{
DataSong ds = new DataSong();
updateMessage("Scanning " + ++currentData + " of " + nbrOfFiles + " Mp3files");
updateProgress(currentData, nbrOfFiles);
try {
mp3 = new Mp3File(mp3file);
} catch (InvalidDataException ex) {
filesCorrupted.add(mp3file);
}
long durationLong = mp3.getLengthInSeconds();
int durationInt = (int) durationLong;
ds.setLenghtOfMp3inSec(durationInt);
ds.setBitRateOfMp3(mp3.getBitrate());
ds.setSampleRate(mp3.getSampleRate());
ds.setVbrOrCbr(mp3.isVbr());
if(mp3 != null){
ds.setAbsoluteLocation(mp3.getFilename());
ds.setLocation(removeSDir(mp3.getFilename(), sDir));
if(mp3.hasId3v2Tag())
{
String artist = "";
String album = "";
String title = "";
String track = "";
String year = "";
String genDesc = "";
String composer = "";
String publisher = "";
String originalArtist = "";
String albumArtist = "";
String copyright = "";
String url = "";
ID3v2 id3v2Tag = mp3.getId3v2Tag();
try{
artist = id3v2Tag.getArtist();
album = id3v2Tag.getAlbum();
title = id3v2Tag.getTitle();
track = id3v2Tag.getTrack();
year = id3v2Tag.getYear();
genDesc = id3v2Tag.getGenreDescription();
composer = id3v2Tag.getComposer();
publisher = id3v2Tag.getPublisher();
originalArtist = id3v2Tag.getOriginalArtist();
albumArtist = id3v2Tag.getAlbumArtist();
copyright = id3v2Tag.getCopyright();
url = id3v2Tag.getUrl();
}
catch(Exception ex){
System.out.println(mp3file);
filesCorrupted.add(mp3file);
}
if(!(artist == null) && !(artist.isEmpty()))
{
ds.setArtist(artist);
}
if(!(album == null) && !(album.isEmpty()))
{
ds.setAlbum(album);
}
if(!(title == null) && !(title.isEmpty()))
{
ds.setTitle(title);
}
if(!(track == null) && !(track.isEmpty()))
{
ds.setTrackOnAlbum(track);
}
if(!(year == null) && !(year.isEmpty()))
{
ds.setYearReleased(year);
}
if(!(genDesc == null) && !(genDesc.isEmpty()))
{
ds.setGenre(genDesc);
}
if(!( composer == null) && !(composer.isEmpty()))
{
ds.setComposer(id3v2Tag.getComposer());
}
if(!(publisher == null) && !(publisher.isEmpty()))
{
ds.setPublisher(publisher);
}
if(!(originalArtist == null) && !(originalArtist.isEmpty()))
{
ds.setOriginArtist(originalArtist);
}
if(!(albumArtist == null) && !(albumArtist.isEmpty()))
{
ds.setAlbumArtString(albumArtist);
}
if(!(copyright == null) && !(copyright.isEmpty()))
{
ds.setCopyright(copyright);
}
if(!(url == null)&& !(url.isEmpty()))
{
ds.setUrl(url);
}
}
}
newLs.add(ds);
}
}
return newLs;
}
};
btnScan.disableProperty().bind(taskScan.runningProperty());
listAdvance.textProperty().bind(taskScan.messageProperty());
pi.progressProperty().bind(taskScan.progressProperty());
taskScan.stateProperty().addListener(new ChangeListener<Worker.State>(){
#Override
public void changed(ObservableValue<? extends Worker.State> observable, Worker.State oldValue, Worker.State newValue)
{
if(newValue == Worker.State.SUCCEEDED)
{
System.out.println("Error : " + taskScan.getException());
listAdvance.textProperty().unbind();
btnScan.disableProperty().unbind();
}
if(newValue == Worker.State.FAILED)
{
listAdvance.textProperty().unbind();
btnScan.disableProperty().unbind();
System.out.println("Error : " + taskScan.getException());
}
}
});
Thread toScanFiles = new Thread(taskScan);
toScanFiles.start();
return newLs;
}
I already thank you for your answers.

Using Android USB Host API to read my USB game controller/Or other USB device data

I am trying to use Android USB Host API to read my USB game controller data, once I get this to work, I will connect other device to test.
My game controller is connected to my Android phone using OTG cable. I am now able to get device, endpoints information, but I don't know how to read the raw data and display it.
Can someone please help me? Some example codes will be appreciated.
TextView countDisplay;
ArrayList<String> listItems = new ArrayList<String>();
ArrayAdapter<String> adapter;
String values = "";
UsbManager mManager;
UsbDevice device = null;
private byte[] bytes;
private static int TIMEOUT = 0;
private boolean forceClaim = true;
static PendingIntent mPermissionIntent;
UsbDeviceConnection connection = null;
UsbEndpoint InputEndpoint = null;
UsbEndpoint OutputEndpoint = null;
private Handler mHandler = new Handler();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mManager = (UsbManager) getSystemService(Context.USB_SERVICE);
mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(
"com.android.example.USB_PERMISSION"), 0);
IntentFilter filter = new IntentFilter();
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
registerReceiver(mUsbReceiver, filter);
HashMap<String, UsbDevice> deviceList = mManager.getDeviceList();
values = values + "deviceListSize:" + deviceList.size() + ",tostring:"
+ deviceList.toString();
Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
while (deviceIterator.hasNext()) {
device = deviceIterator.next();
values = values + ",device id:" + device.getDeviceId()
+ ",device name:" + device.getDeviceName();
values = values + ",Protocol:" + device.getDeviceProtocol()
+ ",ProductId:" + device.getProductId();
values = values + ",DeviceClass:" + device.getDeviceClass()
+ ",VendorId:" + device.getVendorId();
}
if (device != null) {
values = values + ",getInterfaceCount:"
+ device.getInterfaceCount();
UsbInterface intf = device.getInterface(0);
values = values + ",intf.getEndpointCount():"
+ intf.getEndpointCount();
UsbEndpoint endpoint1 = intf.getEndpoint(0);
UsbEndpoint endpoint2 = intf.getEndpoint(1);
mManager.requestPermission(device, mPermissionIntent);
if (mManager.hasPermission(device)) {
values = values + ",has permission over device!";
connection = mManager.openDevice(device);
if (connection == null) {
values = values + ",connection null";
} else {
values = values + ",getFileDescriptor:"
+ connection.getFileDescriptor();
if (endpoint1.getDirection() == UsbConstants.USB_DIR_IN) {
InputEndpoint = endpoint1;
} else {
OutputEndpoint = endpoint1;
}
if (endpoint2.getDirection() == UsbConstants.USB_DIR_IN) {
InputEndpoint = endpoint2;
} else {
OutputEndpoint = endpoint2;
}
}
if (InputEndpoint == null) {
countDisplay.setText(values + ",InputEndpoint is null");
}
if (OutputEndpoint == null) {
countDisplay.setText(values + ",OutputEndPoint is null");
}
connection.claimInterface(intf, forceClaim);
mHandler.postDelayed(runnable, 1);
} else {
values = values + ",Do not have permission over device!";
}
}
setContentView(R.layout.activity_main);
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View v = inflater.inflate(R.layout.activity_main, null);
LinearLayout ll = new LinearLayout(this);
ll.setOrientation(LinearLayout.VERTICAL);
int counter = 1;
countDisplay = new TextView(this);
ll.addView(countDisplay);
countDisplay.setText(values + ",counter here");
final Button button = new Button(this);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if (device != null && mManager.hasPermission(device)) {
values = values + ",device id:" + device.getDeviceId()
+ ",device name:" + device.getDeviceName();
values = values + ",Protocol:" + device.getDeviceProtocol()
+ ",ProductId:" + device.getProductId();
values = values + ",DeviceClass:" + device.getDeviceClass()
+ ",VendorId:" + device.getVendorId();
countDisplay.setText(values + ",okok");
} else {
if (device != null)
mManager.requestPermission(device, mPermissionIntent);
}
}
});
ll.addView(button);
setContentView(ll);
}
And Runnable:
private Runnable runnable = new Runnable() {
public void run() {
if (connection != null) {
int count = connection.bulkTransfer(InputEndpoint, bytes,
bytes.length, TIMEOUT);
countDisplay.setText(values + ",bultTransferNo:" + count);
countDisplay.setText(values + "bulkValue:" + bytes);
} else {
countDisplay.setText(values + ",connection is null");
}
}
};
This program serves as an example of the following USB host features:
Matching devices based on interface class, subclass and protocol (see device_filter.xml)
Asynchronous IO on bulk endpoints
All code Copyright:
/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
AdbDevice
package com.android.adb;
import android.hardware.usb.UsbConstants;
import android.hardware.usb.UsbDeviceConnection;
import android.hardware.usb.UsbEndpoint;
import android.hardware.usb.UsbInterface;
import android.hardware.usb.UsbRequest;
import android.util.SparseArray;
import java.util.LinkedList;
/* This class represents a USB device that supports the adb protocol. */
public class AdbDevice {
private final AdbTestActivity mActivity;
private final UsbDeviceConnection mDeviceConnection;
private final UsbEndpoint mEndpointOut;
private final UsbEndpoint mEndpointIn;
private String mSerial;
// pool of requests for the OUT endpoint
private final LinkedList<UsbRequest> mOutRequestPool = new LinkedList<UsbRequest>();
// pool of requests for the IN endpoint
private final LinkedList<UsbRequest> mInRequestPool = new LinkedList<UsbRequest>();
// list of currently opened sockets
private final SparseArray<AdbSocket> mSockets = new SparseArray<AdbSocket>();
private int mNextSocketId = 1;
private final WaiterThread mWaiterThread = new WaiterThread();
public AdbDevice(AdbTestActivity activity, UsbDeviceConnection connection,
UsbInterface intf) {
mActivity = activity;
mDeviceConnection = connection;
mSerial = connection.getSerial();
UsbEndpoint epOut = null;
UsbEndpoint epIn = null;
// look for our bulk endpoints
for (int i = 0; i < intf.getEndpointCount(); i++) {
UsbEndpoint ep = intf.getEndpoint(i);
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
epOut = ep;
} else {
epIn = ep;
}
}
}
if (epOut == null || epIn == null) {
throw new IllegalArgumentException("not all endpoints found");
}
mEndpointOut = epOut;
mEndpointIn = epIn;
}
// return device serial number
public String getSerial() {
return mSerial;
}
// get an OUT request from our pool
public UsbRequest getOutRequest() {
synchronized(mOutRequestPool) {
if (mOutRequestPool.isEmpty()) {
UsbRequest request = new UsbRequest();
request.initialize(mDeviceConnection, mEndpointOut);
return request;
} else {
return mOutRequestPool.removeFirst();
}
}
}
// return an OUT request to the pool
public void releaseOutRequest(UsbRequest request) {
synchronized (mOutRequestPool) {
mOutRequestPool.add(request);
}
}
// get an IN request from the pool
public UsbRequest getInRequest() {
synchronized(mInRequestPool) {
if (mInRequestPool.isEmpty()) {
UsbRequest request = new UsbRequest();
request.initialize(mDeviceConnection, mEndpointIn);
return request;
} else {
return mInRequestPool.removeFirst();
}
}
}
public void start() {
mWaiterThread.start();
connect();
}
public AdbSocket openSocket(String destination) {
AdbSocket socket;
synchronized (mSockets) {
int id = mNextSocketId++;
socket = new AdbSocket(this, id);
mSockets.put(id, socket);
}
if (socket.open(destination)) {
return socket;
} else {
return null;
}
}
private AdbSocket getSocket(int id) {
synchronized (mSockets) {
return mSockets.get(id);
}
}
public void socketClosed(AdbSocket socket) {
synchronized (mSockets) {
mSockets.remove(socket.getId());
}
}
// send a connect command
private void connect() {
AdbMessage message = new AdbMessage();
message.set(AdbMessage.A_CNXN, AdbMessage.A_VERSION, AdbMessage.MAX_PAYLOAD, "host::\0");
message.write(this);
}
// handle connect response
private void handleConnect(AdbMessage message) {
if (message.getDataString().startsWith("device:")) {
log("connected");
mActivity.deviceOnline(this);
}
}
public void stop() {
synchronized (mWaiterThread) {
mWaiterThread.mStop = true;
}
}
// dispatch a message from the device
void dispatchMessage(AdbMessage message) {
int command = message.getCommand();
switch (command) {
case AdbMessage.A_SYNC:
log("got A_SYNC");
break;
case AdbMessage.A_CNXN:
handleConnect(message);
break;
case AdbMessage.A_OPEN:
case AdbMessage.A_OKAY:
case AdbMessage.A_CLSE:
case AdbMessage.A_WRTE:
AdbSocket socket = getSocket(message.getArg1());
if (socket == null) {
log("ERROR socket not found");
} else {
socket.handleMessage(message);
}
break;
}
}
void log(String s) {
mActivity.log(s);
}
private class WaiterThread extends Thread {
public boolean mStop;
public void run() {
// start out with a command read
AdbMessage currentCommand = new AdbMessage();
AdbMessage currentData = null;
// FIXME error checking
currentCommand.readCommand(getInRequest());
while (true) {
synchronized (this) {
if (mStop) {
return;
}
}
UsbRequest request = mDeviceConnection.requestWait();
if (request == null) {
break;
}
AdbMessage message = (AdbMessage)request.getClientData();
request.setClientData(null);
AdbMessage messageToDispatch = null;
if (message == currentCommand) {
int dataLength = message.getDataLength();
// read data if length > 0
if (dataLength > 0) {
message.readData(getInRequest(), dataLength);
currentData = message;
} else {
messageToDispatch = message;
}
currentCommand = null;
} else if (message == currentData) {
messageToDispatch = message;
currentData = null;
}
if (messageToDispatch != null) {
// queue another read first
currentCommand = new AdbMessage();
currentCommand.readCommand(getInRequest());
// then dispatch the current message
dispatchMessage(messageToDispatch);
}
// put request back into the appropriate pool
if (request.getEndpoint() == mEndpointOut) {
releaseOutRequest(request);
} else {
synchronized (mInRequestPool) {
mInRequestPool.add(request);
}
}
}
}
}
}
AdbMessage
package com.android.adb;
import android.hardware.usb.UsbRequest;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
/* This class encapsulates and adb command packet */
public class AdbMessage {
// command names
public static final int A_SYNC = 0x434e5953;
public static final int A_CNXN = 0x4e584e43;
public static final int A_OPEN = 0x4e45504f;
public static final int A_OKAY = 0x59414b4f;
public static final int A_CLSE = 0x45534c43;
public static final int A_WRTE = 0x45545257;
// ADB protocol version
public static final int A_VERSION = 0x01000000;
public static final int MAX_PAYLOAD = 4096;
private final ByteBuffer mMessageBuffer;
private final ByteBuffer mDataBuffer;
public AdbMessage() {
mMessageBuffer = ByteBuffer.allocate(24);
mDataBuffer = ByteBuffer.allocate(MAX_PAYLOAD);
mMessageBuffer.order(ByteOrder.LITTLE_ENDIAN);
mDataBuffer.order(ByteOrder.LITTLE_ENDIAN);
}
// sets the fields in the command header
public void set(int command, int arg0, int arg1, byte[] data) {
mMessageBuffer.putInt(0, command);
mMessageBuffer.putInt(4, arg0);
mMessageBuffer.putInt(8, arg1);
mMessageBuffer.putInt(12, (data == null ? 0 : data.length));
mMessageBuffer.putInt(16, (data == null ? 0 : checksum(data)));
mMessageBuffer.putInt(20, command ^ 0xFFFFFFFF);
if (data != null) {
mDataBuffer.put(data, 0, data.length);
}
}
public void set(int command, int arg0, int arg1) {
set(command, arg0, arg1, (byte[])null);
}
public void set(int command, int arg0, int arg1, String data) {
// add trailing zero
data += "\0";
set(command, arg0, arg1, data.getBytes());
}
// returns the command's message ID
public int getCommand() {
return mMessageBuffer.getInt(0);
}
// returns command's first argument
public int getArg0() {
return mMessageBuffer.getInt(4);
}
// returns command's second argument
public int getArg1() {
return mMessageBuffer.getInt(8);
}
// returns command's data buffer
public ByteBuffer getData() {
return mDataBuffer;
}
// returns command's data length
public int getDataLength() {
return mMessageBuffer.getInt(12);
}
// returns command's data as a string
public String getDataString() {
int length = getDataLength();
if (length == 0) return null;
// trim trailing zero
return new String(mDataBuffer.array(), 0, length - 1);
}
public boolean write(AdbDevice device) {
synchronized (device) {
UsbRequest request = device.getOutRequest();
request.setClientData(this);
if (request.queue(mMessageBuffer, 24)) {
int length = getDataLength();
if (length > 0) {
request = device.getOutRequest();
request.setClientData(this);
if (request.queue(mDataBuffer, length)) {
return true;
} else {
device.releaseOutRequest(request);
return false;
}
}
return true;
} else {
device.releaseOutRequest(request);
return false;
}
}
}
public boolean readCommand(UsbRequest request) {
request.setClientData(this);
return request.queue(mMessageBuffer, 24);
}
public boolean readData(UsbRequest request, int length) {
request.setClientData(this);
return request.queue(mDataBuffer, length);
}
private static String extractString(ByteBuffer buffer, int offset, int length) {
byte[] bytes = new byte[length];
for (int i = 0; i < length; i++) {
bytes[i] = buffer.get(offset++);
}
return new String(bytes);
}
#Override
public String toString() {
String commandName = extractString(mMessageBuffer, 0, 4);
int dataLength = getDataLength();
String result = "Adb Message: " + commandName + " arg0: " + getArg0() +
" arg1: " + getArg1() + " dataLength: " + dataLength;
if (dataLength > 0) {
result += (" data: \"" + getDataString() + "\"");
}
return result;
}
private static int checksum(byte[] data) {
int result = 0;
for (int i = 0; i < data.length; i++) {
int x = data[i];
// dang, no unsigned ints in java
if (x < 0) x += 256;
result += x;
}
return result;
}
}
AdbSocket
package com.android.adb;
/* This class represents an adb socket. adb supports multiple independent
* socket connections to a single device. Typically a socket is created
* for each adb command that is executed.
*/
public class AdbSocket {
private final AdbDevice mDevice;
private final int mId;
private int mPeerId;
public AdbSocket(AdbDevice device, int id) {
mDevice = device;
mId = id;
}
public int getId() {
return mId;
}
public boolean open(String destination) {
AdbMessage message = new AdbMessage();
message.set(AdbMessage.A_OPEN, mId, 0, destination);
if (! message.write(mDevice)) {
return false;
}
synchronized (this) {
try {
wait();
} catch (InterruptedException e) {
return false;
}
}
return true;
}
public void handleMessage(AdbMessage message) {
switch (message.getCommand()) {
case AdbMessage.A_OKAY:
mPeerId = message.getArg0();
synchronized (this) {
notify();
}
break;
case AdbMessage.A_WRTE:
mDevice.log(message.getDataString());
sendReady();
break;
}
}
private void sendReady() {
AdbMessage message = new AdbMessage();
message.set(AdbMessage.A_OKAY, mId, mPeerId);
message.write(mDevice);
}
}
For additional information on usb and connecting you might find the following article helpfull.
http://android.serverbox.ch/?p=549
The last paragraph explains some of the issue you might face. The example they provide may also show you how to go about reading the data and how you will have to format the messages.
It looks like you face two issue. One setting up your code to read message, which Puspendu's answer aludes to, and the second issue which is "how" to communicate, what messages you will need to send to establish a connection, handshake, and determine the good stuff, i.e. the data you want.
Puspendu has shown one example of reading and writing to a device. However i would imagine that depending on the device you connect, the handshake and message structure will change, hence you'll have to look those parts up (afraid i dont know of any other examples).

Categories