[Huawei Developers] XDARoni:
The HMS Panorama Kit is an SDK to help you display and interact with panoramic images in your app. Instead of creating your own Surfaces and Views, Panorama Kit can do it all for you.

If that's something you're interested in, read on.

Preparation

First up, make sure you have a Huawei Developer Account. This process can take a couple days, and you'll need one to use this SDK, so be sure to start that as soon as possible. You can sign up at https://developer.huawei.com.

Next, you'll want to obtain the SHA-256 representation of your app's signing key. If you don't have a signing key yet, be sure to create one before continuing. To obtain your signing key's SHA-256, you'll need to use Keytool which is part of the JDK installation. Keytool is a command-line program. If you're on Windows, open CMD. If you're on Linux, open Terminal.

On Windows, you'll need to "cd" into the directory containing the Keytool executable. For example, if you have JDK 1.8 v231 installed, Keytool will be located at the following path:

C:\Program Files\Java\jdk1.8.0_231\bin\

Once you find the directory, "cd" into it:

C: #Make sure you're in the right drive
cd C:\Program Files\Java\jdk1.8.0_231\bin\

Next, you need to find the location of your keystore. Using Android's debug keystore as an example, where the Android SDK is hosted on the "E:" drive in Windows, the path will be as follows:

E:\AndroidSDK\.android\debug.keystore

(Keytool also supports JKS-format keystores.)

Now you're ready to run the command. On Windows, it'll look something like this:

keytool -list -v -keystore E:\AndroidSDK\.android\debug.keystore

On Linux, the command should be similar, just using UNIX-style paths instead.

Enter the keystore password, and the key name (if applicable), and you'll be presented with something similar to the following:

Make note of the SHA256 field.

SDK Setup

Now we're ready to add the Panorama Kit SDK to your Android Studio project. Go to your Huawei Developer Console and click the HUAWEI AppGallery tile. Agree to the terms of use if prompted.

Click the "My projects" tile here. If you haven't already added your project to the AppGallery, add it now. You'll be asked for a project name. Make it something descriptive so you know what it's for.

Now, you should be on a screen that looks something like the following:

Click the "Add app" button. Here, you'll need to provide some details about your app, like its name and package name.

Once you click OK, some SDK setup instructions will be displayed. Follow them to get everything added to your project. You'll also need to add the following to the "dependencies" section of your app-level build.gradle file:

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

Panorama Kit also works on devices without HMS. If you're targeting non-Huawei devices as well, make sure to add the following dependency:

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

If you ever need to come back to these instructions, you can always click the "Add SDK" button after "App information" on the "Project setting" page.

Now you should be back on the "Project setting" page. Find the "SHA-256 certificate fingerprint" field under "App information," click the "+" button, and paste your SHA-256.

Now, if you're using obfuscation in your app, you'll need to whitelist a few things for HMS to work properly.

For ProGuard:

-ignorewarnings
-keepattributes *Annotation*
-keepattributes Exceptions
-keepattributes InnerClasses
-keepattributes Signature
-keepattributes SourceFile,LineNumberTable
-keep class com.hianalytics.android.**{*;}
-keep class com.huawei.updatesdk.**{*;}
-keep class com.huawei.hms.**{*;}

For AndResGuard:

"R.string.hms*",
"R.string.agc*",
"R.string.connect_server_fail_prompt_toast",
"R.string.getting_message_fail_prompt_toast",
"R.string.no_available_network_prompt_toast",
"R.string.third_app_*",
"R.string.upsdk_*",
"R.layout.hms*",
"R.layout.upsdk_*",
"R.drawable.upsdk*",
"R.color.upsdk*",
"R.dimen.upsdk*",
"R.style.upsdk*

That's it! The Panorama Kit SDK should now be available in your project.

Basic Usage

There are two ways to use the Panorama Kit: inside your app and outside your app.

Displaying inside your app means you can customize the view and how the interface displays. Outside means the SDK itself presents its own view and takes care resource management for you.

Inside

This guide won't be going through how to organize and set up your own interface, but it'll help you get started.

Here's some code walking through how you can display a panorama in your app.

fun displayInside() {
val instance = Panorama.getInstance().getLocalInstance(context)

//Initialize the API
val result = instance.init()
if (result != 0) {
//API failed to initialize
return
}

//A Uri representation of the panorama to load.
//Currently supports file, content, and resource Uris
val uri = Uri.parse("content://some.uri")

//The type of panorama, either IMAGE_TYPE_SPHERICAL (sphere)
//or IMAGE_TYPE_RING (cylinder)
val type = PanoramaInterface.IMAGE_TYPE_SPHERICAL

//setImage() also takes a Bitmap instead of a Uri
val setResult = instance.setImage(uri, type)
if (setResult != 0) {
//Setting the image failed
return
}

//The Surface to display in your app. You can handle this
//however you want, for example by adding it to a MediaPlayer.
val surface = instance.getSurface(type)

//If you're adding the Surface to a MediaPlayer, you may
//want to specify the aspect ratio.
val player = MediaPlayer()
player.setSurface(surface)
instance.setValue(PanoramaInterface.KEY_VIDEO_RATIO, "${player.videoWidth / player.videoHeight}")

//You can also set the panorama to display in polar
//coordinates.
instance.setValue(PanoramaInterface.KEY_RENDER_MODE, PanoramaInterface.VALUE_RENDER_MODE_POLAR)

//There are three control modes available for panoramas:
//motion control (CONTROL_TYPE_POSE), touch control (CONTROL_TYPE_TOUCH),
//and both (CONTROL_TYPE_MIX).
//If you're using CONTROL_TYPE_TOUCH, or CONTROL_TYPE_MIX,
//make sure you call updateTouchEvent() when the user
//makes a gesture.
instance.setControlMode(PanoramaInterface.CONTROL_TYPE_POSE)
instance.updateTouchEvent(MotionEvent() /* dummy event */)

//For controlling the panorama, you should retrieve the View
//from the API.
val view = instance.view

//You can then set a touch listener on that View
//and pass the touch events to the API.
view.setOnTouchListener { _, e ->
instance.updateTouchEvent(e)
true
}

//After you're done with the panorama API, you should
//deinitialize it. This should be called in your onDestroy().
instance.deInit()
}

Outside

If you don't want to worry about handling your own Surfaces and Views, you can always choose to let HMS display the panorama for you.

Example:

fun displayOutside() {
fun handleResult(result: PanoramaInterface.ImageInfoResult) {
if (result.status.isSuccess) {
//Intent was created successfully. We can start
//the Activity.
context.startActivity(result.imageDisplayIntent)
} else {
//Intent failed to be created.
val error = result.status.errorString
}
}

//A Uri representation of the panorama to load.
//Currently supports file, content, and resource Uris
val uri = Uri.parse("content://some.uri")

val pendingResult = Panorama.getInstance().loadImageInfo(context, uri)

//You can either await() the result, or use a Callback,
//depending on your app's flow.
val result = pendingResult.await() //Will block the current Thread.
handleResult(result)

//Will handle asynchronously
pendingResult.setResultCallback { asyncResult ->
handleResult(asyncResult)
}

//In some cases you may need to specify the panorama type (e.g. if the image has lost its metadata).
//The image type is either IMAGE_TYPE_SPHERICAL or IMAGE_TYPE_CYLINDRICAL.
val typedPendingResult = Panorama.getInstance().loadImageInfo(context, uri, PanoramaInterface.IMAGE_TYPE_SPHERICAL)

//If the image is in a protected data directory, you should use this method to let the API load it.
val permittedPendingResult = Panorama.getInstance().loadImageInfoWithPermission(context, uri)
}

Conclusion[/CODE]

That's it! The HMS Panorama Kit makes displaying panoramic images much easier than doing it yourself, and it doesn't even require a device with HMS. If you're developing a gallery or camera app, this could certainly be a helpful addition.