diff options
38 files changed, 1289 insertions, 0 deletions
diff --git a/AutoMessagingDemo/.gitignore b/AutoMessagingDemo/.gitignore new file mode 100644 index 0000000..afbdab3 --- /dev/null +++ b/AutoMessagingDemo/.gitignore @@ -0,0 +1,6 @@ +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build diff --git a/AutoMessagingDemo/README.txt b/AutoMessagingDemo/README.txt new file mode 100644 index 0000000..cfd4e6a --- /dev/null +++ b/AutoMessagingDemo/README.txt @@ -0,0 +1,39 @@ +Android Auto Messaging API Sample +================================= + +MessagingService.java shows a simple service that sends notifications using NotificationCompat. +In addition to sending a notification, it also extends the notification with a CarExtender. +Each unread conversation from a user is sent as a distinct notification. + +CheckList while building a messaging app that supports Android Auto: +------------------------------------------------------------------- +1. Add or import the android-auto-sdk.jar into your app. +2. Ensure that Message notifications are extended using +NotificationCompat.Builder.extend(new CarExtender()...) +3. Add meta-data to your AndroidManifest.xml to specify that your app +is automotive enabled. + + <meta-data android:name="com.google.android.gms.car.application" + android:resource="@xml/automotive_app_desc"/> + +and include the following to indicate that the application wants to show notifications on +the overview screen. +res/xml/automotive_app_desc.xml + +<automotiveApp> + <uses name="notification"/> +</automotiveApp> + +Flow +----- +MessagingFragment is shown to the user. Depending on the button clicked, the MessagingService is +sent a message. MessagingService inturn creates notifications which can be viewed either on the +emulator or in a car. +When a message is read, the associated PendingIntent is called and MessageReadReceiver is called +with the appropriate conversationId. Similarly, when a reply is received, the MessageReplyReceiver +is called with the appropriate conversationId. MessageLogger logs each event and shows them in a +TextView in MessagingFragment for correlation. + +Known Issues: +------------- +- Emulator: Reply always sends text "This is a reply". No voice input in emulator. diff --git a/AutoMessagingDemo/app/.gitignore b/AutoMessagingDemo/app/.gitignore new file mode 100644 index 0000000..796b96d --- /dev/null +++ b/AutoMessagingDemo/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/AutoMessagingDemo/app/build.gradle b/AutoMessagingDemo/app/build.gradle new file mode 100644 index 0000000..4e7f2ec --- /dev/null +++ b/AutoMessagingDemo/app/build.gradle @@ -0,0 +1,30 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 21 + buildToolsVersion "21.0.0" + + defaultConfig { + applicationId "com.example.android.automessagingdemo" + minSdkVersion 21 + targetSdkVersion 21 + versionCode 1 + versionName "1.0" + } + + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_7 + targetCompatibility JavaVersion.VERSION_1_7 + } + buildTypes { + release { + runProguard false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } +} + +dependencies { + compile fileTree(dir: 'libs', include: ['*.jar']) + compile 'com.android.support:appcompat-v7:21.0+' +} diff --git a/AutoMessagingDemo/app/libs/android-auto-sdk.jar b/AutoMessagingDemo/app/libs/android-auto-sdk.jar Binary files differnew file mode 100644 index 0000000..8a9897d --- /dev/null +++ b/AutoMessagingDemo/app/libs/android-auto-sdk.jar diff --git a/AutoMessagingDemo/app/proguard-rules.pro b/AutoMessagingDemo/app/proguard-rules.pro new file mode 100644 index 0000000..dc41957 --- /dev/null +++ b/AutoMessagingDemo/app/proguard-rules.pro @@ -0,0 +1,17 @@ +# Add project specific ProGuard rules here. +# By default, the flags in this file are appended to flags specified +# in /usr/local/google/home/nageshs/Software/build-1404642-LRW65B/android-sdk_1404642_linux-x86/tools/proguard/proguard-android.txt +# You can edit the include path and order by changing the proguardFiles +# directive in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# Add any project specific keep options here: + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} diff --git a/AutoMessagingDemo/app/src/main/AndroidManifest.xml b/AutoMessagingDemo/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..b0b6f60 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/AndroidManifest.xml @@ -0,0 +1,52 @@ +<!-- + Copyright (C) 2014 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="com.example.android.automessagingdemo"> + + <application android:allowBackup="true" + android:label="@string/app_name" + android:icon="@drawable/ic_launcher" + android:theme="@style/AppTheme"> + + <meta-data android:name="com.google.android.gms.car.application" + android:resource="@xml/automotive_app_desc"/> + + <activity + android:name=".MainActivity" + android:label="@string/app_name" > + <intent-filter> + <action android:name="android.intent.action.MAIN" /> + + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + + <service android:name=".MessagingService"> + </service> + + <receiver android:name=".MessageReadReceiver"> + <intent-filter> + <action android:name="com.example.messaging.messagemedemo.ACTION_MESSAGE_READ"/> + </intent-filter> + </receiver> + + <receiver android:name=".MessageReplyReceiver"> + <intent-filter> + <action android:name="com.example.messaging.messagemedemo.ACTION_MESSAGE_REPLY"/> + </intent-filter> + </receiver> + </application> +</manifest> diff --git a/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/Conversations.java b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/Conversations.java new file mode 100644 index 0000000..d92beec --- /dev/null +++ b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/Conversations.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.example.android.automessagingdemo; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.ThreadLocalRandom; + +/** + * A simple class that denotes unread conversations and messages. In a real world application, + * this would be replaced by a content provider that actually gets the unread messages to be + * shown to the user. + */ +public class Conversations { + + /** + * Set of strings used as messages by the sample. + */ + private static final String[] MESSAGES = new String[]{ + "Are you at home?", + "Can you give me a call?", + "Hey yt?", + "Don't forget to get some milk on your way back home", + "Is that project done?", + "Did you finish the Messaging app yet?" + }; + + /** + * Senders of the said messages. + */ + private static final String[] PARTICIPANTS = new String[]{ + "John Rambo", + "Han Solo", + "Rocky Balboa", + "Lara Croft" + }; + + static class Conversation { + + private final int conversationId; + + private final String participantName; + + /** + * A given conversation can have a single or multiple messages. + * Note that the messages are sorted from *newest* to *oldest* + */ + private final List<String> messages; + + private final long timestamp; + + public Conversation(int conversationId, String participantName, + List<String> messages) { + this.conversationId = conversationId; + this.participantName = participantName; + this.messages = messages == null ? Collections.<String>emptyList() : messages; + this.timestamp = System.currentTimeMillis(); + } + + public int getConversationId() { + return conversationId; + } + + public String getParticipantName() { + return participantName; + } + + public List<String> getMessages() { + return messages; + } + + public long getTimestamp() { + return timestamp; + } + + public String toString() { + return "[Conversation: conversationId=" + conversationId + + ", participantName=" + participantName + + ", messages=" + messages + + ", timestamp=" + timestamp + "]"; + } + } + + private Conversations() { + } + + public static Conversation[] getUnreadConversations(int howManyConversations, + int messagesPerConversation) { + Conversation[] conversations = new Conversation[howManyConversations]; + for (int i = 0; i < howManyConversations; i++) { + conversations[i] = new Conversation( + ThreadLocalRandom.current().nextInt(), + name(), makeMessages(messagesPerConversation)); + } + return conversations; + } + + private static List<String> makeMessages(int messagesPerConversation) { + int maxLen = MESSAGES.length; + List<String> messages = new ArrayList<>(messagesPerConversation); + for (int i = 0; i < messagesPerConversation; i++) { + messages.add(MESSAGES[ThreadLocalRandom.current().nextInt(0, maxLen)]); + } + return messages; + } + + private static String name() { + return PARTICIPANTS[ThreadLocalRandom.current().nextInt(0, PARTICIPANTS.length)]; + } +} diff --git a/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MainActivity.java b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MainActivity.java new file mode 100644 index 0000000..7236c2c --- /dev/null +++ b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MainActivity.java @@ -0,0 +1,34 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.example.android.automessagingdemo; + +import android.app.Activity; +import android.os.Bundle; + +public class MainActivity extends Activity { + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + if (savedInstanceState == null) { + getFragmentManager().beginTransaction() + .add(R.id.container, new MessagingFragment()) + .commit(); + } + } +} diff --git a/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessageLogger.java b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessageLogger.java new file mode 100644 index 0000000..e899a71 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessageLogger.java @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.example.android.automessagingdemo; + +import android.content.Context; +import android.content.SharedPreferences; + +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * A simple logger that uses shared preferences to log messages, their reads + * and replies. Don't use this in a real world application. This logger is only + * used for displaying the messages in the text view. + */ +public class MessageLogger { + + private static final String PREF_MESSAGE = "MESSAGE_LOGGER"; + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + + public static final String LOG_KEY = "message_data"; + public static final String LINE_BREAKS = "\n\n"; + + public static void logMessage(Context context, String message) { + SharedPreferences prefs = getPrefs(context); + message = DATE_FORMAT.format(new Date(System.currentTimeMillis())) + ": " + message; + prefs.edit() + .putString(LOG_KEY, prefs.getString(LOG_KEY, "") + LINE_BREAKS + message) + .apply(); + } + + public static SharedPreferences getPrefs(Context context) { + return context.getSharedPreferences(PREF_MESSAGE, Context.MODE_PRIVATE); + } + + public static String getAllMessages(Context context) { + return getPrefs(context).getString(LOG_KEY, ""); + } + + public static void clear(Context context) { + getPrefs(context).edit().remove(LOG_KEY).apply(); + } +} diff --git a/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessageReadReceiver.java b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessageReadReceiver.java new file mode 100644 index 0000000..1351ffc --- /dev/null +++ b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessageReadReceiver.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.example.android.automessagingdemo; + +import android.app.NotificationManager; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.support.v4.app.NotificationManagerCompat; +import android.util.Log; + +public class MessageReadReceiver extends BroadcastReceiver { + private static final String TAG = MessageReadReceiver.class.getSimpleName(); + + private static final String CONVERSATION_ID = "conversation_id"; + + @Override + public void onReceive(Context context, Intent intent) { + Log.d(TAG, "onReceive"); + int conversationId = intent.getIntExtra(CONVERSATION_ID, -1); + if (conversationId != -1) { + Log.d(TAG, "Conversation " + conversationId + " was read"); + MessageLogger.logMessage(context, "Conversation " + conversationId + " was read."); + NotificationManagerCompat notificationManager = NotificationManagerCompat.from(context); + notificationManager.cancel(conversationId); + } + } +} diff --git a/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessageReplyReceiver.java b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessageReplyReceiver.java new file mode 100644 index 0000000..c9087d2 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessageReplyReceiver.java @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.example.android.automessagingdemo; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.RemoteInput; +import android.util.Log; + +/** + * A receiver that gets called when a reply is sent to a given conversationId + */ +public class MessageReplyReceiver extends BroadcastReceiver { + + private static final String TAG = MessageReplyReceiver.class.getSimpleName(); + + @Override + public void onReceive(Context context, Intent intent) { + if (MessagingService.REPLY_ACTION.equals(intent.getAction())) { + int conversationId = intent.getIntExtra(MessagingService.CONVERSATION_ID, -1); + CharSequence reply = getMessageText(intent); + if (conversationId != -1) { + Log.d(TAG, "Got reply (" + reply + ") for ConversationId " + conversationId); + MessageLogger.logMessage(context, "ConversationId: " + conversationId + + " received a reply: [" + reply + "]"); + } + } + } + + /** + * Get the message text from the intent. + * Note that you should call {@code RemoteInput#getResultsFromIntent(intent)} to process + * the RemoteInput. + */ + private CharSequence getMessageText(Intent intent) { + Bundle remoteInput = RemoteInput.getResultsFromIntent(intent); + if (remoteInput != null) { + return remoteInput.getCharSequence(MessagingService.EXTRA_VOICE_REPLY); + } + return null; + } +} diff --git a/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessagingFragment.java b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessagingFragment.java new file mode 100644 index 0000000..2fe75c6 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessagingFragment.java @@ -0,0 +1,170 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.example.android.automessagingdemo; + +import android.app.Fragment; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.ServiceConnection; +import android.content.SharedPreferences; +import android.os.Bundle; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.os.RemoteException; +import android.text.method.ScrollingMovementMethod; +import android.util.Log; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.TextView; + +/** + * The main fragment that shows the buttons and the text view containing the log. + */ +public class MessagingFragment extends Fragment implements View.OnClickListener { + + private static final String TAG = MessagingFragment.class.getSimpleName(); + + private Button mSendSingleConversation; + private Button mSendTwoConversations; + private Button mSendConversationWithThreeMessages; + private TextView mDataPortView; + private Button mClearLogButton; + + private Messenger mService; + private boolean mBound; + + private ServiceConnection mConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName componentName, IBinder service) { + mService = new Messenger(service); + mBound = true; + setButtonsState(true); + } + + @Override + public void onServiceDisconnected(ComponentName componentName) { + mService = null; + mBound = false; + setButtonsState(false); + } + }; + + private SharedPreferences.OnSharedPreferenceChangeListener listener = + new SharedPreferences.OnSharedPreferenceChangeListener() { + @Override + public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { + if (MessageLogger.LOG_KEY.equals(key)) { + mDataPortView.setText(MessageLogger.getAllMessages(getActivity())); + } + } + }; + + public MessagingFragment() { + } + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, + Bundle savedInstanceState) { + View rootView = inflater.inflate(R.layout.fragment_message_me, container, false); + + mSendSingleConversation = (Button) rootView.findViewById(R.id.send_1_conversation); + mSendSingleConversation.setOnClickListener(this); + + mSendTwoConversations = (Button) rootView.findViewById(R.id.send_2_conversations); + mSendTwoConversations.setOnClickListener(this); + + mSendConversationWithThreeMessages = + (Button) rootView.findViewById(R.id.send_1_conversation_3_messages); + mSendConversationWithThreeMessages.setOnClickListener(this); + + mDataPortView = (TextView) rootView.findViewById(R.id.data_port); + mDataPortView.setMovementMethod(new ScrollingMovementMethod()); + + mClearLogButton = (Button) rootView.findViewById(R.id.clear); + mClearLogButton.setOnClickListener(this); + + setButtonsState(false); + + return rootView; + } + + @Override + public void onClick(View view) { + if (view == mSendSingleConversation) { + sendMsg(1, 1); + } else if (view == mSendTwoConversations) { + sendMsg(2, 1); + } else if (view == mSendConversationWithThreeMessages) { + sendMsg(1, 3); + } else if (view == mClearLogButton) { + MessageLogger.clear(getActivity()); + mDataPortView.setText(MessageLogger.getAllMessages(getActivity())); + } + } + + @Override + public void onStart() { + super.onStart(); + getActivity().bindService(new Intent(getActivity(), MessagingService.class), mConnection, + Context.BIND_AUTO_CREATE); + } + + @Override + public void onPause() { + super.onPause(); + MessageLogger.getPrefs(getActivity()).unregisterOnSharedPreferenceChangeListener(listener); + } + + @Override + public void onResume() { + super.onResume(); + mDataPortView.setText(MessageLogger.getAllMessages(getActivity())); + MessageLogger.getPrefs(getActivity()).registerOnSharedPreferenceChangeListener(listener); + } + + @Override + public void onStop() { + super.onStop(); + if (mBound) { + getActivity().unbindService(mConnection); + mBound = false; + } + } + + private void sendMsg(int howManyConversations, int messagesPerConversation) { + if (mBound) { + Message msg = Message.obtain(null, MessagingService.MSG_SEND_NOTIFICATION, + howManyConversations, messagesPerConversation); + try { + mService.send(msg); + } catch (RemoteException e) { + Log.e(TAG, "Error sending a message", e); + MessageLogger.logMessage(getActivity(), "Error occurred while sending a message."); + } + } + } + + private void setButtonsState(boolean enable) { + mSendSingleConversation.setEnabled(enable); + mSendTwoConversations.setEnabled(enable); + mSendConversationWithThreeMessages.setEnabled(enable); + } +} diff --git a/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessagingService.java b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessagingService.java new file mode 100644 index 0000000..d702369 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/java/com/example/android/automessagingdemo/MessagingService.java @@ -0,0 +1,174 @@ +/* + * Copyright (C) 2014 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. + */ + +package com.example.android.automessagingdemo; + +import android.app.PendingIntent; +import android.app.Service; +import android.content.Intent; +import android.graphics.BitmapFactory; +import android.os.Handler; +import android.os.IBinder; +import android.os.Message; +import android.os.Messenger; +import android.preview.support.v4.app.NotificationCompat.CarExtender; +import android.preview.support.v4.app.NotificationCompat.CarExtender.UnreadConversation; +import android.support.v4.app.NotificationCompat; +import android.support.v4.app.NotificationManagerCompat; +import android.support.v4.app.RemoteInput; +import android.util.Log; + +import java.util.Iterator; + +public class MessagingService extends Service { + private static final String TAG = MessagingService.class.getSimpleName(); + + public static final String READ_ACTION = + "com.example.messaging.messagemedemo.ACTION_MESSAGE_READ"; + public static final String REPLY_ACTION = + "com.example.messaging.messagemedemo.ACTION_MESSAGE_REPLY"; + public static final String CONVERSATION_ID = "conversation_id"; + public static final String EXTRA_VOICE_REPLY = "extra_voice_reply"; + public static final int MSG_SEND_NOTIFICATION = 1; + public static final String EOL = "\n"; + + private NotificationManagerCompat mNotificationManager; + + private final Messenger mMessenger = new Messenger(new IncomingHandler()); + + /** + * Handler of incoming messages from clients. + */ + class IncomingHandler extends Handler { + @Override + public void handleMessage(Message msg) { + switch (msg.what) { + case MSG_SEND_NOTIFICATION: + int howManyConversations = msg.arg1 <= 0 ? 1 : msg.arg1; + int messagesPerConv = msg.arg2 <= 0 ? 1 : msg.arg2; + sendNotification(howManyConversations, messagesPerConv); + break; + default: + super.handleMessage(msg); + } + } + } + + @Override + public void onCreate() { + Log.d(TAG, "onCreate"); + mNotificationManager = NotificationManagerCompat.from(getApplicationContext()); + } + + @Override + public IBinder onBind(Intent intent) { + Log.d(TAG, "onBind"); + return mMessenger.getBinder(); + } + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + Log.d(TAG, "onStartCommand"); + return START_STICKY; + } + + @Override + public void onDestroy() { + super.onDestroy(); + Log.d(TAG, "onDestroy"); + } + + // Creates an intent that will be triggered when a message is marked as read. + private Intent getMessageReadIntent(int id) { + return new Intent() + .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) + .setAction(READ_ACTION) + .putExtra(CONVERSATION_ID, id); + } + + // Creates an Intent that will be triggered when a voice reply is received. + private Intent getMessageReplyIntent(int conversationId) { + return new Intent() + .addFlags(Intent.FLAG_INCLUDE_STOPPED_PACKAGES) + .setAction(REPLY_ACTION) + .putExtra(CONVERSATION_ID, conversationId); + } + + private void sendNotification(int howManyConversations, int messagesPerConversation) { + Conversations.Conversation[] conversations = Conversations.getUnreadConversations( + howManyConversations, messagesPerConversation); + for (Conversations.Conversation conv : conversations) { + sendNotificationForConversation(conv); + } + } + + private void sendNotificationForConversation(Conversations.Conversation conversation) { + // A pending Intent for reads + PendingIntent readPendingIntent = PendingIntent.getBroadcast(getApplicationContext(), + conversation.getConversationId(), + getMessageReadIntent(conversation.getConversationId()), + PendingIntent.FLAG_UPDATE_CURRENT); + + // Build a RemoteInput for receiving voice input in a Car Notification + RemoteInput remoteInput = new RemoteInput.Builder(EXTRA_VOICE_REPLY) + .setLabel(getApplicationContext().getString(R.string.notification_reply)) + .build(); + + // Building a Pending Intent for the reply action to trigger + PendingIntent replyIntent = PendingIntent.getBroadcast(getApplicationContext(), + conversation.getConversationId(), + getMessageReplyIntent(conversation.getConversationId()), + PendingIntent.FLAG_UPDATE_CURRENT); + + // Create the UnreadConversation and populate it with the participant name, + // read and reply intents. + UnreadConversation.Builder unreadConvBuilder = + new UnreadConversation.Builder(conversation.getParticipantName()) + .setLatestTimestamp(conversation.getTimestamp()) + .setReadPendingIntent(readPendingIntent) + .setReplyAction(replyIntent, remoteInput); + + // Note: Add messages from oldest to newest to the UnreadConversation.Builder + StringBuilder messageForNotification = new StringBuilder(); + for (Iterator<String> messages = conversation.getMessages().iterator(); + messages.hasNext(); ) { + String message = messages.next(); + unreadConvBuilder.addMessage(message); + messageForNotification.append(message); + if (messages.hasNext()) { + messageForNotification.append(EOL); + } + } + + NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext()) + .setSmallIcon(R.drawable.notification_icon) + .setLargeIcon(BitmapFactory.decodeResource( + getApplicationContext().getResources(), R.drawable.android_contact)) + .setContentText(messageForNotification.toString()) + .setWhen(conversation.getTimestamp()) + .setContentTitle(conversation.getParticipantName()) + .setContentIntent(readPendingIntent) + .extend(new CarExtender() + .setUnreadConversation(unreadConvBuilder.build()) + .setColor(getApplicationContext() + .getResources().getColor(R.color.default_color_light))); + + MessageLogger.logMessage(getApplicationContext(), "Sending notification " + + conversation.getConversationId() + " conversation: " + conversation); + + mNotificationManager.notify(conversation.getConversationId(), builder.build()); + } +} diff --git a/AutoMessagingDemo/app/src/main/res/drawable-hdpi/ic_launcher.png b/AutoMessagingDemo/app/src/main/res/drawable-hdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..06d85f1 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/drawable-hdpi/ic_launcher.png diff --git a/AutoMessagingDemo/app/src/main/res/drawable-hdpi/notification_icon.png b/AutoMessagingDemo/app/src/main/res/drawable-hdpi/notification_icon.png Binary files differnew file mode 100644 index 0000000..9cdfca1 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/drawable-hdpi/notification_icon.png diff --git a/AutoMessagingDemo/app/src/main/res/drawable-mdpi/ic_launcher.png b/AutoMessagingDemo/app/src/main/res/drawable-mdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..4e1cc86 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/drawable-mdpi/ic_launcher.png diff --git a/AutoMessagingDemo/app/src/main/res/drawable-mdpi/notification_icon.png b/AutoMessagingDemo/app/src/main/res/drawable-mdpi/notification_icon.png Binary files differnew file mode 100644 index 0000000..d6069eb --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/drawable-mdpi/notification_icon.png diff --git a/AutoMessagingDemo/app/src/main/res/drawable-xhdpi/ic_launcher.png b/AutoMessagingDemo/app/src/main/res/drawable-xhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..92f1e2d --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/drawable-xhdpi/ic_launcher.png diff --git a/AutoMessagingDemo/app/src/main/res/drawable-xhdpi/notification_icon.png b/AutoMessagingDemo/app/src/main/res/drawable-xhdpi/notification_icon.png Binary files differnew file mode 100644 index 0000000..786ed17 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/drawable-xhdpi/notification_icon.png diff --git a/AutoMessagingDemo/app/src/main/res/drawable-xxhdpi/android_contact.png b/AutoMessagingDemo/app/src/main/res/drawable-xxhdpi/android_contact.png Binary files differnew file mode 100644 index 0000000..611d565 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/drawable-xxhdpi/android_contact.png diff --git a/AutoMessagingDemo/app/src/main/res/drawable-xxhdpi/ic_launcher.png b/AutoMessagingDemo/app/src/main/res/drawable-xxhdpi/ic_launcher.png Binary files differnew file mode 100644 index 0000000..2476cbd --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/drawable-xxhdpi/ic_launcher.png diff --git a/AutoMessagingDemo/app/src/main/res/drawable-xxhdpi/notification_icon.png b/AutoMessagingDemo/app/src/main/res/drawable-xxhdpi/notification_icon.png Binary files differnew file mode 100644 index 0000000..005207c --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/drawable-xxhdpi/notification_icon.png diff --git a/AutoMessagingDemo/app/src/main/res/layout-land/fragment_message_me.xml b/AutoMessagingDemo/app/src/main/res/layout-land/fragment_message_me.xml new file mode 100644 index 0000000..8f7b60a --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/layout-land/fragment_message_me.xml @@ -0,0 +1,67 @@ +<!-- + Copyright (C) 2014 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. + --> +<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:gravity="center_horizontal" + android:orientation="horizontal" + android:paddingBottom="@dimen/activity_vertical_margin" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin"> + <LinearLayout + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="1" + android:orientation="vertical"> + <Button + android:id="@+id/send_1_conversation" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/send_1_conversation"/> + + <Button + android:id="@+id/send_2_conversations" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/send_2_conversations"/> + + <Button + android:id="@+id/send_1_conversation_3_messages" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/send_1_conv_3_messages"/> + </LinearLayout> + <RelativeLayout + android:layout_width="0dp" + android:layout_height="match_parent" + android:layout_weight="2"> + <Button + android:id="@+id/clear" + android:layout_alignParentBottom="true" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/clear_log"/> + + <TextView + android:id="@+id/data_port" + android:layout_above="@id/clear" + android:layout_width="match_parent" + android:layout_height="match_parent" + android:maxLines="20" + android:scrollbars="vertical"/> + </RelativeLayout> +</LinearLayout> diff --git a/AutoMessagingDemo/app/src/main/res/layout/activity_main.xml b/AutoMessagingDemo/app/src/main/res/layout/activity_main.xml new file mode 100644 index 0000000..79f6adf --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,22 @@ +<!-- + Copyright (C) 2014 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. + --> +<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" + xmlns:tools="http://schemas.android.com/tools" + android:id="@+id/container" + android:layout_width="match_parent" + android:layout_height="match_parent" + tools:context=".MessageMeActivity" + tools:ignore="MergeRootFrame" /> diff --git a/AutoMessagingDemo/app/src/main/res/layout/fragment_message_me.xml b/AutoMessagingDemo/app/src/main/res/layout/fragment_message_me.xml new file mode 100644 index 0000000..e673f0d --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/layout/fragment_message_me.xml @@ -0,0 +1,58 @@ +<!-- + Copyright (C) 2014 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. + --> +<LinearLayout 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:orientation="vertical" + android:gravity="center_horizontal" + android:paddingBottom="@dimen/activity_vertical_margin" + android:paddingLeft="@dimen/activity_horizontal_margin" + android:paddingRight="@dimen/activity_horizontal_margin" + android:paddingTop="@dimen/activity_vertical_margin"> + + <Button + android:id="@+id/send_1_conversation" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/send_1_conversation"/> + + <Button + android:id="@+id/send_2_conversations" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/send_2_conversations"/> + + <Button + android:id="@+id/send_1_conversation_3_messages" + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:text="@string/send_1_conv_3_messages"/> + + <TextView + android:id="@+id/data_port" + android:layout_width="match_parent" + android:layout_height="0dp" + android:layout_weight="1" + android:maxLines="20" + android:scrollbars="vertical"/> + <Button + android:layout_width="match_parent" + android:layout_height="wrap_content" + android:id="@+id/clear" + android:text="@string/clear_log"/> + +</LinearLayout> diff --git a/AutoMessagingDemo/app/src/main/res/values-v21/styles.xml b/AutoMessagingDemo/app/src/main/res/values-v21/styles.xml new file mode 100644 index 0000000..f30c97a --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/values-v21/styles.xml @@ -0,0 +1,22 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 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> + <style name="AppTheme" parent="android:Theme.Material.Light"> + <item name="android:colorPrimary">@color/default_color_light</item> + <item name="android:colorPrimaryDark">@color/default_color_dark</item> + </style> +</resources> diff --git a/AutoMessagingDemo/app/src/main/res/values/colors.xml b/AutoMessagingDemo/app/src/main/res/values/colors.xml new file mode 100644 index 0000000..0e6825b --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/values/colors.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 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> + <color name="default_color_light">#ff4092c3</color> + <color name="default_color_dark">#ff241c99</color> +</resources> diff --git a/AutoMessagingDemo/app/src/main/res/values/dimens.xml b/AutoMessagingDemo/app/src/main/res/values/dimens.xml new file mode 100644 index 0000000..574a35d --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/values/dimens.xml @@ -0,0 +1,21 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 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> + <!-- Default screen margins, per the Android Design guidelines. --> + <dimen name="activity_horizontal_margin">16dp</dimen> + <dimen name="activity_vertical_margin">16dp</dimen> +</resources> diff --git a/AutoMessagingDemo/app/src/main/res/values/strings.xml b/AutoMessagingDemo/app/src/main/res/values/strings.xml new file mode 100644 index 0000000..001b10e --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/values/strings.xml @@ -0,0 +1,26 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 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">Messaging Sample</string> + <string name="action_settings">Settings</string> + <string name="title">Messaging Sample</string> + <string name="notification_reply">Reply by Voice</string> + <string name="send_2_conversations">Send 2 conversations with 1 message</string> + <string name="send_1_conversation">Send 1 conversation with 1 message</string> + <string name="send_1_conv_3_messages">Send 1 conversation with 3 messages</string> + <string name="clear_log">Clear Log</string> +</resources> diff --git a/AutoMessagingDemo/app/src/main/res/values/styles.xml b/AutoMessagingDemo/app/src/main/res/values/styles.xml new file mode 100644 index 0000000..3f1a6af --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/values/styles.xml @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 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> + <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar"> + </style> +</resources> diff --git a/AutoMessagingDemo/app/src/main/res/xml/automotive_app_desc.xml b/AutoMessagingDemo/app/src/main/res/xml/automotive_app_desc.xml new file mode 100644 index 0000000..9e9f174 --- /dev/null +++ b/AutoMessagingDemo/app/src/main/res/xml/automotive_app_desc.xml @@ -0,0 +1,19 @@ +<?xml version="1.0" encoding="utf-8"?> +<!-- + Copyright (C) 2014 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. + --> +<automotiveApp> + <uses name="notification"/> +</automotiveApp> diff --git a/AutoMessagingDemo/build.gradle b/AutoMessagingDemo/build.gradle new file mode 100644 index 0000000..9b8abe4 --- /dev/null +++ b/AutoMessagingDemo/build.gradle @@ -0,0 +1,19 @@ +// Top-level build file where you can add configuration options common to all sub-projects/modules. + +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.android.tools.build:gradle:0.12.2' + + // NOTE: Do not place your application dependencies here; they belong + // in the individual module build.gradle files + } +} + +allprojects { + repositories { + jcenter() + } +} diff --git a/AutoMessagingDemo/gradle.properties b/AutoMessagingDemo/gradle.properties new file mode 100644 index 0000000..34fb461 --- /dev/null +++ b/AutoMessagingDemo/gradle.properties @@ -0,0 +1,18 @@ +# Project-wide Gradle settings. + +# IDE (e.g. Android Studio) users: +# Settings specified in this file will override any Gradle settings +# configured through the IDE. + +# For more details on how to configure your build environment visit +# http://www.gradle.org/docs/current/userguide/build_environment.html + +# Specifies the JVM arguments used for the daemon process. +# The setting is particularly useful for tweaking memory settings. +# Default value: -Xmx10248m -XX:MaxPermSize=256m +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 + +# When configured, Gradle will run in incubating parallel mode. +# This option should only be used with decoupled projects. More details, visit +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects +# org.gradle.parallel=true diff --git a/AutoMessagingDemo/gradle/wrapper/gradle-wrapper.jar b/AutoMessagingDemo/gradle/wrapper/gradle-wrapper.jar Binary files differnew file mode 100644 index 0000000..8c0fb64 --- /dev/null +++ b/AutoMessagingDemo/gradle/wrapper/gradle-wrapper.jar diff --git a/AutoMessagingDemo/gradle/wrapper/gradle-wrapper.properties b/AutoMessagingDemo/gradle/wrapper/gradle-wrapper.properties new file mode 100644 index 0000000..1e61d1f --- /dev/null +++ b/AutoMessagingDemo/gradle/wrapper/gradle-wrapper.properties @@ -0,0 +1,6 @@ +#Wed Apr 10 15:27:10 PDT 2013 +distributionBase=GRADLE_USER_HOME +distributionPath=wrapper/dists +zipStoreBase=GRADLE_USER_HOME +zipStorePath=wrapper/dists +distributionUrl=http\://services.gradle.org/distributions/gradle-1.12-all.zip diff --git a/AutoMessagingDemo/gradlew b/AutoMessagingDemo/gradlew new file mode 100755 index 0000000..91a7e26 --- /dev/null +++ b/AutoMessagingDemo/gradlew @@ -0,0 +1,164 @@ +#!/usr/bin/env bash + +############################################################################## +## +## Gradle start up script for UN*X +## +############################################################################## + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS="" + +APP_NAME="Gradle" +APP_BASE_NAME=`basename "$0"` + +# Use the maximum available, or set MAX_FD != -1 to use that value. +MAX_FD="maximum" + +warn ( ) { + echo "$*" +} + +die ( ) { + echo + echo "$*" + echo + exit 1 +} + +# OS specific support (must be 'true' or 'false'). +cygwin=false +msys=false +darwin=false +case "`uname`" in + CYGWIN* ) + cygwin=true + ;; + Darwin* ) + darwin=true + ;; + MINGW* ) + msys=true + ;; +esac + +# For Cygwin, ensure paths are in UNIX format before anything is touched. +if $cygwin ; then + [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` +fi + +# Attempt to set APP_HOME +# Resolve links: $0 may be a link +PRG="$0" +# Need this for relative symlinks. +while [ -h "$PRG" ] ; do + ls=`ls -ld "$PRG"` + link=`expr "$ls" : '.*-> \(.*\)$'` + if expr "$link" : '/.*' > /dev/null; then + PRG="$link" + else + PRG=`dirname "$PRG"`"/$link" + fi +done +SAVED="`pwd`" +cd "`dirname \"$PRG\"`/" >&- +APP_HOME="`pwd -P`" +cd "$SAVED" >&- + +CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + +# Determine the Java command to use to start the JVM. +if [ -n "$JAVA_HOME" ] ; then + if [ -x "$JAVA_HOME/jre/sh/java" ] ; then + # IBM's JDK on AIX uses strange locations for the executables + JAVACMD="$JAVA_HOME/jre/sh/java" + else + JAVACMD="$JAVA_HOME/bin/java" + fi + if [ ! -x "$JAVACMD" ] ; then + die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." + fi +else + JAVACMD="java" + which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. + +Please set the JAVA_HOME variable in your environment to match the +location of your Java installation." +fi + +# Increase the maximum file descriptors if we can. +if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then + MAX_FD_LIMIT=`ulimit -H -n` + if [ $? -eq 0 ] ; then + if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then + MAX_FD="$MAX_FD_LIMIT" + fi + ulimit -n $MAX_FD + if [ $? -ne 0 ] ; then + warn "Could not set maximum file descriptor limit: $MAX_FD" + fi + else + warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" + fi +fi + +# For Darwin, add options to specify how the application appears in the dock +if $darwin; then + GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" +fi + +# For Cygwin, switch paths to Windows format before running java +if $cygwin ; then + APP_HOME=`cygpath --path --mixed "$APP_HOME"` + CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` + + # We build the pattern for arguments to be converted via cygpath + ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` + SEP="" + for dir in $ROOTDIRSRAW ; do + ROOTDIRS="$ROOTDIRS$SEP$dir" + SEP="|" + done + OURCYGPATTERN="(^($ROOTDIRS))" + # Add a user-defined pattern to the cygpath arguments + if [ "$GRADLE_CYGPATTERN" != "" ] ; then + OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" + fi + # Now convert the arguments - kludge to limit ourselves to /bin/sh + i=0 + for arg in "$@" ; do + CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` + CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option + + if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition + eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` + else + eval `echo args$i`="\"$arg\"" + fi + i=$((i+1)) + done + case $i in + (0) set -- ;; + (1) set -- "$args0" ;; + (2) set -- "$args0" "$args1" ;; + (3) set -- "$args0" "$args1" "$args2" ;; + (4) set -- "$args0" "$args1" "$args2" "$args3" ;; + (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; + (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; + (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; + (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; + (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; + esac +fi + +# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules +function splitJvmOpts() { + JVM_OPTS=("$@") +} +eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS +JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" + +exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" diff --git a/AutoMessagingDemo/settings.gradle b/AutoMessagingDemo/settings.gradle new file mode 100644 index 0000000..e7b4def --- /dev/null +++ b/AutoMessagingDemo/settings.gradle @@ -0,0 +1 @@ +include ':app' |