Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Exit from google maps intent in android

I am implementing custom turn-by-turn navigation in my android application. To achieve this, I have started the activity from my MainActivity using an intent which uses Intent.ACTION_VIEW as action and "google.navigation:q" as uri string.The google maps navigation page is successfully loaded in my app.

But, I don't know how to gracefully exit from this page. If I use back button press, it takes 4 back button clicks to display my main activity screen. Is there any possibility to place "exit" button in this page.

I have tried "onActivityForResult" and "onBackPressed" for destroying the google maps screens. None of this works. Please provide some suggestions to go further.

like image 985
BhagyaNivi Avatar asked Jun 15 '15 06:06

BhagyaNivi


1 Answers

I know I am pretty late to answer this but maybe it can help someone.

You cannot come back from google map to your activity/app on single back press for this you need to create a floating view/widget like ola/uber which will do this for you after proper implementation. Here is my implementation.

First the user will go to map app from YourActivity. In this activity we will ask the permission for SYSTEM_ALERT_WINDOW (DRAW OVER, for SDK > MarshMallow) on click of some view. Then we will launch google map as well as a Service created by us to create a floating icon.

class YourActivity extends AppCompatActivity{

private GetFloatingIconClick mGetServiceClick;
public static boolean isFloatingIconServiceAlive = false;

onCreate(){
    mGetServiceClick = new GetFloatingIconClick();

    somebtn.onclick(){
        askDrawOverPermission();
    }
}

private class GetFloatingIconClick extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent selfIntent = new Intent(YourActivity.this, YourActivity.class);
        selfIntent.setFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT | Intent.FLAG_ACTIVITY_SINGLE_TOP
                | Intent.FLAG_ACTIVITY_CLEAR_TOP);
        startActivity(selfIntent);
    }
}

private void askDrawOverPermission() {
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
        // if OS is pre-marshmallow then create the floating icon, no permission is needed
        createFloatingBackButton();
    } else {
        if (!Settings.canDrawOverlays(this)) {
            // asking for DRAW_OVER permission in settings
            Intent intent = new Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
                    Uri.parse("package:" + getApplicationContext().getPackageName()));
            startActivityForResult(intent, REQ_CODE_DRAW_OVER);
        } else {
            createFloatingBackButton();
        }
    }
}

// starting service for creating a floating icon over map
private void createFloatingBackButton() {
    Intent iconServiceIntent = new Intent(YourActivity.this, FloatingOverMapIconService.class);
    iconServiceIntent.putExtra("RIDE_ID", str_rideId);

    Intent navigation = new Intent(Intent.ACTION_VIEW, Uri
            .parse("google.navigation:q=" + lat_DEST + "," + lng_DEST + "&mode=d"));
    navigation.setPackage("com.google.android.apps.maps");
    startActivityForResult(navigation, 1234);

    startService(iconServiceIntent);
}

@TargetApi(Build.VERSION_CODES.M)
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == REQ_CODE_DRAW_OVER) {
        // as permissions from Settings don't provide any callbacks, hence checking again for the permission
        // so that we can draw our floating without asking user to click on the previously clicked view
        // again
        if (Settings.canDrawOverlays(this)) {
            createFloatingBackButton();
        } else {
            //permission is not provided by user, do your task
            //GlobalVariables.alert(mContext, "This permission is necessary for this application's functioning");
        }
    } else if (requestCode == 1234) {
        // no result is returned by google map, as google don't provide any apis or documentation
        // for it.
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }
}
}

Service Class:-

public class FloatingOverMapIconService extends Service {
private WindowManager windowManager;
private FrameLayout frameLayout;
private String str_ride_id;
public static final String BROADCAST_ACTION = "com.yourpackage.YourActivity";

@Nullable
@Override
public IBinder onBind(Intent intent) {
    return null;
}

@Override
public void onCreate() {
    super.onCreate();
    createFloatingBackButton();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    // to receive any data from activity
    str_ride_id = intent.getStringExtra("RIDE_ID");
    return START_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
    windowManager.removeView(frameLayout);
}

private void createFloatingBackButton() {

    CurrentJobDetail.isFloatingIconServiceAlive = true;

    WindowManager.LayoutParams params = new WindowManager.LayoutParams(
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.WRAP_CONTENT,
            WindowManager.LayoutParams.TYPE_PHONE,
            WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE,
            PixelFormat.TRANSLUCENT);
    params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;

    windowManager = (WindowManager) getSystemService(WINDOW_SERVICE);
    frameLayout = new FrameLayout(this);

    LayoutInflater layoutInflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);

    // Here is the place where you can inject whatever layout you want in the frame layout
    layoutInflater.inflate(R.layout.custom_start_ride_back_button_over_map, frameLayout);

    ImageView backOnMap = (ImageView) frameLayout.findViewById(R.id.custom_drawover_back_button);
    backOnMap.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent intent = new Intent(BROADCAST_ACTION);
            intent.putExtra("RIDE_ID", str_ride_id);
            sendBroadcast(intent);

            //stopping the service
            FloatingOverMapIconService.this.stopSelf();
            CurrentJobDetail.isFloatingIconServiceAlive = false;
        }
    });

    windowManager.addView(frameLayout, params);
}
}

Floating Icon Xml:-

<LinearLayout 
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">

<ImageView
    android:id="@+id/custom_drawover_back_button"
    android:layout_width="70dp"
    android:layout_height="100dp"
    android:src="@drawable/common_full_open_on_phone"
    android:scaleType="center"
    android:background="@color/colorAccent"/>
</LinearLayout>

Manifest file :-

<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />

<activity
        android:name=".Activities.YourActivity"
        android:launchMode="singleTop" />

<service
        android:name=".Utils.FloatingOverMapIconService"
        android:exported="false" />
like image 86
beginner Avatar answered Oct 26 '22 00:10

beginner