How to create and show Qr Code in Android App [duplicate] - java

This question already has answers here:
How to generate a QR Code for an Android application? [closed]
(6 answers)
Closed 9 years ago.
can you help me please. I want to write small app for Android that has one button. When you push it it must show you qr code. Qr code must be generated form some string.
Tryed so far:
public void onClick(View v){
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder("Hello",
null,
Contents.Type.TEXT,
BarcodeFormat.QR_CODE.toString(),
smallerDimension);
Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();
}

first you will need to add zing2.1.jar file in your project then do the below code
QRCodeEncoder.java
public final class QRCodeEncoder {
private static final int WHITE = 0xFFFFFFFF;
private static final int BLACK = 0xFF000000;
private int dimension = Integer.MIN_VALUE;
private String contents = null;
private String displayContents = null;
private String title = null;
private BarcodeFormat format = null;
private boolean encoded = false;
public QRCodeEncoder(String data, Bundle bundle, String type, String format, int dimension) {
this.dimension = dimension;
encoded = encodeContents(data, bundle, type, format);
}
public String getContents() {
return contents;
}
public String getDisplayContents() {
return displayContents;
}
public String getTitle() {
return title;
}
private boolean encodeContents(String data, Bundle bundle, String type, String formatString) {
// Default to QR_CODE if no format given.
format = null;
if (formatString != null) {
try {
format = BarcodeFormat.valueOf(formatString);
} catch (IllegalArgumentException iae) {
// Ignore it then
}
}
if (format == null || format == BarcodeFormat.QR_CODE) {
this.format = BarcodeFormat.QR_CODE;
encodeQRCodeContents(data, bundle, type);
} else if (data != null && data.length() > 0) {
contents = data;
displayContents = data;
title = "Text";
}
return contents != null && contents.length() > 0;
}
private void encodeQRCodeContents(String data, Bundle bundle, String type) {
if (type.equals(Contents.Type.TEXT)) {
if (data != null && data.length() > 0) {
contents = data;
displayContents = data;
title = "Text";
}
} else if (type.equals(Contents.Type.EMAIL)) {
data = trim(data);
if (data != null) {
contents = "mailto:" + data;
displayContents = data;
title = "E-Mail";
}
} else if (type.equals(Contents.Type.PHONE)) {
data = trim(data);
if (data != null) {
contents = "tel:" + data;
displayContents = PhoneNumberUtils.formatNumber(data);
title = "Phone";
}
} else if (type.equals(Contents.Type.SMS)) {
data = trim(data);
if (data != null) {
contents = "sms:" + data;
displayContents = PhoneNumberUtils.formatNumber(data);
title = "SMS";
}
} else if (type.equals(Contents.Type.CONTACT)) {
if (bundle != null) {
StringBuilder newContents = new StringBuilder(100);
StringBuilder newDisplayContents = new StringBuilder(100);
newContents.append("MECARD:");
String name = trim(bundle.getString(ContactsContract.Intents.Insert.NAME));
if (name != null) {
newContents.append("N:").append(escapeMECARD(name)).append(';');
newDisplayContents.append(name);
}
String address = trim(bundle.getString(ContactsContract.Intents.Insert.POSTAL));
if (address != null) {
newContents.append("ADR:").append(escapeMECARD(address)).append(';');
newDisplayContents.append('\n').append(address);
}
Collection<String> uniquePhones = new HashSet<String>(Contents.PHONE_KEYS.length);
for (int x = 0; x < Contents.PHONE_KEYS.length; x++) {
String phone = trim(bundle.getString(Contents.PHONE_KEYS[x]));
if (phone != null) {
uniquePhones.add(phone);
}
}
for (String phone : uniquePhones) {
newContents.append("TEL:").append(escapeMECARD(phone)).append(';');
newDisplayContents.append('\n').append(PhoneNumberUtils.formatNumber(phone));
}
Collection<String> uniqueEmails = new HashSet<String>(Contents.EMAIL_KEYS.length);
for (int x = 0; x < Contents.EMAIL_KEYS.length; x++) {
String email = trim(bundle.getString(Contents.EMAIL_KEYS[x]));
if (email != null) {
uniqueEmails.add(email);
}
}
for (String email : uniqueEmails) {
newContents.append("EMAIL:").append(escapeMECARD(email)).append(';');
newDisplayContents.append('\n').append(email);
}
String url = trim(bundle.getString(Contents.URL_KEY));
if (url != null) {
// escapeMECARD(url) -> wrong escape e.g. http\://zxing.google.com
newContents.append("URL:").append(url).append(';');
newDisplayContents.append('\n').append(url);
}
String note = trim(bundle.getString(Contents.NOTE_KEY));
if (note != null) {
newContents.append("NOTE:").append(escapeMECARD(note)).append(';');
newDisplayContents.append('\n').append(note);
}
// Make sure we've encoded at least one field.
if (newDisplayContents.length() > 0) {
newContents.append(';');
contents = newContents.toString();
displayContents = newDisplayContents.toString();
title = "Contact";
} else {
contents = null;
displayContents = null;
}
}
} else if (type.equals(Contents.Type.LOCATION)) {
if (bundle != null) {
// These must use Bundle.getFloat(), not getDouble(), it's part of the API.
float latitude = bundle.getFloat("LAT", Float.MAX_VALUE);
float longitude = bundle.getFloat("LONG", Float.MAX_VALUE);
if (latitude != Float.MAX_VALUE && longitude != Float.MAX_VALUE) {
contents = "geo:" + latitude + ',' + longitude;
displayContents = latitude + "," + longitude;
title = "Location";
}
}
}
}
public Bitmap encodeAsBitmap() throws WriterException {
if (!encoded) return null;
Map<EncodeHintType, Object> hints = null;
String encoding = guessAppropriateEncoding(contents);
if (encoding != null) {
hints = new EnumMap<EncodeHintType, Object>(EncodeHintType.class);
hints.put(EncodeHintType.CHARACTER_SET, encoding);
}
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix result = writer.encode(contents, format, dimension, dimension, hints);
int width = result.getWidth();
int height = result.getHeight();
int[] pixels = new int[width * height];
// All are 0, or black, by default
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE;
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
private static String guessAppropriateEncoding(CharSequence contents) {
// Very crude at the moment
for (int i = 0; i < contents.length(); i++) {
if (contents.charAt(i) > 0xFF) { return "UTF-8"; }
}
return null;
}
private static String trim(String s) {
if (s == null) { return null; }
String result = s.trim();
return result.length() == 0 ? null : result;
}
private static String escapeMECARD(String input) {
if (input == null || (input.indexOf(':') < 0 && input.indexOf(';') < 0)) { return input; }
int length = input.length();
StringBuilder result = new StringBuilder(length);
for (int i = 0; i < length; i++) {
char c = input.charAt(i);
if (c == ':' || c == ';') {
result.append('\\');
}
result.append(c);
}
return result.toString();
}
}
Contents.java
import android.provider.ContactsContract;
public final class Contents {
private Contents() {
}
public static final class Type {
// Plain text. Use Intent.putExtra(DATA, string). This can be used for URLs too, but string
// must include "http://" or "https://".
public static final String TEXT = "TEXT_TYPE";
// An email type. Use Intent.putExtra(DATA, string) where string is the email address.
public static final String EMAIL = "EMAIL_TYPE";
// Use Intent.putExtra(DATA, string) where string is the phone number to call.
public static final String PHONE = "PHONE_TYPE";
// An SMS type. Use Intent.putExtra(DATA, string) where string is the number to SMS.
public static final String SMS = "SMS_TYPE";
// A contact. Send a request to encode it as follows:
// <p/>
// import android.provider.Contacts;
// <p/>
// Intent intent = new Intent(Intents.Encode.ACTION); intent.putExtra(Intents.Encode.TYPE,
// CONTACT); Bundle bundle = new Bundle(); bundle.putString(Contacts.Intents.Insert.NAME,
// "Jenny"); bundle.putString(Contacts.Intents.Insert.PHONE, "8675309");
// bundle.putString(Contacts.Intents.Insert.EMAIL, "jenny#the80s.com");
// bundle.putString(Contacts.Intents.Insert.POSTAL, "123 Fake St. San Francisco, CA 94102");
// intent.putExtra(Intents.Encode.DATA, bundle);
public static final String CONTACT = "CONTACT_TYPE";
// A geographic location. Use as follows:
// Bundle bundle = new Bundle();
// bundle.putFloat("LAT", latitude);
// bundle.putFloat("LONG", longitude);
// intent.putExtra(Intents.Encode.DATA, bundle);
public static final String LOCATION = "LOCATION_TYPE";
private Type() {
}
}
public static final String URL_KEY = "URL_KEY";
public static final String NOTE_KEY = "NOTE_KEY";
// When using Type.CONTACT, these arrays provide the keys for adding or retrieving multiple
// phone numbers and addresses.
public static final String[] PHONE_KEYS = {
ContactsContract.Intents.Insert.PHONE, ContactsContract.Intents.Insert.SECONDARY_PHONE,
ContactsContract.Intents.Insert.TERTIARY_PHONE
};
public static final String[] PHONE_TYPE_KEYS = {
ContactsContract.Intents.Insert.PHONE_TYPE,
ContactsContract.Intents.Insert.SECONDARY_PHONE_TYPE,
ContactsContract.Intents.Insert.TERTIARY_PHONE_TYPE
};
public static final String[] EMAIL_KEYS = {
ContactsContract.Intents.Insert.EMAIL, ContactsContract.Intents.Insert.SECONDARY_EMAIL,
ContactsContract.Intents.Insert.TERTIARY_EMAIL
};
public static final String[] EMAIL_TYPE_KEYS = {
ContactsContract.Intents.Insert.EMAIL_TYPE,
ContactsContract.Intents.Insert.SECONDARY_EMAIL_TYPE,
ContactsContract.Intents.Insert.TERTIARY_EMAIL_TYPE
};
}
Do the below code to add string and set it to ImageView
String qrData = "Name : "+name+"\n Company : "+comp;
int qrCodeDimention = 500;
QRCodeEncoder qrCodeEncoder = new QRCodeEncoder(qrData, null,
Contents.Type.TEXT, BarcodeFormat.QR_CODE.toString(), qrCodeDimention);
try {
Bitmap bitmap = qrCodeEncoder.encodeAsBitmap();
imageView.setImageBitmap(bitmap);
} catch (WriterException e) {
e.printStackTrace();
}

I dont know which library are you using.
I am calling my zxing library QRReaderActivity in my app like this.
startActivity(QRReaderActivity.class);
the method is
private void startActivity(Class<?> className) {
Intent intent = new Intent(this, className);
startActivityForResult(intent, 0);
}

Related

Create a Bitmap from image gallery path in Android 7.0?

I have an issue where I'm trying to convert Image gallery path into Bitmap
Here is my code. Please help me.
Error
Unable to decode stream: java.io.FileNotFoundException:
/storage/emulated/0/DCIM/100ANDRO/DSC_0013.JPG
(No such file or directory)
Code
public static final int MY_BACKGROUND_JOB = 0;
JobParameters mRunningParams;
public Context context;
static final Uri MEDIA_URI = Uri.parse("content://" + MediaStore.AUTHORITY + "/");
static final List<String> EXTERNAL_PATH_SEGMENTS = MediaStore.Images.Media.EXTERNAL_CONTENT_URI.getPathSegments();
static final String[] PROJECTION = new String[]{
MediaStore.Images.ImageColumns._ID, MediaStore.Images.ImageColumns.DATA};
static final int PROJECTION_ID = 0;
static final int PROJECTION_DATA = 1;
static final String DCIM_DIR = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath();
#Override
public boolean onStartJob(JobParameters params) {
Log.i("PhotosContentJob", "JOB STARTED!");
_sharedPreferencesUtility = new SharedPreferencesUtility(getApplicationContext());
_globalTypeface = new Global_Typeface(getApplication());
_mainContext = new MainActivity();
SetGPSLocation();
SetPreferenceData();
SetCheckLocationFormat();
mRunningParams = params;
mJobHandler.sendMessage(Message.obtain(mJobHandler, 1, params));
StringBuilder sb = new StringBuilder();
if (params.getTriggeredContentAuthorities() != null) {
boolean rescanNeeded = false;
if (params.getTriggeredContentUris() != null) {
ArrayList<String> ids = new ArrayList<>();
for (Uri uri : params.getTriggeredContentUris()) {
List<String> path = uri.getPathSegments();
if (path != null && path.size() == EXTERNAL_PATH_SEGMENTS.size() + 1) {
// This is a specific file.
ids.add(path.get(path.size() - 1));
} else {
rescanNeeded = true;
}
}
if (ids.size() > 0) {
StringBuilder selection = new StringBuilder();
for (int i = 0; i < ids.size(); i++) {
if (selection.length() > 0) {
selection.append(" OR ");
}
selection.append(MediaStore.Images.ImageColumns._ID);
selection.append("='");
selection.append(ids.get(i));
selection.append("'");
}
Cursor cursor = null;
boolean haveFiles = false;
try {
cursor = getContentResolver().query(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, PROJECTION, selection.toString(), null, null);
while (cursor.moveToNext()) {
String dir = cursor.getString(PROJECTION_DATA);
if (dir.startsWith(DCIM_DIR)) {
if (!haveFiles) {
haveFiles = true;
}
sb.append(dir);
sb.append("\n");
}
}
} catch (SecurityException e) {
sb.append("Error: no access to media!");
} finally {
if (cursor != null) {
cursor.close();
}
}
}
} else {
rescanNeeded = true;
}
if (rescanNeeded) {
sb.append("Photos rescan needed!");
}
} else {
sb.append("(No photos content)");
}
Log.e("TAG_URL_24", sb.toString());
_st_ImagePath = sb.toString();
Bitmap bitmap = BitmapFactory.decodeFile(stImagePath);
Bitmap.Config config = bitmap.getConfig();
if (config == null) {
config = Bitmap.Config.ARGB_8888;
}
mHandler.postDelayed(mWorker, 1);
return true;
}
Thanking you.
Here is the solution for you
With this reference there is a solution for your query
use the string value of dir in your program as file path you can get the result.
File sd = Environment.getExternalStorageDirectory();
File image = new File("YOUR FILE PATH", imageName);
BitmapFactory.Options bmOptions = new BitmapFactory.Options();
Bitmap bitmap = BitmapFactory.decodeFile(image.getAbsolutePath(),bmOptions);
bitmap = Bitmap.createScaledBitmap(bitmap,parent.getWidth(),parent.getHeight(),true);
imageView.setImageBitmap(bitmap);

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.

Writing custom Android ViewAction to take screenshot

I'm trying to take a screenshot before I perform an action in Android using espresso.
protected T performAction(ViewAction viewAction) {
ViewAction screenShotAction = new ScreenShotAction();
viewInteraction.perform(screenShotAction);
viewInteraction.perform(viewAction);
return returnGeneric();
}
For example if in my test I perform a click() then I would take a screenshot of the device before I performed the click().
This is the code for taking the screenshot in the ScreenShotAction class
#Override
public void perform(UiController uiController, View view) {
View rootView = view.getRootView();
String state = Environment.getExternalStorageState();
if(Environment.MEDIA_MOUNTED.equals(state)) {
File picDir = new File(Environment.getExternalStorageDirectory() + "app_" + "test");
if (!picDir.exists()) {
picDir.mkdir();
}
rootView.setDrawingCacheEnabled(true);
rootView.buildDrawingCache(true);
Bitmap bitmap = rootView.getDrawingCache();
String fileName = "test.jpg";
File picFile = new File(picDir + "/" + fileName);
try {
picFile.createNewFile();
FileOutputStream picOut = new FileOutputStream(picFile);
bitmap = Bitmap.createBitmap(rootView.getWidth(), rootView.getHeight(), Bitmap.Config.ARGB_8888);
boolean saved = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, picOut);
if (saved) {
// good
} else {
// error
throw new Exception("Image not saved");
}
picOut.flush();
picOut.close();
} catch (Exception e) {
e.printStackTrace();
}
rootView.destroyDrawingCache();
}
}
I do not see any image files in the phone's Pictures directory or any other directory. I believe the screenshot method is solid but am unsure if I am calling the method correctly.
Is viewInteraction.perform(screenShotAction) the corret way to call my custom view action?
Please help and thank you in advance.
You can do the following:
public class CaptureImage {
#SuppressWarnings("unused")
private static final String TAG = CaptureImage.class.getSimpleName();
private static final String NAME_SEPARATOR = "_";
private static final String EXTENSION = ".png";
private static final Object LOCK = new Object();
private static boolean outputNeedsClear = true;
private static final Pattern NAME_VALIDATION = Pattern.compile("[a-zA-Z0-9_-]+");
public static void takeScreenshot(View currentView, String className,
String methodName, #Nullable String prefix) {
methodName = methodName.replaceAll("[\\[\\](){}]", "");
if (!NAME_VALIDATION.matcher(methodName).matches()) {
throw new IllegalArgumentException(
"Name must match " + NAME_VALIDATION.pattern() +
" and " + methodName + " was received.");
}
Context context = InstrumentationRegistry.getTargetContext();
MyRunnable myRunnable = new MyRunnable(context, currentView, className, methodName, prefix);
Activity activity =
((Application)context.getApplicationContext()).getCurrentActivity();
activity.runOnUiThread(myRunnable);
}
private static class MyRunnable implements Runnable {
private View mView;
private Context mContext;
private String mClassName;
private String mMethodName;
private String mPrefix;
MyRunnable(Context context, View view, String className, String methodName, String prefix) {
mContext = context;
mView = view;
mClassName = className;
mMethodName = methodName;
mPrefix = prefix;
}
#TargetApi(VERSION_CODES.JELLY_BEAN_MR2)
public void run() {
UiAutomation uiAutomation = InstrumentationRegistry.getInstrumentation().getUiAutomation();
if (uiAutomation == null) {
return;
}
OutputStream out = null;
Bitmap bitmap = null;
try {
String timestamp = new SimpleDateFormat("MM_dd_HH_mm_ss", Locale.ENGLISH)
.format(new Date());
File screenshotDirectory = getScreenshotFolder();
int statusBarHeight = getStatusBarHeightOnDevice();
bitmap = uiAutomation.takeScreenshot();
Bitmap screenshot = Bitmap.createBitmap(bitmap, 0, statusBarHeight,
mView.getWidth(), mView.getHeight() - statusBarHeight);
String screenshotName = mMethodName + NAME_SEPARATOR +
(mPrefix != null ? (mPrefix + NAME_SEPARATOR) : "") +
timestamp + EXTENSION;
Log.d("YOUR_TAG", "Screenshot name: " + screenshotName);
File imageFile = new File(screenshotDirectory, screenshotName);
out = new FileOutputStream(imageFile);
screenshot.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
} catch (Throwable t) {
Log.e("YOUR_LOG", "Unable to capture screenshot.", t);
} finally {
try {
if (out != null) {
out.close();
}
} catch (Exception ignored) {
}
if (bitmap != null) {
bitmap.recycle();
}
}
}
private int getStatusBarHeightOnDevice() {
int _StatusBarHeight = 0;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
mView.setDrawingCacheEnabled(true);
Bitmap screenShot = Bitmap.createBitmap(mView.getDrawingCache());
mView.setDrawingCacheEnabled(false);
if (screenShot != null) {
int StatusColor = screenShot.getPixel(0, 0);
for (int y = 1; y < (screenShot.getHeight() / 4); y++) {
if (screenShot.getPixel(0, y) != StatusColor) {
_StatusBarHeight = y - 1;
break;
}
}
}
if (_StatusBarHeight == 0) {
_StatusBarHeight = 50; // Set a default in case we don't find a difference
}
Log.d("YOUR_TAG", "Status Bar was measure at "
+ _StatusBarHeight + " pixels");
return _StatusBarHeight;
}
private File getScreenshotFolder() throws IllegalAccessException {
File screenshotsDir;
if (Build.VERSION.SDK_INT >= 21) {
// Use external storage.
screenshotsDir = new File(getExternalStorageDirectory(),
"screenshots");
} else {
// Use internal storage.
screenshotsDir = new File(mContext.getApplicationContext().getFilesDir(),
"screenshots");
}
synchronized (LOCK) {
if (outputNeedsClear) {
deletePath(screenshotsDir);
outputNeedsClear = false;
}
}
File dirClass = new File(screenshotsDir, mClassName);
File dirMethod = new File(dirClass, mMethodName);
createDir(dirMethod);
return dirMethod;
}
private void createDir(File dir) throws IllegalAccessException {
File parent = dir.getParentFile();
if (!parent.exists()) {
createDir(parent);
}
if (!dir.exists() && !dir.mkdirs()) {
throw new IllegalAccessException(
"Unable to create output dir: " + dir.getAbsolutePath());
}
}
private void deletePath(File path) {
if (path.isDirectory() && path.exists()) {
File[] children = path.listFiles();
if (children != null) {
for (File child : children) {
Log.d("YOUR_TAG", "Deleting " + child.getPath());
deletePath(child);
}
}
}
if (!path.delete()) {
// log message here
}
}
}
Then you can call it from a ViewAction or from the test case class directly:
View Action Class:
class ScreenshotViewAction implements ViewAction {
private final String mClassName;
private final String mMethodName;
private final int mViewId;
private final String mPrefix;
protected ScreenshotViewAction(final int viewId, final String className,
final String methodName, #Nullable final String prefix) {
mViewId = viewId;
mClassName = className;
mMethodName = methodName;
mPrefix = prefix;
}
#Override
public Matcher<View> getConstraints() {
return ViewMatchers.isDisplayed();
}
#Override
public String getDescription() {
return "Taking a screenshot.";
}
#Override
public void perform(final UiController aUiController, final View aView) {
aUiController.loopMainThreadUntilIdle();
final long startTime = System.currentTimeMillis();
final long endTime = startTime + 2000;
final Matcher<View> viewMatcher = ViewMatchers.withId(mViewId);
do {
for (View child : TreeIterables.breadthFirstViewTraversal(aView)) {
// found view with required ID
if (viewMatcher.matches(child)) {
CaptureImage.takeScreenshot(aView.getRootView(), mClassName,
mMethodName, mPrefix);
return;
}
}
aUiController.loopMainThreadForAtLeast(50);
}
while (System.currentTimeMillis() < endTime);
}
}
Now from your test case class, create the following static methods:
public static void takeScreenshot(int prefix) {
View currentView = ((ViewGroup)mActivity
.getWindow().getDecorView().findViewById(android.R.id.content)).getChildAt(0);
String fullClassName = Thread.currentThread().getStackTrace()[3].getClassName();
String testClassName = fullClassName.substring(fullClassName.lastIndexOf(".") + 1);
String testMethodName = Thread.currentThread().getStackTrace()[3].getMethodName();
CaptureImage.takeScreenshot(currentView, testClassName, testMethodName,
String.valueOf(prefix));
}
public static ViewAction takeScreenshot(#Nullable String prefix) {
String fullClassName = Thread.currentThread().getStackTrace()[3].getClassName();
String className = fullClassName.substring(fullClassName.lastIndexOf(".") + 1);
String methodName = Thread.currentThread().getStackTrace()[3].getMethodName();
return new ScreenshotViewAction(getDecorView().getId(), className, methodName, prefix);
}
Or you can invoke it from the perform view action:
takeScreenshot(0);
onView(withContentDescription(sContext
.getString(R.string.abc_action_bar_up_description)))
.perform(
ScreenshotViewAction.takeScreenshot(String.valueOf(1)),
click()
);

UI not showing up after switching to AsyncTask

I have recently switched over to AsyncTask after reading how efficent it is. It took some time porting my code, but I did it in the end. I have 1 AsyncTask that gets run first, setting up the background image/color that it gets off a json object. After that, it sets up TableRows for all the other fields in the JSON file. The background changes, but the UI does not show up. I placed System.out.println's inside my AsyncTask and I see that the code has been executed (the onPostExecute method), but none of the UI shows up. I have no idea what the problem is, hence me posting this question.
Here is my AsyncTask:
class GetImageAsync extends AsyncTask<String, Void, Drawable> {
private final WeakReference<View> ViewReference;
private String data;
private Context context;
private boolean isImageView;
private boolean scale;
private int id = -1;
private int color = -1;
private int height = -1;
public GetImageAsync(TableLayout tr, String data, Context context) {
isImageView = false;
this.context = context;
this.data = data;
ViewReference = new WeakReference<View>(tr);
System.out.println("inside async");
}
public GetImageAsync(ImageView iv, int id, Context context) {
isImageView = true;
this.context = context;
this.id = id;
ViewReference = new WeakReference<View>(iv);
}
public GetImageAsync(ImageView imageView,String data, Context context, int height) {
System.out.println("profile async");
this.height = height;
isImageView = true;
this.context = context;
this.data = data;
ViewReference = new WeakReference<View>(imageView);
}
// Decode image in background.
#Override
protected Drawable doInBackground(String... params) {
System.out.println(id + " : " + isImageView);
if(isImageView && id != -1) {
return getImageFromResource();
} else {
if(data.startsWith("#")) {
color = Color.parseColor(data);
return null;
}
try {
return getImageFromWeb(data, scale);
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
private Drawable getImageFromResource() {
return context.getResources().getDrawable(id);
}
private Drawable getImageFromWeb(String data, boolean b) throws MalformedURLException, IOException {
Bitmap img = BitmapFactory.decodeStream(new URL(data).openConnection().getInputStream());
if(height != -1) {
return new BitmapDrawable(context.getResources(), getCroppedBitmap(Bitmap.createScaledBitmap(
Bitmap.createScaledBitmap(img,
img.getWidth(),
img.getWidth(), true),
height * 2,
height * 2, true)));
}
return new BitmapDrawable(context.getResources(), img);
}
// Once complete, see if ImageView is still around and set bitmap.
#Override
protected void onPostExecute(Drawable bitmap) {
if(isImageView) { //this block does not {
System.out.println("post "+isImageView);
System.out.println("iv");
if (ViewReference != null && bitmap != null) {
final ImageView imageView = (ImageView) ViewReference.get();
if (imageView != null) {
imageView.setImageDrawable(bitmap);
}
} // }
} else { //this block runs {
System.out.println("post "+isImageView);
if (ViewReference != null) {
final TableLayout tr = (TableLayout) ViewReference.get();
if (tr != null) {
if(color != -1) {
tr.setBackgroundColor(color);
} else {
tr.setBackground(bitmap);
}
}
}
} // }
}
public static Bitmap getCroppedBitmap(Bitmap bitmap) {
int w = bitmap.getWidth();
int h = bitmap.getHeight();
int radius = Math.min(h / 2, w / 2);
Bitmap output = Bitmap.createBitmap(w + 8, h + 8, Config.ARGB_8888);
Paint p = new Paint();
p.setAntiAlias(true);
Canvas c = new Canvas(output);
c.drawARGB(0, 0, 0, 0);
p.setStyle(Style.FILL);
c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p);
p.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));
c.drawBitmap(bitmap, 4, 4, p);
p.setXfermode(null);
p.setStyle(Style.STROKE);
p.setColor(Color.BLACK);
p.setStrokeWidth(1);
c.drawCircle((w / 2) + 4, (h / 2) + 4, radius, p);
return output;
}
}
and here is how I create the UI:
private void createUI(JSONObject jObject) throws JSONException {
int absIndex = 0;
if (android.os.Build.VERSION.SDK_INT >= 16) {
new GetImageAsync(tr, jObject.getString(("bg")), getApplicationContext()).execute("");
System.out.println("after async");
/*if (bgcolor != -1) {
System.out.println("color: " + bgcolor);
tr.setBackgroundColor(bgcolor);
} else if (bgpic != null) {
tr.setBackground(bgpic);
}*/
}
for (int i = 0; i < keys.length; i++) {
values.add(i, new ArrayList<String>());
values.get(i).add(0, keys[i]);
values.get(i).add(1, jObject.getString(keys[i]));
}
String lastString = WhoIsLast(jObject);
trcard.setBackground(getResources()
.getDrawable(R.drawable.bg_card/* abc_menu_dropdown_panel_holo_light */));
trcard.addView(tlcard);
tr.setPadding(0, 0, 0, 0);
TableLayout.LayoutParams tableRowParams = new TableLayout.LayoutParams(
TableLayout.LayoutParams.MATCH_PARENT,
TableLayout.LayoutParams.WRAP_CONTENT);
int[] attrs = { android.R.attr.dividerVertical };
TypedArray typedArray = getApplicationContext().obtainStyledAttributes(
attrs);
Drawable divider = typedArray.getDrawable(0);
typedArray.recycle();
tableRowParams.setMargins(20, 20, 20, 0);
trcard.setLayoutParams(tableRowParams);
tlcard.setDividerDrawable(divider);
tlcard.setDividerPadding(4);
tableScrollView.addView(trcard);
for (int i = 0; i < keys.length; i++) {
String value = values.get(i).get(1);
if (value != "") {
String key = values.get(i).get(0);
boolean last = false;
if (i == keys.length || value.equals(lastString) || i == 0) {
last = true;
System.out.println(value +" = "+lastString);
}
insertElement(value, key, absIndex++, last, drawables[i]);
if (!last) {
absIndex++;
}
}
}
}
private String WhoIsLast(JSONObject j) throws JSONException {
if (j.getString("facebook").equals("")) {
return "";
}
if (j.getString("twitter").equals("")) {
return "facebook";
}
if (j.getString("email").equals("")) {
return "twitter";
}
if (j.getString("phone").equals("")) {
return "email";
}
return "";
}
int absIndex = 0;
private void insertElement(String data, String key, int i,
boolean b, Integer id) throws JSONException {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View newRow = inflater.inflate(R.layout.row, null, false);
newRow.setLayoutParams(new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT,
TableRow.LayoutParams.WRAP_CONTENT));
TextView dataTextView = (TextView) newRow
.findViewById(R.id.rowTextView);
dataTextView.setText("\t " + data);
ImageView iv = (ImageView) newRow.findViewById(R.id.rowImageView);
newRow.setId(absIndex++);
newRow.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
//omitted
});
View v = new View(this);
v.setLayoutParams(new TableRow.LayoutParams(
TableRow.LayoutParams.MATCH_PARENT, 1));
v.setBackgroundColor(Color.argb(25, 111, 111, 111));
dataTextView.measure(MeasureSpec.UNSPECIFIED, MeasureSpec.UNSPECIFIED);
if (i == 0) {
System.out.println("before async iv");
new GetImageAsync(iv, jObject.getString("profilepic"), getApplicationContext(), dataTextView.getMeasuredHeight()).execute("");
System.out.println("after async iv");
//async.execute("");
dataTextView.setShadowLayer(3, 0, 0, Color.BLACK);
dataTextView.setTextColor(getResources().getColor(R.color.white));
} else {
new GetImageAsync(iv, id, getApplicationContext()).execute("");
}
if (i == 0) {
dataTextView.setTextSize(30);
tableScrollView.addView(newRow, i);
System.out.println("adding i=0null");
} else {
System.out.println("adding i = "+i +tlcard);
tlcard.addView(newRow, i - 1);
if (!b) {
tlcard.addView(v, i);
}
}
}
Edit: where I call createUi method:
final Thread thread = new Thread(new Runnable() {
#Override
public void run() {
jObject = getJson("http://www.tabcards.com/req/androidapi/L2o30H8JlFMtFYHW3KLxkts20ztc5Be6Z6m6v315/json/"
+ value);
System.out.println(value);
if (jObject != null) {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
createUI(jObject);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
});
thread.start();

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