package melaniezhao.excitementdocumentation;
import android.app.Activity;
import android.content.Intent;
import android.os.Handler;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.TextView;
import com.twitter.sdk.android.Twitter;
import com.twitter.sdk.android.core.TwitterAuthConfig;
import io.fabric.sdk.android.Fabric;
import com.twitter.sdk.android.core.Callback;
import com.twitter.sdk.android.core.Result;
import com.twitter.sdk.android.core.TwitterException;
import com.twitter.sdk.android.core.TwitterSession;
import com.twitter.sdk.android.core.identity.TwitterLoginButton;
public class MobileMainActivity extends Activity {
// Note: Your consumer key and secret should be obfuscated in your source code before shipping.
private static final String TWITTER_KEY = "nFJsTaEXJDBtt1pT2NvOMQxey";
private static final String TWITTER_SECRET = "0XSCETadrqpK4u86Fs6Bn2lrh3gciR3sTA7toGggjdInDSnyBG";
private TwitterLoginButton loginButton;
private Handler mHandler = new Handler();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
TwitterAuthConfig authConfig = new TwitterAuthConfig(TWITTER_KEY, TWITTER_SECRET);
Fabric.with(this, new Twitter(authConfig));
setContentView(R.layout.activity_mobile_main);
loginButton = (TwitterLoginButton) findViewById(R.id.login_button);
loginButton.setCallback(new Callback<TwitterSession>() {
@Override
public void success(Result<TwitterSession> result) {
TextView v = (TextView) findViewById(R.id.textView2);
v.setText(getString(R.string.done));
loginButton.setVisibility(View.GONE);
mHandler.postDelayed(new Runnable() {
public void run() {
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}, 2000);
}
@Override
public void failure(TwitterException exception) {
TextView v = (TextView) findViewById(R.id.textView2);
v.setText(getString(R.string.try_again));
}
});
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Pass the activity result to the login button.
loginButton.onActivityResult(requestCode, resultCode, data);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_mobile_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
MobileSubmitActivity.java
JavagetOutputMediaFile and getOutputMediaFileUri functions are from Android Developers (http://developer.android.com/index.html).
package melaniezhao.excitementdocumentation;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ImageView;
import com.twitter.sdk.android.core.models.Tweet;
import com.twitter.sdk.android.tweetcomposer.TweetComposer;
import com.twitter.sdk.android.tweetui.SearchTimeline;
import com.twitter.sdk.android.tweetui.TweetTimelineListAdapter;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Date;
import io.fabric.sdk.android.Fabric;
public class MobileSubmitActivity extends Activity {
public static final int CAMERA_REQUEST = 10;
public static final int MEDIA_TYPE_IMAGE = 1;
public static final int MEDIA_TYPE_VIDEO = 2;
public static final int notificationId = 1;
private ImageView imageView;
private Uri fileUri;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
fileUri = getOutputMediaFileUri(MEDIA_TYPE_IMAGE);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri);
startActivityForResult(cameraIntent, CAMERA_REQUEST);
setContentView(R.layout.activity_mobile_submit);
imageView = (ImageView) findViewById(R.id.imageContainer);
imageView.setImageResource(R.drawable.good);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (requestCode == CAMERA_REQUEST) {
Fabric.with(this, new TweetComposer());
TweetComposer.Builder builder = new TweetComposer.Builder(this)
.text(getString(R.string.text_field))
.image(fileUri);
builder.show();
// final SearchTimeline searchTimeline = new SearchTimeline.Builder().query("#cs160excited").build();
// final TweetTimelineListAdapter adapter = new TweetTimelineListAdapter(this, searchTimeline);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.cat)
.setContentTitle("WOW")
.setContentText("Someone else was excited about this!");
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, notificationBuilder.build());
}
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_mobile_submit, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
/** Create a file Uri for saving an image or video */
private static Uri getOutputMediaFileUri(int type){
return Uri.fromFile(getOutputMediaFile(type));
}
/** Create a File for saving an image or video */
private static File getOutputMediaFile(int type){
// To be safe, you should check that the SDCard is mounted
// using Environment.getExternalStorageState() before doing this.
File mediaStorageDir = new File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), "MyCameraApp");
// This location works best if you want the created images to be shared
// between applications and persist after your app has been uninstalled.
// Create the storage directory if it does not exist
if (! mediaStorageDir.exists()){
if (! mediaStorageDir.mkdirs()){
Log.d("MyCameraApp", "failed to create directory");
return null;
}
}
// Create a media file name
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
File mediaFile;
if (type == MEDIA_TYPE_IMAGE){
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"IMG_"+ timeStamp + ".jpg");
} else if(type == MEDIA_TYPE_VIDEO) {
mediaFile = new File(mediaStorageDir.getPath() + File.separator +
"VID_"+ timeStamp + ".mp4");
} else {
return null;
}
return mediaFile;
}
}
package melaniezhao.excitementdocumentation;
import android.content.Intent;
import android.util.Log;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.WearableListenerService;
public class ReceiverService extends WearableListenerService {
private static final String RECEIVER_SERVICE_PATH = "/picture";
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onMessageReceived(MessageEvent messageEvent) {
// if (messageEvent.getPath().equals(RECEIVER_SERVICE_PATH)) {
Log.i("Success", "I got a message!");
Intent submitActivity = new Intent(this, MobileSubmitActivity.class);
submitActivity.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(submitActivity);
// }
}
}
<resources>
<string name="app_name">Excitement Documentation</string>
<string name="action_settings">Settings</string>
<string name="title_activity_mobile_submit">MobileSubmitActivity</string>
<!-- MobileMainActivity-->
<string name="app_desc">Welcome to Excitement Documentation!\n</string>
<string name="excited">Let\'s get excited!</string>
<string name="done">All Done!</string>
<string name="try_again">Try Again!</string>
<!-- MobileSecondActivity-->
<string name="text_field">#cs160excited </string>
<string name="submit">tweet</string>
<string name="desc"></string>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string-array name="android_wear_capabilities">
<item>take_picture</item>
</string-array>
</resources>
SenderService.java
JavaThe functions here are from slide #18 of section 04 (messages and twitter) slides and pickBestNodeId is from the Android Developers (http://developer.android.com/index.html) page.
package melaniezhao.excitementdocumentation;
import android.app.Service;
import android.content.Intent;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.wearable.CapabilityApi;
import com.google.android.gms.wearable.Node;
import com.google.android.gms.wearable.Wearable;
import java.util.Set;
public class SenderService extends Service {
private GoogleApiClient mGoogleApiClient;
private String CAPABILITY_NAME = "take_picture";
private String RECEIVER_SERVICE_PATH = "/picture";
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
@Override
public void onConnected(Bundle bundle) {
// Do something
}
@Override
public void onConnectionSuspended(int i) {
// Do something
}
})
.addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// Do something
}
})
.addApi(Wearable.API)
.build();
this.mGoogleApiClient.connect();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
CapabilityApi.GetCapabilityResult capResult =
Wearable.CapabilityApi.getCapability(
mGoogleApiClient, CAPABILITY_NAME,
CapabilityApi.FILTER_REACHABLE)
.await();
Log.i("Success", "I sent a message!");
Wearable.MessageApi.sendMessage(
mGoogleApiClient, pickBestNodeId(capResult.getCapability().getNodes()),
RECEIVER_SERVICE_PATH, new byte[3]
);
}
});
thread.start();
return Service.START_STICKY;
}
private String pickBestNodeId(Set<Node> nodes) {
String bestNodeId = null;
// Find a nearby node or pick one arbitrarily
for (Node node : nodes) {
if (node.isNearby()) {
return node.getId();
}
bestNodeId = node.getId();
}
return bestNodeId;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
package melaniezhao.excitementdocumentation;
import android.app.Notification;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.IBinder;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;
import android.support.v4.app.NotificationCompat.WearableExtender;
public class SensorActivity extends Service implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mSensor;
private void initSensor(){
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
private void getAccelerometer(SensorEvent event) {
float [] values = event.values;
float x = values[0];
float y = values[1];
float z = values[2];
int notificationId = 1;
double accelerationSquareRoot = Math.sqrt(x * x + y * y + z * z);
if (accelerationSquareRoot >= 20) {
PendingIntent pendingIntent = PendingIntent.getService(this, 0, new Intent(this, SenderService.class),0);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentTitle(getString(R.string.notification_title))
.setContentText(getString(R.string.notification_text))
.addAction(R.drawable.camera, getString(R.string.camera), pendingIntent);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(this);
notificationManager.notify(notificationId, notificationBuilder.build());
}
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
initSensor();
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
getAccelerometer(event);
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
package melaniezhao.excitementdocumentation;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.support.wearable.view.WatchViewStub;
import android.widget.TextView;
public class WatchMainActivity extends Activity {
private TextView mTextView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_watch_main);
final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
@Override
public void onLayoutInflated(WatchViewStub stub) {
mTextView = (TextView) stub.findViewById(R.id.text);
}
});
Intent sensorActivity = new Intent(this, SensorActivity.class);
startService(sensorActivity);
}
}
<?xml version="1.0" encoding="utf-8"?>
<android.support.wearable.view.WatchViewStub
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/watch_view_stub"
android:layout_width="match_parent" android:layout_height="match_parent"
app:rectLayout="@layout/rect_activity_watch_main"
app:roundLayout="@layout/round_activity_watch_main" tools:context=".WatchMainActivity"
tools:deviceIds="wear"></android.support.wearable.view.WatchViewStub>
<resources>
<string name="app_name">Excitement Documentation</string>
<string name="hello_round">Hello Round World!</string>
<string name="hello_square">Hello Square World!</string>
<string name="camera">Camera</string>
<string name="notification_title">Excitement Detected!</string>
<string name="notification_text">You seem excited! Document it!</string>
</resources>
<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" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MobileMainActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_vertical|center_horizontal">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/app_desc"
android:id="@+id/textView"
android:gravity="center_horizontal" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceLarge"
android:text="@string/excited"
android:id="@+id/textView2"
android:layout_gravity="center_horizontal" />
<com.twitter.sdk.android.core.identity.TwitterLoginButton
android:id="@+id/login_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="69dp" />
</LinearLayout>
</RelativeLayout>
<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" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin"
tools:context="melaniezhao.excitementdocumentation.MobileSubmitActivity">
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:weightSum="1">
<ImageView
android:layout_width="match_parent"
android:layout_height="350dp"
android:contentDescription="@string/desc"
android:id="@+id/imageContainer"
android:layout_gravity="center_horizontal" />
</LinearLayout>
</RelativeLayout>
Comments