web-dev-qa-db-ja.com

GoogleマップのスクリーンショットをキャプチャAndroid API V2

最終更新

機能のリクエストはGoogleによって処理されました。以下の この回答をご覧ください。

元の質問

Googleマップの古いバージョンAndroid APIを使用して、ソーシャルマップ経由で共有するためにGoogleマップのスクリーンショットをキャプチャできました。次のコードを使用してスクリーンショットをキャプチャし、画像を保存しましたファイルにすると、うまくいきました:

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;
}

ただし、APIのV2で使用される新しいGoogleMapオブジェクトには、MapViewのような「getRootView()」メソッドがありません。

私はこれをやろうとしました:

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.basicMap);

    View v1 = mapFragment.getView();

しかし、私が取得したスクリーンショットにはマップコンテンツがなく、次のようになります。 Blank Map Screenshot

新しいGoogle Maps Android API V2のスクリーンショットを撮る方法を誰かが考えましたか?

更新

また、私はこの方法でrootViewを取得しようとしました:

View v1 = getWindow().getDecorView().getRootView();

これにより、スクリーン上部にアクションバーを含むスクリーンショットが表示されますが、マップは添付したスクリーンショットのように空白のままです。

更新

機能のリクエストがGoogleに送信されました。これが今後Googleに追加したい機能リクエストの場合は、スターを付けてください: Google Maps API V2にスクリーンショット機能を追加します

45
DiscDev

更新-Googleがスナップショットメソッドを追加しました** !:

Android Google Map API V2 OpenGLレイヤーのスクリーンショットを撮るメソッドの機能要求は満たされました。

スクリーンショットを撮るには、次のインターフェイスを実装するだけです。

_public abstract void onSnapshotReady (Bitmap snapshot)
_

そして電話:

public final void snapshot (GoogleMap.SnapshotReadyCallback callback)

スクリーンショットを撮り、標準の「画像共有」オプションを提示する例:

_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);
    }
_

画像のキャプチャが完了すると、標準の[画像の共有]ダイアログがトリガーされるため、ユーザーは共有方法を選択できます。

_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);
}
}
_

ドキュメントは こちら です

62
DiscDev

以下は、例とともにGoogle Map V2のスクリーンショットをキャプチャする手順です。

ステップ1 open Android Sdk Manager (Window > Android Sdk Manager) then Expand Extras now update/install Google Play Services to Revision 10すでにこのステップを無視するinstalled

ここでメモを読む https://developers.google.com/maps/documentation/Android/releases#august_201

ステップ2。Restart Eclipse

ステップ3。import com.google.Android.gms.maps.GoogleMap.SnapshotReadyCallback;

ステップ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();
}

ステップ5画像をキャプチャする場所でこのCaptureMapScreen()メソッドを呼び出します

私の場合、私は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();
            }

        }
    });

Doc here および here を確認してください

30
Tarsem Singh

編集:この回答は無効になりました-Googleマップのスクリーンショットの機能リクエストAndroid API V2が満たされました 例についてはこの回答 を参照してください。

元の回答

新しいAndroid API v2マップはOpenGLを使用して表示されるため、スクリーンショットを作成する可能性はありません。

4
Greeny

地図のスクリーンショットをキャプチャしました。

  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()メソッド

 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);
}

私の出力は以下です enter image description here

4
Narendra.kr

上位の回答は、マップフラグメント上のポリラインやその他のオーバーレイ(探していたもの)では機能しないため、このソリューションを共有したいと思います。

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);
        }
3
danielrosero
private GoogleMap mMap;
SupportMapFragment mapFragment;
LinearLayout linearLayout;
String jobId="1";

ファイル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) {

        }
    });

}

}

2
AndroHelper

これが地図のスクリーンショットのキャプチャに役立つことを願っています

メソッド呼び出し:

gmap.setOnMapLoadedCallback(mapLoadedCallback);

メソッド宣言:

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);
        }
};
0
Mahendran Candy