How to retrieve snapshot of map from place-picker activity?
Asked Answered
H

5

26

I'm creating an app which picks places from the Google maps and stores the address in the database. I also want to store the snapshot of the picked place in the storage, so I can display the data with corresponding snapshot.

When I select a place from the map, the place-picker activity shows the following dialog:

enter image description here

Here in the dialog, the address, latitude and longitude and also the snapshot is shown. I know how to get address and latLng. but don't know how to store that displayed snapshot.

Here is my method which retrieves everything other than that image:

  //opening place picker activity.
protected void onActivityResult(int requestCode,
                                int resultCode, Intent data) {

    if (requestCode == PLACE_PICKER_REQUEST
            && resultCode == Activity.RESULT_OK) {

        final Place place = PlacePicker.getPlace(this, data);
        final CharSequence name = place.getName();
        final CharSequence address = place.getAddress();

        String attributions = (String) place.getAttributions();
        if (attributions == null) {
            attributions = "";
        }
        tv4.setText(place.getLatLng().toString()+"\n"+name+"\n"+address+"\n"+attributions);


    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}

I don't know how to get the image and store it in external or internal storage. Is it possible? I've to take snapshot as explained in this link?

EDIT

I have the following activity, which is calling activity of place-picker:

Main2Activity.java:

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Bundle;
 import android.os.Environment;
import android.support.v4.app.NavUtils;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
import  com.google.android.gms.common.GooglePlayServicesRepairableException;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.places.Place;
import com.google.android.gms.location.places.ui.PlacePicker;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import android.database.Cursor;
import android.widget.EditText;
import android.widget.Toast;
import com.google.android.gms.maps.OnMapReadyCallback;

import java.io.File;
import java.io.FileOutputStream;
import java.util.Date;


public class Main2Activity extends AppCompatActivity implements OnMapReadyCallback{
private static final int PLACE_PICKER_REQUEST = 1;
private TextView mName;
private TextView mAddress;
private TextView mAttributions;
private GoogleApiClient mGoogleApiClient;
public TextView tv4;
private static final LatLngBounds BOUNDS_MOUNTAIN_VIEW = new LatLngBounds(
        new LatLng(37.398160, -122.180831), new LatLng(37.430610, -121.972090));

private Toolbar toolbar;
private GoogleMap mMap;
private boolean flag = false;
DatabaseHelper myDb;
EditText newevent;
Button submit;
Button viewremainders;
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main2);


    MapFragment mapFragment = (MapFragment) getFragmentManager() .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);



    myDb =new DatabaseHelper(this);
    newevent=(EditText)findViewById(R.id.newEvent);
    submit=(Button)findViewById(R.id.submit);
    viewremainders=(Button)findViewById(R.id.view);

    toolbar = (Toolbar)findViewById(R.id.app_bar0);
    setSupportActionBar(toolbar);

    getSupportActionBar().setHomeButtonEnabled(true);          //for back button to main activity.
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    Button pickerButton = (Button) findViewById(R.id.pickerButton);
    tv4 = (TextView)findViewById(R.id.textView4);
    pickerButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            try {
                PlacePicker.IntentBuilder intentBuilder =
                        new PlacePicker.IntentBuilder();
                intentBuilder.setLatLngBounds(BOUNDS_MOUNTAIN_VIEW);
                Intent intent = intentBuilder.build(Main2Activity.this);
                startActivityForResult(intent, PLACE_PICKER_REQUEST);


            } catch (GooglePlayServicesRepairableException
                    | GooglePlayServicesNotAvailableException e) {
                e.printStackTrace();
            }
        }
    });

    AddData();
    viewremainders();
}

@Override
public void onMapReady(GoogleMap map) {


    mMap = map;
}

//method for adding data in Database.
public void AddData(){
    submit.setOnClickListener(
            new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    boolean isInserted =myDb.insertData(newevent.getText().toString(),tv4.getText().toString());
                    if(isInserted==true)
                        Toast.makeText(Main2Activity.this,"Data Inserted",Toast.LENGTH_LONG).show();
                    else
                        Toast.makeText(Main2Activity.this,"Data not Inserted",Toast.LENGTH_LONG).show();

                }
            }
    );
}

//Method for view all data from database.
public void viewremainders(){
    viewremainders.setOnClickListener(
            new View.OnClickListener(){
                @Override
                public void onClick(View v){
                    Cursor res= myDb.getAllData();
                    if(res.getCount()==0)
                    {
                        Showmessage("Error","No remainders found");
                        return;
                    }
                    StringBuffer buffer=new StringBuffer();
                    while(res.moveToNext())
                    {
                        buffer.append("Id : " +res.getString(0)+"\n");
                        buffer.append("Event : " +res.getString(1)+"\n");
                        buffer.append("Location : " +res.getString(2)+"\n");
                    }
                    Showmessage("Data",buffer.toString());

                }



            }
    );
}

public void Showmessage(String title,String message)
{
    AlertDialog.Builder builder=new AlertDialog.Builder(this);
    builder.setCancelable(true);
    builder.setTitle(title);
    builder.setMessage(message);
    builder.show();
}


//opening place picker activity.
protected void onActivityResult(int requestCode, int resultCode, Intent data) {


    if (requestCode == PLACE_PICKER_REQUEST
            && resultCode == Activity.RESULT_OK) {

        final Place place = PlacePicker.getPlace(this, data);
        final CharSequence name = place.getName();
        final CharSequence address = place.getAddress();



        String attributions = (String) place.getAttributions();
        if (attributions == null) {
            attributions = "";
        }
     //   tv4.setText(place.getLatLng().toString()+"\n"+name+"\n"+address+"\n"+attributions);  To get latitide and longitudes.
        tv4.setText(address+"\n"+attributions);





   /*     LatLngBounds selectedPlaceBounds = PlacePicker.getLatLngBounds(data);
        // move camera to selected bounds
        CameraUpdate camera = CameraUpdateFactory.newLatLngBounds(selectedPlaceBounds,0);
        mMap.moveCamera(camera);

        // take snapshot and implement the snapshot ready callback
        mMap.snapshot(new GoogleMap.SnapshotReadyCallback() {
            Bitmap bitmap=null;
            public void onSnapshotReady(Bitmap snapshot) {
                // handle snapshot here
                bitmap = snapshot;
                try {
                    FileOutputStream out = new FileOutputStream(Environment.getExternalStorageDirectory().toString()+"/ing.png");
                    bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
                    Toast.makeText(Main2Activity.this,"dsfds",Toast.LENGTH_LONG).show();
                } catch (Exception e) {
                    Toast.makeText(Main2Activity.this,e.toString(),Toast.LENGTH_SHORT).show();
                    e.printStackTrace();
                }
            }
        });*/



    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}


private void capture(){
    try {
        // image naming and path  to include sd card  appending name you choose for file
        String mPath = Environment.getExternalStoragePublicDirectory(
                Environment.DIRECTORY_MOVIES).toString();

        // 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(Environment.getExternalStorageDirectory().toString()+"/"+"lllll.jpg");

        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 OOM
        e.printStackTrace();
    }
}


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

//Methods for toolbar


@Override
public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
    getMenuInflater().inflate(R.menu.menu_main2, menu);
    return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
    // Handle action bar item clicks here. The action bar will
    // automatically handle clicks on the Home/Up button, so long
    // as you specify a parent activity in AndroidManifest.xml.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_settings) {
        return true;
    }

    if(id == android.R.id.home){
        NavUtils.navigateUpFromSameTask(this);
    }

    return super.onOptionsItemSelected(item);
}
}

enter image description here enter image description here

Halley answered 18/8, 2016 at 10:49 Comment(12)
Let us continue this discussion in chat.Corded
RESULT OF THE ANSWER : #39233184Arronarrondissement
@14bce109 Can you clarify your question? When do you want to create the snapshot (image screenshot of the map)? Instead of using an image screenshot, have you considered to just show a GoogleMap and moving the camera to the stored coordinates?Germander
@Germander actually I've a place picker activity, and from this user can select the places from the map. Now when user select a place on the map, the above dialogue box appears to ask for confirmation. From this dialogue box use can change the selected location(By tapping on CHANGE LOCATION) or can confirm and finalize the location which is displayed in the dialogue. At this point, when user finalize his/her location, I want a snap-shop of the selected place (Which is already displayed in the above dialogue box.) so that I can further display it in my application.Halley
@fernandospr, Now It is not mandatory that I've to retrieve this snapshot from the dialogue only. The alternative is to take a screen shot when user finalize the location. But it gives the snapshot of calling activity, because when user tap on SELECT, the dialogue disappears and the calling activity is now on the screen. I've tried this.Halley
@Germander The problem is here: I'm using Place-picker API, So I don't have access to the methods which are used in that API (or I don't know how to access it.) So I can't trigger the method of taking screen shot in the place-picker activity itself. I've to do it only when SELECT is pressed. This is what I know. You can suggest even better way to do it. Thank you in advance!Halley
Thanks for adding the code. Why do you want a screenshot of the map? What is the purpose? If you just want to display the place afterwards, you can just store the coordinates when you return from the PlacePicker. Wherever you want to display the place you can use a GoogleMap and update the camera to the stored coordinates.Germander
@Germander actually I want to display like this:: #39011748Halley
Check this if it is useful or not.Brimmer
I've already tried this too many times. The problem is that we don't know when the above dialogue is opened by user. and We don't have access to the method opening the dialogue(or I don't know how to access it).Halley
Use Google Static Map APIClaresta
google static map api need billingBarbarbarbara
A
8

Since you are able to get the long and lat coordinates, you can get the map image by using the Google maps api.

Here's the link with examples and docs:

https://developers.google.com/maps/documentation/static-maps/intro

I assume this is what the dialog is doing in the background.

If that does not work, or you want something more exact, I suggest using Wireshark to monitor exactly what data is being sent and received.

I just ran a test with your map locations, and with this url:

https://maps.googleapis.com/maps/api/staticmap?center=37.430610,%20-121.972090&zoom=17&size=400x400&key=[myAPIKey]

I got this image:

enter image description here

Using the coords from your dialog:

enter image description here

Using https://maps.googleapis.com/maps/api/staticmap?markers=37.414333,-122.076444&zoom=17&size=400x250&key=[myKey]

enter image description here

Atmospheric answered 12/9, 2016 at 20:36 Comment(0)
M
3

You can use the GoogleMap.SnapshotReadyCallback interface.

Here is a code example on how to use it:

SnapshotReadyCallback callback = new SnapshotReadyCallback() {
                    Bitmap bitmap;

                    @Override
                    public void onSnapshotReady(Bitmap snapshot) {
                        bitmap = snapshot;
                        try {
                            FileOutputStream out = new FileOutputStream("/some/where/to/save/it/thesnapshot.png");
                            bitmap.compress(Bitmap.CompressFormat.PNG, 90, out);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                };

                map.snapshot(callback);

You can add this in your code when you show the dialog and in the same time save the snapshot. Read more about it in the link above.

I hope this will be of any help to you and good luck.

Mellisamellisent answered 12/9, 2016 at 20:51 Comment(0)
B
0

If you want to show snapshot of the picked place in the dialog first you have to save the screen of map view into bitmap.

Refer this code to converting your map view into bitmap

Bitmap screen;
View v1 = MyView.getRootView();
v1.setDrawingCacheEnabled(true);
screen= Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);

From above code you can get Bitmap which You can further use in your Dialog box by setting this bitmap into image view. But keep in mind u have to perform all operation before generating dialog and on worker thread.

Bleed answered 5/9, 2016 at 7:49 Comment(3)
when u r opening ur dialog on any click then on same click u have to do all this before creating the dialog.Bleed
What is MyView here?Halley
My view can be replace by id of that view in which u r showing the map.Bleed
A
0

You might look into maps Lite. It uses the google maps api and map views, but treats each one similar to an image rather than an interactive map. You can still choose your zoom level and add markers to the map.

declare the map in your xml like you would a regular google map fragment but include the tag map:liteMode="true"

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    android:name="com.google.android.gms.maps.MapFragment"
    android:id="@+id/map"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    map:cameraZoom="13"
    map:mapType="normal"
    map:liteMode="true"/>

or if you're creating the map programmatically you can use

GoogleMapOptions options = new GoogleMapOptions().liteMode(true);

it looks from your Activity code like you know how set up a google map, so you can then modify your onActivityResult to look like this

protected void onActivityResult(int requestCode,
                            int resultCode, Intent data) {

if (requestCode == PLACE_PICKER_REQUEST
        && resultCode == Activity.RESULT_OK) {

    final Place place = PlacePicker.getPlace(this, data);
    final CharSequence name = place.getName();
    final CharSequence address = place.getAddress();

    String attributions = (String) place.getAttributions();
    if (attributions == null) {
        attributions = "";
    }

    tv4.setText(place.getLatLng().toString()+"\n"+name+"\n"+address+"\n"+attributions);

    // Add this line to make the lite map show the location you just chose
    // and set the zoom level (10f is arbitrary)
    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(place.getLatLng(), 10f));

} else {
    super.onActivityResult(requestCode, resultCode, data);
}
}

More information and citations:

You can start here if you're looking for more info, there are tons of good links on this page https://developers.google.com/maps/documentation/android-api/lite

you can also check out the Google Lite Maps Demo Activity here: https://github.com/googlemaps/android-samples/blob/master/ApiDemos/app/src/main/java/com/example/mapdemo/LiteDemoActivity.java

And here's a great video that explains Lite Maps really well: https://youtu.be/N0N1Xkc_1pU

Anticipation answered 13/9, 2016 at 5:35 Comment(0)
V
0

I faced same issue. I've tried with API key and Server key in both case I faced same error like "The Google Maps API server rejected your request... ". Finally I noticed that "Google Static Maps API" was disable from console. I just enable and everything works fine.

Visconti answered 30/3, 2017 at 5:44 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.