Due to the security mechanism of Ubuntu OS, no third-party application can access another application’s storage. This raises questions, such as what if we want to access the pictures in the Gallery? We can use the ContentHub API provided by Ubuntu OS to access accessible content provided by another application. The prerequisite is that the other application must have a corresponding function to implement the export function. In this article, we’ll show you how to use ContentHub to get images provided by the Gallery. For more information about the ContentHub API, see the link. \
\
On the desktop system, we must install the following packages:
$ sudo apt-get install content-hub
$ sudo apt-get install qtdeclarative5-ubuntu-content1
Copy the code
\
1) Create a basic QML application
Let’s open the SDK to create a basic QML application. We use the “App with Simple UI” template. And give a name as “contenthub-importer”. Here, we must pay attention to the following:
\
applicationName: "com.ubuntu.developer.liu-xiao-guo.contenthub-importer"
Copy the code
The name of the application must be the same as the name of the Package. Otherwise, when we import images into the application, the directory created will be inaccessible due to the different path of the directory. The package name we will generate is:
\
Com. Ubuntu. Developer. Liu - xiao - guo. Contenthub - importer_0. 1 _all. ClickCopy the code
The import path on the phone will be:
\
\
Of course, this is the path we can create when we finally run the application, after we import the image. \
\
2) Design our interface
Our design interface is as follows:
\
\
\
At the top of the screen is a “ComboButton”. Our design is as follows:
\
ListModel {
id: typemodel
ListElement { name: "Import single item" }
ListElement { name: "Import multiple items" }
}
ListItem.Empty {
id: options
ComboButton {
id: type
anchors {
left: parent.left
margins: units.gu(2)
}
dropdownColor: "red"
width: root.width/2
expanded: false
text: "Import single item"
ListView {
anchors.fill: parent
model: typemodel
delegate: ListItem.Standard {
text: modelData
onClicked: {
console.log("item is clicked!" + index + " " + name);
type.expanded = false;
type.text = text;
console.log("type is: " + type.text);
if ( name === "Import single item") {
activeTransfer = picSourceSingle.request(appStore);
} else if ( name === "Import multiple items" ) {
activeTransfer = picSourceMulti.request(appStore);
}
}
}
}
}
Button {
anchors {
right: parent.right
margins: units.gu(2)
}
text: "Finalize import"
enabled: activeTransfer.state === ContentTransfer.Collected
onClicked: activeTransfer.finalize()
}
}
Copy the code
We can choose to import one or more images. We also define two ContentPeers. A ContentPeer is a destination that has registered with ContentHub as a data source or has a ContentType definition.
\
ContentPeer {
id: picSourceSingle
contentType: ContentType.Pictures
handler: ContentHandler.Source
selectionType: ContentTransfer.Single
}
ContentPeer {
id: picSourceMulti
contentType: ContentType.Pictures
handler: ContentHandler.Source
selectionType: ContentTransfer.Multiple
}
Copy the code
We can also define a “ContentPeerModel” to display all the applications that can provide images.
\
// Provides a list<ContentPeer> suitable for use as a model
ContentPeerModel {
id: picSources
// Type of handler: Source, Destination, or Share
handler: ContentHandler.Source
// well know content type
contentType: ContentType.Pictures
}
Copy the code
We can use the following ListView to display these applications:
\
ListView {
id: peerList
anchors {
left: parent.left
right: parent.right
top: options.bottom
}
height: childrenRect.height
model: picSources.peers
delegate: ListItem.Standard {
text: modelData.name
control: Button {
text: "Import"
onClicked: {
// Request the transfer, it needs to be created and dispatched from the hubactiveTransfer = modelData.request(); }}}}Copy the code
We can use the following methods to detect the state in the transfer process:
\
Connections {
target: activeTransfer
onStateChanged: {
// console.log("StateChanged: " + activeTransfer.state);
switch (activeTransfer.state) {
case ContentTransfer.Created:
console.log("Created");
break
case ContentTransfer.Initiated:
console.log("Initiated");
break;
case ContentTransfer.InProgress:
console.log("InProgress");
break;
case ContentTransfer.Downloading:
console.log("Downloading");
break;
case ContentTransfer.Downloaded:
console.log("Downloaded");
break;
case ContentTransfer.Charged:
console.log("Charged");
break;
case ContentTransfer.Collected:
console.log("Collected");
break;
case ContentTransfer.Aborted:
console.log("Aborted");
break;
case ContentTransfer.Finalized:
console.log("Finalized");
break;
default:
console.log("not recognized state!")
break;
}
if (activeTransfer.state === ContentTransfer.Charged) {
importItems = activeTransfer.items;
for ( var i = 0; i < importItems.length; i ++ ) {
console.log(importItems[i].url);
}
var item;
for ( item in importItems ) {
console.log( "imported url: "+ importItems[item].url); }}}Copy the code
In the code above, we show the path to the files saved in the application. Here activeTransfer and importItems are defined as follows:
\
property list<ContentItem> importItems
property var activeTransfer
Copy the code
We use another ListView to display the photos we imported:
\
ListView {
id: peerList
anchors {
left: parent.left
right: parent.right
top: options.bottom
}
height: childrenRect.height
model: picSources.peers
delegate: ListItem.Standard {
text: modelData.name
control: Button {
text: "Import"
onClicked: {
// Request the transfer, it needs to be created and dispatched from the hubactiveTransfer = modelData.request(); }}}}Copy the code
\
The most useful display effect is as follows:
\
\
\
The entire code can be found at the following address:
\
bzr branch lp:~liu-xiao-guo/debiantrial/contenthub-importer\
\
\