在这篇文章中,我们将使用Ubuntu SDK所提供的online account API来访问微博的API并显示所需要的内容。这篇文章的重点是展示如何使用online account API的使用。我们将创建一个简单的QML应用。我们最终显示的画面如下:
更多关于QML应用开发的资料可以在地址:https://developer.ubuntu.com/zh-cn/apps/qml/
1)创建一个最基本的应用
我们还是像以前一样使用我们的Ubuntu SDK来创建一个最基本的weibo QML应用。
这样我们就创建了一个最基本的weibo QML应用。你可以使用热键Ctrl + R来运行它虽然它并不能做什么事。
2)加入online account所需要的文件
我们可以参考
文章来对
online account API有更深的了解。为了能够访问,需要创建如下的文件:
1)
weibo.application
它的具体内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<application>
<description>Weibo QML</description>
<desktop-entry>weibo.ubuntu_weibo.desktop</desktop-entry>
<services>
<service id="qml-weibo.ubuntu_qmlweibo">
<description>Watch your favorite Weibo messages</description>
</service>
</services>
</application>
2) weibo.service
它的具体的内容为:
<?xml version="1.0" encoding="UTF-8"?>
<service>
<type>sharing</type>
<name>Weibo QML</name>
<icon>qml-weibo.png</icon>
<provider>qml-weibo.ubuntu_plugin</provider>
<translations>unity-scope-weibo</translations>
</service>
3) 创建一个plugin文件目录并在它的下面创建
a)Main.qml, 它的内容为:
import Ubuntu.OnlineAccounts.Plugin 1.0
OAuthMain {}
b) qml-weibo.ubuntu_plugin.provider,它的内容为:
<?xml version="1.0" encoding="UTF-8"?>
<provider>
<name>Weibo</name>
<icon>weibo/icon.png</icon>
<translations>unity-scope-weibo</translations>
<plugin>generic-oauth</plugin>
<domains>.*weibo\.com</domains>
<single-account>true</single-account>
<template>
<group name="auth">
<setting name="method">oauth2</setting>
<setting name="mechanism">web_server</setting>
<group name="oauth2">
<group name="web_server">
<setting name="Host">api.weibo.com</setting>
<setting name="AuthPath">oauth2/authorize</setting>
<setting name="TokenPath">oauth2/access_token</setting>
<setting name="RedirectUri">https://api.weibo.com/oauth2/default.html</setting>
<setting name="ResponseType">code</setting>
<setting name="ClientId">your developer key</setting>
<setting type="as" name="AllowedSchemes">['https','http']</setting>
<setting name="ClientSecret">your developer secret</setting>
<setting name="ForceClientAuthViaRequestBody" type="b">true</setting>
</group>
</group>
</group>
</template>
</provider>
在上面的文件中一定要输入自己的“ your developer key”及“ your developer secret”。这个你需要在 微博API的网站上去申请。整个文件的架构为:
4)
修改manifest.json文件如下:
{
"name": "qml-weibo.ubuntu",
"description": "description of qml-weibo",
"architecture": "all",
"title": "qml-weibo",
"hooks": {
"qmlweibo": {
"account-application": "weibo.application",
"account-service": "weibo.service",
"apparmor": "qmlweibo.apparmor",
"desktop": "qmlweibo.desktop"
},
"plugin": {
"account-provider": "plugin/qml-weibo.ubuntu_plugin.provider",
"account-qml-plugin": "plugin/qml"
}
},
"version": "0.1",
"maintainer": "XiaoGuo, Liu <xiaoguo.liu@canonical.com>",
"framework": "ubuntu-sdk-14.10"
}
这里添加了account及plugin的一些设置。
5)
为了能够让.service,.application及.provider文件能正常得到显示,我们对“qml-weibo.qmlproject”添加如下的东西:
Files {
filter: "*.service"
}
Files {
filter: "*.application"
}
Files {
filter: "*.provider"
}
到这里,我们已经基本上已经修改或添加好我们所需要的文件。
3)设计应用的UI
我们来修改我们的main.qml文件。我们使用了一个Column的列layout manager来管理我们的控件。
- 使用一个ListView (accountsList)来显示所有我们相关的账号。这个可以在“系统设置”中的“账号”可以看到
- 使用一个叫做“createAccountBtn”的按钮来创建一个weibo的online账号
- 使用另外一个ListView (weiboList)列表来显示微博的内容
import QtQuick 2.0
import Ubuntu.Components 0.1
import Ubuntu.Components.ListItems 0.1 as ListItem
import Ubuntu.OnlineAccounts 0.1
import Ubuntu.OnlineAccounts.Client 0.1
import "weiboapi.js" as API
/*!
\brief MainView with a Label and Button elements.
*/
MainView {
id: main
// objectName for functional testing purposes (autopilot-qt5)
objectName: "mainView"
// Note! applicationName needs to match the "name" field of the click manifest
applicationName: "qml-weibo.ubuntu"
/*
This property enables the application to change orientation
when the device is rotated. The default is false.
*/
//automaticOrientation: true
property string accesstoken:""
width: units.gu(100)
height: units.gu(90)
Page {
id: root
clip:true
title: i18n.tr("Weibo")
Column {
spacing: units.gu(2)
width: parent.width
ListView {
id: accountsList
anchors.horizontalCenter: parent.Center
anchors.verticalCenter: parent.Center
height: contentHeight
width: parent.width
spacing: units.gu(1)
model: accountsModel
delegate: Rectangle {
id: wrapper
width: accountsList.width
height: units.gu(10)
color: accts.enabled ? "green" : "red"
AccountService {
id: accts
objectHandle: accountServiceHandle
onAuthenticated: {
console.log("reply: " + JSON.stringify(reply));
var obj = JSON.parse(JSON.stringify(reply));
console.log("AccessToken: " + obj.AccessToken);
main.accesstoken = obj.AccessToken;
// Make the authenticate button invisile
accountsList.visible = false;
// Start to get the data
API.getStatus();
}
onAuthenticationError: {
console.log("Authentication failed, code " + error.code)
// accountsList.headerItem.text = "Error " + error.code
authenticateBtn.text = displayName + " Error " + error.code + " please do it again";
}
}
Button {
id: authenticateBtn
anchors.fill: parent
anchors.margins: units.gu(2)
text: i18n.tr("Authenticate %1").arg(model.displayName + " " + model.providerName)
onClicked: {
var params = {}
accts.authenticate(params)
}
}
}
}
Button {
id: createAccountBtn
anchors.horizontalCenter: parent.horizontalCenter
width: parent.width
height: units.gu(8)
text: i18n.tr("Request access")
onClicked: setup.exec()
}
ListModel {
id: modelWeibo
}
ListView {
id: weiboList
width: parent.width
height: parent.height
spacing: units.gu(1)
model: modelWeibo
delegate: Rectangle {
width: parent.width
height: units.gu(8)
color: "lightgrey"
BorderImage {
id: image
source: {return JSON.parse('' + JSON.stringify(user) + '').profile_image_url}
width: parent.height; height: parent.height
border.left: 5; border.top: 5
border.right: 5; border.bottom: 5
}
Column {
spacing: units.gu(1)
x: image.width + 10
width: parent.width - image.width - 20
height: parent.height
Text {
id: title
text: {return JSON.parse('' + JSON.stringify(user) + '').name }
}
Text {
id: subtitle
text: {return model.text }
}
}
}
}
}
}
AccountServiceModel {
id: accountsModel
// serviceType: ""
applicationId: "qml-weibo.ubuntu_qmlweibo"
}
Setup {
id: setup
providerId: "qml-weibo.ubuntu_plugin"
applicationId: "qml-weibo.ubuntu_qmlweibo"
onFinished: {
createAccountBtn.visible = false;
}
}
Component.onCompleted: {
if ( accountsModel.count == 0 ) {
// If there is no such an account, we need to create such one
setup.exec();
} else {
// hide the button since the account has already been created
createAccountBtn.visible = false
}
}
}
我们通过设计weiboapi.js文件来帮我们来得到微博的具体的内容:
// weibo
//home status
function weiboHomeStatus(token, page , observer)
{
var url = "https://api.weibo.com/2/statuses/home_timeline.json?access_token=" + token + "&page=" + page
console.log("home status start...")
console.log("url: " + url);
var doc = new XMLHttpRequest();
doc.onreadystatechange = function() {
if (doc.readyState == XMLHttpRequest.HEADERS_RECEIVED) {
console.log(" home status in progress...");
}
else if (doc.readyState == XMLHttpRequest.DONE)
{
if(doc.status != 200) {
console.log("!!!Network connection failed!")
observer.update("error", doc.status)
}
else {
console.log("-- home status succeeded !");
if(doc.responseText == null) {
observer.update("null", doc.status)
}
else {
// console.log("home status: done" + doc.responseText)
console.log("Some data received!")
var json = JSON.parse('' + doc.responseText+ '');
observer.update("fine", json);
}
}
}
}
doc.open("GET", url, true);
doc.setRequestHeader("Content-type", "application/json");
doc.send();
}
function getStatus() {
// We can get some data from the web and display them
console.log("Going to get some data from web")
function observer() {}
observer.prototype = {
update: function(status, result)
{
console.log("got updated!");
if(status != "error"){
if( result.error ) {
console.log("result.error: " + result.error);
}else {
console.log("got updated1!");
for ( var i = 0; i < result.statuses.length; i++) {
modelWeibo.append( result.statuses[i] )
}
}
}else{
console.log("Something is wrong!");
}
}
}
weiboHomeStatus(main.accesstoken, 1, new observer() );
}
整个应用的源码在地址
当所有的账号文件被成功创建后,我们可以在手机的如下目录看到所有的文件: