Jak mogę zrobić zrzut ekranu z wybranego obszaru ekranu telefonu nie przez żaden program, ale z kodu?
Jak mogę zrobić zrzut ekranu z wybranego obszaru ekranu telefonu nie przez żaden program, ale z kodu?
Odpowiedzi:
Oto kod, który pozwolił mi zapisać mój zrzut ekranu na karcie SD i wykorzystać go później do jakichkolwiek potrzeb:
Najpierw musisz dodać odpowiednie uprawnienie do zapisania pliku:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
A to jest kod (działający w działaniu):
private void takeScreenshot() {
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
try {
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".jpg";
// create bitmap screen capture
View v1 = getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
File imageFile = new File(mPath);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
openScreenshot(imageFile);
} catch (Throwable e) {
// Several error may come out with file handling or DOM
e.printStackTrace();
}
}
I w ten sposób możesz otworzyć ostatnio wygenerowany obraz:
private void openScreenshot(File imageFile) {
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = Uri.fromFile(imageFile);
intent.setDataAndType(uri, "image/*");
startActivity(intent);
}
Jeśli chcesz użyć tego w widoku fragmentu, użyj:
View v1 = getActivity().getWindow().getDecorView().getRootView();
zamiast
View v1 = getWindow().getDecorView().getRootView();
na funkcji takeScreenshot ()
Uwaga :
To rozwiązanie nie działa, jeśli okno dialogowe zawiera widok powierzchni. Aby uzyskać szczegółowe informacje, sprawdź odpowiedź na następujące pytanie:
Android Zrzut ekranu z widoku powierzchni pokazuje czarny ekran
mCurrentUrlMask
musi być View
odkąd jest unikalną klasą w interfejsie API Androida, która ma tę getRootView()
metodę. Prawdopodobnie jest to widok w interfejsie użytkownika.
View v1 = mCurrentUrlMask.getRootView();
użyłem View v1 = getWindow().getDecorView().getRootView();
i to działa dla mnie.
Wywołaj tę metodę, przekazując najbardziej zewnętrzną grupę ViewGroup, z której chcesz zrzut ekranu:
public Bitmap screenShot(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
view
? '
getWindow().getDecorView().getRootView()
jako widok powoduje wykonanie zrzutu ekranu samej aplikacji - nie ekranu.
Uwaga: działa tylko dla zrootowanego telefonu
Programowo możesz uruchomić adb shell /system/bin/screencap -p /sdcard/img.png
jak poniżej
Process sh = Runtime.getRuntime().exec("su", null,null);
OutputStream os = sh.getOutputStream();
os.write(("/system/bin/screencap -p " + "/sdcard/img.png").getBytes("ASCII"));
os.flush();
os.close();
sh.waitFor();
następnie przeczytaj img.png
jako Bitmap
i użyj według własnego uznania.
System.err : java.io.IOException: Error running exec(). Command: [su] Working Directory: null Environment: null
, moje urządzenie to Android 5.0
EDYCJA: zmiłuj się nad głosującymi. Tak było w 2010 roku, kiedy odpowiedziałem na pytanie.
Wszystkie programy zezwalające na zrzuty ekranu działają tylko na zrootowanych telefonach.
Ta metoda nie wymaga uprawnień administratora ani dużego kodowania .
W powłoce adb za pomocą poniższego polecenia możesz zrobić zrzut ekranu.
input keyevent 120
To polecenie nie wymaga żadnych uprawnień roota, więc możesz wykonać je również z kodu Java aplikacji na Androida.
Process process;
process = Runtime.getRuntime().exec("input keyevent 120");
Więcej informacji o kluczowym kodzie w Androidzie można znaleźć na stronie http://developer.android.com/reference/android/view/KeyEvent.html
Tutaj wykorzystaliśmy. KEYCODE_SYSRQ jego wartość wynosi 120 i jest używana dla klucza żądania systemu / ekranu drukowania.
Jak powiedział CJBS, obraz wyjściowy zostanie zapisany w / sdcard / Pictures / Screenshots
/sdcard/Pictures/Screenshots
su -c "input keyevent 120"
jest ok !!
Odpowiedź Mualiga jest bardzo dobra, ale miałem ten sam problem, który opisuje Ewoks, nie dostaję tła. Czasami więc jest wystarczająco dobry, a czasem pojawia się czarny tekst na czarnym tle (w zależności od tematu).
To rozwiązanie jest mocno oparte na kodzie Mualig i kodzie, który znalazłem w Robotium. Odrzucam użycie pamięci podręcznej rysowania, dzwoniąc bezpośrednio do metody rysowania. Wcześniej postaram się wyciągnąć tło z bieżącej aktywności, aby narysować je jako pierwsze.
// Some constants
final static String SCREENSHOTS_LOCATIONS = Environment.getExternalStorageDirectory().toString() + "/screenshots/";
// Get device dimmensions
Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
// Get root view
View view = mCurrentUrlMask.getRootView();
// Create the bitmap to use to draw the screenshot
final Bitmap bitmap = Bitmap.createBitmap(size.x, size.y, Bitmap.Config.ARGB_4444);
final Canvas canvas = new Canvas(bitmap);
// Get current theme to know which background to use
final Activity activity = getCurrentActivity();
final Theme theme = activity.getTheme();
final TypedArray ta = theme
.obtainStyledAttributes(new int[] { android.R.attr.windowBackground });
final int res = ta.getResourceId(0, 0);
final Drawable background = activity.getResources().getDrawable(res);
// Draw background
background.draw(canvas);
// Draw views
view.draw(canvas);
// Save the screenshot to the file system
FileOutputStream fos = null;
try {
final File sddir = new File(SCREENSHOTS_LOCATIONS);
if (!sddir.exists()) {
sddir.mkdirs();
}
fos = new FileOutputStream(SCREENSHOTS_LOCATIONS
+ System.currentTimeMillis() + ".jpg");
if (fos != null) {
if (!bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos)) {
Log.d(LOGTAG, "Compress/Write failed");
}
fos.flush();
fos.close();
}
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
private void captureScreen() {
View v = getWindow().getDecorView().getRootView();
v.setDrawingCacheEnabled(true);
Bitmap bmp = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
try {
FileOutputStream fos = new FileOutputStream(new File(Environment
.getExternalStorageDirectory().toString(), "SCREEN"
+ System.currentTimeMillis() + ".png"));
bmp.compress(CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
Dodaj uprawnienie do manifestu
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Aby obsługiwać Marshmallow lub nowsze wersje, dodaj poniższy kod w metodzie działania onCreate
ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},00);
Jako odniesienie, jednym ze sposobów przechwytywania ekranu (a nie tylko aktywności aplikacji) jest przechwycenie bufora ramki (device / dev / graphic / fb0). Aby to zrobić, musisz mieć uprawnienia administratora lub aplikacja musi być aplikacją z uprawnieniami do podpisu („Zezwolenie, które system przyznaje tylko wtedy, gdy wnioskująca aplikacja jest podpisana tym samym certyfikatem co aplikacja, która zadeklarowała pozwolenie”) - bardzo mało prawdopodobne, chyba że skompilowałeś własny ROM.
Każde przechwycenie bufora ramki, z kilku testowanych urządzeń, zawierało dokładnie jeden zrzut ekranu. Ludzie zgłaszali, że zawiera więcej, myślę, że zależy to od rozmiaru ramki / wyświetlacza.
Próbowałem ciągle czytać bufor ramki, ale wydaje się, że zwraca określoną ilość odczytanych bajtów. W moim przypadku jest to (3 410 432) bajtów, co wystarcza do przechowywania ramki wyświetlania 854 * 480 RGBA (3 279 360 bajtów). Tak, ramka w formacie binarnym wyprowadzana z fb0 to RGBA w moim urządzeniu. Najprawdopodobniej będzie to zależeć od urządzenia. Będzie to ważne, aby go zdekodować =)
W moim urządzeniu / dev / graphic / fb0 uprawnienia są tak, że tylko root i użytkownicy z grafiki grupowej mogą odczytać fb0.
grafika jest grupą ograniczoną, więc prawdopodobnie będziesz uzyskiwać dostęp do fb0 tylko przy użyciu zrootowanego telefonu za pomocą polecenia su.
Aplikacje na Androida mają identyfikator użytkownika (identyfikator użytkownika) = aplikacja _ ## i identyfikator grupy (identyfikator GUID) = aplikacja _ ## .
adb shell ma uid = shell i guid = shell , który ma znacznie więcej uprawnień niż aplikacja. Możesz faktycznie sprawdzić te uprawnienia na /system/permissions/platform.xml
Oznacza to, że będziesz mógł odczytać fb0 w powłoce adb bez roota, ale nie będziesz czytać jej w aplikacji bez rootowania.
Ponadto udzielenie uprawnień READ_FRAME_BUFFER i / lub ACCESS_SURFACE_FLINGER w AndroidManifest.xml nie zrobi nic w przypadku zwykłej aplikacji, ponieważ będą one działać tylko w przypadku aplikacji „ podpisowych ”.
Sprawdź także ten zamknięty wątek, aby uzyskać więcej informacji.
Moje rozwiązanie to:
public static Bitmap loadBitmapFromView(Context context, View v) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
v.measure(MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap returnedBitmap = Bitmap.createBitmap(v.getMeasuredWidth(),
v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(returnedBitmap);
v.draw(c);
return returnedBitmap;
}
i
public void takeScreen() {
Bitmap bitmap = ImageUtils.loadBitmapFromView(this, view); //get Bitmap from the view
String mPath = Environment.getExternalStorageDirectory() + File.separator + "screen_" + System.currentTimeMillis() + ".jpeg";
File imageFile = new File(mPath);
OutputStream fout = null;
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
fout.close();
}
}
Obrazy są zapisywane w folderze pamięci zewnętrznej.
view
czego przekazujesz ImageUtils.loadBitmapFromView(this, view)
?
Możesz wypróbować następującą bibliotekę: http://code.google.com/p/android-screenshot-library/ Biblioteka zrzutów ekranu Androida (ASL) umożliwia programowe przechwytywanie zrzutów ekranu z urządzeń z Androidem bez konieczności posiadania uprawnień dostępu root. Zamiast tego ASL wykorzystuje natywną usługę działającą w tle, uruchamianą przez Android Debug Bridge (ADB) raz na urządzenie.
Na podstawie odpowiedzi @JustinMorris powyżej i @NiravDangi tutaj https://stackoverflow.com/a/8504958/2232148 musimy wziąć tło i pierwszy plan widoku i złożyć je w następujący sposób:
public static Bitmap takeScreenshot(View view, Bitmap.Config quality) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), quality);
Canvas canvas = new Canvas(bitmap);
Drawable backgroundDrawable = view.getBackground();
if (backgroundDrawable != null) {
backgroundDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
return bitmap;
}
Parametr jakości zajmuje stałą Bitmap.Config, zwykle albo Bitmap.Config.RGB_565
czy Bitmap.Config.ARGB_8888
.
public class ScreenShotActivity extends Activity{
private RelativeLayout relativeLayout;
private Bitmap myBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
relativeLayout = (RelativeLayout)findViewById(R.id.relative1);
relativeLayout.post(new Runnable() {
public void run() {
//take screenshot
myBitmap = captureScreen(relativeLayout);
Toast.makeText(getApplicationContext(), "Screenshot captured..!", Toast.LENGTH_LONG).show();
try {
if(myBitmap!=null){
//save image to SD card
saveImage(myBitmap);
}
Toast.makeText(getApplicationContext(), "Screenshot saved..!", Toast.LENGTH_LONG).show();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
public static Bitmap captureScreen(View v) {
Bitmap screenshot = null;
try {
if(v!=null) {
screenshot = Bitmap.createBitmap(v.getMeasuredWidth(),v.getMeasuredHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(screenshot);
v.draw(canvas);
}
}catch (Exception e){
Log.d("ScreenShotActivity", "Failed to capture screenshot because:" + e.getMessage());
}
return screenshot;
}
public static void saveImage(Bitmap bitmap) throws IOException{
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 40, bytes);
File f = new File(Environment.getExternalStorageDirectory() + File.separator + "test.png");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
}
}
DODAJ ZEZWOLENIE
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Możesz spróbować zrobić coś takiego,
Uzyskiwanie bufora bitmapy z układu lub widoku, wykonując coś takiego: Najpierw musisz setDrawingCacheEnabled
przejść do układu (liniowy układ lub układ względny lub widok)
następnie
Bitmap bm = layout.getDrawingCache()
Następnie rób co chcesz z bitmapą. Przekształć go w plik obrazu lub wyślij bitmapę do innego miejsca.
Stworzyłem prostą bibliotekę, która pobiera zrzut ekranu z View
i albo daje obiekt Bitmap, albo zapisuje go bezpośrednio do dowolnej ścieżki, którą chcesz
Screenshot.takeScreenshot(view, mPath); imageView.setImageBitmap(Screenshot.getBitmapScreenshot(view, mPath));
jak uzyskać widok bieżącej działalności. Nie chcę używać identyfikatora xml.
takeScreenshotForScreen()
zamiast tego.
Krótka droga jest
FrameLayout layDraw = (FrameLayout) findViewById(R.id.layDraw); /*Your root view to be part of screenshot*/
layDraw.buildDrawingCache();
Bitmap bmp = layDraw.getDrawingCache();
Po prostu rozszerzam odpowiedź taraloca. Musisz dodać następujące wiersze, aby działało. Nazwa obrazu stała się statyczna. Upewnij się, że używasz zmiennej znacznika czasu Taraloca, ponieważ potrzebujesz dynamicznej nazwy obrazu.
// Storage Permissions
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
private void verifyStoragePermissions() {
// Check if we have write permission
int permission = ActivityCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (permission != PackageManager.PERMISSION_GRANTED) {
// We don't have permission so prompt the user
ActivityCompat.requestPermissions(this, PERMISSIONS_STORAGE, REQUEST_EXTERNAL_STORAGE);
}else{
takeScreenshot();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
if (requestCode == REQUEST_EXTERNAL_STORAGE) {
takeScreenshot();
}
}
}
A w pliku AndroidManifest.xml należy wprowadzić następujące wpisy:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Jeśli chcesz zrobić zrzut ekranu, fragment
wykonaj następujące czynności:
Zastąp onCreateView()
:
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
View view = inflater.inflate(R.layout.fragment_one, container, false);
mView = view;
}
Logika robienia zrzutu ekranu:
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
View view = mView.findViewById(R.id.scrollView1);
shareScreenShotM(view, (NestedScrollView) view);
}
metoda shareScreenShotM)()
:
public void shareScreenShotM(View view, NestedScrollView scrollView){
bm = takeScreenShot(view,scrollView); //method to take screenshot
File file = savePic(bm); // method to save screenshot in phone.
}
metoda takeScreenShot ():
public Bitmap takeScreenShot(View u, NestedScrollView z){
u.setDrawingCacheEnabled(true);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
Log.d("yoheight",""+ totalHeight);
Log.d("yowidth",""+ totalWidth);
u.layout(0, 0, totalWidth, totalHeight);
u.buildDrawingCache();
Bitmap b = Bitmap.createBitmap(u.getDrawingCache());
u.setDrawingCacheEnabled(false);
u.destroyDrawingCache();
return b;
}
Metoda savePic ():
public static File savePic(Bitmap bm){
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bm.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
File sdCardDirectory = new File(Environment.getExternalStorageDirectory() + "/Foldername");
if (!sdCardDirectory.exists()) {
sdCardDirectory.mkdirs();
}
// File file = new File(dir, fileName);
try {
file = new File(sdCardDirectory, Calendar.getInstance()
.getTimeInMillis() + ".jpg");
file.createNewFile();
new FileOutputStream(file).write(bytes.toByteArray());
Log.d("Fabsolute", "File Saved::--->" + file.getAbsolutePath());
Log.d("Sabsolute", "File Saved::--->" + sdCardDirectory.getAbsolutePath());
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
Do aktywności możesz po prostu użyć View v1 = getWindow().getDecorView().getRootView();
zamiastmView
Większość odpowiedzi na to pytanie używa Canvas
metody rysowania lub pamięci podręcznej rysowania. Jednak View.setDrawingCache()
metoda jest przestarzała w API 28 . Obecnie zalecanym API do tworzenia zrzutów ekranu jest PixelCopy
klasa dostępna z API 24 (ale metody, które akceptują Window
parametry, są dostępne z API 26 == Android 8.0 Oreo). Oto przykładowy kod Kotlin do pobierania Bitmap
:
@RequiresApi(Build.VERSION_CODES.O)
fun saveScreenshot(view: View) {
val window = (view.context as Activity).window
if (window != null) {
val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
val locationOfViewInWindow = IntArray(2)
view.getLocationInWindow(locationOfViewInWindow)
try {
PixelCopy.request(window, Rect(locationOfViewInWindow[0], locationOfViewInWindow[1], locationOfViewInWindow[0] + view.width, locationOfViewInWindow[1] + view.height), bitmap, { copyResult ->
if (copyResult == PixelCopy.SUCCESS) {
saveBitmap(bitmap)
}
// possible to handle other result codes ...
}, Handler())
} catch (e: IllegalArgumentException) {
// PixelCopy may throw IllegalArgumentException, make sure to handle it
}
}
}
Widok parametrów jest obiektem układu głównego.
public static Bitmap screenShot(View view) {
Bitmap bitmap = null;
if (view.getWidth() > 0 && view.getHeight() > 0) {
bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
}
return bitmap;
}
Zrzut ekranu z przewijaniem całej strony
Jeśli chcesz przechwycić pełny zrzut ekranu (który zawiera mniej więcej widok przewijania), sprawdź tę bibliotekę
Wszystko, co musisz zrobić, to zaimportować Gradel i stworzyć obiekt BigScreenshot
BigScreenshot longScreenshot = new BigScreenshot(this, x, y);
Oddzwonienie zostanie odebrane z bitmapą Zrzutów ekranu wykonanych podczas automatycznego przewijania grupy widoków ekranu i na końcu połączonych razem.
@Override public void getScreenshot(Bitmap bitmap) {}
Które można zapisać w galerii lub jakikolwiek sposób użycia jest konieczny po ich zakończeniu
Wykonaj zrzut ekranu widoku w Androidzie.
public static Bitmap getViewBitmap(View v) {
v.clearFocus();
v.setPressed(false);
boolean willNotCache = v.willNotCacheDrawing();
v.setWillNotCacheDrawing(false);
int color = v.getDrawingCacheBackgroundColor();
v.setDrawingCacheBackgroundColor(0);
if (color != 0) {
v.destroyDrawingCache();
}
v.buildDrawingCache();
Bitmap cacheBitmap = v.getDrawingCache();
if (cacheBitmap == null) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
v.destroyDrawingCache();
v.setWillNotCacheDrawing(willNotCache);
v.setDrawingCacheBackgroundColor(color);
return bitmap;
}
jeśli chcesz uchwycić widok lub układ, taki jak RelativeLayout lub LinearLayout itp., po prostu użyj kodu:
LinearLayout llMain = (LinearLayout) findViewById(R.id.linearlayoutMain);
Bitmap bm = loadBitmapFromView(llMain);
teraz możesz zapisać tę bitmapę w pamięci urządzenia poprzez:
FileOutputStream outStream = null;
File f=new File(Environment.getExternalStorageDirectory()+"/Screen Shots/");
f.mkdir();
String extStorageDirectory = f.toString();
File file = new File(extStorageDirectory, "my new screen shot");
pathOfImage = file.getAbsolutePath();
try {
outStream = new FileOutputStream(file);
bm.compress(Bitmap.CompressFormat.PNG, 100, outStream);
Toast.makeText(getApplicationContext(), "Saved at "+f.getAbsolutePath(), Toast.LENGTH_LONG).show();
addImageGallery(file);
//mail.setEnabled(true);
flag=true;
} catch (FileNotFoundException e) {e.printStackTrace();}
try {
outStream.flush();
outStream.close();
} catch (IOException e) {e.printStackTrace();}