Last active
August 29, 2015 13:57
-
-
Save emil10001/9456564 to your computer and use it in GitHub Desktop.
These are notes for a presentation on building a GifCamera Glassware - http://goo.gl/vZrxSQ
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<activity | |
android:name=".GGMainActivity" | |
android:label="@string/app_name" > | |
<intent-filter> | |
<action android:name="android.intent.action.MAIN"/> | |
<category android:name="android.intent.category.LAUNCHER" /> | |
</intent-filter> | |
</activity> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<application | |
android:allowBackup="true" | |
android:icon="@drawable/ic_launcher" | |
android:label="@string/app_name" | |
android:theme="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen"> | |
<!-- ... --> | |
</application> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<activity | |
android:name=".GGMainActivity" | |
android:icon="@drawable/ic_launcher" | |
android:label="@string/app_name" | |
android:immersive="true" > | |
<intent-filter> | |
<action android:name="android.intent.action.MAIN"/> | |
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" /> | |
<category android:name="android.intent.category.LAUNCHER" /> | |
</intent-filter> | |
<meta-data | |
android:name="com.google.android.glass.VoiceTrigger" | |
android:resource="@xml/voice_launch" /> | |
</activity> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" | |
package="com.feigdev.gg_test" > | |
<uses-permission android:name="android.permission.CAMERA"/> | |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> | |
<uses-feature android:name="android.hardware.camera"/> | |
<uses-feature android:name="android.hardware.camera.autofocus"/> | |
<application | |
android:allowBackup="true" | |
android:icon="@drawable/ic_launcher" | |
android:label="@string/app_name" | |
android:theme="@android:style/Theme.Holo.Light.NoActionBar.Fullscreen"> | |
<activity | |
android:name=".GGMainActivity" | |
android:label="@string/app_name" | |
android:immersive="true"> | |
<intent-filter> | |
<action android:name="android.intent.action.MAIN"/> | |
<action android:name="com.google.android.glass.action.VOICE_TRIGGER" /> | |
<category android:name="android.intent.category.LAUNCHER" /> | |
</intent-filter> | |
<meta-data | |
android:name="com.google.android.glass.VoiceTrigger" | |
android:resource="@xml/voice_launch" /> | |
</activity> | |
</application> | |
</manifest> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
dependencies { | |
// requires library project https://github.com/emil10001/ReusableAndroidUtils | |
compile project(':ReusableAndroidUtils') | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
android { | |
compileSdkVersion "Google Inc.:Glass Development Kit Sneak Peek:15" | |
buildToolsVersion "19.0.1" | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?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="@android:color/black"> | |
<ImageView | |
android:id="@+id/cur_img" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent"/> | |
<ProgressBar | |
style="?android:attr/progressBarStyleLarge" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:id="@+id/progressBar" | |
android:layout_gravity="center"/> | |
</FrameLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context="com.feigdev.gg_runthrough.MainActivity$ImageGrabFrag"> | |
<SurfaceView | |
android:id="@+id/preview1" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
android:layout_alignParentBottom="true" | |
android:layout_alignParentLeft="true" /> | |
</RelativeLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GGMainActivity extends Activity implements GifFlowControl { | |
private static final String TAG = "GGMainActivity"; | |
static ArrayList<String> listOfFiles = new ArrayList<String>(); | |
static String gifFile; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main2); | |
} | |
@Override | |
public void onResume() { | |
super.onResume(); | |
getFragmentManager().beginTransaction() | |
.replace(R.id.container, new ImageGrabFrag()) | |
.commit(); | |
} | |
@Override | |
public void startBuild() { | |
getFragmentManager().beginTransaction() | |
.replace(R.id.container, new GifBuilderFrag()) | |
.commit(); | |
} | |
@Override | |
public void startDisplay() { | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Override | |
protected void onCreate(Bundle savedInstanceState) { | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main2); | |
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GifBuilderFrag extends Fragment { | |
private static final String TAG = "GifBuilderFrag"; | |
private GifFlowControl flowControl; | |
private ImageView curImg; | |
private ProgressBar progressBar; | |
private AsyncTask updater; | |
@Override | |
public void onAttach(Activity activity) { | |
super.onAttach(activity); | |
flowControl = (GifFlowControl) activity; | |
} | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, | |
Bundle savedInstanceState) { | |
Log.d(TAG, "onCreateView"); | |
View rootView = inflater.inflate(R.layout.builder, container, false); | |
return rootView; | |
} | |
@Override | |
public void onResume() { | |
super.onResume(); | |
new BackgroundGif().execute(); | |
} | |
private class BackgroundGif extends AsyncTask<Void, Bitmap, String> { | |
@Override | |
protected String doInBackground(Void... params) { | |
Log.d(TAG, "GlassPhotoDelay"); | |
String gifFile = SimpleFileUtils.getDir() + File.separator + System.currentTimeMillis() + ".gif"; | |
// http://stackoverflow.com/a/20277649/974800 | |
ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(); | |
for (String filename : MainActivity.listOfFiles) { | |
File f = new File(filename); | |
if (!f.exists()) | |
continue; | |
Bitmap b = ImageTools.generatePic(filename); | |
bitmaps.add(b); | |
publishProgress(b); | |
} | |
byte[] bytes = ImageTools.generateGIF(bitmaps); | |
SimpleFileUtils.write(gifFile, bytes); | |
String newGifFile = SimpleFileUtils.getSdDir() + File.separator | |
+ "DCIM" + File.separator + "Camera" + File.separator | |
+ System.currentTimeMillis() + ".gif"; | |
try { | |
SimpleFileUtils.copy(gifFile, newGifFile); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
for (String filename : MainActivity.listOfFiles) { | |
File f = new File(filename); | |
if (f.exists()) | |
f.delete(); | |
} | |
return gifFile; | |
} | |
@Override | |
protected void onPostExecute(String params) { | |
flowControl.startDisplay(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GifBuilderFrag extends Fragment { | |
private static final String TAG = "GifBuilderFrag"; | |
private GifFlowControl flowControl; | |
private ImageView curImg; | |
private ProgressBar progressBar; | |
private AsyncTask updater; | |
@Override | |
public void onAttach(Activity activity) { | |
super.onAttach(activity); | |
flowControl = (GifFlowControl) activity; | |
} | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, | |
Bundle savedInstanceState) { | |
Log.d(TAG, "onCreateView"); | |
View rootView = inflater.inflate(R.layout.builder2, container, false); | |
curImg = (ImageView) rootView.findViewById(R.id.cur_img); | |
progressBar = (ProgressBar) rootView.findViewById(R.id.progressBar); | |
return rootView; | |
} | |
@Override | |
public void onResume() { | |
super.onResume(); | |
new BackgroundGif().execute(); | |
updater = new ProgressUpdater().execute(); | |
} | |
@Override | |
public void onPause() { | |
updater.cancel(true); | |
super.onPause(); | |
} | |
private class ProgressUpdater extends AsyncTask<Void, Integer, Void> { | |
@Override | |
protected Void doInBackground(Void... params) { | |
int count = 0; | |
try { | |
while (true) { | |
publishProgress((count++ % 100)); | |
Thread.sleep(50); | |
} | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
protected void onProgressUpdate(Integer... progress) { | |
progressBar.setProgress(progress[0]); | |
} | |
} | |
private class BackgroundGif extends AsyncTask<Void, Bitmap, String> { | |
@Override | |
protected String doInBackground(Void... params) { | |
Log.d(TAG, "GlassPhotoDelay"); | |
String gifFile = SimpleFileUtils.getDir() + File.separator + System.currentTimeMillis() + ".gif"; | |
ArrayList<Bitmap> bitmaps = new ArrayList<Bitmap>(); | |
for (String filename : GGMainActivity.listOfFiles) { | |
File f = new File(filename); | |
if (!f.exists()) | |
continue; | |
Bitmap b = ImageTools.generatePic(filename); | |
bitmaps.add(b); | |
publishProgress(b); | |
} | |
byte[] bytes = ImageTools.generateGIF(bitmaps); | |
SimpleFileUtils.write(gifFile, bytes); | |
String newGifFile = SimpleFileUtils.getSdDir() + File.separator | |
+ "DCIM" + File.separator + "Camera" + File.separator | |
+ System.currentTimeMillis() + ".gif"; | |
try { | |
SimpleFileUtils.copy(gifFile, newGifFile); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
for (String filename : GGMainActivity.listOfFiles) { | |
File f = new File(filename); | |
if (f.exists()) | |
f.delete(); | |
} | |
return gifFile; | |
} | |
protected void onProgressUpdate(Bitmap... progress) { | |
curImg.setImageBitmap(progress[0]); | |
} | |
@Override | |
protected void onPostExecute(String params) { | |
Log.d(TAG, "creating card with params: " + params); | |
flowControl.startDisplay(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GifDisplayFrag extends Fragment { | |
private static final String TAG = "GifDisplayFrag"; | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, | |
Bundle savedInstanceState) { | |
View v = new GifWebView(getActivity(), GGMainActivity.gifFile, "480", "360"); | |
return v; | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GifDisplayFrag extends Fragment { | |
private static final String TAG = "GifDisplayFrag"; | |
public static final String GOOGLE_DRIVE = "com.google.android.apps.docs"; | |
public static final String GOOGLE_PLUS = "com.google.android.apps.plus"; | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, | |
Bundle savedInstanceState) { | |
View v = new GifWebView(getActivity(), GGMainActivity.gifFile, "480", "360"); | |
new DriveUpload().execute(); | |
return v; | |
} | |
private class DriveUpload extends AsyncTask<Void, Void, Void> { | |
@Override | |
protected Void doInBackground(Void... params) { | |
Log.d(TAG, "GlassPhotoDelay"); | |
try { | |
Thread.sleep(5000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
@Override | |
protected void onPostExecute(Void params) { | |
try { | |
// http://divingintoglass.blogspot.com/2014/01/how-to-upload-files-using-google-drive.html | |
Uri imageUri = Uri.fromFile(new File(GGMainActivity.gifFile)); | |
Intent shareIntent = ShareCompat.IntentBuilder.from(getActivity()) | |
.setText("#glassgif #throughglass") | |
.setType("image/gif") | |
.setStream(imageUri ) | |
.getIntent() | |
.setPackage(GOOGLE_DRIVE); | |
startActivity(shareIntent); | |
getActivity().finish(); | |
} catch (Exception ex) { | |
ex.printStackTrace(); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.feigdev.gg_test; | |
public interface GifFlowControl { | |
public void startBuild(); | |
public void startDisplay(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.feigdev.gg_test; | |
import android.app.Activity; | |
import android.app.Fragment; | |
import android.content.pm.PackageManager; | |
import android.hardware.Camera; | |
import android.os.Bundle; | |
import android.util.Log; | |
import android.view.*; | |
// requires library project https://github.com/emil10001/ReusableAndroidUtils | |
import com.feigdev.reusableandroidutils.graphics.PhotoCallback; | |
import com.feigdev.reusableandroidutils.graphics.PhotoHandler; | |
import com.google.android.glass.sample.camera.CameraPreview; | |
import java.io.IOException; | |
/** | |
* Created by ejf3 on 3/11/14. | |
*/ | |
public class ImageGrabFrag extends Fragment implements PhotoCallback { | |
private static final String TAG = "ImageGrabFrag"; | |
private Camera camera; | |
private CameraPreview cameraPreview; | |
private SurfaceView preview; | |
private SurfaceHolder holder; | |
private static boolean isAlive = false; | |
@Override | |
public void onAttach(Activity activity) { | |
super.onAttach(activity); | |
} | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, | |
Bundle savedInstanceState) { | |
View rootView = inflater.inflate(R.layout.fragment_main2, container, false); | |
preview = (SurfaceView) rootView.findViewById(R.id.preview1); | |
preview.getHolder().addCallback(mSurfaceHolderCallback); | |
return rootView; | |
} | |
@Override | |
public void onResume() { | |
Log.d(TAG, "onResume"); | |
super.onResume(); | |
isAlive = true; | |
} | |
@Override | |
public void onPause() { | |
Log.d(TAG, "onPause"); | |
isAlive = false; | |
if (camera != null) { | |
camera.stopPreview(); | |
camera.release(); | |
camera = null; | |
} | |
super.onPause(); | |
} | |
private void initCamera() { | |
Log.d(TAG, "initCamera"); | |
// do we have a camera? | |
if (!getActivity().getPackageManager() | |
.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { | |
Log.d(TAG, "No camera on this device"); | |
return; | |
} | |
camera = Camera.open(); | |
cameraPreview = new CameraPreview(getActivity()); | |
cameraPreview.setCamera(camera); | |
try { | |
camera.setPreviewDisplay(holder); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
camera.startPreview(); | |
} | |
private void takePicture() { | |
Log.d(TAG, "takePicture"); | |
if (!isAlive) | |
return; | |
camera.takePicture(null, null, | |
new PhotoHandler(this)); | |
} | |
@Override | |
public void pictureTaken(String filename){ | |
Log.d(TAG, "captured file " + filename); | |
getActivity().finish(); | |
} | |
private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() { | |
@Override | |
public void surfaceCreated(SurfaceHolder hldr) { | |
holder = hldr; | |
initCamera(); | |
} | |
@Override | |
public void surfaceDestroyed(SurfaceHolder holder) { | |
// Nothing to do here. | |
} | |
@Override | |
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { | |
// Nothing to do here. | |
} | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public void onResume() { | |
Log.d(TAG, "onResume"); | |
super.onResume(); | |
isAlive = true; | |
new GlassPhotoDelay().execute(); | |
} | |
private void initCamera() { | |
Log.d(TAG, "initCamera"); | |
// do we have a camera? | |
if (!getActivity().getPackageManager() | |
.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { | |
Log.d(TAG, "No camera on this device"); | |
return; | |
} | |
camera = Camera.open(); | |
camera.setDisplayOrientation(0); | |
/** | |
* The camera preview on Glass needs certain special parameters to run properly | |
* SO help: http://stackoverflow.com/a/19257078/974800 | |
*/ | |
Camera.Parameters params = camera.getParameters(); | |
params.setPreviewFpsRange(30000, 30000); | |
params.setJpegQuality(90); | |
// hard-coding is bad, but I'm a bit lazy | |
params.setPictureSize(640, 480); | |
params.setPreviewSize(640, 480); | |
camera.setParameters(params); | |
cameraPreview = new CameraPreview(getActivity()); | |
cameraPreview.setCamera(camera); | |
try { | |
camera.setPreviewDisplay(holder); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
camera.startPreview(); | |
// note we removed the call to takePicture() | |
} | |
/** | |
* There is currently a race condition where using a voice command to launch, | |
* then trying to grab the camera will fail, because the microphone is still locked | |
* <p/> | |
* http://stackoverflow.com/a/20154537/974800 | |
* https://code.google.com/p/google-glass-api/issues/detail?id=259 | |
*/ | |
private class GlassPhotoDelay extends AsyncTask<Void, Void, Void> { | |
@Override | |
protected Void doInBackground(Void... params) { | |
Log.d(TAG, "GlassPhotoDelay"); | |
try { | |
Thread.sleep(1000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
@Override | |
protected void onPostExecute(Void params) { | |
if (!isAlive) | |
return; | |
initCamera(); | |
takePicture(); | |
} | |
} | |
private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() { | |
@Override | |
public void surfaceCreated(SurfaceHolder hldr) { | |
holder = hldr; | |
// removed initCamera call | |
} | |
@Override | |
public void surfaceDestroyed(SurfaceHolder holder) { | |
// Nothing to do here. | |
} | |
@Override | |
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { | |
// Nothing to do here. | |
} | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.feigdev.gg_test; | |
import android.app.Activity; | |
import android.app.Fragment; | |
import android.content.pm.PackageManager; | |
import android.hardware.Camera; | |
import android.os.AsyncTask; | |
import android.os.Bundle; | |
import android.util.Log; | |
import android.view.*; | |
import com.feigdev.reusableandroidutils.graphics.PhotoCallback; | |
import com.feigdev.reusableandroidutils.graphics.PhotoHandler; | |
import com.google.android.glass.sample.camera.CameraPreview; | |
import java.io.IOException; | |
/** | |
* Created by ejf3 on 3/11/14. | |
*/ | |
public class ImageGrabFrag extends Fragment implements PhotoCallback { | |
private static final String TAG = "ImageGrabFrag"; | |
private Camera camera; | |
private CameraPreview cameraPreview; | |
private SurfaceView preview; | |
private SurfaceHolder holder; | |
private int count = 0; | |
private static boolean isAlive = false; | |
private GifFlowControl flowControl; | |
@Override | |
public void onAttach(Activity activity) { | |
super.onAttach(activity); | |
flowControl = (GifFlowControl)activity; | |
} | |
@Override | |
public View onCreateView(LayoutInflater inflater, ViewGroup container, | |
Bundle savedInstanceState) { | |
View rootView = inflater.inflate(R.layout.fragment_main2, container, false); | |
preview = (SurfaceView) rootView.findViewById(R.id.preview1); | |
preview.getHolder().addCallback(mSurfaceHolderCallback); | |
return rootView; | |
} | |
@Override | |
public void onResume() { | |
Log.d(TAG, "onResume"); | |
super.onResume(); | |
isAlive = true; | |
count = 0; | |
new GlassPhotoDelay().execute(); | |
} | |
@Override | |
public void onPause() { | |
Log.d(TAG, "onPause"); | |
isAlive = false; | |
if (camera != null) { | |
camera.stopPreview(); | |
camera.release(); | |
camera = null; | |
} | |
super.onPause(); | |
} | |
private void initCamera() { | |
Log.d(TAG, "initCamera"); | |
// do we have a camera? | |
if (!getActivity().getPackageManager() | |
.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { | |
Log.d(TAG, "No camera on this device"); | |
return; | |
} | |
camera = Camera.open(); | |
camera.setDisplayOrientation(0); | |
/** | |
* The camera preview on Glass needs certain special parameters to run properly | |
* SO help: http://stackoverflow.com/a/19257078/974800 | |
*/ | |
Camera.Parameters params = camera.getParameters(); | |
params.setPreviewFpsRange(30000, 30000); | |
params.setJpegQuality(90); | |
// hard-coding is bad, but I'm a bit lazy | |
params.setPictureSize(640, 480); | |
params.setPreviewSize(640, 480); | |
camera.setParameters(params); | |
cameraPreview = new CameraPreview(getActivity()); | |
cameraPreview.setCamera(camera); | |
try { | |
camera.setPreviewDisplay(holder); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
camera.startPreview(); | |
} | |
private void takePicture() { | |
Log.d(TAG, "takePicture"); | |
count++; | |
if (!isAlive) | |
return; | |
camera.takePicture(null, null, | |
new PhotoHandler(this)); | |
} | |
@Override | |
public void pictureTaken(String filename){ | |
GGMainActivity.listOfFiles.add(filename); | |
if (count >= 5){ | |
Log.d(TAG, "taken 5"); | |
flowControl.startBuild(); | |
return; | |
} | |
if (!isAlive) | |
return; | |
camera.startPreview(); | |
takePicture(); | |
} | |
/** | |
* There is currently a race condition where using a voice command to launch, | |
* then trying to grab the camera will fail, because the microphone is still locked | |
* <p/> | |
* http://stackoverflow.com/a/20154537/974800 | |
* https://code.google.com/p/google-glass-api/issues/detail?id=259 | |
*/ | |
private class GlassPhotoDelay extends AsyncTask<Void, Void, Void> { | |
@Override | |
protected Void doInBackground(Void... params) { | |
Log.d(TAG, "GlassPhotoDelay"); | |
try { | |
Thread.sleep(1000); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
@Override | |
protected void onPostExecute(Void params) { | |
if (!isAlive) | |
return; | |
initCamera(); | |
takePicture(); | |
} | |
} | |
private final SurfaceHolder.Callback mSurfaceHolderCallback = new SurfaceHolder.Callback() { | |
@Override | |
public void surfaceCreated(SurfaceHolder hldr) { | |
holder = hldr; | |
} | |
@Override | |
public void surfaceDestroyed(SurfaceHolder holder) { | |
// Nothing to do here. | |
} | |
@Override | |
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { | |
// Nothing to do here. | |
} | |
}; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private void initCamera() { | |
Log.d(TAG, "initCamera"); | |
// do we have a camera? | |
if (!getActivity().getPackageManager() | |
.hasSystemFeature(PackageManager.FEATURE_CAMERA)) { | |
Log.d(TAG, "No camera on this device"); | |
return; | |
} | |
camera = Camera.open(); | |
camera.setDisplayOrientation(0); | |
/** | |
* The camera preview on Glass needs certain special parameters to run properly | |
* SO help: http://stackoverflow.com/a/19257078/974800 | |
*/ | |
Camera.Parameters params = camera.getParameters(); | |
params.setPreviewFpsRange(30000, 30000); | |
params.setJpegQuality(90); | |
// hard-coding is bad, but I'm a bit lazy | |
params.setPictureSize(640, 480); | |
params.setPreviewSize(640, 480); | |
camera.setParameters(params); | |
cameraPreview = new CameraPreview(getActivity()); | |
cameraPreview.setCamera(camera); | |
try { | |
camera.setPreviewDisplay(holder); | |
} catch (IOException e) { | |
e.printStackTrace(); | |
} | |
camera.startPreview(); | |
takePicture(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// in BackgroundGif subclass | |
protected void onPostExecute(String params) { | |
Log.d(TAG, "creating card with params: " + params); | |
if (PlatformUtils.isGlass()) { | |
if (null == params) | |
return; | |
// http://stackoverflow.com/a/21843601/974800 | |
Uri imgUri = Uri.fromFile(new File(params)); | |
GGMainActivity.gifFile = params; | |
// create card | |
Card gifCard = new Card(getActivity()); | |
if (null != imgUri) { | |
gifCard.addImage(imgUri); | |
gifCard.setImageLayout(Card.ImageLayout.FULL); | |
gifCard.setText(MainActivity.gifFile); | |
} else | |
gifCard.setText("failed to get image uri"); | |
// menus currently not supported | |
// https://code.google.com/p/google-glass-api/issues/detail?id=320 | |
TimelineManager tlm = TimelineManager.from(getActivity()); | |
tlm.insert(gifCard); | |
Log.d(TAG, "inserted into timeline!"); | |
} | |
flowControl.startDisplay(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
static ArrayList<String> listOfFiles = new ArrayList<String>(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private GifFlowControl flowControl; | |
@Override | |
public void onAttach(Activity activity) { | |
super.onAttach(activity); | |
flowControl = (GifFlowControl)activity; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Override | |
public void pictureTaken(String filename){ | |
GGMainActivity.listOfFiles.add(filename); | |
if (count >= 5){ | |
Log.d(TAG, "taken 5"); | |
// use the interface to do a fragment transaction in the activity | |
flowControl.startBuild(); | |
return; | |
} | |
if (!isAlive) | |
return; | |
camera.startPreview(); | |
takePicture(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
private static int count = 0; | |
//... | |
@Override | |
public void onResume() { | |
count = 0; | |
//... | |
} | |
private void takePicture() { | |
Log.d(TAG, "takePicture"); | |
count++; | |
if (!isAlive) | |
return; | |
camera.takePicture(null, null, | |
new PhotoHandler(this)); | |
} | |
@Override | |
public void pictureTaken(String filename){ | |
GGMainActivity.listOfFiles.add(filename); | |
if (count >= 5){ | |
count = 0; | |
Log.d(TAG, "taken 5"); | |
getActivity().finish(); | |
return; | |
} | |
if (!isAlive) | |
return; | |
camera.startPreview(); | |
takePicture(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@Override | |
public void startDisplay() { | |
// https://www.grokkingandroid.com/adding-files-to-androids-media-library-using-the-mediascanner/ | |
try { | |
Intent intent = | |
new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); | |
intent.setData(Uri.fromFile(new File(gifFile))); | |
sendBroadcast(intent); | |
} catch (Exception e) { | |
e.printStackTrace(); | |
} | |
getFragmentManager().beginTransaction() | |
.replace(R.id.container, new GifDisplayFrag()) | |
.commit(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<string name="voice_launch">launch the app</string> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0" encoding="utf-8"?> | |
<!-- res/xml/voice_launch.xml --> | |
<trigger keyword="@string/voice_launch"> | |
</trigger> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment