I want to change the visibility of a view from GONE to VISIBLE and take a screenshot of my whole application and save it in a file.
I'm able to take the screenshot, but the view remain not visible (GONE) in the jpeg file. The method is called from a button click:
public void onClick(View v) {
View screen = (View) findViewById(R.id.mainLayout);
//I change this from View.GONE
TextView hiddenText = (TextView) findViewById(R.id.hiddenText);
hiddenText.setVisibility(View.VISIBLE);
hiddenText.setText( "WEEEEEEEEEE" + (int)(Math.random()*10) );
View rootview = screen.getRootView();
//View rootview = getWindow().getDecorView().getRootView();
rootview.invalidate(); //I try to redraw the view without success
rootview.requestLayout();
rootview.setDrawingCacheEnabled(true);
Bitmap bitmap = rootview.getDrawingCache();
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 40, bytes);
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES) +
File.separator + "Facebook" + File.separator + "my_screenshot.jpeg";
File file = new File(path);
file.getParentFile().mkdirs(); //if the folder doesn't exists it's created
try {
boolean asd = file.createNewFile();
FileOutputStream ostream = new FileOutputStream(file);
ostream.write(bytes.toByteArray());
ostream.close();
}
catch (Exception e){
e.printStackTrace();
}
//hiddenText.setVisibility(View.GONE);
}
After that I save the file I should hide again the TextView hiddenText, but I doesn't know in which point to set the visibility GONE.
Related
I'm trying to use an Activity which displays a random object from my array. This object is passed in from an intent.
I am trying to use an image for each of these objects and then display the correct image for the correct object.
So far I've been using the drawable folder to hold my images and then loading them in through the XML however this stops me using multiple images for the same ImageView.
I tried using imageview.setImageResource(R.drawable.imagename); but that doesn't seem to like loading in for some reason.
Do I need to make a new activity for each of the objects in this case?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_random_race);
TextView name = (TextView)findViewById(R.id.raceName);
Intent secondIntent = getIntent();
Race message = (Race)secondIntent.getSerializableExtra("RACE");
ImageView image = (ImageView) findViewById(R.id.raceImage);
image.setImageResource(R.drawable.hacan);
image.setImageBitmap(imageToBitmapImage(message, image));
name.setText(message.getName());
}
Bytes to Bitmap method
public Bitmap imageToBitmapImage (Race message, ImageView image){
Bitmap bmp;
try {
FileInputStream in = new FileInputStream(message.getImageName());
BufferedInputStream buffer = new BufferedInputStream(in);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
int input = buffer.read();
while (input != -1){
baos.write(input);
input = buffer.read();
}
byte[] bytes = baos.toByteArray();
bmp = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
return bmp;
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
Class of each object I'm talking about.
public class Race implements Serializable {
private String name;
private String imageName; //name of file within drawable
As #XavierFalempin commented, you can't access ressources through a file stream. Using setImageResource() should work. Following this answer your onCreate() method should look something like this:
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_random_race);
TextView name = (TextView)findViewById(R.id.raceName);
Intent secondIntent = getIntent();
Race message = (Race)secondIntent.getSerializableExtra("RACE");
ImageView image = (ImageView) findViewById(R.id.raceImage);
image.setImageResource(getResources().getIdentifier(message.getImageName(),
"drawable",
getPackageName()));
name.setText(message.getName());
}
When I navigate to a page in the app, I expect the text from the text file to be displayed but it isn't. Am I missing something?
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_content);
Button backButton = findViewById(R.id.button_back);
Button selectAnotherButton = findViewById(R.id.button_select_another);
TextView contentText = findViewById(R.id.content_text);
String text = "";
try {
// file to inputstream
InputStream input = getAssets().open("jokes.txt");
int size = input.available();
byte[] buffer = new byte[size];
input.read(buffer);
input.close();
// byte buffer into a string
text = new String(buffer);
} catch (Exception e) {
System.out.println(e);
}
contentText.setText(text);
}
The code above is fine, it works as expected. The reason the text could not be seen is because there was a textview layout overlapping the file text text view layout so I couldn't see the text
contentText.invalidate();
contentText.requestLayout();
I am creating a button dynamically in Android Studio in a class that extends Fragment. I have my button created (btn) and a text that I want to go under that button (appName), but now I want to place the button next to another button that already exists (lets call it btn_2). I am having trouble finding out how to place one widget next to another using Java, and not xml. Here is what I have so far:
public void createButton (BitmapDrawable bitmapdrawable, String applicationName){
LayoutInflater inflater=null;
ViewGroup container = null;
// Get Layout home_fragment
View rootView = inflater.inflate(R.layout.home_fragment, container, false);
RelativeLayout rLayout = (RelativeLayout) rootView.findViewById(R.id.home_fragment);
// create image button with background as bitmapdrawable
ImageButton btn = new ImageButton(getActivity());
btn.setImageDrawable(bitmapdrawable);
// create textview with applicationName
TextView appName = new TextView(getActivity());
appName.setText(applicationName);
// place new button next to existing button
RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(
RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT);
params.addRule(RelativeLayout.RIGHT_OF);
btn.setLayoutParams(params);
// place text under newly created button
// Put button and text in layout
rLayout.addView(btn);
rLayout.addView(appName);
}
Where I am running into errors is:
params.addRule(RelativeLayout.RIGHT_OF);
How do I pass through the ID of the EXISTING button (btn_2), that I want my new button (btn) to be placed next to?
Then, I want to fill in this empty gap
// place text under newly created button
of how to place my newly created textview (appName) under my newly created btn and under my existing btn_2. (Maybe this will be more straight forward after I figure out how to place one button next to the other.)
Here is my MainActivity. My image and string that I am passing to HomeFragment createButton method are being sent to MainActivity through a socket from another device:
// main activity (FragmentActivity provides fragment compatibility pre-HC)
public class MainActivity extends FragmentActivity implements MenuFragment.OnMenufragListener {
private Thread repeatTaskThread;
private byte[] byteArray;
// called when the activity is first created
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Listening for last installed app to create button
RepeatTask();
}
#Override
public void onMenufrag(Fragment s) {
// get body fragment (native method is getFragmentManager)
HomeFragment fragment = (HomeFragment) getSupportFragmentManager().findFragmentById(R.id.home_fragment);
// if fragment is not null and in layout, set text, else launch BodyActivity
if ((fragment!=null)&&fragment.isInLayout()) {
fragment.getView();
} else {
Intent intent = new Intent(this,HomeFragment.class);
startActivity(intent);
}
}
private void RepeatTask()
{
repeatTaskThread = new Thread()
{
public void run()
{
while (true)
{
try {
System.out.println("TRY_1");
Socket socket = new Socket("192.168.0.26", 5050);
// Get data sent through socket
DataInputStream DIS = new DataInputStream(socket.getInputStream());
System.out.println("DataInputStream Started");
// read data that got sent
String applicationName = DIS.readUTF();
// read array data for bitmap
//Drawable icon = getPackageManager().getApplicationIcon(packagename);
//System.out.println("icon" + icon);
int len = DIS.readInt();
byte[] data = new byte[len];
DIS.readFully(data, 0, data.length);
// Convert data to jpeg first then to bitmap (cant convert byte array directly to bitmap)
YuvImage yuvimage=new YuvImage(data, ImageFormat.NV21, 100, 100, null);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
yuvimage.compressToJpeg(new Rect(0, 0, 100, 100), 80, baos);
byte[] jdata = baos.toByteArray();
// Convert to Bitmap
Bitmap bmp = BitmapFactory.decodeByteArray(jdata, 0, jdata.length);
// Image to png in file directory
// STREAM IMAGE DATA TO FILE
// This is how I know I am correctly getting my png image (no errors here)
// convert bitmap to drawable
Drawable d = new BitmapDrawable(getResources(), bmp);
// convert drawable to bitmapdrawable
BitmapDrawable bitmapdrawable = (BitmapDrawable)d;
Log.d("tag_name", "BITMAP Drawable" + bitmapdrawable);
// Create file to stream bitmpadrawable
FileOutputStream fosIcon = openFileOutput(applicationName + ".png", Context.MODE_PRIVATE);
// compress bitmapdrawable into png and write to file that was just created
bitmapdrawable.getBitmap().compress(Bitmap.CompressFormat.PNG, 100, fosIcon);
InputStream inputStream = openFileInput(applicationName + ".png");
Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
// GET FILE DIRECTORY
File imageFile = new File(getFilesDir(), applicationName + ".png");
HomeFragment createbutton = new HomeFragment();
createbutton.createButton(bitmapdrawable, applicationName);
Log.d("tag_name", "Entered Home Fragment");
socket.close();
} catch (Exception e) {
System.out.println("Exception is "+e.toString());
}
try
{
// Sleep for 5 seconds
Thread.sleep(5000);
}
catch (Exception e)
{
e.printStackTrace();
}
}
};
};
repeatTaskThread.start();
}
}
Here is my xml for HomeFragment:
<?xml version="1.0" encoding="utf-8"?>
<HorizontalScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:layout_margin="5dp"
android:id="#+id/home_fragment"
>
</RelativeLayout>
</HorizontalScrollView>
You have to specify the view id to make your view right of . Try -
TextView appName = new TextView(getActivity());
int id = 1001;
appName.setId(id);
params.addRule(RelativeLayout.RIGHT_OF, id);
how to make users to download the image in the listview onclick of the list item.The images are from drawable folder, not from the web?
if you are referring to saving images to your phone, from your drawable folder.you should check this link out.
How to save a bitmap image with imageview onclick
it says how to save an image from the app to your phone
To get bitmap from imageview:
imageview.buildDrawingCache();
Bitmap bm=imageview.getDrawingCache();
To save it in a file:
OutputStream fOut = null;
Uri outputFileUri;
try {
File root = new File(Environment.getExternalStorageDirectory() + File.separator + "folder_name" + File.separator);
root.mkdirs();
File sdImageMainDirectory = new File(root, "myPicName.jpg");
outputFileUri = Uri.fromFile(sdImageMainDirectory);
fOut = new FileOutputStream(sdImageMainDirectory);
} catch (Exception e) {
Toast.makeText(this, "Error occured. Please try again later.",
Toast.LENGTH_SHORT).show();
}
try {
bm.compress(Bitmap.CompressFormat.PNG, 100, fOut);
fOut.flush();
fOut.close();
} catch (Exception e) {
}
give this inside the listview on click
You can store your images id in an int[] integer array like this:
int[] myImages = {R.drawable.myfirstimage,R.drawable.mysecondimage};
and add to your listView an onItemClick method where you change your corresponding ImageView based on the position of the item clicked
myListview.setOnItemClickListener(new OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
ImageView imageView = (ImageView) view.findViewById(R.id.myImageView);
imageView.setBackgroundResource(myImages[position]);
}
});
I am pretty new to Android development and I'm trying to figure out how to tap an image in my app and save it to the device. When the image is tapped I want a Save button to appear and when that is pressed, a toast should appear saying the picture was saved. On iOS I am able to do this with UIActionSheet.
I should also mention that the image view image is downloaded from a URL using Picasso.
I just tried this and it says the image saved but when I go to the photos app on my phone, the image is not there.
largeImage.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
saveButton.setVisibility(View.VISIBLE);
}
});
saveButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
largeImage.getDrawable();
Bitmap bitmap = ((BitmapDrawable)largeImage.getDrawable()).getBitmap();
OutputStream outStream = null;
File file = new File(storageDirectory, "er.PNG");
try {
outStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outStream);
outStream.flush();
outStream.close();
Toast.makeText(FlickrImageActivity.this, "Saved", Toast.LENGTH_LONG).show();
}
catch (FileNotFoundException e) {
e.printStackTrace();
Toast.makeText(FlickrImageActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
catch (IOException e) {
e.printStackTrace();
Toast.makeText(FlickrImageActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
saveButton.setVisibility(View.GONE);
}
});
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
Random generator = new Random();
int n = 10000;
n = generator.nextInt(n);
String fname = "Image-"+ n +".jpg";
File file = new File (myDir, fname);
if (file.exists ()) file.delete ();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
Manifest permission
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
You can use RelativeLayout to contain a ImageView and a Button.
Align both of them center in parent
inside the activity, set the button visibility to "gone"
call setOnClickListener of the ImageView and Button to your Activity
implement OnClickListener in your Activity
inside onClick(View v), if the view clicked is the ImageView, set the visibility of Button to "visible"
inside onClick(View v), if the view clicked is the Button, save the image to disk
** how to save image to disk
if the image source is drawable resources, use BitmapFactory.decodeResource to create a Bitmap then use Bitmap.compress to export to a specific path
specific path is recommended to be obtained from Environment.getExternalStoragePublicDirectory
then notify the Android to refresh gallery
MediaScannerConnection.scanFile(context,
new String[] { imagePath }, null,
new MediaScannerConnection.OnScanCompletedListener() {
#Override
public void onScanCompleted(String path, Uri uri) {
//....
}
});
Then use a Toast.makeText(context, "message here").show(); to show the message to user
See below steps to acheive this in Android :
1. Create layout with ImageView & 'Save' named Button
2.By deafult set 'Save' Button's visibility = gone/invisible
3. Apply click listener on both the views (ImageView & Button)
4. OnClick of ImageView, set 'Save' Button's visibility = visible
5. onclick of save button click call your save image to sdcard logic. Check below link for that.
http://android-er.blogspot.in/2010/07/save-file-to-sd-card.html
Hope this will help you.