[英]Capture screen shot of GoogleMap Android API V2
Final Update最后更新
The feature request has been fulfilled by Google. Google 已满足功能请求。 Please see this answer below.
请在下面查看此答案。
Original Question原问题
Using the old version of the Google Maps Android API, I was able to capture a screenshot of the google map to share via social media.使用旧版谷歌地图 Android API,我能够截取谷歌 map 的屏幕截图并通过社交媒体分享。 I used the following code to capture the screenshot and save the image to a file and it worked great:
我使用以下代码捕获屏幕截图并将图像保存到文件中,效果很好:
public String captureScreen()
{
String storageState = Environment.getExternalStorageState();
Log.d("StorageState", "Storage state is: " + storageState);
// image naming and path to include sd card appending name you choose for file
String mPath = this.getFilesDir().getAbsolutePath();
// create bitmap screen capture
Bitmap bitmap;
View v1 = this.mapView.getRootView();
v1.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
OutputStream fout = null;
String filePath = System.currentTimeMillis() + ".jpeg";
try
{
fout = openFileOutput(filePath,
MODE_WORLD_READABLE);
// Write the string to the file
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
fout.close();
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
Log.d("ImageCapture", "FileNotFoundException");
Log.d("ImageCapture", e.getMessage());
filePath = "";
}
catch (IOException e)
{
// TODO Auto-generated catch block
Log.d("ImageCapture", "IOException");
Log.d("ImageCapture", e.getMessage());
filePath = "";
}
return filePath;
}
However, the new GoogleMap object used by V2 of the api does not have a "getRootView()" method like MapView does.但是,api 的 V2 使用的新 GoogleMap object 没有像 MapView 那样的“getRootView()”方法。
I tried to do this:我试图这样做:
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.basicMap);
View v1 = mapFragment.getView();
But the screenshot that I get does not have any map content and looks like this:但是我得到的屏幕截图没有任何 map 内容,看起来像这样:
Has anyone figured out how to take a screenshot of the new Google Maps Android API V2?有没有人想出如何截取新的谷歌地图 Android API V2 的截图?
Update更新
I also tried to get the rootView this way:我也尝试通过这种方式获取 rootView:
View v1 = getWindow().getDecorView().getRootView();
This results in a screenshot that includes the action bar at the top of the screen, but the map is still blank like the screenshot I attached.这会生成屏幕顶部包含操作栏的屏幕截图,但 map 仍然像我附上的屏幕截图一样空白。
Update更新
A feature request has been submitted to Google.已向 Google 提交功能请求。 Please go star the feature request if this is something you want google to add in the future:Add screenshot ability to Google Maps API V2
请 go 星标功能请求,如果这是你希望谷歌在未来添加的东西:Add screenshot ability to Google Maps API V2
Update - Google has added a snapshot method**!: 更新 - 谷歌添加了快照方法**!:
The feature request for a method to take a screen shot of the Android Google Map API V2 OpenGL layer has been fulfilled. 已完成针对Android Google Map API V2 OpenGL图层的屏幕截图的方法的功能请求。
To take a screenshot, simply implement the following interface: 要截取屏幕截图,只需实现以下界面:
public abstract void onSnapshotReady (Bitmap snapshot)
and call: 并致电:
public final void snapshot (GoogleMap.SnapshotReadyCallback callback)
Example that takes a screenshot, then presents the standard "Image Sharing" options: 截取屏幕截图的示例,然后显示标准的“图像共享”选项:
public void captureScreen()
{
SnapshotReadyCallback callback = new SnapshotReadyCallback()
{
@Override
public void onSnapshotReady(Bitmap snapshot)
{
// TODO Auto-generated method stub
bitmap = snapshot;
OutputStream fout = null;
String filePath = System.currentTimeMillis() + ".jpeg";
try
{
fout = openFileOutput(filePath,
MODE_WORLD_READABLE);
// Write the string to the file
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
fout.close();
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
Log.d("ImageCapture", "FileNotFoundException");
Log.d("ImageCapture", e.getMessage());
filePath = "";
}
catch (IOException e)
{
// TODO Auto-generated catch block
Log.d("ImageCapture", "IOException");
Log.d("ImageCapture", e.getMessage());
filePath = "";
}
openShareImageDialog(filePath);
}
};
mMap.snapshot(callback);
}
Once the image is finished being captured, it will trigger the standard "Share Image" dialog so the user can pick how they'd like to share it: 一旦图像完成捕获,它将触发标准的“共享图像”对话框,以便用户可以选择他们想要共享的方式:
public void openShareImageDialog(String filePath)
{
File file = this.getFileStreamPath(filePath);
if(!filePath.equals(""))
{
final ContentValues values = new ContentValues(2);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.DATA, file.getAbsolutePath());
final Uri contentUriFile = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
final Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("image/jpeg");
intent.putExtra(android.content.Intent.EXTRA_STREAM, contentUriFile);
startActivity(Intent.createChooser(intent, "Share Image"));
}
else
{
//This is a custom class I use to show dialogs...simply replace this with whatever you want to show an error message, Toast, etc.
DialogUtilities.showOkDialogWithText(this, R.string.shareImageFailed);
}
}
Below are the steps to capture screen shot of Google Map V2 with example 以下是捕获Google Map V2屏幕截图的步骤
Step 1. open Android Sdk Manager (Window > Android Sdk Manager)
then Expand Extras
now update/install Google Play Services to Revision 10
ignore this step if already installed
步骤1.打开
Android Sdk Manager (Window > Android Sdk Manager)
然后Expand Extras
现在update/install Google Play Services to Revision 10
忽略此步骤(如果已经installed
Read Notes here https://developers.google.com/maps/documentation/android/releases#august_2013 在此处阅读说明https://developers.google.com/maps/documentation/android/releases#august_2013
Step 2. Restart Eclipse
步骤2.
Restart Eclipse
Step 3. import com.google.android.gms.maps.GoogleMap.SnapshotReadyCallback;
第3步。
import com.google.android.gms.maps.GoogleMap.SnapshotReadyCallback;
Step 4. Make Method to Capture/Store Screen/image of Map like below 步骤4.制作方法以捕获/存储地图的屏幕/图像,如下所示
public void CaptureMapScreen()
{
SnapshotReadyCallback callback = new SnapshotReadyCallback() {
Bitmap bitmap;
@Override
public void onSnapshotReady(Bitmap snapshot) {
// TODO Auto-generated method stub
bitmap = snapshot;
try {
FileOutputStream out = new FileOutputStream("/mnt/sdcard/"
+ "MyMapScreen" + System.currentTimeMillis()
+ ".png");
// above "/mnt ..... png" => is a storage path (where image will be stored) + name of image you can customize as per your Requirement
bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
}
}
};
myMap.snapshot(callback);
// myMap is object of GoogleMap +> GoogleMap myMap;
// which is initialized in onCreate() =>
// myMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map_pass_home_call)).getMap();
}
Step 5. Now call this CaptureMapScreen()
method where you want to capture the image 步骤5.现在调用此
CaptureMapScreen()
方法来捕获图像
in my case i am calling this method on Button click in my onCreate()
which is working fine 在我的情况下,我
calling this method on Button click in my onCreate()
,这是正常的
like: 喜欢:
Button btnCap = (Button) findViewById(R.id.btnTakeScreenshot);
btnCap.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
try {
CaptureMapScreen();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
});
Edit : this answer is no longer valid - the feature request for screenshots on Google Maps Android API V2 has been fulfilled. 编辑 :此答案不再有效 - 已完成Google Maps Android API V2上的屏幕截图功能请求。 See this answer for an example .
请参阅此答案以获取示例 。
Original Accepted Answer 原始接受的答案
Since the new Android API v2 Maps are displayed using OpenGL, there are no possibilities to create a screenshot. 由于使用OpenGL显示新的Android API v2 Maps,因此无法创建屏幕截图。
I capctured Map screenshot.It will be helpful 我制作了地图截图。它会很有帮助
private GoogleMap map;
private static LatLng latLong;
` `
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
setMap(this.map);
animateCamera();
map.moveCamera (CameraUpdateFactory.newLatLng (latLong));
map.setOnMapLoadedCallback (new GoogleMap.OnMapLoadedCallback () {
@Override
public void onMapLoaded() {
snapShot();
}
});
}
` `
snapShot() method for taking screenshot of map 用于截取地图截图的snapShot()方法
public void snapShot(){
GoogleMap.SnapshotReadyCallback callback=new GoogleMap.SnapshotReadyCallback () {
Bitmap bitmap;
@Override
public void onSnapshotReady(Bitmap snapshot) {
bitmap=snapshot;
try{
file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),"map.png");
FileOutputStream fout=new FileOutputStream (file);
bitmap.compress (Bitmap.CompressFormat.PNG,90,fout);
Toast.makeText (PastValuations.this, "Capture", Toast.LENGTH_SHORT).show ();
}catch (Exception e){
e.printStackTrace ();
Toast.makeText (PastValuations.this, "Not Capture", Toast.LENGTH_SHORT).show ();
}
}
};map.snapshot (callback);
}
Since the top voted answer doesnt work with polylines and other overlays on top of the map fragment (What I was looking for), I want to share this solution. 由于最高投票的答案不适用于地图片段顶部的折线和其他叠加(我在寻找什么),我想分享这个解决方案。
public void captureScreen()
{
GoogleMap.SnapshotReadyCallback callback = new GoogleMap.SnapshotReadyCallback()
{
@Override
public void onSnapshotReady(Bitmap snapshot) {
try {
getWindow().getDecorView().findViewById(android.R.id.content).setDrawingCacheEnabled(true);
Bitmap backBitmap = getWindow().getDecorView().findViewById(android.R.id.content).getDrawingCache();
Bitmap bmOverlay = Bitmap.createBitmap(
backBitmap.getWidth(), backBitmap.getHeight(),
backBitmap.getConfig());
Canvas canvas = new Canvas(bmOverlay);
canvas.drawBitmap(snapshot, new Matrix(), null);
canvas.drawBitmap(backBitmap, 0, 0, null);
OutputStream fout = null;
String filePath = System.currentTimeMillis() + ".jpeg";
try
{
fout = openFileOutput(filePath,
MODE_WORLD_READABLE);
// Write the string to the file
bmOverlay.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
fout.close();
}
catch (FileNotFoundException e)
{
// TODO Auto-generated catch block
Log.d("ImageCapture", "FileNotFoundException");
Log.d("ImageCapture", e.getMessage());
filePath = "";
}
catch (IOException e)
{
// TODO Auto-generated catch block
Log.d("ImageCapture", "IOException");
Log.d("ImageCapture", e.getMessage());
filePath = "";
}
openShareImageDialog(filePath);
} catch (Exception e) {
e.printStackTrace();
}
}
};
;
map.snapshot(callback);
}
private GoogleMap mMap;
SupportMapFragment mapFragment;
LinearLayout linearLayout;
String jobId="1";
File file; 文件文件;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate (savedInstanceState);
setContentView (R.layout.activity_maps);
linearLayout=(LinearLayout)findViewById (R.id.linearlayout);
// Obtain the SupportMapFragment and get notified when the map is ready to be used.
mapFragment = (SupportMapFragment)getSupportFragmentManager ()
.findFragmentById (R.id.map);
mapFragment.getMapAsync (this);
//Taking Snapshot of Google Map
}
/**
* Manipulates the map once available.
* This callback is triggered when the map is ready to be used.
* This is where we can add markers or lines, add listeners or move the camera. In this case,
* we just add a marker near Sydney, Australia.
* If Google Play services is not installed on the device, the user will be prompted to install
* it inside the SupportMapFragment. This method will only be triggered once the user has
* installed Google Play services and returned to the app.
*/
@Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
// Add a marker in Sydney and move the camera
LatLng sydney = new LatLng (-26.888033, 75.802754);
mMap.addMarker (new MarkerOptions ().position (sydney).title ("Kailash Tower"));
mMap.moveCamera (CameraUpdateFactory.newLatLng (sydney));
mMap.setOnMapLoadedCallback (new GoogleMap.OnMapLoadedCallback () {
@Override
public void onMapLoaded() {
snapShot();
}
});
}
// Initializing Snapshot Method
public void snapShot(){
GoogleMap.SnapshotReadyCallback callback=new GoogleMap.SnapshotReadyCallback () {
Bitmap bitmap;
@Override
public void onSnapshotReady(Bitmap snapshot) {
bitmap=snapshot;
bitmap=getBitmapFromView(linearLayout);
try{
file=new File (getExternalCacheDir (),"map.png");
FileOutputStream fout=new FileOutputStream (file);
bitmap.compress (Bitmap.CompressFormat.PNG,90,fout);
Toast.makeText (MapsActivity.this, "Capture", Toast.LENGTH_SHORT).show ();
sendSceenShot (file);
}catch (Exception e){
e.printStackTrace ();
Toast.makeText (MapsActivity.this, "Not Capture", Toast.LENGTH_SHORT).show ();
}
}
};mMap.snapshot (callback);
}
private Bitmap getBitmapFromView(View view) {
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas (returnedBitmap);
Drawable bgDrawable =view.getBackground();
if (bgDrawable!=null) {
//has background drawable, then draw it on the canvas
bgDrawable.draw(canvas);
} else{
//does not have background drawable, then draw white background on the canvas
canvas.drawColor(Color.WHITE);
}
view.draw(canvas);
return returnedBitmap;
}
//Implementing Api using Retrofit
private void sendSceenShot(File file) {
RequestBody job=null;
Gson gson = new GsonBuilder ()
.setLenient ()
.create ();
Retrofit retrofit = new Retrofit.Builder ()
.baseUrl (BaseUrl.url)
.addConverterFactory (GsonConverterFactory.create (gson))
.build ();
final RequestBody requestBody = RequestBody.create (MediaType.parse ("image/*"),file);
job=RequestBody.create (MediaType.parse ("text"),jobId);
MultipartBody.Part fileToUpload = MultipartBody.Part.createFormData ("name",file.getName (), requestBody);
API service = retrofit.create (API.class);
Call<ScreenCapture_Pojo> call=service.sendScreen (job,fileToUpload);
call.enqueue (new Callback<ScreenCapture_Pojo> () {
@Override
public void onResponse(Call <ScreenCapture_Pojo> call, Response<ScreenCapture_Pojo> response) {
if (response.body ().getMessage ().equalsIgnoreCase ("Success")){
Toast.makeText (MapsActivity.this, "success", Toast.LENGTH_SHORT).show ();
}
}
@Override
public void onFailure(Call <ScreenCapture_Pojo> call, Throwable t) {
}
});
}
} }
I hope this would help to capture the screenshot of your map 我希望这有助于捕获地图的屏幕截图
Method call: 方法调用:
gmap.setOnMapLoadedCallback(mapLoadedCallback);
Method declaration: 方法声明:
final SnapshotReadyCallback snapReadyCallback = new SnapshotReadyCallback() {
Bitmap bitmap;
@Override
public void onSnapshotReady(Bitmap snapshot) {
bitmap = snapshot;
try {
//do something with your snapshot
imageview.setImageBitmap(bitmap);
} catch (Exception e) {
e.printStackTrace();
}
}
};
GoogleMap.OnMapLoadedCallback mapLoadedCallback = new GoogleMap.OnMapLoadedCallback() {
@Override
public void onMapLoaded() {
gmap.snapshot(snapReadyCallback);
}
};
Use mapcalback for get screenshot of map使用 mapcalback 获取地图截图
GoogleMap.SnapshotReadyCallback callback = new GoogleMap.SnapshotReadyCallback() {
Bitmap bitmap=null;
@Override
public void onSnapshotReady(Bitmap snapshot) {
// TODO Auto-generated method stub
bitmap = snapshot;
try {
saveImage(bitmap);
Toast.makeText(getActivity().getApplicationContext(), "Successful.Screenshot Saved.", Toast.LENGTH_LONG).show();
} catch (Exception e) {
e.printStackTrace();
}
}
private void saveImage(Bitmap bitmap) throws IOException {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
Date date = new Date();
CharSequence format = android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", date);
String dirpath = Environment.getExternalStorageDirectory() + "";
File file = new File(dirpath);
if (!file.exists()) {
boolean mkdir = file.mkdir();
}
String path1 = dirpath + "/Documents/SCREENSHOT/";
File imageurl1 = new File(path1);
imageurl1.mkdirs();
File f = new File(path1 +"/"+ format + ".png");
f.createNewFile();
FileOutputStream fo = new FileOutputStream(f);
fo.write(bytes.toByteArray());
fo.close();
}
};
mMap.snapshot(callback);
Eclipse DDMS can capture the screen even it's google map V2. Eclipse DDMS可以捕获屏幕,即使它是谷歌地图V2。
Try to call /system/bin/screencap or /system/bin/screenshot if you have the "root". 如果你有“root”,请尝试调用/ system / bin / screencap或/ system / bin / screenshot。 I learned that from How Eclipse android DDMS implement "screen capture"
我从Eclipse android DDMS如何实现“屏幕截图”中了解到
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.