基于注释去关联安卓APP的deep links - OkDeepLink

2017-06-11      197      Android
项目简介

OkDeepLink

OkDeepLink provides a annotation-based api to manipulate app deep links.

  • register deep links with annotation@Path、@Activity
  • start deep links by service which generates an implementation byAnnotation-processor, auto inject to activity with annotation@Service
  • url or bundle parameters auto inject to activity , restore when activity recreate by annotation@Query
  • async intercept deep links in ui thread with annotation@Intercept
  • support activity result withrxJava

Config

In Root Gradle

repositories {
   jcenter()
}
dependencies {
    classpath 'com.hongjun:okdeeplink-gradle:1.0.0'
}

In App Or Lib Gradle

apply plugin: 'okdeeplink.plugin'

if use multiple apt lib, you must use

packagingOptions {
        exclude 'META-INF/services/javax.annotation.processing.Processor'
}

Example

If you want defineold://app/main?key=valueuri, you can do like this

Define Host And Scheme

you can define dispatch activity which receive deep links in yourAndroidManifest.xmlfile (usingodlas an example):

In App AndroidManifest

<activity
            android:name="okdeeplink.DeepLinkActivity"
            android:theme="@android:style/Theme.Translucent.NoTitleBar">
            <intent-filter>
                <action android:name="android.intent.action.VIEW" />

                <category android:name="android.intent.category.DEFAULT" />
                <category android:name="android.intent.category.BROWSABLE" />

                <data
                    android:host="app"
                    android:scheme="odl" />
            </intent-filter>
 </activity>

In the future, I will use annotation@AppLinkwhich define scheme and host instead ofAndroidManifest.xml. I already have a simple way.

In Service File

public interface SampleService {


    @Path("/main")
    @Activity(MainActivity.class)
    void startMainActivity(@Query("key") String key);
}

path must start with "/" when app receive uri likeold://app/main?key=value,DeepLinkActivitywill start ,then dispatch the deep link to the appropriateActivity.

In Activity Or Fragment File

You also start MainActivity by service in app.

public class SecondActivity extends AppCompatActivity {

       @Service
       SampleService sampleService;
       @Query("key")
       String key;


       sampleService.startMainActivity("value");
}

Intercept

If you want Interceptold://app/second, you can use@Intercept

@Intercept(path = "/second")
public class SecondInterceptor extends Interceptor {
    @Override
    public void intercept(final Call call) {
        Request request = call.getRequest();
        final Intent intent = request.getIntent();
        Context context = request.getContext();

        StringBuffer stringBuffer = new StringBuffer();
        stringBuffer.append("Intercept\n");
        stringBuffer.append("URL: " + request.getUrl() + "\n");

        AlertDialog.Builder builder = new AlertDialog.Builder(context,R.style.Theme_AppCompat_Dialog_Alert);
        builder.setTitle("Notice");
        builder.setMessage(stringBuffer);
        builder.setNegativeButton("cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                call.cancel();
            }
        });
        builder.setPositiveButton("ok", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                intent.putExtra("key1", "value3");
                call.proceed();
            }
        });
        builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                call.cancel();
            }
        });
        builder.show();
    }
}

Log

I defineLogInterceptor, this can log deep links which start、notFound、error , log tag isOkDeepLink

Other Way

You can start intent action by service

public interface SampleService {

    @Action(MediaStore.ACTION_IMAGE_CAPTURE)
    Observable<Response> startImageCapture();

     @Action(Intent.ACTION_DIAL)
     @Uri("tel:{phone}")
     void startTel(@UriReplace("phone") String phone);
}
public void startImageCapture(){
        sampleService
                .startImageCapture()
                .subscribe(new Action1<Response>() {
                    @Override
                    public void call(Response response) {
                        Intent data = response.getData();
                        int resultCode = response.getResultCode();
                        if (resultCode == RESULT_OK) {
                            Bitmap imageBitmap = (Bitmap) data.getExtras().get("data");
                            ImageView imageView = (ImageView) findViewById(R.id.ImageView_Capture_Image);
                            imageView.setImageBitmap(imageBitmap);
                        }
                    }
                });
    }

    public void startTel(String phone){
            sampleService
                    .startTel(phone);
        }