Giter VIP home page Giter VIP logo

android-app's Introduction

android-app's People

Contributors

kokoichi206 avatar

Stargazers

 avatar

Watchers

 avatar

android-app's Issues

Java vs Kotlin

access

Java Kotlin
access modifier default package private public
is final need final keyword default
open keyword to override

navigation-compose

deeplink

Tools > App Links Assistant

Screen Shot 2022-10-31 at 1 37 23

Build > Generate Signed Bundle/APK... > APK に従って、APK の keystore を作る必要がある。

かなり苦戦中

Disabled になってるの良くない?

$ adb -d shell dumpsys package d | grep -A10 jp.mydns.kokoichi
  jp.mydns.kokoichi0206.deeplink ceae76a2-f4a9-4862-9830-1e464797327e:
    User all:
      Verification link handling allowed: true
      Selection state:
        Disabled:
          kokoichi0206.mydns.jp

youtube と比較

  com.google.android.youtube:
    ID: e0b8eea4-0b3c-48dd-9aa4-f02dfe0e0d8c
    Signatures: [3D:7A:12:23:01:9A:A3:9D:9E:A0:E3:43:6A:B7:C0:89:6B:FB:4F:B6:79:F4:DE:5F:E7:C2:3F:32:6C:8F:99:4A]
    Domain verification state:
      youtu.be: system_configured
      m.youtube.com: system_configured
      youtube.com: system_configured
      www.youtube.com: system_configured
    User all:
      Verification link handling allowed: true
      Selection state:
        Disabled:
          youtu.be
          m.youtube.com
          youtube.com
          www.youtube.com

むしろ、Domain verification state: がないのが問題かも。

keystore ファイルの SHA256 の値をゲット

keytool -list -v -keystore app/debug-keystore

gradlew signingReport

./gradlew signingReport
Starting a Gradle Daemon, 1 incompatible Daemon could not be reused, use --status for details                                                                    ─╯

> Task :app:signingReport
Variant: debug
Config: debug
Store: /Users/kokoichi/ghq/github.com/kokoichi206/android-app/deeplink/app/debug-keystore
Alias: keystore
MD5: xxx
SHA1: xxx
SHA-256: xxx
Valid until: Friday, October 25, 2047

navOption がある時に、mockK のテストができない

テストしたいコード

navController.navigate(
    Screen.MemberDetailScreen.route
            + "/${Constants.NAV_PARAM_MEMBER_PROPS}=${getJsonFromMember(member)}"
) {
    launchSingleTop = true
}

テストコード

@ExperimentalCoroutinesApi
@HiltAndroidTest
@UninstallModules(AppModule::class)
class MemberListScreenTest {

    @get:Rule(order = 0)
    val hiltRule = HiltAndroidRule(this)

    @get:Rule(order = 1)
    val composeRule = createAndroidComposeRule<MainActivity>()

    @RelaxedMockK
    lateinit var navController: NavController

    private val testDispatcher = TestCoroutineDispatcher()


    @Before
    fun setUp() {

        hiltRule.inject()
        MockKAnnotations.init(this)

        composeRule.setContent {
            MemberListScreen(
                navController = navController,
            )
        }
    }

    @Test
    fun memberImage_canTapOnlyOnce() {

        // Members are defined in data/remote/MockSakamichiApi
        composeRule.onNodeWithContentDescription("image of 秋元 真夏").assertIsDisplayed()

        composeRule.onNodeWithContentDescription("image of 秋元 真夏").performClick()
        composeRule.onNodeWithContentDescription("image of 秋元 真夏").performClick()
        val memberJson = StringBuilder()
            .append("{\"birthday\":\"1993年8月20日\",")
            .append("\"blogUrl\":\"https:%2F%2Fblog.nogizaka46.com%2Fmanatsu.akimoto\",")
            .append("\"bloodType\":\"B型\",\"generation\":\"1期生\",\"group\":\"乃木坂\",\"height\":\"154cm\",")
            .append("\"imgUrl\":\"https:%2F%2Fkokoichi0206.mydns.jp%2Fimgs%2Fnogi%2Fakimotomanatsu.jpeg\",")
            .append("\"name\":\"秋元 真夏\"}")
            .toString()
        val member = Member(
            name = "秋元 真夏",
            birthday = "1993年8月20日",
            height = "154cm",
            bloodType = "B型",
            generation = "1期生",
            blogUrl = "https://blog.nogizaka46.com/manatsu.akimoto",
            imgUrl = "https://kokoichi0206.mydns.jp/imgs/nogi/akimotomanatsu.jpeg",
            group = "乃木坂",
        )

        verify {
            navController.
            navController.navigate(
                // ここでの navOption の渡し方わからん
                Screen.MemberDetailScreen.route
                        + "/${Constants.NAV_PARAM_MEMBER_PROPS}=${getJsonFromMember(member)}") {launchSingleTop = true}
        }
}

上記でのエラー

java.lang.AssertionError: Verification failed: call 1 of 1: 
NavController(navController#1).navigate(eq(member_detail_screen/memberJson=
{"birthday":"1993年8月20
日","blogUrl":"https:%2F%2Fblog.nogizaka46.com%2Fmanatsu.akimoto","bloodType":"B
型","generation":"1期生","group":"乃木
坂","height":"154cm","imgUrl":"https:%2F%2Fkokoichi0206.mydns.jp%2Fimgs%2Fnogi%2F
akimotomanatsu.jpeg","name":"秋元 真夏"}), eq(lambda {}))). No matching calls found.

Calls to same method:
1) NavController(navController#1).navigate(member_detail_screen/memberJson=
{"birthday":"1993年8月20
日","blogUrl":"https:%2F%2Fblog.nogizaka46.com%2Fmanatsu.akimoto","bloodType":"B
型","generation":"1期生","group":"乃木
坂","height":"154cm","imgUrl":"https:%2F%2Fkokoichi0206.mydns.jp%2Fimgs%2Fnogi%2F
akimotomanatsu.jpeg","name":"秋元 真夏"}, lambda {})
2) NavController(navController#1).navigate(member_detail_screen/memberJson=
{"birthday":"1993年8月20
日","blogUrl":"https:%2F%2Fblog.nogizaka46.com%2Fmanatsu.akimoto","bloodType":"B
型","generation":"1期生","group":"乃木
坂","height":"154cm","imgUrl":"https:%2F%2Fkokoichi0206.mydns.jp%2Fimgs%2Fnogi%2F
akimotomanatsu.jpeg","name":"秋元 真夏"}, lambda {})

Retrofit memo

multipart request (using image file)

interface

@Multipart
@POST("/api/post/create")
suspend fun createPost(
    @Part postData: MultipartBody.Part,
    @Part postImage: MultipartBody.Part
): BasicApiResponse<Unit>

Impl

val response = api.createPost(
    postData = MultipartBody.Part
        .createFormData(
            "post_data",
            gson.toJson(request)
        ),
    postImage = MultipartBody.Part
        .createFormData(
            name = "post_image",
            filename = imageFile.name,
            body = imageFile.asRequestBody()
        )
)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.