实现谷歌玻璃低频卡直播 [英] Implement low-frequency live card in google glass

查看:207
本文介绍了实现谷歌玻璃低频卡直播的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试使用在 GDK提供的指令,以实现低频直播卡导游的。
我有我想要呈现布局和LiveCard服务类(扩展服务)。我也有菜单:活动处理菜单回调,使得菜单透明的,并且在LiveCard服务使用的setAction()为卡的动作提供的PendingIntent。

我加载应用到玻璃时,也得到了成功的消息,但它并不在我的玻璃出现。
我不知道还有什么缺失。

  [2014年4月22日0点45分01秒 -  MyApp的]安装MyApp.apk ...
[2014年4月22日0时45分04秒 - MyApp的]成功!
[2014年4月22日0时45分04秒 - MyApp的] /MyApp/bin/MyApp.apk安装设备
[2014年4月22日0时45分04秒 - MyApp的]完成!

下面是我的LiveCardService:

 公共类LiveCardService延伸服务{
私人的ArrayList< FeedItem> feedItems =新的ArrayList< FeedItem>();
//私人FeedAdapter feedAdapter = NULL;// NYC:40.758895,-73.985131
私人双重纬度= 0;
私人双人经度= 0;私人的LocationManager mlocManager;
私人LocationListener的mlocListener;
/ ****** /私有静态最后弦乐LIVE_CARD_TAG =LiveCardDemo;//私人TimelineManager mTimelineManager;
私人LiveCard mLiveCard;
私人RemoteViews mLiveCardView;私人诠释homeScore,awayScore;
私人随机mPointsGenerator;私人最终处理程序mHandler =新的处理程序();
私人最终UpdateLiveCardRunnable mUpdateLiveCardRunnable =
    新UpdateLiveCardRunnable();
私有静态最后长DELAY_MILLIS = 30000;@覆盖
公共无效的onCreate(){
    super.onCreate();
    // mTimelineManager = TimelineManager.from(本);
    mPointsGenerator =新的随机();
}@覆盖
公众诠释onStartCommand(意向意图,诠释标志诠释startId){    如果(mLiveCard == NULL){        //获取活卡的实例
       // mLiveCard = mTimelineManager.createLiveCard(LIVE_CARD_TAG);
        mLiveCard =新LiveCard(这一点,LIVE_CARD_TAG);        //充气布局到一个远程视图
        mLiveCardView =新RemoteViews(getPackageName()
            R.layout.score);        mLiveCard.setViews(mLiveCardView); //!      //设置初始值RemoteViews
        homeScore = 0;
        awayScore = 0;
        / ** /
        mLiveCardView.setTextViewText(R.id.homeTeamNameTextView,
                /*getString(R.id.home_team)*/\"HOME TEAM);
        mLiveCardView.setTextViewText(R.id.awayTeamNameTextView,
                /*getString(R.id.away_team)*/\"AWAY TEAM NAME);
        mLiveCardView.setTextViewText(R.id.footer_text,
                /*getString(R.id.game_quarter)*/\"FOOTER_TEXT);
        / ** /        //设置现场卡的行动,意图待定
        //显示一个菜单时拍了拍
        意图menuIntent =新意图(这一点,MenuActivity.class);
        menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
            Intent.FLAG_ACTIVITY_CLEAR_TASK);
        mLiveCard.setAction(PendingIntent.getActivity(
            此,0,menuIntent,0));        //发布现场卡
        mLiveCard.publish(PublishMode.REVEAL);        //队列中的更新文本可运行
        mHandler.post(mUpdateLiveCardRunnable);
    }
    返回START_STICKY;
}@覆盖
公共无效的onDestroy(){
    如果(mLiveCard =空&放大器;!&放大器; mLiveCard.isPublished()){
      //从排队更可运行的工作停止处理程序
        mUpdateLiveCardRunnable.setStop(真);        mLiveCard.unpublish();
        mLiveCard = NULL;
    }
    super.onDestroy();
}/ **
 *可运行的实时更新卡上的内容
 * /
私有类UpdateLiveCardRunnable实现Runnable {    私人布尔mIsStopped = FALSE;    / *
     *更新与假分数作为示范每30秒存储卡。
     *您也可能想显示有用您的生活卡什么的。
     *
     *如果您执行长时间运行的任务中获得的数据更新
     *活卡(例如,使得网络电话),这样做的另一个线程或
     * AsyncTask的。
     * /
    公共无效的run(){
        如果(!isStopped()){
          //生成假货点。
            homeScore + = mPointsGenerator.nextInt(3);
            awayScore + = mPointsGenerator.nextInt(3);            //更新与新的成绩远程视图。
            mLiveCardView.setTextViewText(R.id.home_score_text_view,
                将String.valueOf(homeScore));
            mLiveCardView.setTextViewText(R.id.away_score_text_view,
                将String.valueOf(awayScore));            //总是调用setViews()来更新实时卡的RemoteViews。
            mLiveCard.setViews(mLiveCardView);            //队列中的另一个得分更新在30秒内。
            mHandler.postDelayed(mUpdateLiveCardRunnable,DELAY_MILLIS);
        }
    }    公共布尔isStopped(){
        返回mIsStopped;
    }    公共无效setStop(布尔isStopped){
        this.mIsStopped = isStopped;
    }
}@覆盖
公众的IBinder onBind(意向意图){
  / *
   *如果您需要设置进程间通信
   *(活动服务,例如),返回粘合剂对象
   *,以使客户机可以接收和在此服务修改数据。
   *
   *一个典型用途在于给粘合剂对象的菜单访问活动
   *如果试图改变这种状况是由活卡管理的设置
   *服务。这样的菜单活性不需要任何
   *这些功能,所以这只是返回null。
   * /
    返回null;
}

和这里是我的清单文件

 <?XML版本=1.0编码=UTF-8&GT?;
<清单的xmlns:机器人=htt​​p://schemas.android.com/apk/res/android
包=com.coeverywhere.google_glass
安卓版code =5
机器人:=的versionName1.0><用途-SDK
    安卓的minSdkVersion =15
    机器人:targetSdkVersion =15/><使用许可权的android:NAME =android.permission.INTERNET对/>
<使用许可权的android:NAME =android.permission.ACCESS_FINE_LOCATION/>
<使用许可权的android:NAME =android.permission.ACCESS_COARSE_LOCATION/>
<使用许可权的android:NAME =com.google.android.glass.permission.DEVELOPMENT/><应用
    机器人:allowBackup =真
    机器人:图标=@绘制/ mylogo
    机器人:标签=@字符串/ APP_NAME>
    <活动
        机器人:名字=com.myapp.google_glass.MenuActivity
        机器人:主题=@风格/ MenuTheme
        机器人:启用=真
        >
    < /活性GT;    < - 机器人:图标=@绘制/ ic_lap - >
    <服务
        机器人:名字=com.myapp.google_glass.LiveCardService
        机器人:标签=@字符串/ APP_NAME
        机器人:启用=真
        机器人:出口=真正的>
        &所述;意图滤光器>
            <作用机器人:名字=com.google.android.glass.action.VOICE_TRIGGER/>
        &所述; /意图滤光器>
        &所述;元数据
            机器人:名字=com.google.android.glass.VoiceTrigger
            机器人:资源=@ XML / voice_trigger_start/>
    < /服务>< /用途>< /清单>

这是我的voice_trigger_start.xml。我将它们放在RES / XML

 <?XML版本=1.0编码=UTF-8&GT?;
<触发命令=篮球/>


解决方案

下面是原来的答案,因为我已经做了一个参考项目,是以谷歌文档和使用秒表项目作为参考更新它XE16。检查code和提交历史学会了很多:

https://github.com/mscheel/GoogleGlass-XE16-LowFrequencyLiveCardBasketballScore

一种方法是申报语音触发启动服务/ livecard。

这是这个模式的解释中提到:

https://developers.google.com/glass/develop/patterns/正在进行的任务

的技术是这里描述

https://developers.google.com/glass/develop/gdk/starting-glassware#unlisted_commands

我与你code测试了它和它的工作,如果清单的这些项目(修改当然是你的包名)......这第一个进入该应用程序标签中:

 <服务
        机器人:名字=com.example.lowfrequencylivecardexample.LiveCardService
        机器人:启用=真
        机器人:出口=真
        机器人:标签=@字符串/ APP_NAME>
        &所述;意图滤光器>
            <作用机器人:名字=com.google.android.glass.action.VOICE_TRIGGER/>
        &所述; /意图滤光器>
        &所述;元数据
            机器人:名字=com.google.android.glass.VoiceTrigger
            机器人:资源=@ XML / voice_trigger/>
    < /服务>

您还需要:

 <使用许可权的android:NAME =com.google.android.glass.permission.DEVELOPMENT/>

您还需要这个文件...... RES / XML / voice_trigger.xml:

 <?XML版本=1.0编码=UTF-8&GT?;
<触发关键字=篮球/>

我发现定时器项目将在想出这个有用,这里是它的清单:

https://github.com/googleglass/gdk-timer-sample/blob/master/AndroidManifest.xml

您也可以选择让主队凯尔特人和客队湖人。 拉里传奇永远!

I try to implement low-frequency Live Card using the instruction provided in the GDK guides. I have a layout that I want to render and the LiveCard service class (that extends Service). I also have the Menu: activity to handle menu callbacks, making the menu transparent, and provide a PendingIntent for the card's action using setAction() in the LiveCard service.

I also got a successful message when loading the app into Glass but it doesn't show up in my Glass. I'm not sure what else is missing.

[2014-04-22 00:45:01 - MyApp] Installing MyApp.apk...
[2014-04-22 00:45:04 - MyApp] Success!
[2014-04-22 00:45:04 - MyApp] /MyApp/bin/MyApp.apk installed on     device
[2014-04-22 00:45:04 - MyApp] Done!

Below is my LiveCardService:

public class LiveCardService extends Service {
private ArrayList<FeedItem> feedItems = new ArrayList<FeedItem>();
//private FeedAdapter feedAdapter = null;

// NYC: 40.758895, -73.985131
private double latitude = 0;
private double longitude = 0;

private LocationManager mlocManager;
private LocationListener mlocListener;
/******/

private static final String LIVE_CARD_TAG = "LiveCardDemo";

//private TimelineManager mTimelineManager;
private LiveCard mLiveCard;
private RemoteViews mLiveCardView;

private int homeScore, awayScore;
private Random mPointsGenerator;

private final Handler mHandler = new Handler();
private final UpdateLiveCardRunnable mUpdateLiveCardRunnable =
    new UpdateLiveCardRunnable();
private static final long DELAY_MILLIS = 30000;

@Override
public void onCreate() {
    super.onCreate();
    //mTimelineManager = TimelineManager.from(this);
    mPointsGenerator = new Random();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {

    if (mLiveCard == null) {

        // Get an instance of a live card
       // mLiveCard = mTimelineManager.createLiveCard(LIVE_CARD_TAG);
        mLiveCard = new LiveCard(this, LIVE_CARD_TAG);

        // Inflate a layout into a remote view
        mLiveCardView = new RemoteViews(getPackageName(),
            R.layout.score);

        mLiveCard.setViews(mLiveCardView); // !!!

      // Set up initial RemoteViews values
        homeScore = 0;
        awayScore = 0;
        /**/
        mLiveCardView.setTextViewText(R.id.homeTeamNameTextView,
                /*getString(R.id.home_team)*/"HOME TEAM");
        mLiveCardView.setTextViewText(R.id.awayTeamNameTextView,
                /*getString(R.id.away_team)*/"AWAY TEAM NAME");
        mLiveCardView.setTextViewText(R.id.footer_text,
                /*getString(R.id.game_quarter)*/"FOOTER_TEXT");
        /**/

        // Set up the live card's action with a pending intent
        // to show a menu when tapped
        Intent menuIntent = new Intent(this, MenuActivity.class);
        menuIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
            Intent.FLAG_ACTIVITY_CLEAR_TASK);
        mLiveCard.setAction(PendingIntent.getActivity(
            this, 0, menuIntent, 0));

        // Publish the live card
        mLiveCard.publish(PublishMode.REVEAL);

        // Queue the update text runnable
        mHandler.post(mUpdateLiveCardRunnable);
    }
    return START_STICKY;
}

@Override
public void onDestroy() {
    if (mLiveCard != null && mLiveCard.isPublished()) {
      //Stop the handler from queuing more Runnable jobs
        mUpdateLiveCardRunnable.setStop(true);

        mLiveCard.unpublish();
        mLiveCard = null;
    }
    super.onDestroy();
}

/**
 * Runnable that updates live card contents
 */
private class UpdateLiveCardRunnable implements Runnable{

    private boolean mIsStopped = false;

    /*
     * Updates the card with a fake score every 30 seconds as a demonstration.
     * You also probably want to display something useful in your live card.
     *
     * If you are executing a long running task to get data to update a
     * live card(e.g, making a web call), do this in another thread or
     * AsyncTask.
     */
    public void run(){
        if(!isStopped()){
          // Generate fake points.
            homeScore += mPointsGenerator.nextInt(3);
            awayScore += mPointsGenerator.nextInt(3);

            // Update the remote view with the new scores.
            mLiveCardView.setTextViewText(R.id.home_score_text_view,
                String.valueOf(homeScore));
            mLiveCardView.setTextViewText(R.id.away_score_text_view,
                String.valueOf(awayScore));

            // Always call setViews() to update the live card's RemoteViews.
            mLiveCard.setViews(mLiveCardView);

            // Queue another score update in 30 seconds.
            mHandler.postDelayed(mUpdateLiveCardRunnable, DELAY_MILLIS);
        }
    }

    public boolean isStopped() {
        return mIsStopped;
    }

    public void setStop(boolean isStopped) {
        this.mIsStopped = isStopped;
    }
}

@Override
public IBinder onBind(Intent intent) {
  /*
   *  If you need to set up interprocess communication
   * (activity to a service, for instance), return a binder object
   * so that the client can receive and modify data in this service.
   *
   * A typical use is to give a menu activity access to a binder object
   * if it is trying to change a setting that is managed by the live card
   * service. The menu activity in this sample does not require any
   * of these capabilities, so this just returns null.
   */
    return null;
}

and here is my Manifest file

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.coeverywhere.google_glass"
android:versionCode="5"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="15"
    android:targetSdkVersion="15" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />

<application
    android:allowBackup="true"
    android:icon="@drawable/mylogo"
    android:label="@string/app_name">
    <activity
        android:name="com.myapp.google_glass.MenuActivity"
        android:theme="@style/MenuTheme"
        android:enabled="true"
        >
    </activity>

    <!--  android:icon="@drawable/ic_lap" -->
    <service
        android:name="com.myapp.google_glass.LiveCardService"    
        android:label="@string/app_name"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
        </intent-filter>
        <meta-data
            android:name="com.google.android.glass.VoiceTrigger"
            android:resource="@xml/voice_trigger_start" />
    </service>

</application>

</manifest>

and here's my voice_trigger_start.xml. I put them under res/xml

<?xml version="1.0" encoding="utf-8"?>
<trigger command = "basketball" />

解决方案

Below is original answer, I have since made a reference project that takes the Google documentation and updates it for XE16 using the StopWatch project as a reference. Check the code and commit history to learn a lot more:

https://github.com/mscheel/GoogleGlass-XE16-LowFrequencyLiveCardBasketballScore

One way is to declare a voice trigger to start the service/livecard.

This is mentioned in this pattern explanation:

https://developers.google.com/glass/develop/patterns/ongoing-task

The technique is described here:

https://developers.google.com/glass/develop/gdk/starting-glassware#unlisted_commands

I tested it out with your code and it worked if the manifest has these items (modify for your package name of course) ... this first one goes inside the application tag:

        <service
        android:name="com.example.lowfrequencylivecardexample.LiveCardService"
        android:enabled="true"
        android:exported="true"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="com.google.android.glass.action.VOICE_TRIGGER" />
        </intent-filter>
        <meta-data
            android:name="com.google.android.glass.VoiceTrigger"
            android:resource="@xml/voice_trigger" />
    </service>

You also need:

    <uses-permission android:name="com.google.android.glass.permission.DEVELOPMENT" />

You will also need this file ... res/xml/voice_trigger.xml:

<?xml version="1.0" encoding="utf-8"?>
<trigger keyword="basketball" />

I found the Timer project to be helpful in coming up with this, here is its manifest:

https://github.com/googleglass/gdk-timer-sample/blob/master/AndroidManifest.xml

Optionally you can make the home team the Celtics and the away team the Lakers. Larry Legend forever!

这篇关于实现谷歌玻璃低频卡直播的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆