当我的应用程序安装并在后台运行200毫秒时,我需要以编程方式截取Android设备或模拟器,并将图像保存在我的计算机中。我已使用下面的代码实现了此过程,仅在我的应用程序位于前台时才有效。当我的应用程序也在后台时,我想截取屏幕截图。以下是我的代码:
public static Bitmap takeScreenshot(Activity activity, int ResourceID) {
Random r = new Random();
int iterator=r.nextInt();
String mPath = Environment.getExternalStorageDirectory().toString() + "/screenshots/";
View v1 = activity.getWindow().getDecorView().findViewById(ResourceID);
v1.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED),
MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
v1.layout(0, 0, v1.getMeasuredWidth(), v1.getMeasuredHeight());
v1.setDrawingCacheEnabled(true);
final Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
Bitmap resultBitmap = Bitmap.createScaledBitmap(bitmap, 640, 480, false);
v1.setDrawingCacheEnabled(false);
File imageFile = new File(mPath);
imageFile.mkdirs();
imageFile = new File(imageFile+"/"+iterator+"_screenshot.png");
try {
ByteArrayOutputStream bos = new ByteArrayOutputStream();
resultBitmap.compress(CompressFormat.PNG, 100, bos);
byte[] bitmapdata = bos.toByteArray();
//write the bytes in file
FileOutputStream fos = new FileOutputStream(imageFile);
fos.write(bitmapdata);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return bitmap;
}
如何以编程方式在Devices -> DDMS
中实现Screencapture的“刷新”和“保存”按钮的功能?我可以实现吗?
答案 0 :(得分:17)
如果您的手机已植根,请尝试使用
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();
然后将img.png作为位图读取并将其转换为jpg如下
Bitmap screen = BitmapFactory.decodeFile(Environment.getExternalStorageDirectory()+
File.separator +"img.png");
//my code for saving
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
screen.compress(Bitmap.CompressFormat.JPEG, 15, bytes);
//you can create a new file name "test.jpg" in sdcard folder.
File f = new File(Environment.getExternalStorageDirectory()+ File.separator + "test.jpg");
f.createNewFile();
//write the bytes in file
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
// remember close de FileOutput
fo.close();
如果您的应用程序处于后台,除非您扎根,否则您无权访问该屏幕,即使您在后台,上面的代码也可以最有效地截取屏幕截图。
<强>更新强>
谷歌有一个图书馆,你可以用它来截取而不需要生根,我试过了,但我确信它会尽快消耗内存。
答案 1 :(得分:13)
这是做到这一点的方法。
Android taking Screen shots through code
结果输出:
public class CaptureScreenShots extends Activity {
LinearLayout L1;
ImageView image;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.screen_shots);
L1 = (LinearLayout) findViewById(R.id.LinearLayout01);
Button but = (Button) findViewById(R.id.munchscreen);
but.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
View v1 = L1.getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bm = v1.getDrawingCache();
BitmapDrawable bitmapDrawable = new BitmapDrawable(bm);
image = (ImageView) findViewById(R.id.screenshots);
image.setBackgroundDrawable(bitmapDrawable);
}
});
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.screen_shots, menu);
return true;
}
}
答案 2 :(得分:4)
在后台拍摄屏幕截图(如ADB)需要 groups = 1003(图形)。否则,您只能获得自己进程的屏幕截图。因此,您只能在root设备上执行此操作,或者通过运行ADB本机程序来执行此操作。
可以在https://android.googlesource.com/platform/frameworks/base/+/android-4.3_r2.3/cmds/screencap/
找到原生cpp代码示例如果你想在java代码中这样做,你需要访问Surface类的隐藏API:
/**
* Like {@link #screenshot(int, int, int, int)} but includes all
* Surfaces in the screenshot.
*
* @hide
*/
public static native Bitmap screenshot(int width, int height);
这两个应该都可以,因为ICS发布,对于早期版本,如GB,你可以查看本机cpp代码。
但是,在某些Android设备中,媒体系统和画布等的实现并不是很好,因此,在这种情况下,您无法捕获任何视频播放或任何表面视图内容。
答案 3 :(得分:0)
您可以考虑将MediaProjection和AccessibilityService混合使用。第一个轻松获取屏幕截图,第二个始终在所有应用“之上”运行
教程如何在CODELABS中运行k <- {tmp <- table(x); names(tmp)[order(tmp, decreasing = TRUE)]}
k
[1] "pen" "banana" "apple" "desk"
上述HERE的全部来源
在THIS答案中,您可以找到AccessibilityService
的非常有用的代码。记住要设置适当的完全透明的Activity
:
Theme
然后根据需要在您的<style name="Theme.AppCompat.Translucent" parent="Theme.AppCompat.NoActionBar">
<item name="android:background">#00000000</item>
<item name="android:windowNoTitle">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:colorBackgroundCacheHint">@null</item>
<item name="android:windowIsTranslucent">true</item>
<item name="android:windowAnimationStyle">@null</item>
</style>
中循环startActivity
,甚至更好-使用AccessibilityService
通知LocalBroadcastManager
Service
截屏并完成(因此Activity
可以再次启动此Service
)
我做过类似的事情(仅供内部使用)+屏幕截图已通过OCR分析,以从中获取文本。 Kinda解析,当非您的应用以某种方式抵御Activity
功能(这种AccesibilityService
类型旨在帮助残疾人,例如在阅读文本时,通常可以访问Service
))< / p>
答案 4 :(得分:-1)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select name="select1" id="select1">
<option value="1">Fruit</option>
<option value="2">Animal</option>
<option value="3">Bird</option>
<option value="4">Car</option>
</select>
<div id="selsear">
</div>
将此方法添加到按钮单击事件或选项菜单项选择事件中,屏幕截图将存储在“下载”文件夹中,因为在private void takeScreenshot() throws IOException {
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
String fileName = now + ".jpg";
try {
File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "");
folder.mkdirs(); //create directory
// 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(folder, fileName);
imageFile.createNewFile();
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, outputStream);
outputStream.flush();
outputStream.close();
Toast.makeText(MainActivity.this, "ScreenShot Captured", Toast.LENGTH_SHORT).show();
MediaScannerConnection.scanFile(this,
new String[]{imageFile.toString()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
}
});
} catch (Throwable e) {
// Several error may come out with file handling or OOM
e.printStackTrace();
}
}
变量中我提供了下载路径,您可以更改文件夹路径。文件添加写入权限
folder