为什么accountsservice总是返回一个空的用户列表?

时间:2017-06-19 10:10:18

标签: linux vala accountsservice

我试图获取Vala中的系统用户列表,但我得到的只是一个空列表。由于Vala文档非常简单,我不知道如何解决这个问题。这就是我正在尝试的:

mInterstitialAd = new InterstitialAd(this);
mInterstitialAd.setAdUnitId("ca-app-pub-3940256099942544/1033173712");
mInterstitialAd.loadAd(new AdRequest.Builder().build());
handler = new Handler();

final Runnable r = new Runnable() {
    public void run() {
        if (mInterstitialAd.isLoaded()) {
            mInterstitialAd.show();
        }
        handler.postDelayed(this, 1000);
    }
};
handler.postDelayed(r, 1000);

1 个答案:

答案 0 :(得分:2)

看起来好像UserManager在创建时没有可用的数据。数据仅在is_loaded属性为真时可用。

在GLib中,当属性发生变化时,可以发出notify信号。因此,我们将在以下工作示例中利用它:

int main () {
    var loop = new EventLoop ();
    var manager = new UserManager (loop);
    if (!manager.is_running) {
        print ("AccountsService is not running\n");
        return 1;
    }
    loop.run ();
    return 0;
}

class UserManager {

    private Act.UserManager manager;
    private EventLoop loop;

    public bool is_running {
        get { return !manager.no_service (); }
    }

    public UserManager (EventLoop event_loop) {
        loop = event_loop;
        manager = Act.UserManager.get_default ();
        manager.notify["is-loaded"].connect( this.loaded );
    }

    void loaded (ParamSpec property) {
        print (@"Property \"$(property.name)\" has changed\n");
        this.print_users ();
        this.loop.quit ();
    }

    void print_users () {
        if (!manager.is_loaded) { return; }
        print ("%-20s | %-20s\n", "User name", "Logged In Time");
        foreach (var user in manager.list_users ()) {
            print ("%-20s | %-20s\n",
                   user.user_name,
                   new DateTime.from_unix_local(user.login_time).to_string()
                   );
            }
    }
}

class EventLoop {

    private MainLoop loop;

    public EventLoop () {
        loop = new MainLoop ();
    }

    public void run() {
        this.loop.run ();
    }

    public void quit() {
        Idle.add (()=> { 
            this.loop.quit ();
            return Source.REMOVE;
        });
    }
}

该示例创建一个UserManager类来包装AccountsService UserManager。假设用户管理器在Act.UserManager.get_default ()首次返回时从不加载,因此作为构造函数的一部分,当is_loaded属性更改时,将设置回调。这是一行:

manager.notify["is-loaded"].connect( this.loaded );

manager有任何属性更改时发出的通知信号。该示例使用信号详细信息仅在is-loaded属性更改时触发。出于某种原因,它在名称中使用破折号,而不是下划线。我无法找到有关原因的文档。使用notify信号,回调可以将ParamSpec作为参数。这用于查找已更改的属性的详细信息,但在示例中不再需要,因为使用了"is-loaded"信号详细信息。

该示例还创建了一个EventLoop类,它充当了GLib MainLoop的包装器。 UserManagerEventLoop作为依赖项,因此事件循环可以退出并完成程序。

另一种方法是直接从Vala使用org.freedesktop.Accounts D-Bus服务。