Android 외부 환기 적용 점프 지정 페이지

6578 단어
보통 이런 장면이 있는데 위챗 모멘트 등에 내용을 공유하고 내용 중의 어떤 버튼을 클릭하면 자신의 앱을 불러일으킬 수 있다.
여기서 말하고자 하는 것은 scheme 방식으로 점프를 실현하는 것이다. 먼저 생각을 요약하자면 먼저 외부에서 앱을 깨울 수 있다면 앱은 반드시 전체적인 사건 감청을 등록해야 한다.그 다음에 이벤트를 처리하고 구체적인 파라미터를 해석한 다음에 구체적인 페이지를 돌려야 한다.이렇게 간단해.
생각이 간단히 정리되었으니, 그럼 하나하나 실현해 보자.
등록 이벤트 수신
여기에는 Android Activity에 있는 를 사용해야 합니다. 현재는 해석 점프Activity를 만들 수 있습니다. 이름을 마음대로 지어서manifest 파일에 구체적인 를 설정해야 합니다.

    
    

    
    



위에서 설정한 바와 같이 현재 이것Activity은 외부에서 깨우는 능력을 갖추고 있다. 아래의 관련 설정을 주의해라. 위에서 설정한 바와 같이 외부의 링크 형식은 다음과 같아야 한다: test://lovejjfg.com/xxx.에는 다른 내용을 정의할 수 있으니 여기서 설명하지 않겠습니다.
페이지 이동
콜록콜록, 여기서 주의해야 한다. 예를 들어 시작 페이지 A가 있는데, 메인 페이지는 B이고, 지금은 지정한 C 페이지로 넘어가야 한다.그러면 외부에서 앱을 환기시킬 때 사실 몇 가지 상황이 있는데 이것은 모두 우리가 고려해야 할 것이다.
먼저 제품의 수요를 살펴보면 구체적인 페이지를 열어야 한다. 이 페이지만 시작하고 반환하면 브라우저로 돌아갈지, 아니면 앱을 시작해야 할지 결정한다.만약 페이지만 열면 된다면, 아주 간단합니다. 새 작업 창고의 상황을 고려할 필요가 없습니다.만약에 리베이트를 하려면 목표 앱을 시작해야 한다. 그렇지 않으면 사용자가 직접 브라우저로 돌아가면 몇 가지 상황을 구분해야 한다.
첫 번째 상황은 현재 휴대전화에서 목표 앱을 시작한 적이 없다는 것이다.쉽게 말하면 브라우저가 C 페이지로 바로 건너뛰고 되돌아갈 때 A 페이지를 표시하고 B 페이지로 들어간다.여기는 바로 우리가 직접 창고를 만들고 A, C를 순서대로 넣어야 하기 때문에 C는 A로 되돌아가고 A는 B를 시작할 수 있다.지식점은 TaskStackBuilder인데 그것과 결합하면 Manifest에서 Parent의 속성을 지정할 수 있다.
Activity 논리 상위 클래스의 이름입니다.이 이름은android:name 속성에 지정된 클래스 이름과 일치해야 합니다.사용자가 작업 표시줄의 [위쪽] 버튼을 누를 때 어떤 Activity를 시작해야 하는지 확인하기 위해 시스템이 이 속성을 읽습니다.또한 TaskStackBuilder를 통해 Activity의 반환 스택을 작성하는 데 사용할 수 있습니다.API 레벨 4 - 16을 지원하려면 "android.support.PARENT ACTIVITY"에 지정된 값의 요소를 사용하여 부모 Activity를 선언할 수도 있습니다.
그러니까 여기는 니가 잘 어울리는 걸로.다음에 이것TaskStackBuilder의 사용을 보세요. 사실 어렵지 않아요. 베끼면 돼요.하하.상세한 공식 문서 참조는 여기에서 말한 PendingIntent의 오픈 방식일 뿐입니다. 저희는 사실 직접startActivity()의 방법입니다. 이걸 어떻게 조작해야 합니까?
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(resultIntent.getComponent());
stackBuilder.addNextIntent(resultIntent);
stackBuilder.startActivities();

사실 저는 처음에 바로 켜는 방법Activity을 어떻게 해야 할지 몰랐어요. 베낀 곳에 이렇게 쓰지 않았기 때문에 베낀 것이 없으면 직접 방법을 보러 갔어요.처음에 나는 stackBuilder.getIntents()의 방법을 보았고 슬기로운 나는 서둘러 시험해 보았는데 context.startActivities() 역시 효과가 있었다. 뒤에서 다른 사람의builder가 직접 Activity를 켜는 방법이 있다는 것을 발견했다. 바로 위에 쓴 방법이다.
잠깐만, Builder 왜 나한테 이렇게 썼어?모욕Builder 아닌가요?
TaskStackBuilder.create(this)
        .addParentStack(resultIntent.getComponent())
        .addNextIntent(resultIntent)
        .startActivities();

이것이야말로 가장 정확한 조작이잖아.이어서 두 번째 상황은 목표 앱이 이미 시작되었고 백그라운드에서 실행되고 있으며 지정된 C 페이지가 열리지 않았다.위의 방식은 네가 앱을 시작하든 안 시작하든 다시 시작할 거야. 이것도 좀 불편하다. 그런데 왜 매번 다시 시작하지?시동 거는 방법을 보면 알 수 있을 거예요.
public void startActivities(Bundle options) {
    if (mIntents.isEmpty()) {
        throw new IllegalStateException(
                "No intents added to TaskStackBuilder; cannot startActivities");
    }

    Intent[] intents = mIntents.toArray(new Intent[mIntents.size()]);
    intents[0] = new Intent(intents[0]).addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
            IntentCompat.FLAG_ACTIVITY_CLEAR_TASK |
            IntentCompat.FLAG_ACTIVITY_TASK_ON_HOME);
    if (!ContextCompat.startActivities(mSourceContext, intents, options)) {
        Intent topIntent = new Intent(intents[intents.length - 1]);
        topIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        mSourceContext.startActivity(topIntent);
    }
}

요점을 보면 이 방법은 매번 첫 번째 Intent에 Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK | IntentCompat.FLAG_ACTIVITY_TASK_ON_HOME라는 세 개의 Flag를 첨가하는데 IntentCompat.FLAG_ACTIVITY_CLEAR_TASK가 있기 때문에 이렇게 된 거예요. 그럼 어떻게 해결할까요?사실 아주 간단합니다. 우리는 점프할 때 현재 앱이 이미 켜졌는지 판단을 해야 합니다. 없으면 바로 위에 있는 코드가 있고 있으면 스택을 만들지 않고 바로 켜면 됩니다.직접 시작할 때 Intent.FLAG_ACTIVITY_NEW_TASK의Flag를 넣어야 한다. 그렇지 않으면 브라우저가 있는 창고 안에 있다.
if (ViewUtils.isLaunchedActivity(this, HomeActivity.class)) {
    resultIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(resultIntent);
} else {
    TaskStackBuilder.create(this)
            .addParentStack(resultIntent.getComponent())
            .addNextIntent(resultIntent)
            .startActivities();
}

public static boolean isLaunchedActivity(@NonNull Context context, Class> clazz) {
    Intent intent = new Intent(context, clazz);
    ComponentName cmpName = intent.resolveActivity(context.getPackageManager());
    boolean flag = false;
    if (cmpName != null) { 
        ActivityManager am = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE);
        List taskInfoList = am.getRunningTasks(10);
        for (ActivityManager.RunningTaskInfo taskInfo : taskInfoList) {
            if (taskInfo.baseActivity.equals(cmpName)) { 
                flag = true;
                break;
            }
        }
    }
    return flag;
}

세 번째 경우 목표 앱이 시작되었고 백그라운드에서 실행되며 지정한 C 페이지가 열려 있다.
이것은 사실 시작 모드의 문제입니다. C는 이미 열었고 다시 열었습니다. 만약에 정식적인 시작 모드라면 여기에 여러 개의 C 페이지가 중복되어 나타날 것입니다. 그래서 SingleTop을 설정하면 문제를 해결할 수 있습니다.물론 이 모드를 설정하면 onNewIntent() 처리하는 방법이 필요합니다.
매개 변수 해석
매개 변수는 내가 어떻게 정의하는지에 달려 있다. 예를 들어 내가 정의한 것은 test://lovejjfg.com/C?10086이다.
Uri data = getIntent().getData();
String host = data.getHost();
String path = data.getPath();
String id = data.getQueryParameter("id")
String scheme = data.getScheme();
Log.i(TAG, "host: " + host);//lovejjfg.com
Log.i(TAG, "path: " + path);//C
Log.i(TAG, "scheme: " + scheme);//test
Log.i(TAG, "id: " + id);//'10086'

위의 사고방식은 scheme 점프 응용의 사용에 국한되지 않고 Notification의 방식도 마찬가지다.그리고 startActivities() 포즈 멋있죠?
PS: 일이 없으면 공식 문서를 많이 보세요. 많은 것들이 이미 한화되었어요.
-20171228 업데이트 -
많은 젊은이들도 비슷한 수요를 가지고 있기 때문에, 몇몇 문제는 이미 평론 회답에서 해결되었다.테스트 데모와 테스트 링크를 추가하고 알림을 추가하여 테스트를 편리하게 합니다.
주소:https://github.com/lovejjfg/EasyJump

좋은 웹페이지 즐겨찾기