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);
Related
I want to retrive pdf files from a custom file path and show them all recyclerview.
My Code is Here,
public static final File PDF_DIRECTORY =
new File(Environment.DIRECTORY_DOCUMENTS + File.separator + "/AppName/");
File file;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
file = new File(Environment.DIRECTORY_DOCUMENTS, "/AppName/");
} else {
file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/AppName");
}
if (!file.exists()) {
file.mkdirs();
}
After creating this directory, I have write the code below,
private void getPdf(View view) {
new Thread(() -> {
PDFModel pdfModel;
allFiles = PDF_DIRECTORY.listFiles();
if (allFiles != null) {
try {
Arrays.sort(allFiles, (o1, o2) -> Long.compare(o2.lastModified(), o1.lastModified()));
for (File file : allFiles) {
if (file.getName().endsWith(".pdf")) {
pdfModel = new PDFModel(
file.getAbsolutePath());
pdfModelArrayList.add(pdfModel);
}
}
} catch (Exception e) {
e.printStackTrace();
}
handler.post(() -> {
if (pdfModelArrayList.size() <= 0) {
} else {
// noResultSwipeImage.setVisibility(View.GONE);
}
pdfAdapter = new PdfAdapter(pdfModelArrayList, view.getContext());
recyclerView.setAdapter(pdfAdapter);
recyclerView.setHasFixedSize(true);
pdfAdapter.notifyDataSetChanged();
});
} else {
}
}).start();
}
private void getStatusScope(View view) {
ContentResolver cr = requireActivity().getContentResolver();
Uri uri = MediaStore.Files.getContentUri("external");
String[] projection = {MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DISPLAY_NAME};
String selection = MediaStore.Files.FileColumns.MEDIA_TYPE + "="
+ MediaStore.Files.FileColumns.MEDIA_TYPE;
String[] selectionArgs = null;
String selectionMimeType = MediaStore.Files.FileColumns.MIME_TYPE + "=?";
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension("pdf");
String[] selectionArgsPdf = new String[]{mimeType};
Cursor c = cr.query(uri, projection, selectionMimeType, selectionArgsPdf, null);
if (c != null) {
while (c.moveToNext()) {
PDFModel whatsappstatusmodel = new PDFModel(c.getString(0));
pdfModelArrayList.add(whatsappstatusmodel);
}
c.close();
}
if (pdfModelArrayList.size() <= 0) {
//Do Something Here
} else {
pdfAdapter = new PdfAdapter(pdfModelArrayList, view.getContext());
recyclerView.setAdapter(pdfAdapter);
recyclerView.setHasFixedSize(true);
pdfAdapter.notifyDataSetChanged();
}
}
But this code does not work! This code returns a zero-item array list, actually, I'm a little confused about android scope storage, can anyone give me an example code or give me any idea about this?
I have a simple CursorAdapter that gets a title and image.
It shows the title and then loads the image from the Internet.
However, when I call the image loader the image is loaded at the wrong place, and it starts going really wild: see here.
My complete code is here.
The adapter is RestaurantListActivityCursorAdapter
public class RestaurantListActivityCursorAdapter extends CursorAdapter {
/* Api variables */
String websiteURL = "http://cicolife.com";
public RestaurantListActivityCursorAdapter(Context context, Cursor cursor) {
super(context, cursor, 0);
}
#Override
public View newView(Context context, Cursor cursor, ViewGroup parent) {
return LayoutInflater.from(context).inflate(R.layout.activity_main_list_item, parent, false);
}
#Override
public void bindView(View view, Context context, Cursor cursor) {
// Extract properties from cursor
int get_Id = cursor.getInt(cursor.getColumnIndexOrThrow("_id"));
String getTitle = cursor.getString(cursor.getColumnIndexOrThrow("title"));
String getImage = cursor.getString(cursor.getColumnIndexOrThrow("image"));
// Name
TextView listViewTitle = (TextView) view.findViewById(R.id.listViewTitle);
listViewTitle.setText(getTitle);
// Img
ImageView listViewImage = (ImageView) view.findViewById(R.id.listViewImage);
if(getImage != null) {
if (!(getImage.equals(""))) {
String destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+ File.separatorChar+"/Android/data/com.nettport.restaurants/imgs";
File file = new File (destinationPath, getImage);
if (file.exists ()){
Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
listViewImage.setImageBitmap(myBitmap);
}
else {
String loadImage = websiteURL + "/_cache/" + getImage;
new HttpRequestImageLoadTask(context, loadImage, listViewImage, getImage,"imgs").execute();
}
}
}
}
}
The image loader HttpRequestImageLoadTask
public class HttpRequestImageLoadTask extends AsyncTask<Void, Void, Bitmap> {
private String url;
private ImageView imageView;
private LinearLayout linearLayout;
private Resources resources;
private Context context;
private String storeDirectory;
private String imageName;
public interface TaskListener {
void onFinished(String result);
}
public HttpRequestImageLoadTask(Context ctx, String url, ImageView imageView, String imgName, String storeDirectory) {
this.context = ctx;
this.url = url;
this.imageView = imageView;
this.imageName = imgName;
this.storeDirectory = storeDirectory;
}
public HttpRequestImageLoadTask(Context ctx, String url, LinearLayout linearLayout, Resources resources, String imgName, String storeDirectory) {
this.context = ctx;
this.url = url;
this.linearLayout = linearLayout;
this.imageName = imgName;
this.storeDirectory = storeDirectory;
}
#Override
protected Bitmap doInBackground(Void... params) {
if (checkIfCacheExists(imageName)) {
String destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data/com.nettport.restaurants/" + storeDirectory;
File file = new File (destinationPath, imageName);
Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
return myBitmap;
} else {
try {
URL urlConnection = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlConnection
.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
saveImage(myBitmap);
return myBitmap;
} catch(Exception e){
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPostExecute(Bitmap result) {
super.onPostExecute(result);
if(imageView != null) {
imageView.setImageBitmap(result);
} else {
if(linearLayout != null){
BitmapDrawable background = new BitmapDrawable(resources, result);
linearLayout.setBackground(background);
}
}
}
public boolean checkIfCacheExists(String imgName){
String destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data/com.nettport.restaurants/" + storeDirectory;
File file = new File (destinationPath, imgName);
return file.exists();
}
private void saveImage(Bitmap finalBitmap) {
// Make dir
String destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data/com.nettport.restaurants/" + storeDirectory;
File folder = new File(destinationPath);
try {
if (!folder.exists()) {
// Make Android
destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android";
folder = new File(destinationPath);
if (!folder.exists()) {
folder.mkdir();
}
// Make Android/data
destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data";
folder = new File(destinationPath);
if (!folder.exists()) {
folder.mkdir();
}
// Make Android/data/com.nettport.restaurants
destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data/com.nettport.restaurants";
folder = new File(destinationPath);
if (!folder.exists()) {
folder.mkdir();
}
// Make Android/data/com.nettport.restaurants/storeDirectory
destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+File.separatorChar+"/Android/data/com.nettport.restaurants/" + storeDirectory;
folder = new File(destinationPath);
if (!folder.exists()) {
folder.mkdir();
}
}
} catch (Exception e){
Toast.makeText(context, "Could not create directory:\n" + e.toString(), Toast.LENGTH_LONG).show();
}
if(imageName != null) {
File file = new File(destinationPath, imageName);
if (file.exists()) file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
// Toast.makeText(context, "Cant save image\n" + e.toString(), Toast.LENGTH_LONG).show();
}
}
}
}
You have not put any else condition for your ImageView in your adapter. I see there are several else blocks are missing here.
if(getImage != null) {
if (!(getImage.equals(""))) {
String destinationPath = android.os.Environment.getExternalStorageDirectory().getPath()+ File.separatorChar+"/Android/data/com.nettport.restaurants/imgs";
File file = new File (destinationPath, getImage);
if (file.exists()){
Bitmap myBitmap = BitmapFactory.decodeFile(file.getAbsolutePath());
listViewImage.setImageBitmap(myBitmap);
} else {
String loadImage = websiteURL + "/_cache/" + getImage;
// Add nothing here when the image is being fetched
listViewImage.setImageBitmap(null);
new HttpRequestImageLoadTask(context, loadImage, listViewImage, getImage,"imgs").execute();
}
} else {
// Add an else block here when image is equals ""
listViewImage.setImageBitmap(null);
}
} else {
// Add an else block here when image is null
listViewImage.setImageBitmap(null);
}
You need to specify every possible combination in your adapter while loading the images in your ImageView.
And if you have the image url from server, just use Glide to load the images when they are not available in cache.
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
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()
);
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);
}