{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
In previous two articles I covered development environment setup and anatomy of SmartWatch. This article will contain deep dive into coding with simple Hello Word example.
http://forum.xda-developers.com/smartwatch/sony/tut-introduction-smart-watch-t2807896
http://forum.xda-developers.com/smartwatch/sony/tut-smartwatch-app-development-part-2-t2807954
This demo will cover Notification API only. We will develop a single Android project named "Hello SmartWatch" which acts as a Host application and Extension application both. It means I will use single codebase for both things. Hello SmartWatch project has an Activity to send and clear notification to SmartWatch.
I assume that you have already imported SmartExtensionAPI and SmartExtensionUtils libraries in workspace.
Let's jump to the code.
List of Classes and purpose
MainActivity.java: It is use to generate and clear notification.
HelloExtensionReceiver.java: It receives input event generated by SmartWatch and forward control to the Extension Service.
HelloExtensionService.java: core logic of Host application needs to be written in ExtensionService. It is also responsible to register a host application to SmartWatch.
HelloRegistrationInformation.java: It provides essential information to register host application and API requirement.
This demo application contains only above four classes but actual application may have more classes. In above classes MainActivity acts as a Smart Extension application and rest of classes acts as a Host application.
Step 1: Create new Android project in eclipse named "HelloSmartWatch".
Step 2: Let's create UI first. Open activity_main.xml and put two EditText box for Title and Message respectively and two buttons for Send and Clear notification respectively.
Code:
<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:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:text="Send Notification"
android:textAppearance="?android:attr/textAppearanceLarge" />
<EditText
android:id="@+id/etTitle"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Title" >
</EditText>
<EditText
android:id="@+id/etMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ems="10"
android:hint="Message" >
</EditText>
<Button
android:id="@+id/btnSend"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="buttonClicked"
android:text="Send Notification" />
<Button
android:id="@+id/btnClearn"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="buttonClicked"
android:text="Clear Notification" />
</LinearLayout>
Step 3: Let's make button alive by writing action in MainActivity.java. I am using onClick property of buttons, so I don't require to find object of button and setOnClickListener. I can write code in "buttonClicked" method which is defined. When a user click on "Send Notification" button I am simply firing ExtensionService with INTENT_ACTION_ADD action and other required data and same for "Clear Notification" but with INTENT_ACTION_CLEAR action.
Code:
package com.kpbird.hellosmartwatch;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.EditText;
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void buttonClicked(View v){
if(v.getId() == R.id.btnSend){
Intent serviceIntent = new Intent(this, HelloExtensionService.class);
serviceIntent.setAction(HelloExtensionService.INTENT_ACTION_ADD);
EditText etName = (EditText) findViewById(R.id.etTitle);
EditText etMsg = (EditText) findViewById(R.id.etMessage);
serviceIntent.putExtra("name", etName.getText().toString());
serviceIntent.putExtra("message", etMsg.getText().toString());
startService(serviceIntent);
}
else if(v.getId() == R.id.btnClearn){
Intent serviceIntent = new Intent(this, HelloExtensionService.class);
serviceIntent.setAction(HelloExtensionService.INTENT_ACTION_CLEAR);
startService(serviceIntent);
}
}
}
Step 4: Create HelloExtensionReceiver.java, It extends BroadcastReceiver. It works as bridge between SmartWatch and Host application, It will receive event generated in SmartWatch and forward it to HelloExtensionService.java
Code:
package com.kpbird.hellosmartwatch;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class HelloExtensionReceiver extends BroadcastReceiver{
private String TAG = this.getClass().getSimpleName();
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "HelloExtensionReceiver onReceiver: " + intent.getAction());
intent.setClass(context, HelloExtensionService.class);
context.startService(intent);
}
}
Step 5: Create HelloRegistrationInformation.java and extends with RegistrationInformation class. As the name suggests, It will use to register host application in Smart Connect. It has six methods that we need to override, among these four methods are used to declare required APIs and two methods used for extension registration and source registration. You can have multiple sources in a host application.
Code:
package com.kpbird.hellosmartwatch;
import java.util.ArrayList;
import java.util.List;
import android.content.ContentValues;
import android.content.Context;
import com.sonyericsson.extras.liveware.aef.notification.Notification;
import com.sonyericsson.extras.liveware.aef.registration.Registration;
import com.sonyericsson.extras.liveware.extension.util.ExtensionUtils;
import com.sonyericsson.extras.liveware.extension.util.registration.RegistrationInformation;
public class HelloRegistrationInformation extends RegistrationInformation{
private Context mContext;
public HelloRegistrationInformation(Context ctx){
if (ctx == null) {
throw new IllegalArgumentException("context == null");
}
mContext = ctx;
}
@Override
public int getRequiredNotificationApiVersion() {
return 1;
}
@Override
public int getRequiredWidgetApiVersion() {
return 0;
}
@Override
public int getRequiredControlApiVersion() {
return 0;
}
@Override
public int getRequiredSensorApiVersion() {
return 0;
}
@Override
public ContentValues getExtensionRegistrationConfiguration() {
String extensionIcon = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher);
String iconHostapp = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher);
String extensionIcon48 = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher_48);
String configurationText = "Hello SmartWatch";
String extensionName = "Hello SmartWatch";
ContentValues values = new ContentValues();
values.put(Registration.ExtensionColumns.CONFIGURATION_ACTIVITY,MainActivity.class.getName());
values.put(Registration.ExtensionColumns.CONFIGURATION_TEXT, configurationText);
values.put(Registration.ExtensionColumns.EXTENSION_ICON_URI, extensionIcon);
values.put(Registration.ExtensionColumns.EXTENSION_48PX_ICON_URI, extensionIcon48);
values.put(Registration.ExtensionColumns.EXTENSION_KEY,HelloExtensionService.EXTENSION_KEY);
values.put(Registration.ExtensionColumns.HOST_APP_ICON_URI, iconHostapp);
values.put(Registration.ExtensionColumns.NAME, extensionName);
values.put(Registration.ExtensionColumns.NOTIFICATION_API_VERSION,getRequiredNotificationApiVersion());
values.put(Registration.ExtensionColumns.PACKAGE_NAME, mContext.getPackageName());
return values;
}
@Override
public ContentValues[] getSourceRegistrationConfigurations() {
ContentValues sourceValues = null;
String iconSource1 = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher_30);
String iconSource2 = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher_18);
String iconBw = ExtensionUtils.getUriString(mContext,R.drawable.ic_launcher_18_bw);
String textToSpeech = "Notification from Hello SmartWatch Application";
sourceValues = new ContentValues();
sourceValues.put(Notification.SourceColumns.ENABLED, true);
sourceValues.put(Notification.SourceColumns.ICON_URI_1, iconSource1);
sourceValues.put(Notification.SourceColumns.ICON_URI_2, iconSource2);
sourceValues.put(Notification.SourceColumns.ICON_URI_BLACK_WHITE, iconBw);
sourceValues.put(Notification.SourceColumns.UPDATE_TIME, System.currentTimeMillis());
sourceValues.put(Notification.SourceColumns.NAME, mContext.getString(R.string.app_name));
sourceValues.put(Notification.SourceColumns.EXTENSION_SPECIFIC_ID, HelloExtensionService.EXTENSION_SPECIFIC_ID);
sourceValues.put(Notification.SourceColumns.PACKAGE_NAME, mContext.getPackageName());
sourceValues.put(Notification.SourceColumns.TEXT_TO_SPEECH, textToSpeech);
sourceValues.put(Notification.SourceColumns.ACTION_1,"Hello");
sourceValues.put(Notification.SourceColumns.ACTION_ICON_1,ExtensionUtils.getUriString(mContext, R.drawable.ic_launcher));
List<ContentValues> bulkValues = new ArrayList<ContentValues>();
bulkValues.add(sourceValues);
return bulkValues.toArray(new ContentValues[bulkValues.size()]);
}
}
Step 6: Create HelloExtensionService.java and extends with ExtensionService. It will contain main logic of SmartWatch host application. We need to implement two abstract methods named "getRegistrationInformation()", which sends object of HelloRegistrationInformation class and "keepRunningWhenConnected()",return true if you want to keep ExtensionService running as long as SmartWatch is connected with Smart Phone. For notification example we need to create two methods named "addData" and "clearData". It will generate and clear notification in SmartWatch respectively. We also need to implement onStartCommand to interact with Service.
Code:
package com.kpbird.hellosmartwatch;
import android.content.ContentValues;
import android.content.Intent;
import android.database.Cursor;
import android.database.SQLException;
import android.util.Log;
import android.widget.Toast;
import com.sonyericsson.extras.liveware.aef.notification.Notification;
import com.sonyericsson.extras.liveware.aef.registration.Registration;
import com.sonyericsson.extras.liveware.extension.util.ExtensionService;
import com.sonyericsson.extras.liveware.extension.util.ExtensionUtils;
import com.sonyericsson.extras.liveware.extension.util.notification.NotificationUtil;
import com.sonyericsson.extras.liveware.extension.util.registration.DeviceInfoHelper;
import com.sonyericsson.extras.liveware.extension.util.registration.RegistrationInformation;
public class HelloExtensionService extends ExtensionService {
public static final String EXTENSION_SPECIFIC_ID = "EXTENSION_SPECIFIC_ID_HELLO_NOTIFICATION";
public static final String EXTENSION_KEY = "com.kpbird.hellosmartwatch.key";
public static final String INTENT_ACTION_ADD = "com.kpbird.hellosmartwatch.action.add";
public static final String INTENT_ACTION_CLEAR = "com.kpbird.hellosmartwatch.action.clear";
private String TAG = this.getClass().getSimpleName();
public HelloExtensionService() {
super(EXTENSION_KEY);
Log.i(TAG, "Constructor");
}
@Override
public void onCreate() {
super.onCreate();
Log.i(TAG, "onCreate()");
}
@Override
public void onDestroy() {
super.onDestroy();
Log.i(TAG, "onDestroy()");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
int retVal = super.onStartCommand(intent, flags, startId);
if (intent != null) {
if (INTENT_ACTION_CLEAR.equals(intent.getAction())) {
Log.d(TAG, "onStart action: INTENT_ACTION_CLEAR");
clearData(intent);
stopSelfCheck();
} else if (INTENT_ACTION_ADD.equals(intent.getAction())) {
Log.d(TAG, "onStart action: INTENT_ACTION_ADD");
addData(intent);
stopSelfCheck();
}
}
return retVal;
}
@Override
protected RegistrationInformation getRegistrationInformation() {
return new HelloRegistrationInformation(this);
}
@Override
protected boolean keepRunningWhenConnected() {
return false;
}
private void clearData(Intent intent) {
NotificationUtil.deleteAllEvents(this);
}
private void addData(Intent intent) {
String name = "Name";
String message = "Message";
if (intent.getExtras().containsKey("name"))
name = intent.getExtras().getString("name");
if (intent.getExtras().containsKey("message"))
message = intent.getExtras().getString("message");
long time = System.currentTimeMillis();
long sourceId = NotificationUtil.getSourceId(this,
EXTENSION_SPECIFIC_ID);
Log.i(TAG, "Source ID :" + sourceId);
if (sourceId == NotificationUtil.INVALID_ID) {
Log.e(TAG, "Failed to insert data");
return;
}
String profileImage = ExtensionUtils.getUriString(this,R.drawable.ic_launcher);
ContentValues eventValues = new ContentValues();
eventValues.put(Notification.EventColumns.EVENT_READ_STATUS, false);
eventValues.put(Notification.EventColumns.DISPLAY_NAME, name);
eventValues.put(Notification.EventColumns.MESSAGE, message);
eventValues.put(Notification.EventColumns.PERSONAL, 1);
eventValues.put(Notification.EventColumns.PROFILE_IMAGE_URI,profileImage);
eventValues.put(Notification.EventColumns.PUBLISHED_TIME, time);
eventValues.put(Notification.EventColumns.SOURCE_ID, sourceId);
try {
getContentResolver().insert(Notification.Event.URI, eventValues);
} catch (IllegalArgumentException e) {
Log.e(TAG, "Failed to insert event", e);
} catch (SecurityException e) {
Log.e(TAG,
"Failed to insert event, is Live Ware Manager installed?",
e);
} catch (SQLException e) {
Log.e(TAG, "Failed to insert event", e);
}
}
@Override
protected void onViewEvent(Intent intent) {
String action = intent.getStringExtra(Notification.Intents.EXTRA_ACTION);
Log.i(TAG, "Action : " + action);
String hostAppPackageName = intent.getStringExtra(Registration.Intents.EXTRA_AHA_PACKAGE_NAME);
Log.i(TAG, "HostAppPackageName: " + hostAppPackageName);
boolean advancedFeaturesSupported = DeviceInfoHelper.isSmartWatch2ApiAndScreenDetected(this, hostAppPackageName);
Log.i(TAG, "Advanced Features Supported: " + advancedFeaturesSupported);
int eventId = intent.getIntExtra(Notification.Intents.EXTRA_EVENT_ID,-1);
try {
Cursor cursor = getContentResolver().query(Notification.Event.URI,null, Notification.EventColumns._ID + " = " + eventId,null, null);
if (cursor != null && cursor.moveToFirst()) {
String name = cursor.getString(cursor.getColumnIndex(Notification.EventColumns.DISPLAY_NAME));
String message = cursor.getString(cursor.getColumnIndex(Notification.EventColumns.MESSAGE));
Toast.makeText(this,"Notification: Name: " + name + " Message: " + message,Toast.LENGTH_LONG).show();
Log.i(TAG, "Name: " + name);
Log.i(TAG, "Message: "+ message);
}
cursor.close();
} catch (Exception ex) {
ex.printStackTrace();
}
}
@Override
public void onRegisterResult(boolean success) {
super.onRegisterResult(success);
Log.d(TAG, "onRegisterResult :" + success);
}
}
Step 7: Finally we need to register HelloExtensionReceiver and HelloExtensionService in AndroidManifest.xml like following. We also need to provide user permission "EXTENSION_PERMISSION".
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.kpbird.hellosmartwatch"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="16"
android:targetSdkVersion="16" />
<uses-permission android:name="com.sonyericsson.extras.liveware.aef.EXTENSION_PERMISSION" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.kpbird.hellosmartwatch.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=".HelloExtensionService" />
<receiver
android:name=".HelloExtensionReceiver"
android:permission="com.sonyericsson.extras.liveware.aef.HOSTAPP_PERMISSION" >
<intent-filter>
<!-- Generic extension intents. -->
<action android:name="com.sonyericsson.extras.liveware.aef.registration.EXTENSION_REGISTER_REQUEST" />
<action android:name="com.sonyericsson.extras.liveware.aef.registration.ACCESSORY_CONNECTION" />
<action android:name="android.intent.action.LOCALE_CHANGED" />
<!-- Notification intents -->
<action android:name="com.sonyericsson.extras.liveware.aef.notification.VIEW_EVENT_DETAIL" />
<action android:name="com.sonyericsson.extras.liveware.aef.notification.REFRESH_REQUEST" />
<!-- Widget intents -->
<action android:name="com.sonyericsson.extras.aef.widget.START_REFRESH_IMAGE_REQUEST" />
<action android:name="com.sonyericsson.extras.aef.widget.STOP_REFRESH_IMAGE_REQUEST" />
<action android:name="com.sonyericsson.extras.aef.widget.ONTOUCH" />
<action android:name="com.sonyericsson.extras.liveware.extension.util.widget.scheduled.refresh" />
<!-- Control intents -->
<action android:name="com.sonyericsson.extras.aef.control.START" />
<action android:name="com.sonyericsson.extras.aef.control.STOP" />
<action android:name="com.sonyericsson.extras.aef.control.PAUSE" />
<action android:name="com.sonyericsson.extras.aef.control.RESUME" />
<action android:name="com.sonyericsson.extras.aef.control.ERROR" />
<action android:name="com.sonyericsson.extras.aef.control.KEY_EVENT" />
<action android:name="com.sonyericsson.extras.aef.control.TOUCH_EVENT" />
<action android:name="com.sonyericsson.extras.aef.control.SWIPE_EVENT" />
</intent-filter>
</receiver>
</application>
</manifest>
Step 8: Connect your SmartPhone and run this example. It will display MainActivity. Before jumping to "Send Notification", open Accessory Emulator and select Extension to verify that our HelloExtension is installed or not. Click on extension menu and it will display the registration details. If extension gets registered successfully then you can go back to Hello SmartWatch application and play with Send and Clear Notification functionality.
Screen Shots
Download Source CodeNote: 1. Import project in eclipse 2. Make sure that you change SmartExtensionUtils and SmartExtensionAPI path from project properties.
guys please help i have stucked in this problem for a long time.
Code:
public class Activity_Calculator extends StandOutWindow {
@Override
public String getAppName() {
return "test";
}
@Override
public int getAppIcon() {
return android.R.drawable.ic_menu_close_clear_cancel;
}
@Override
public void createAndAttachView(int id, FrameLayout frame) {
// create a new layout from body.xml
LayoutInflater inflater = (LayoutInflater) getSystemService(LAYOUT_INFLATER_SERVICE);
View child= inflater.inflate(R.layout.activity_activity__calculator, frame, true);
WebView myWebView = (WebView)child.findViewById(R.id.webView1);
EditText field = (EditText)child.findViewById(R.id.urlField);
//myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.setWebViewClient(new MyBrowser());
//myWebView.getSettings().setJavaScriptEnabled(true);
//myWebView.getSettings().setPluginsEnabled(true);
//myWebView.getSettings().setDomStorageEnabled(true);
}
private class MyBrowser extends WebViewClient {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
}
// the window will be centered
@Override
public StandOutLayoutParams getParams(int id, Window window) {
return new StandOutLayoutParams(id, 500, 600,
StandOutLayoutParams.CENTER, StandOutLayoutParams.CENTER);
}
// move the window by dragging the view
@Override
public int getFlags(int id) {
return StandOutFlags.FLAG_DECORATION_SYSTEM
| StandOutFlags.FLAG_BODY_MOVE_ENABLE
| StandOutFlags.FLAG_WINDOW_HIDE_ENABLE
| StandOutFlags.FLAG_WINDOW_BRING_TO_FRONT_ON_TAP
| StandOutFlags.FLAG_WINDOW_EDGE_LIMITS_ENABLE
| StandOutFlags.FLAG_WINDOW_PINCH_RESIZE_ENABLE;
}
@Override
public String getPersistentNotificationMessage(int id) {
return "Click to close the SimpleWindow";
}
@Override
public Intent getPersistentNotificationIntent(int id) {
return StandOutWindow.getCloseIntent(this, Activity_Calculator.class, id);
}
}
xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android=
xmlns:tools=
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".Activity_Calculator" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<EditText
android:id="@+id/urlField"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignTop="@+id/textView1"
android:layout_centerHorizontal="true"
android:ems="10" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/urlField"
android:layout_centerHorizontal="true"
android:onClick="open"
/>
<WebView
android:id="@+id/webView1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignLeft="@+id/textView1"
android:layout_alignParentBottom="true"
android:layout_below="@+id/button1" />
</RelativeLayout>
the webview does not respond and the apps force closed, the attachment below is the logcat,guys please help
Since this site does not allow me to post to Developer forum, i post this Android Software development related question here.
I asked a question on Stackoverflow however nobody answered it. So i'm asking the same question here.
Its question topic is the same in the stackoverflow. Since i'm new i couldn't share the link here now.
I copy paste it below :
I developed a bottom sheet with the source codes shown below. However, when i change state of bottom sheet(by changing its state collapsed, expanded, or hide) onStateChanged and onSlide method is called forever. I don't understand why. Is this behaviour normal?
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private BottomSheetBehavior mBottomSheetBehavior;
@override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
View bottomSheet = findViewById( R.id.bottom_sheet );
Button button1 = (Button) findViewById( R.id.button_1 );
Button button2 = (Button) findViewById( R.id.button_2 );
Button button3 = (Button) findViewById( R.id.button_3 );
button1.setOnClickListener(this);
button2.setOnClickListener(this);
button3.setOnClickListener(this);
mBottomSheetBehavior = BottomSheetBehavior.from(bottomSheet);
mBottomSheetBehavior.setHideable(true);
mBottomSheetBehavior.setPeekHeight(300);
//mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
mBottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() {
@override
public void onStateChanged(View bottomSheet, int newState) {
Toast.makeText(getApplicationContext(), "onStateChanged() is called.", Toast.LENGTH_SHORT).show();
// this method is called forever i dont understand why???
}
@override
public void onSlide(View bottomSheet, float slideOffset) {
Toast.makeText(getApplicationContext(), "onStateChanged() is called. in onSlide()", Toast.LENGTH_SHORT).show();
// this method is also called forever i dont understand why???
}
});
}
@override
public void onClick(View v) {
switch( v.getId() ) {
case R.id.button_1: {
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED);
break;
}
case R.id.button_2: {
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED);
break;
}
case R.id.button_3: {
mBottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN);
break;
}
}
}
}
activity_main.xml
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
androidrientation="vertical"
androidaddingTop="24dp">
<Button
android:id="@+id/button_1"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Button 1"
androidadding="16dp"
android:layout_margin="8dp"
android:textColor="@android:color/white"
android:background="@android:color/holo_green_dark"/>
<Button
android:id="@+id/button_2"
android:layout_width="match_parent"
android:layout_height="wrap_content"
androidadding="16dp"
android:layout_margin="8dp"
android:text="Button 2"
android:textColor="@android:color/white"
android:background="@android:color/holo_blue_light"/>
<Button
android:id="@+id/button_3"
android:layout_width="match_parent"
android:layout_height="wrap_content"
androidadding="16dp"
android:layout_margin="8dp"
android:text="Button 3"
android:textColor="@android:color/white"
android:background="@android:color/holo_red_dark"/>
</LinearLayout>
</ScrollView>
<android.support.v4.widget.NestedScrollView
android:id="@+id/bottom_sheet"
android:layout_width="match_parent"
android:layout_height="350dp"
android:clipToPadding="true"
android:background="@android:color/holo_orange_light"
app:layout_behavior="android.support.design.widget.BottomSheetBehavior"
>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="@string/ipsum"
androidadding="16dp"
android:textSize="16sp"/>
</android.support.v4.widget.NestedScrollView>
Thanks in advance...
I have an android app which turns on a sensor on my device and collects and displays data in the app to the user.
On the home screen the user presses "START" which opens a new page that displays the data.
When the user presses the back button it take them back to the home page.
The problem I am facing is when the user presses "START" again, the display page still shows values from the previous test.
Here is the AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="19" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<!--<uses-permission android:name="com.google.android.things.permission.USE_PERIPHERAL_IO" />
<uses-permission android:name="com.google.android.things.permission.MANAGE_INPUT_DRIVERS" />-->
<application
android:allowBackup="true"
android:icon="@drawable/company"
android:label="Company"
android:theme="@style/TempTheme" >
<activity
android:clearTaskOnLaunch="true"
android:name="MainActivity"
android:label="Company" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Part of the MainActivity code:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.hrbp_main);
findViewById(R.id.btn_test_temp).setOnClickListener(this);
mWrist = (TextView) findViewById(R.id.txt_wrist);
mTemp = (TextView) findViewById(R.id.txt_temp);
ClearHistory();
}
@Override
protected void onNewIntent(Intent intent) {
Log.i("DHYCO", "onNewIntent:"+intent);
super.onNewIntent(intent);
}
@Override
public void onBackPressed() {
// TODO Auto-generated method stub
if (mCurrentTag != null) {
showFragment(false, mCurrentTag);
enableSensorOrNot(false);
startFlashSensor(false);
ClearHistory();
serviceconnection.StopCount();
mFlashThread = null;
} else
super.onBackPressed();
}
private void ClearHistory() {
Tempresult = -1;
Tempcircle = (ImageView) findViewById(R.id.Tempcircle);
}
@Override
protected void onStop() {
// TODO Auto-generated method stub
super.onStop();
ClearHistory();
enableSensorOrNot(false);
startFlashSensor(false);
serviceconnection.StopCount();
mFlashThread = null;
}
Spoiler
```java
if (type=="dialer") {
String timestamp = list.get(position).get(Constants.DATE);
holder.txtTimestamp.setVisibility(View.VISIBLE);
holder.imgDelete.setVisibility(View.GONE);
holder.txtTimestamp.setText(getDate(Long.parseLong(timestamp),"dd/MM/yyyy hh:mm:ss"));
if (Integer.parseInt(callType) == CallLog.Calls.BLOCKED_TYPE)
holder.imgCallType.setImageDrawable(context.getResources().getDrawable(R.drawable.block));
if (Integer.parseInt(callType) == CallLog.Calls.BLOCKED_TYPE)
holder.imgCallType.setImageDrawable(context.getResources().getDrawable(R.drawable.rejected));
if (Integer.parseInt(callType) == CallLog.Calls.OUTGOING_TYPE)
holder.imgCallType.setImageDrawable(context.getResources().getDrawable(R.drawable.outgoing_call));
if (Integer.parseInt(callType) == CallLog.Calls.INCOMING_TYPE)
holder.imgCallType.setImageDrawable(context.getResources().getDrawable(R.drawable.incoming_call));
if (Integer.parseInt(callType) == CallLog.Calls.MISSED_TYPE)
holder.imgCallType.setImageDrawable(context.getResources().getDrawable(R.drawable.missed_call));
if (Integer.parseInt(callType) == CallLog.Calls.ANSWERED_EXTERNALLY_TYPE)
holder.imgCallType.setImageDrawable(context.getResources().getDrawable(R.drawable.call_received));
}else if (type=="contact") {
holder.txtTimestamp.setVisibility(View.GONE);
holder.imgCallType.setVisibility(View.GONE);
holder.imgDelete.setVisibility(View.GONE);
}else if (type=="favourite"){
holder.txtTimestamp.setVisibility(View.GONE);
holder.imgCallType.setVisibility(View.GONE);
}
// listener
Bitmap finalBitmap = imgBitmap;
holder.imgPic.setOnLongClickListener(view -> {
CustomDialog imageDialog = new CustomDialog(activity,R.layout.image_dialog,"","","", finalBitmap);
imageDialog.setCancelable(true);
imageDialog.show();
return false;
});
holder.itemView.setOnLongClickListener(view->{
if (type=="dialer"){
}else if (type=="contact"){
Intent intent = new Intent(context, ContactDetailsActivity.class);
intent.putExtra("id",list.get(position).get(Constants.ID));
context.startActivity(intent);
}else if (type=="favourite"){
Intent intent = new Intent(context, FavouriteContactDetailsActivity.class);
intent.putExtra(Constants.FAVOURITE_ID,list.get(position).get(Constants.FAVOURITE_ID));
intent.putExtra(Constants.ID,list.get(position).get(Constants.ID));
ActivityOptions anim = ActivityOptions.makeSceneTransitionAnimation(activity);
context.startActivity(intent, anim.toBundle());
}
return false;
});
holder.imgDelete.setOnClickListener(v->{
SqliteFavourite sqliteFavourite = new SqliteFavourite(context.getApplicationContext());
boolean check = sqliteFavourite.deleteData("",list.get(position).get(Constants.ID));
if (check)
Snackbar.make(v,"Successfully deleted",Snackbar.LENGTH_SHORT).show();
else Snackbar.make(v,"Error occurred when deleting",Snackbar.LENGTH_SHORT).show();
});
holder.itemView.setOnClickListener(view->{
call(activity,phoneNumber);
});
```
I was using these code in an adapter.
```java
@override
public int getItemCount() {
return list.size();
}
@override
public int getItemViewType(int position) {
return position;
}
public class MyViewHolder extends RecyclerView.ViewHolder {
TextView txtContactName,txtContactNumber,txtTimestamp;
ImageView imgPic,imgCallType,imgDelete;
ConstraintLayout contactItem;
public MyViewHolder(@NonNull View itemView) {
super(itemView);
txtContactName = itemView.findViewById(R.id.txtName);
txtContactNumber = itemView.findViewById(R.id.txtContactNumber);
txtTimestamp = itemView.findViewById(R.id.txtTimestamp);
imgPic = itemView.findViewById(R.id.imgContact);
imgCallType = itemView.findViewById(R.id.imgCallType);
contactItem = itemView.findViewById(R.id.contactItem);
imgDelete = itemView.findViewById(R.id.imgDeleteContact);
}
}
```
Whenever I am clicking on first or second item then I can hear the clickListener. But when I click on 3rd 4th or higher item then I can't hear the clickListener. Even I had set a selector there but the selector is only working for 1st and 2nd
```xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:layout_width="match_parent"
android:layout_height="wrap_content"
androidadding="5dp">
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/contactItem"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/selector"
android:clickable="true">
<de.hdodenhof.circleimageview.CircleImageView
android:id="@+id/imgContact"
android:layout_width="50dp"
android:layout_height="0dp"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:src="@drawable/user_profile"
app:civ_border_color="#FF000000"
app:civ_border_width="2dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
tools:ignore="SpeakableTextPresentCheck" />
<TextView
android:id="@+id/txtName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="Name"
android:textStyle="bold"
app:layout_constraintBottom_toTopOf="@+id/txtContactNumber"
app:layout_constraintEnd_toStartOf="@+id/imgCallType"
app:layout_constraintStart_toEndOf="@+id/imgContact"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/txtContactNumber"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="Contact Number"
app:layout_constraintBottom_toTopOf="@iD/txtTimestamp"
app:layout_constraintEnd_toStartOf="@+id/imgCallType"
app:layout_constraintStart_toEndOf="@+id/imgContact"
app:layout_constraintTop_toBottomOf="@+id/txtName" />
<TextView
android:id="@+id/txtTimestamp"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:text="TextView"
android:textSize="12sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="@+id/txtContactNumber"
app:layout_constraintStart_toEndOf="@+id/imgContact"
app:layout_constraintTop_toBottomOf="@iD/txtContactNumber" />
<ImageView
android:id="@+id/imgCallType"
android:layout_width="30dp"
android:layout_height="30dp"
android:src="@drawable/call_received"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<ImageView
android:id="@+id/imgDeleteContact"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/selector"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@android:drawable/ic_menu_delete" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
```
When I scroll down then I can hear the listener but whenever I am on top at that layout then I can't access the listener in 3rd or more. Why it's happening? I am not getting any error in logcat. Although I can't click on some items why? I had tried to use `holder.contactItem.setOn....` but it wasn't working also.
<hr/>
When I scroll down I can listen the click. But whenever I am at top I can't listen. But I wonder I can click on Image. I meant `holder.imgPic.setOnLongClickListener.....`.
<hr/>
I have set `onTouchListener` to `itemView` but it's working. It's only not working for onCLickListener and onLongClickListener (As I said earlier it's working when I scroll down).
xxxxxx
MOD EDIT: Unnecessary link removed.