Skip to content

Instantly share code, notes, and snippets.

@navarr
Last active December 31, 2015 02:49
Show Gist options
  • Save navarr/7923282 to your computer and use it in GitHub Desktop.
Save navarr/7923282 to your computer and use it in GitHub Desktop.
Meow.apk
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="me.navarr.app.meow"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="15"
android:targetSdkVersion="15" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_lap"
android:label="@string/app_name" >
<activity
android:name="me.navarr.app.meow.MenuActivity"
android:label="@string/app_name"
android:theme="@style/MenuTheme"
android:enabled="true" >
</activity>
<service
android:name="me.navarr.app.meow.MeowService"
android:icon="@drawable/ic_lap"
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>
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.6.+'
}
}
apply plugin: 'android'
repositories {
mavenCentral()
}
android {
compileSdkVersion "Google Inc.:Glass Development Kit Sneak Peek:15"
buildToolsVersion "18.1.1"
defaultConfig {
minSdkVersion 15
targetSdkVersion 15
}
buildTypes {
release {
runProguard true
proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
}
}
productFlavors {
defaultFlavor {
proguardFile 'proguard-rules.txt'
}
}
}
dependencies {
}
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/black" >
<TextView
android:id="@+id/seconds_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:layout_marginTop="-10px"
android:text="@string/meow"
android:textSize="140sp"
android:gravity="center" />
</FrameLayout>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/stop"
android:title="@string/stop"
android:icon="@drawable/ic_stop" />
</menu>
package me.navarr.app.meow;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
/**
* Activity showing the options menu.
*/
public class MenuActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
@Override
public void onResume() {
super.onResume();
openOptionsMenu();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection.
switch (item.getItemId()) {
case R.id.stop:
stopService(new Intent(this, MeowService.class));
return true;
default:
return super.onOptionsItemSelected(item);
}
}
@Override
public void onOptionsMenuClosed(Menu menu) {
// Nothing else to do, closing the Activity.
finish();
}
}
package me.navarr.app.meow;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.util.Log;
import android.widget.RemoteViews;
import com.google.android.glass.timeline.LiveCard;
import com.google.android.glass.timeline.TimelineManager;
public class MeowService extends Service {
private static final String TAG = "MeowService";
private static final String LIVE_CARD_ID = "meow_card";
private TimelineManager mTimelineManager;
private LiveCard mLiveCard;
@Override
public void onCreate() {
super.onCreate();
/**
* TimelineManager is the object to, well, manage the Timeline.
* If you're unfamiliar with the terminology, the timeline is the list
* of cards that appear on Glass. The cards to the right of the homescreen
* are cards from the past (notifications, emails, texts). Cards to the left of the
* homescreen are cards happening right now or in the future (LiveCards and Google Now)
*/
mTimelineManager = TimelineManager.from(this);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
/**
* For obvious reasons, you will probably only ever want ONE version of your
* LiveCard running
*/
if (mLiveCard == null) {
Log.d(TAG, "Publishing LiveCard");
mLiveCard = mTimelineManager.getLiveCard(LIVE_CARD_ID);
/**
* LiveCard.setViews is how we give it the low-frequency layout. For higher
* frequency rendering (real-time rendering) you will need to use
* LiveCard.enableDirectRendering and attach your rendering to LiveCard.getSurfaceHolder
*/
mLiveCard.setViews(new RemoteViews(this.getPackageName(), R.layout.card_meow));
/**
* Setting the LiveCard as non-silent means that we will be taken to the Timeline as
* soon as the card is published, rather than it just appearing in the background.
*
* If you are not doing anything else in the foreground, you definitely want to do this.
*/
mLiveCard.setNonSilent(true);
/**
* An action intent IS REQUIRED. After all, the user should have a way to stop your app
* or interact with it if there are other actions. Here we set the action as a
* PendingIntent to call up the MenuActivity.
*/
Intent menuIntent = new Intent(this, MenuActivity.class);
mLiveCard.setAction(PendingIntent.getActivity(this, 0, menuIntent, 0));
/**
* This immediately publishes the live card, and with setNonSilent as true, we're
* immediately taken to it.
*/
mLiveCard.publish();
Log.d(TAG, "Done publishing LiveCard");
}
return START_STICKY;
}
@Override
public void onDestroy() {
if (mLiveCard != null && mLiveCard.isPublished()) {
// I think you can figure out what we're doing here.
Log.d(TAG, "Unpublishing LiveCard");
mLiveCard.unpublish();
mLiveCard = null;
}
super.onDestroy();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">Meow</string>
<string name="stop">Stop</string>
<string name="open">Meow</string>
<string name="meow">ニャン</string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2013 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<trigger keyword="@string/open" />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment