forked from organicmaps/organicmaps
Compare commits
28 commits
master
...
android_au
Author | SHA1 | Date | |
---|---|---|---|
|
0d608e8bba | ||
|
e8c8e68362 | ||
|
662762234b | ||
|
eea8650115 | ||
79e1056384 | |||
b0129d66f3 | |||
|
3169a335e7 | ||
|
7a0b48a4e4 | ||
|
635a879ee9 | ||
|
6d0aa7a89f | ||
|
50d5dfab25 | ||
|
86e61239e6 | ||
|
983d8ac4d9 | ||
|
90a23c5317 | ||
|
65170c84f7 | ||
|
8bbffa1a33 | ||
|
ecce76d82d | ||
|
95c00aee21 | ||
|
41a4ee1a70 | ||
|
1facdb164a | ||
|
a6996634d5 | ||
|
7424c71b57 | ||
|
a2da6fffcc | ||
|
9a4d5c3887 | ||
|
c44a4a8d4b | ||
|
6f73a3c67b | ||
|
cdfa65b53a | ||
|
110d6df3e7 |
9 changed files with 302 additions and 13 deletions
|
@ -4,6 +4,8 @@
|
|||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:installLocation="auto">
|
||||
|
||||
|
||||
|
||||
<uses-feature
|
||||
android:glEsVersion="0x00020000"
|
||||
android:required="true"/>
|
||||
|
@ -27,6 +29,9 @@
|
|||
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
|
||||
<uses-permission android:name="android.permission.INTERNET"/>
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
|
||||
<!--Permissions For android Auto -->
|
||||
<uses-permission android:name="androidx.car.app.NAVIGATION_TEMPLATES"/>
|
||||
<uses-permission android:name="androidx.car.app.ACCESS_SURFACE"/>
|
||||
<!--
|
||||
https://developer.android.com/reference/androidx/core/app/JobIntentService:
|
||||
When running on Android O, the JobScheduler will take care of wake locks
|
||||
|
@ -40,6 +45,7 @@
|
|||
<uses-permission android:name="android.permission.BATTERY_STATS"/>
|
||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
|
||||
|
||||
|
||||
<queries>
|
||||
<intent>
|
||||
<action android:name="android.intent.action.TTS_SERVICE"/>
|
||||
|
@ -63,11 +69,14 @@
|
|||
android:supportsRtl="true"
|
||||
android:networkSecurityConfig="@xml/network_security_config">
|
||||
|
||||
|
||||
|
||||
<activity
|
||||
android:name="com.mapswithme.maps.SplashActivity"
|
||||
android:label="@string/app_name"
|
||||
android:exported="true">
|
||||
|
||||
|
||||
<!-- standard "geo" scheme -->
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW"/>
|
||||
|
@ -795,5 +804,20 @@
|
|||
<!-- Disable Google's anonymous stats collection -->
|
||||
<meta-data android:name="android.webkit.WebView.MetricsOptOut" android:value="true" />
|
||||
|
||||
<!-- For android Auto -->
|
||||
<meta-data android:name="com.google.android.gms.car.application"
|
||||
android:resource="@xml/automotive_app_desc"/>
|
||||
|
||||
<service
|
||||
android:name="com.androidAuto.AndroidAutoService"
|
||||
android:exported="true">
|
||||
<intent-filter>
|
||||
<action android:name="androidx.car.app.CarAppService" />
|
||||
</intent-filter>
|
||||
</service>
|
||||
<meta-data
|
||||
android:name="androidx.car.app.minCarApiLevel"
|
||||
android:value="1"/>
|
||||
|
||||
</application>
|
||||
</manifest>
|
||||
|
|
|
@ -96,6 +96,9 @@ dependencies {
|
|||
testImplementation 'junit:junit:4.13.2'
|
||||
testImplementation 'org.mockito:mockito-core:4.6.0'
|
||||
testImplementation 'org.mockito:mockito-inline:4.6.0'
|
||||
|
||||
//Android Auto
|
||||
implementation "androidx.car.app:app:1.2.0-rc01"
|
||||
}
|
||||
|
||||
def run(cmd) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
propMinSdkVersion=21
|
||||
propMinSdkVersion=23
|
||||
propTargetSdkVersion=31
|
||||
propCompileSdkVersion=31
|
||||
propBuildToolsVersion=32.0.0
|
||||
|
|
3
android/res/xml/automotive_app_desc.xml
Normal file
3
android/res/xml/automotive_app_desc.xml
Normal file
|
@ -0,0 +1,3 @@
|
|||
<automotiveApp>
|
||||
<uses name="template" />
|
||||
</automotiveApp>
|
51
android/src/com/androidAuto/AndroidAutoService.java
Normal file
51
android/src/com/androidAuto/AndroidAutoService.java
Normal file
|
@ -0,0 +1,51 @@
|
|||
package com.androidAuto;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.content.pm.ApplicationInfo;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.car.app.CarAppService;
|
||||
import androidx.car.app.Screen;
|
||||
import androidx.car.app.Session;
|
||||
import androidx.car.app.validation.HostValidator;
|
||||
|
||||
public final class AndroidAutoService extends CarAppService
|
||||
{
|
||||
|
||||
public AndroidAutoService()
|
||||
{
|
||||
// Exported services must have an empty public constructor.
|
||||
}
|
||||
|
||||
@Override
|
||||
@NonNull
|
||||
public Session onCreateSession()
|
||||
{
|
||||
return new Session()
|
||||
{
|
||||
@Override
|
||||
@NonNull
|
||||
public Screen onCreateScreen(@Nullable Intent intent)
|
||||
{
|
||||
return new MainScreen(getCarContext());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public HostValidator createHostValidator()
|
||||
{
|
||||
if ((getApplicationInfo().flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0)
|
||||
{
|
||||
return HostValidator.ALLOW_ALL_HOSTS_VALIDATOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
return new HostValidator.Builder(getApplicationContext())
|
||||
.addAllowedHosts(androidx.car.app.R.array.hosts_allowlist_sample)
|
||||
.build();
|
||||
}
|
||||
}
|
||||
}
|
197
android/src/com/androidAuto/MainScreen.java
Normal file
197
android/src/com/androidAuto/MainScreen.java
Normal file
|
@ -0,0 +1,197 @@
|
|||
package com.androidAuto;
|
||||
|
||||
import android.content.Context;
|
||||
import android.graphics.Rect;
|
||||
import android.util.Log;
|
||||
import android.view.Surface;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.car.app.AppManager;
|
||||
import androidx.car.app.CarContext;
|
||||
import androidx.car.app.Screen;
|
||||
import androidx.car.app.SurfaceCallback;
|
||||
import androidx.car.app.SurfaceContainer;
|
||||
import androidx.car.app.model.Action;
|
||||
import androidx.car.app.model.ActionStrip;
|
||||
import androidx.car.app.model.CarIcon;
|
||||
import androidx.car.app.model.Template;
|
||||
import androidx.car.app.navigation.NavigationManager;
|
||||
import androidx.car.app.navigation.model.NavigationTemplate;
|
||||
import androidx.core.graphics.drawable.IconCompat;
|
||||
import com.mapswithme.maps.BuildConfig;
|
||||
import com.mapswithme.maps.MapFragment;
|
||||
import com.mapswithme.maps.MwmApplication;
|
||||
import com.mapswithme.maps.R;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public class MainScreen extends Screen implements SurfaceCallback
|
||||
{
|
||||
private static final String TAG = MainScreen.class.getSimpleName();
|
||||
@Nullable
|
||||
private MapFragment mMapFragment;
|
||||
private SurfaceCallback mSurfaceCallback;
|
||||
|
||||
public MainScreen(@NonNull CarContext carContext)
|
||||
{
|
||||
super(carContext);
|
||||
|
||||
MwmApplication cat = MwmApplication.from(carContext);
|
||||
try
|
||||
{
|
||||
cat.init();
|
||||
}
|
||||
catch (IOException e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
carContext.getCarService(AppManager.class).setSurfaceCallback(this);
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Template onGetTemplate()
|
||||
{
|
||||
Log.e("Show Up", "Shows Up");
|
||||
NavigationTemplate.Builder builder = new NavigationTemplate.Builder();
|
||||
ActionStrip.Builder actionStripBuilder = new ActionStrip.Builder();
|
||||
actionStripBuilder.addAction(new Action.Builder().setTitle("Exit")
|
||||
.setOnClickListener(this::exit)
|
||||
.build());
|
||||
|
||||
Action panAction = new Action.Builder(Action.PAN).build();
|
||||
Action zoomIn = new Action.Builder().setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_zoom_in)).build())
|
||||
.setOnClickListener(this::zoomIn)
|
||||
.build();
|
||||
Action zoomOut = new Action.Builder().setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_zoom_out)).build())
|
||||
.setOnClickListener(this::zoomOut)
|
||||
.build();
|
||||
|
||||
Action openMic = new Action.Builder().setIcon(new CarIcon.Builder(IconCompat.createWithResource(getCarContext(), R.drawable.ic_booking)).build())
|
||||
.setOnClickListener(this::zoomOut)
|
||||
.build();
|
||||
|
||||
ActionStrip mapActionStrip = new ActionStrip.Builder().addAction(zoomIn)
|
||||
.addAction(zoomOut)
|
||||
.addAction(panAction).addAction(openMic)
|
||||
.build();
|
||||
builder.setMapActionStrip(mapActionStrip);
|
||||
builder.setActionStrip(actionStripBuilder.build());
|
||||
NavigationManager navigationManager = getCarContext().getCarService(NavigationManager.class);
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
private void zoomOut()
|
||||
{
|
||||
MapFragment.nativeScaleMinus();
|
||||
}
|
||||
|
||||
private void zoomIn()
|
||||
{
|
||||
MapFragment.nativeScalePlus();
|
||||
}
|
||||
|
||||
private void exit()
|
||||
{
|
||||
getCarContext().finishCarApp();
|
||||
MapFragment.nativeDetachSurface(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceAvailable(@NonNull SurfaceContainer surfaceContainer)
|
||||
{
|
||||
Log.i(TAG, "Surface available " + surfaceContainer);
|
||||
|
||||
final Surface surface = surfaceContainer.getSurface();
|
||||
if (surface == null)
|
||||
{
|
||||
Log.e(TAG, "Surface is NULL");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (MapFragment.nativeIsEngineCreated()){
|
||||
MapFragment.nativeDetachSurface(true);
|
||||
}
|
||||
|
||||
|
||||
if (MapFragment.nativeIsEngineCreated())
|
||||
{
|
||||
if (!MapFragment.nativeAttachSurface(surface))
|
||||
{
|
||||
reportUnsupported();
|
||||
return;
|
||||
}
|
||||
MapFragment.nativeResumeSurfaceRendering();
|
||||
return;
|
||||
}
|
||||
|
||||
final int WIDGET_COPYRIGHT = 0x04;
|
||||
MapFragment.nativeSetupWidget(WIDGET_COPYRIGHT, 0.0f, 0.0f, 0);
|
||||
|
||||
if (!MapFragment.nativeCreateEngine(surface, surfaceContainer.getDpi(), true, false, BuildConfig.VERSION_CODE))
|
||||
{
|
||||
reportUnsupported();
|
||||
return;
|
||||
}
|
||||
|
||||
MapFragment.nativeResumeSurfaceRendering();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onVisibleAreaChanged(@NonNull Rect visibleArea)
|
||||
{
|
||||
SurfaceCallback.super.onVisibleAreaChanged(visibleArea);
|
||||
Log.e("Something", "Lets see");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStableAreaChanged(@NonNull Rect stableArea)
|
||||
{
|
||||
SurfaceCallback.super.onStableAreaChanged(stableArea);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceDestroyed(@NonNull SurfaceContainer surfaceContainer)
|
||||
{
|
||||
SurfaceCallback.super.onSurfaceDestroyed(surfaceContainer);
|
||||
MapFragment.nativeDetachSurface(true);
|
||||
Log.i(TAG, "Surface destroyed");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScroll(float distanceX, float distanceY)
|
||||
{
|
||||
SurfaceCallback.super.onScroll(distanceX, distanceY);
|
||||
Log.i("Scroll", "Scrolled ");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onFling(float velocityX, float velocityY)
|
||||
{
|
||||
SurfaceCallback.super.onFling(velocityX, velocityY);
|
||||
Log.i("Fling", "Flinged");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onScale(float focusX, float focusY, float scaleFactor)
|
||||
{
|
||||
SurfaceCallback.super.onScale(focusX, focusY, scaleFactor);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(float x, float y)
|
||||
{
|
||||
SurfaceCallback.super.onClick(x, y);
|
||||
}
|
||||
|
||||
private void reportUnsupported()
|
||||
{
|
||||
final Context context = getCarContext();
|
||||
Log.e(TAG, context.getString(R.string.unsupported_phone));
|
||||
}
|
||||
}
|
|
@ -5,6 +5,7 @@ import android.content.DialogInterface;
|
|||
import android.graphics.Rect;
|
||||
import android.os.Bundle;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.util.Log;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.MotionEvent;
|
||||
import android.view.Surface;
|
||||
|
@ -153,6 +154,12 @@ public class MapFragment extends BaseMwmFragment
|
|||
@Override
|
||||
public void surfaceCreated(SurfaceHolder surfaceHolder)
|
||||
{
|
||||
|
||||
if (MapFragment.nativeIsEngineCreated())
|
||||
{
|
||||
nativeDetachSurface(true);
|
||||
}
|
||||
|
||||
if (isThemeChangingProcess())
|
||||
{
|
||||
Logger.d(TAG, "Activity is being recreated due theme changing, skip 'surfaceCreated' callback");
|
||||
|
@ -333,6 +340,7 @@ public class MapFragment extends BaseMwmFragment
|
|||
@Override
|
||||
public boolean onTouch(View view, MotionEvent event)
|
||||
{
|
||||
Log.i("MOTION EVENT",event.toString());
|
||||
final int count = event.getPointerCount();
|
||||
|
||||
if (count == 0)
|
||||
|
@ -384,22 +392,22 @@ public class MapFragment extends BaseMwmFragment
|
|||
}
|
||||
|
||||
static native void nativeCompassUpdated(double north, boolean forceRedraw);
|
||||
static native void nativeScalePlus();
|
||||
static native void nativeScaleMinus();
|
||||
public static native void nativeScalePlus();
|
||||
public static native void nativeScaleMinus();
|
||||
public static native boolean nativeShowMapForUrl(String url);
|
||||
static native boolean nativeIsEngineCreated();
|
||||
public static native boolean nativeIsEngineCreated();
|
||||
static native boolean nativeDestroySurfaceOnDetach();
|
||||
private static native boolean nativeCreateEngine(Surface surface, int density,
|
||||
public static native boolean nativeCreateEngine(Surface surface, int density,
|
||||
boolean firstLaunch,
|
||||
boolean isLaunchByDeepLink,
|
||||
int appVersionCode);
|
||||
private static native boolean nativeAttachSurface(Surface surface);
|
||||
private static native void nativeDetachSurface(boolean destroySurface);
|
||||
public static native boolean nativeAttachSurface(Surface surface);
|
||||
public static native void nativeDetachSurface(boolean destroySurface);
|
||||
private static native void nativePauseSurfaceRendering();
|
||||
private static native void nativeResumeSurfaceRendering();
|
||||
public static native void nativeResumeSurfaceRendering();
|
||||
private static native void nativeSurfaceChanged(Surface surface, int w, int h);
|
||||
private static native void nativeOnTouch(int actionType, int id1, float x1, float y1, int id2, float x2, float y2, int maskedPointer);
|
||||
private static native void nativeSetupWidget(int widget, float x, float y, int anchor);
|
||||
public static native void nativeSetupWidget(int widget, float x, float y, int anchor);
|
||||
private static native void nativeApplyWidgets();
|
||||
private static native void nativeCleanWidgets();
|
||||
private static native void nativeSetRenderingInitializationFinishedListener(
|
||||
|
|
|
@ -5,6 +5,7 @@ import android.content.Context;
|
|||
import android.content.SharedPreferences;
|
||||
import android.os.Handler;
|
||||
import android.os.Message;
|
||||
import android.util.Log;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import com.mapswithme.maps.background.AppBackgroundTracker;
|
||||
|
@ -97,6 +98,7 @@ public class MwmApplication extends Application implements AppBackgroundTracker.
|
|||
return context.getSharedPreferences(context.getString(R.string.pref_file_name), MODE_PRIVATE);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onCreate()
|
||||
{
|
||||
|
@ -104,6 +106,7 @@ public class MwmApplication extends Application implements AppBackgroundTracker.
|
|||
Logger.i(TAG, "Initializing application");
|
||||
LogsManager.INSTANCE.initFileLogging(this);
|
||||
|
||||
|
||||
// Set configuration directory as early as possible.
|
||||
// Other methods may explicitly use Config, which requires settingsDir to be set.
|
||||
final String settingsPath = StorageUtils.getSettingsPath(this);
|
||||
|
@ -143,7 +146,7 @@ public class MwmApplication extends Application implements AppBackgroundTracker.
|
|||
initNativeFramework();
|
||||
}
|
||||
|
||||
private void initNativePlatform() throws IOException
|
||||
public void initNativePlatform() throws IOException
|
||||
{
|
||||
if (mPlatformInitialized)
|
||||
return;
|
||||
|
@ -188,7 +191,7 @@ public class MwmApplication extends Application implements AppBackgroundTracker.
|
|||
StorageUtils.requireDirectory(tempPath);
|
||||
}
|
||||
|
||||
private void initNativeFramework()
|
||||
public void initNativeFramework()
|
||||
{
|
||||
if (mFrameworkInitialized)
|
||||
return;
|
||||
|
@ -262,7 +265,7 @@ public class MwmApplication extends Application implements AppBackgroundTracker.
|
|||
}
|
||||
|
||||
private static native void nativeSetSettingsDir(String settingsPath);
|
||||
private native void nativeInitPlatform(String apkPath, String writablePath, String privatePath,
|
||||
public native void nativeInitPlatform(String apkPath, String writablePath, String privatePath,
|
||||
String tmpPath, String flavorName, String buildType,
|
||||
boolean isTablet);
|
||||
private static native void nativeInitFramework();
|
||||
|
|
|
@ -106,7 +106,7 @@ bool SupportManager::IsVulkanForbidden() const
|
|||
bool forbidden;
|
||||
if (!settings::Get(kVulkanForbidden, forbidden))
|
||||
forbidden = false;
|
||||
return forbidden;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SupportManager::IsVulkanForbidden(std::string const & deviceName,
|
||||
|
|
Loading…
Add table
Reference in a new issue