[Huawei Developers] Freemind R:
Hello everyone, in this article we will create a demo application using the core features of Panorama Kit to help you better understand the implementation of this kit. This app will simply allow users to quickly display interactive viewing of panoramic images in simulated 3D space.

What is Panorama Kit and Why Should We Use It?

By integrating the HUAWEI Panorama Kit, your app can quickly display interactive viewing of 360-degree spherical or cylindrical panoramic images in simulated 3D space, delivering immersive 360-degree showcases and interactions to users.

Features

360-degree spherical panorama, partially 360-degree spherical panorama, and cylindrical panorama

Parsing and display of panorama images in JPG, JPEG, and PNG formats

Interactive viewing of panoramic videos

Panorama view adjustment by swiping the screen or rotating the mobile phone to any degree

Interactive viewing of 360-degree spherical panoramas shot by mainstream panoramic cameras

Flexible use of panorama services, such as displaying panoramas in a certain area of your app, instead of in a window outside the app, made possible with in-app panorama display APIs

Integration Preparations

Panorama SDK can be directly called by devices, without connecting to AppGallery Connect so you don’t need agconnect-services.json. You just need the add Maven repository address in the project-level build.gradle file.

Software Requirements

Android Studio 3.0 or later

Java SDK 1.7 or later

HMS Core (APK) 4.0.0.300 or later

HMS Core SDK 4.0.0.300 or later

Android 5.0 or later

Supported Locations

To see all supported locations, please refer to HUAWEI Panorama Kit Supported Locations

Configuration

Add Maven repository address in the project-level build.gradle file

buildscript {
repositories {
...
maven { url 'https://developer.huawei.com/repo/' }
}
...
}
allprojects {
repositories {
...
maven { url 'https://developer.huawei.com/repo/' }
}
}
...

And add build dependencies in the app-level build.gradle file.

implementation 'com.huawei.hms:panorama:4.0.4.301'

Keep in mind that the SDK version used in this article may be not the latest one. If you want to use the latest SDK version, please refer to Version Change History.

Finally, add read and write permissions in the AndroidManifest.xml.

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

Remember, in Android 6.0 or later, you need to dynamically request the permissions.

Implementation

There are 3 different ways to call Panorama View;

Load a panorama image without a specified panorama type.

Load a panorama image with a specified panorama type.

Start an activity, which shows how to call panorama image display using the PanoramaLocalInterface.

Now we’ll go through each of these ways to implement Panorama Kit.

Load a panorama image without a specified panorama type

If you don’t specify a panorama type, users will be able to move both horizontally and vertically. But if suitable, it’s best that you specify a panorama type to give your users a better viewing experience.

private fun loadImageWithoutType() {
Panorama.getInstance().loadImageInfoWithPermission(
this,
Uri.parse("android.resource://$packageName/${R.raw.pano1}")
)
.setResultCallback(ResultCallbackImpl(this@MainActivity))
}

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/026/578/271/5190090000026578271.20200923105542.94562791035218916780856713671415:50511014010325:2800:64972B4E0664CE75FCAA3D2AFF963E8ED9B26F5F0DF80D5359603901D84C9AD0.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/026/578/271/5190090000026578271.20200923105542.94562791035218916780856713671415:50511014010325:2800:64972B4E0664CE75FCAA3D2AFF963E8ED9B26F5F0DF80D5359603901D84C9AD0.gif[/IMG]

Load a panorama image with a specified panorama type

Here we specify the panorama type of IMAGE_TYPE_RING to improve the viewing experience of this particular image.

private fun loadImageWithType() {
Panorama.getInstance().loadImageInfoWithPermission(
this,
Uri.parse("android.resource://$packageName/${R.raw.pano1}"),
PanoramaInterface.IMAGE_TYPE_RING
).setResultCallback(ResultCallbackImpl(this@MainActivity))
}

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/026/578/271/5190090000026578271.20200923110616.30520525521879957980936027022265:50511014010325:2800:257E8830D90977AEA8E4397B2E09B0134FDB5B65E64558F0A0F0853B7EC5181B.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/026/578/271/5190090000026578271.20200923110616.30520525521879957980936027022265:50511014010325:2800:257E8830D90977AEA8E4397B2E09B0134FDB5B65E64558F0A0F0853B7EC5181B.gif[/IMG]

Load panorama image inside a custom activity

Finally, if you want to show panorama view in a custom activity of yours, you can do so by sending the necessary data detailed in the code below and calling the local interface api of Panorama Kit in that specific activity.

private fun panoramaWithLocalInterface() {
val intent = Intent(this@MainActivity, LocalInterfaceActivity::class.java)
intent.apply {
data = Uri.parse("android.resource://$packageName/${R.raw.pano1}");
putExtra("PanoramaType", PanoramaInterface.IMAGE_TYPE_SPHERICAL)
}
startActivity(intent)
}

Init local interface and set image uri and type, obtain the view and add it to your layout. And listen on the changeInputButton event to change the control mode.

private fun callLocalApi(imageUri: Uri?, imageType: Int) {
mLocalInterface = Panorama.getInstance().getLocalInstance(this)
if (mLocalInterface.init() == 0 && mLocalInterface.setImage(imageUri, imageType) == 0) {
val view: View = mLocalInterface.view
relativeLayout.addView(view)
view.setOnTouchListener(this@LocalInterfaceActivity)
changeInputButton.apply {
bringToFront()
setOnClickListener(this@LocalInterfaceActivity)
}
} else {
Log.e(TAG, "local api error")
}
}

override fun onClick(v: View?) {
if (v?.id == R.id.changeInputButton) {
if (mIsGyroEnabled) {
mIsGyroEnabled = false
mLocalInterface.setControlMode(PanoramaInterface.CONTROL_TYPE_TOUCH)
} else {
mIsGyroEnabled = true
mLocalInterface.setControlMode(PanoramaInterface.CONTROL_TYPE_POSE)
}
}
}

Send the view touch control event to the HMS Core Panorama SDK. (This step assumes that the touch mode is enabled.)

@SuppressLint("ClickableViewAccessibility")
override fun onTouch(v: View?, event: MotionEvent?): Boolean {
mLocalInterface.let {
mLocalInterface.updateTouchEvent(event)
}
return true
}

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/026/578/271/5190090000026578271.20200923111005.58679457804886194699357732163489:50511014010325:2800:9B04D7807E528EF0DA5E009A4876FD7598FD35C8FF84D2D21437B029EE80A537.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/026/578/271/5190090000026578271.20200923111005.58679457804886194699357732163489:50511014010325:2800:9B04D7807E528EF0DA5E009A4876FD7598FD35C8FF84D2D21437B029EE80A537.gif[/IMG]

Keep in mind: After loading a panoramic image, you can call the setImage API to replace it with another one, if necessary.

mLocalInterface.setImage(resourceUri, imageType)

And that’s it! These were the 3 ways of implementing Panorama Kit into your app. You can find the full source code of this demo application in the link below.

https://github.com/tolunayozturk/hms-panoramakitdemo

As always, thank you for reading this article and using HMS. Please let me know if you have any questions!