birkir / react-native-carplay

CarPlay with React Native
https://birkir.dev/react-native-carplay/
MIT License
642 stars 107 forks source link

Android implementation #81

Open birkir opened 2 years ago

birkir commented 2 years ago

Stumbled upon this implementation initially borrowed from Shopify.

https://github.com/jqn/AndroidAutoExample

If I were to port this over to our repository, would you like to rename this library to something more generic?

react-native-auto react-native-car react-native-vehicle

Or just stick to CarPlay

gorbypark commented 2 years ago

If this one repo was going to support both CarPlay and Android Auto, I'd vote for react-native-vehicle.

tomdye commented 2 years ago

agree re. react-native-vehicle

DanielKuhn commented 1 year ago

There's active development for android auto in https://github.com/doublesymmetry/react-native-track-player/pull/2094 For anyone using react-native-track-player for audio playback this looks very promising.

nicomontanari commented 10 months ago

Hi @birkir, are there any updated about the Android Auto implementation?

susonthapa commented 10 months ago

I do have a repo for Android Auto. I worked on it a while back and I have implemented a couple of features. I started from Shopify's Android Auto.

I'm planning on creating a new repo that integrates both Android Auto and CarPlay. I'm thinking of rewriting the CarPlay implementation from scratch as Android Auto uses a declarative approach. I would definitely take inspiration from this repository.

If anyone is interested feel free to contribute. This is the link to the repository, it is currently empty 😂, I will integrate Android Auto.

nicomontanari commented 10 months ago

@susonthapa sorry for the basic question, but why not implement the Android part in this repository? Then you could change the name of the library and repository without starting another library from scratch

susonthapa commented 10 months ago

@susonthapa sorry for the basic question, but why not implement the Android part in this repository? Then you could change the name of the library and repository without starting another library from scratch

This is just my opinion so I don't expect everyone to agree with it. This library uses an imperative approach, and changing it to declarative would be a huge undertaking not to mention that it is written in Objective-C which I think is quite outdated.

After working on the Android Auto library and this library(more or less), I think the declarative approach is the way to go. Either way, I'm just sharing something I worked on.

nixolas1 commented 10 months ago

Awesome stuff, @susonthapa ! Will definitely keep an eye on it, and maybe help out when we start CarPlay & Android Auto development :) Especially if it has some Expo support

birkir commented 10 months ago

@susonthapa sorry for the basic question, but why not implement the Android part in this repository? Then you could change the name of the library and repository without starting another library from scratch

This is just my opinion so I don't expect everyone to agree with it. This library uses an imperative approach, and changing it to declarative would be a huge undertaking not to mention that it is written in Objective-C which I think is quite outdated.

After working on the Android Auto library and this library(more or less), I think the declarative approach is the way to go. Either way, I'm just sharing something I worked on.

I’m actively working on the platform integration for Android Auto. A significant part of this effort involves bridging the differences between CarPlay and Android Auto, creating common templates, configs, and types, which I’ll document in detail. Expect updates on this soon.

Regarding the debate on whether imperative API is a bad approach for template API proxy. It’s actually the primary reason I didn’t chose the reconciler route, I’ve done some fiber work in the past.

With AA it makes a little bit more sense, as the platform has few more cases like the map template. But I’d still stick with imperative and offer declarative react for free-form rendering. Heck, I think RN-carplay could easily be sugarcoated with a reconciler on top of the current API, if that's the verdict we want.

I don't think that Obective-C is necessary a bad thing, worse dx for the library mainteners but easier for users and I feel the same with Kotlin, is it a no brainer today or are there still compatability/conflict issues like it used to a year ago?

Great discussion 👍

susonthapa commented 10 months ago

Thanks for the info @birkir. I didn't know you were actively working on AA. Looking at the comments I thought AA won't be implemented anytime soon(my bad 🙂) so I took matters into my own hands.

I think I might have created confusion around the declarative and imperative approaches. The native library will still expose the imperative API, but the reconciler will expose a declarative API.

I'm not familiar with Objective-C so I don't know what limitations were there a year before. I find it very difficult to work with Objective-C(and even Swift, I'm originally an Android developer so maybe that's why 🤷‍♂️).

I don't want to create another implementation for the same thing, Do you have a branch or a repo where you are doing the work? I will be more than happy to contribute. I kinda have a deadline for adding AA support on one of the apps that I work on so I was just building what I can. In the meantime, I will still be messing around with my implementation.

birkir commented 10 months ago

After looking at your repo @susonthapa I am pretty sure I will start pointing the work towards your implementation, you seem have gotten the furthest in terms of building the parser. Just need to start using Kotlin, not a big deal.

I am currently jumping between these implementations - so my working branch is a hot mess atm 🔥

But what I can do is start a PR with changes that makes sense as a starting point.

  1. Make Android example app working.
  2. Support Android Auto in example app manifest
  3. Add my documentation updates, which so far only covers ListTemplate and a bunch of other things.
  4. No implementation at this point, because what I am unsure about is how to manage the react context (another entry point, registerComponent or something else). I'll just put a random screen up there.

https://github.com/birkir/react-native-carplay/pull/151

susonthapa commented 10 months ago

After looking at your repo @susonthapa I am pretty sure I will start pointing the work towards your implementation, you seem have gotten the furthest in terms of building the parser. Just need to start using Kotlin, not a big deal.

I am currently jumping between these implementations - so my working branch is a hot mess atm 🔥

But what I can do is start a PR with changes that makes sense as a starting point.

  1. Make Android example app working.
  2. Support Android Auto in example app manifest
  3. Add my documentation updates, which so far only covers ListTemplate and a bunch of other things.
  4. No implementation at this point, because what I am unsure about is how to manage the react context (another entry point, registerComponent or something else). I'll just put a random screen up there.

151

I started with https://github.com/Shopify/react-native-android-auto and fixed a lot of issues there. I have also implemented the MapTemplate which was quite hard. Unlike CarPlay where you can access the Window and tell ReactNative to render there, AndroidAuto only exposes a SurfaceContainer. I had to resort to Virtual rendering but I got it to work. This is how it looks right now.

https://github.com/birkir/react-native-carplay/assets/33973551/88cca453-5436-4b9a-8e32-ce18087f5d13

The Redbox is being rendered from React, we can render anything in there including a Map.

@birkir Let me know if you need any help with the implementation of Android Auto.

birkir commented 10 months ago

Awesome! Haven't tried to render a map or anything dynamic, but hope it will be smooth. I guess it is also how iOS CarPlay works behind the scenes.

Quick question, https://github.com/susonthapa/react-native-android-auto/blob/main/android/src/main/java/com/reactnativeandroidauto/CarServiceSession.kt#L43-L65

Any concerns about doing it this way? Are we limited to any specific RN version or all good?

susonthapa commented 10 months ago

Awesome! Haven't tried to render a map or anything dynamic, but hope it will be smooth. I guess it is also how iOS CarPlay works behind the scenes.

Quick question, https://github.com/susonthapa/react-native-android-auto/blob/main/android/src/main/java/com/reactnativeandroidauto/CarServiceSession.kt#L43-L65

Any concerns about doing it this way? Are we limited to any specific RN version or all good?

Looks like the ReactInstanceEventListener is deprecated and the currentReactContext is only visible for testing. This is working for the time being but I think we should come up with an alternative.

It's been quite a while since I looked into this portion of the code, I will need to refresh my memory 🙂.

birkir commented 10 months ago

Makes sense, reason I am in that section of the implementation, is because of hot reload and dev menu refresh. I can't seem to figure it out, the module appears to always be cached.

I have updated the PR if you want to take a look.

susonthapa commented 10 months ago

Makes sense, reason I am in that section of the implementation, is because of hot reload and dev menu refresh. I can't seem to figure it out, the module appears to always be cached.

I have updated the PR if you want to take a look.

Interesting, let me look into it. I didn't think about the HMR 😁. I will let you know if I find any way to make the HMR work.

susonthapa commented 10 months ago

@birkir I did some research but couldn't find a way to detect when the JS code changes. If we could detect that we can call the reload function to reload the app.

I was curious how the hot reload works on CarPlay. Did you have to do something to make the HMR work on CarPlay?

birkir commented 10 months ago

@birkir I did some research but couldn't find a way to detect when the JS code changes. If we could detect that we can call the reload function to reload the app.

I was curious how the hot reload works on CarPlay. Did you have to do something to make the HMR work on CarPlay?

The main difference is that the whole CarPlay experience is driven through the host (app) so we get hmr for free.

AA runs three processes if I understand it correctly. (Host, communications and screen). Spotify went the route of calling AppRegistry.registerRunnable which doesn't have any connection to the metro bundler.

I was able to communicate between the two using classic broadcasts but that's about it.

susonthapa commented 10 months ago

@birkir I did some research but couldn't find a way to detect when the JS code changes. If we could detect that we can call the reload function to reload the app. I was curious how the hot reload works on CarPlay. Did you have to do something to make the HMR work on CarPlay?

The main difference is that the whole CarPlay experience is driven through the host (app) so we get hmr for free.

AA runs three processes if I understand it correctly. (Host, communications and screen). Spotify went the route of calling AppRegistry.registerRunnable which doesn't have any connection to the metro bundler.

I was able to communicate between the two using classic broadcasts but that's about it.

I didn't know about that, good info.

When doing my research I found the invalidate function which gets called whenever we reload the bundle(by pressing 'r' from the terminal). In my implementation, I get an error when manually reloading the bundle which I can fix by adding some cleanup code to the invalidate function.

birkir commented 10 months ago

I have release the draft version of AndroidAuto in version 2.4.0-beta.2 of react-native-carplay.

Would be great to get community help taking this forward, testing, docs, features etc.

Refer to the example app to see how this is setup.

https://github.com/birkir/react-native-carplay/releases/tag/2.4.0-beta.2

elieT27 commented 9 months ago

@birkir The documentation says that on three car app categories are supported: androidx.car.app.category.NAVIGATION androidx.car.app.category.POI androidx.car.app.category.IOT So audio/Media is not supported ? I am looking to add react-native-track-player to android auto, is it feasible or is it too unstable at the moment ? thanks

andreknieriem commented 5 months ago

@birkir The documentation says that on three car app categories are supported: androidx.car.app.category.NAVIGATION androidx.car.app.category.POI androidx.car.app.category.IOT So audio/Media is not supported ? I am looking to add react-native-track-player to android auto, is it feasible or is it too unstable at the moment ? thanks

I am here to ask exactly this. I've tried it, but my headunit keeps crashing the app. Any advice would be great

DanielKuhn commented 5 months ago

@andreknieriem we are successfully using https://github.com/doublesymmetry/react-native-track-player/pull/2094 in production - works like a charm.

There's active development for android auto in doublesymmetry/react-native-track-player#2094 For anyone using react-native-track-player for audio playback this looks very promising.

andreknieriem commented 5 months ago

@andreknieriem we are successfully using doublesymmetry/react-native-track-player#2094 in production - works like a charm.

There's active development for android auto in doublesymmetry/react-native-track-player#2094 For anyone using react-native-track-player for audio playback this looks very promising.

Hey this seems to look really nice. How can use this unmerged version?

DanielKuhn commented 5 months ago

This is the source branch: https://github.com/lovegaoshi/react-native-track-player/tree/dev-android-auto Try forking it or use it directly in your package.json

andreknieriem commented 5 months ago

This is the source branch: https://github.com/lovegaoshi/react-native-track-player/tree/dev-android-auto Try forking it or use it directly in your package.json

Sorry to bother you, but I've tried it and I am not able to get this to work via package.json. Do you have an example config? Thanks!

DanielKuhn commented 5 months ago

Add this to your dependencies:

"react-native-track-player": "git+https://github.com/lovegaoshi/react-native-track-player.git#a5451f75dec3d5863f480d559053848f6050a564",

This will install the latest commit on that branch. Since the maintainer keeps rebasing/merging the changes from react-native-track-player, it will install version 4.1.1 of RNTP with the Android changes on top.

andreknieriem commented 4 months ago

Hey @DanielKuhn. Thanks I got it working. So you using trackplayer standalone or with this package for the other views?

DanielKuhn commented 4 months ago

We're using RNTP for music playback on both platforms and the changes by @lovegaoshi in the branch for displaying the list views/media items on Android Auto. On iOS we're using this package to display the CarPlay UI, triggering playback onItemSelect, displaying the currently playing track on the NowPlayingTemplate and displaying track progress on the list items.

7ur813z commented 2 months ago

Can someone please provide me with a starter code for Android? Thank you.

mefjuu commented 2 months ago

@7ur813z There is already working example in the repo's master branch

7ur813z commented 2 months ago

@mefjuu I followed the exact steps in the documentation to run that example but it didn't work. Can you please help me regarding this? May I contact you on their Discord server? Thank you.

mefjuu commented 2 months ago

@7ur813z I meant this example https://github.com/birkir/react-native-carplay/tree/master/apps/example Docs seems to be a bit out of date

7ur813z commented 2 months ago

@mefjuu Yes, I used that example. These are the exact steps that I did:

git clone https://github.com/birkir/react-native-carplay.git cd react-native-carplay/apps/example yarn install yarn run android

But I get this error:

Error: Activity class {org.birkir.carplay/org.birkir.carplay.MainActivity} does not exist.