I've started to program an app in Android Studio and I downloaded Moverio SDK and sample from here: https://tech.moverio.epson.com/en/bt-35e/developers_guide/developing_android_apps.html#ac2-3-2
I'm able to set the glasses resolution and all the other stuff described in the doc, in short:
using a SurfaceView I can see a video preview on the device that come from glasses camera.
What I need to do is to use the glasses camera in a WebView that load an html page with AR javascript lib.
I've tried in a easy way to make it with ionic and all works great except that I can't setup camera resolution..
this is my code, I hope someone can help me. Thank you
//SetupActivity.java
package io.ionic.starter;
import android.os.Bundle;
import android.os.Handler;
import androidx.core.app.ActivityCompat;
import androidx.appcompat.app.AppCompatActivity;
import android.view.SurfaceView;
import android.view.WindowManager;
import android.widget.TextView;
import android.webkit.WebView;
import com.epson.moverio.hardware.camera.CameraDevice;
import com.epson.moverio.hardware.camera.CameraManager;
import com.epson.moverio.hardware.camera.CameraProperty;
import com.epson.moverio.hardware.camera.CaptureDataCallback;
import com.epson.moverio.hardware.camera.CaptureStateCallback;
import com.epson.moverio.util.PermissionHelper;
import java.io.IOException;
import java.util.Timer;
import java.util.TimerTask;
public class SetupActivity extends AppCompatActivity implements ActivityCompat.OnRequestPermissionsResultCallback {
private final String TAG = this.getClass().getSimpleName();
private CameraManager mCameraManager = null;
private CameraDevice mCameraDevice = null;
private SurfaceView mSurfaceView = null;
private PermissionHelper mPermissionHelper = null;
private TextView mTextView_captureRate = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_setup);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
mPermissionHelper = new PermissionHelper(this);
mCameraManager = new CameraManager(this);
}
private CaptureStateCallback mCaptureStateCallback = null;
private CaptureDataCallback mCaptureDataCallback = null;
private TimerTask mTimerTask = new TimerTask(){
#Override
public void run() {
mHandler.post( new Runnable() {
public void run() {
if(null != mTextView_captureRate) mTextView_captureRate.setText(String.valueOf(mFps) + "[fps]");
else ;
}
});
}
};
private Timer mTimer = null;
private Handler mHandler = new Handler();
private float mFps = 0;
private final Handler handler = new Handler();
#Override
protected void onStart() {
super.onStart();
mSurfaceView = (SurfaceView) findViewById(R.id.surfaceView);
mTimer = new Timer(true);
mTimer.schedule( mTimerTask, 1000, 1000);
//mTextView_captureRate = (TextView) findViewById(R.id.textView_rate);
String launchUrl = "";
WebView Webv = null;
try {
mCaptureStateCallback = new CaptureStateCallback() {
#Override
public void onCaptureStarted() {
mCameraDevice.startPreview();
}
#Override
public void onCaptureStopped() {
}
#Override
public void onPreviewStarted() {
//setContentView(R.layout.activity_testo);
// Load and use views afterwards
}
#Override
public void onPreviewStopped() {
}
#Override
public void onRecordStarted() {
}
#Override
public void onRecordStopped() {
}
#Override
public void onPictureCompleted() {
}
};
mCameraDevice = mCameraManager.open(mCaptureStateCallback, null, mSurfaceView.getHolder());
CameraProperty property = mCameraDevice.getProperty();
property.setExposureMode(CameraProperty.EXPOSURE_MODE_MANUAL);
property.setExposureStep(5);
property.setCaptureSize(1920, 1080);
property.setCaptureFps(30);
mCameraDevice.setProperty(property);
//mCameraDevice.startCapture();
mCameraDevice.startCapture();
TextView sample = (TextView)findViewById(R.id.textView3);
if(null != mCameraDevice){
if(null != property){
String str = "";
str += "Size : " + property.getCaptureSize()[0] + "x" + property.getCaptureSize()[1] + " / " + property.getCaptureFps() + " [fps] ";
str += "Exposure : " + (property.getExposureMode().equals(CameraProperty.EXPOSURE_MODE_AUTO) ? property.getExposureMode() + "(" + property.getExposureStep() + ")" : property.getExposureStep()) + " ";
str += "Brightness : " + property.getBrightness() + " ";
str += "Sharpness : " + property.getSharpness() + " ";
//str += "Whitebalance : " + (property.getWhiteBalanceMode().equals(CameraProperty.WHITE_BALANCE_MODE_AUTO) ? property.getWhiteBalanceMode() + "(" + property.getWhiteBalanceTemperature() + ")" : property.getWhiteBalanceTemperature()) + "\n";
//str += "PowerLineFrequency : " + property.getPowerLineFrequencyControlMode() + "\n";
str += "CaptureDataFormat : " + property.getCaptureDataFormat() + "\n";
sample.setText(str);
}
else {
sample.setText("null");
}
}
//sample.setText("Hello");
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
protected void onRestart() {
super.onRestart();
if(null != mCameraDevice) {
mCameraDevice.stopCapture();
} else;
}
#Override
protected void onStop(){
super.onStop();
if(null != mCameraDevice) {
mCameraDevice.stopCapture();
} else ;
}
#Override
protected void onDestroy() {
super.onDestroy();
if(null != mCameraDevice) {
mCameraDevice.stopCapture();
mCameraManager.close(mCameraDevice);
} else;
mTimer.cancel();
mTimer = null;
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
mPermissionHelper.onRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
and this is the xml
<!---activity_setup.xml-->
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout 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="match_parent"
tools:context=".SetupActivity">
<SurfaceView
android:id="#+id/surfaceView"
android:layout_width="965dp"
android:layout_height="541dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.161" />
<TextView
android:id="#+id/textView3"
android:layout_width="943dp"
android:layout_height="75dp"
android:text="Prova"
android:textColor="#FFFFFF"
android:textSize="24sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.157"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="1.0" />
</androidx.constraintlayout.widget.ConstraintLayout>
Related
I have to apply autocomplete inside home fragment in bottom nav menu but I am unable to type anything in search tab.
I am getting this interface but when I try to enter anything in the search tab it doesn't take any input as if it don't even open the keyboard:
My JavaScript code for homefragment is as follows:
public class HomeFragment extends Fragment implements OnMapReadyCallback {
private HomeViewModel homeViewModel;
FragmentHomeBinding binding;
private GoogleMap mMap;
private FusedLocationProviderClient fusedLocationProviderClient;
private LocationRequest locationRequest;
private LocationCallback locationCallback;
private Marker marker;
private MarkerOptions markerOptions;
SupportMapFragment mapFragment;
#Override
public void onDestroy() {
fusedLocationProviderClient.removeLocationUpdates(locationCallback);
super.onDestroy();
}
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater,
#Nullable ViewGroup container,
#Nullable Bundle savedInstanceState) {
((AppCompatActivity)getActivity()).getSupportActionBar().hide();
binding = FragmentHomeBinding.inflate(inflater, container, false);
homeViewModel = new ViewModelProvider(this).get(HomeViewModel.class);
mapFragment = (SupportMapFragment) getChildFragmentManager().findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
init();
return binding.getRoot();
}
private void setupAutoCompleteFragment()
{
SupportPlaceAutocompleteFragment autocompleteFragment = (SupportPlaceAutocompleteFragment) getChildFragmentManager().findFragmentById(R.id.place_autocomplete_fragment);
autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
}
#Override
public void onError(Status status) {
Log.e("Error", status.getStatusMessage());
}
});
}
#SuppressLint("MissingPermission")
private void init() {
locationRequest = new LocationRequest();
locationRequest.setSmallestDisplacement(10f);
locationRequest.setInterval(3000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setFastestInterval(1500);
locationCallback = new LocationCallback() {
#Override
public void onLocationResult(#NonNull LocationResult locationResult) {
super.onLocationResult(locationResult);
LatLng newPosition = new LatLng(locationResult.getLastLocation().getLatitude(), locationResult.getLastLocation().getLongitude());
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(newPosition, 18f));
}
;
};
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getContext());
fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallback, Looper.myLooper());
}
private void gotoLatLng(double latitude, double longitude, float v) {
LatLng latLng = new LatLng(latitude, longitude);
CameraUpdate update = CameraUpdateFactory.newLatLngZoom(latLng,18f);
mMap.animateCamera(update);
}
#Override
public void onMapReady(#NonNull GoogleMap googleMap) {
mMap = googleMap;
Dexter.withContext(getContext()).
withPermission(Manifest.permission.ACCESS_FINE_LOCATION)
.withListener(new PermissionListener() {
#SuppressLint("MissingPermission")
#Override
public void onPermissionGranted(PermissionGrantedResponse permissionGrantedResponse) {
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(true);
mMap.setOnMyLocationButtonClickListener(() -> {
fusedLocationProviderClient.getLastLocation().addOnFailureListener(e -> Toast.makeText(getContext(), "" + e.getMessage(), Toast.LENGTH_SHORT).show())
.addOnSuccessListener(location -> {
LatLng userLatLng = new LatLng(location.getLatitude(), location.getLongitude());
mMap.animateCamera(CameraUpdateFactory.newLatLngZoom(userLatLng, 21f));
});
return true;
});
View locationButton = ((View)mapFragment.getView().findViewById(Integer.parseInt("1")).getParent()).findViewById(Integer.parseInt("2"));
RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) locationButton.getLayoutParams();
params.addRule(RelativeLayout.ALIGN_PARENT_TOP, 0);
params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM,RelativeLayout.TRUE);
params.setMargins(0,0,0,50);
}
#Override
public void onPermissionDenied(PermissionDeniedResponse permissionDeniedResponse) {
Toast.makeText(getContext(), "Permission" + permissionDeniedResponse.getPermissionName() + "" + "was denied !", Toast.LENGTH_SHORT).show();
}
#Override
public void onPermissionRationaleShouldBeShown(PermissionRequest permissionRequest, PermissionToken permissionToken) {
permissionToken.continuePermissionRequest();
}
}).check();
}
}
And the layout used is for same fragment is as follows:
<?xml version="1.0" encoding="UTF-8" ?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.home.HomeFragment">
<fragment
android:id="#+id/map"
class="com.google.android.gms.maps.SupportMapFragment"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MapsActivity"
android:layout_gravity="center_horizontal|bottom" />
<androidx.cardview.widget.CardView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="#color/backcolor">
<fragment
android:id="#+id/place_autocomplete_fragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter Place"
android:background="#fff"
android:name="com.google.android.gms.location.places.ui.SupportPlaceAutocompleteFragment"
/>
</androidx.cardview.widget.CardView>
</FrameLayout>
Having issues with the app, shuts down any time I click on the chat button. I just submitted my manifest, gradle , xml, and the mainactivity to check what really went wrong. Thanks
I have an error from the logcat
GoldfishAddressSpaceHostMemoryAllocator: ioctl_ping failed for device_type=5, ret=-1.
So I don't know if this is the reason why it keeps shutting down any time I tap the button chat. The button chat is created in an activity.xml.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="c.bawp.securemessenger">
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#drawable/icon"
android:label="#string/app_name"
android:supportsRtl="true"
android:usesCleartextTraffic="true"
android:theme="#style/Theme.SecureMessenger">
<activity android:name=".MainActivity" />
<activity android:name=".Main2Activity" />
<activity android:name=".ChooseActivity" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity android:name=".FileExchangeActivity"></activity>
</application>
</manifest>
package c.bawp.securemessenger;
import android.app.Activity;
import android.app.Dialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.material.textfield.TextInputLayout;
import java.util.ArrayList;
import java.util.Objects;
import java.util.Set;
public class MainActivity extends AppCompatActivity {
private TextView status;
private Button btnConnect;
private ListView listView;
private Dialog dialog;
private TextInputLayout inputLayout;
private MessageAdapter messageAdapter;
private ArrayAdapter<String> chatAdapter;
private ArrayList<String> chatMessages;
private BluetoothAdapter bluetoothAdapter;
public static final int MESSAGE_STATE_CHANGE = 1;
public static final int MESSAGE_READ = 2;
public static final int MESSAGE_WRITE = 3;
public static final int MESSAGE_DEVICE_OBJECT = 4;
public static final int MESSAGE_TOAST = 5;
public static final String DEVICE_OBJECT = "device_name";
private static final int REQUEST_ENABLE_BLUETOOTH = 1;
private ChatController chatController;
private BluetoothDevice connectingDevice;
private ArrayAdapter<String> discoveredDevicesAdapter;
private Encrypt encrypt;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
findViewsByIds();
//check device support bluetooth or not
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (bluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available!", Toast.LENGTH_SHORT).show();
finish();
}
//show bluetooth devices dialog when click connect button
btnConnect.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
showPrinterPickDialog();
}
});
//set chat adapter
messageAdapter = new MessageAdapter(this);
listView.setAdapter(messageAdapter);
encrypt = new Encrypt();
}
private final Handler handler = new Handler(new Handler.Callback() {
#Override
public boolean handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case ChatController.STATE_CONNECTED:
setStatus("Connected to: " + connectingDevice.getName());
btnConnect.setVisibility(View.INVISIBLE);
break;
case ChatController.STATE_CONNECTING:
setStatus("Connecting...");
//btnConnect.setEnabled(false);
break;
case ChatController.STATE_LISTEN:
case ChatController.STATE_NONE:
setStatus("Not connected");
break;
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
String writeMessage = new String(writeBuf);
writeMessage = encrypt.decrypt(writeMessage);
//check out
MemberData data1 = new MemberData("Me","#C62828");
c.bawp.securemessenger.Message message1 = new c.bawp.securemessenger.Message(writeMessage, data1, true);
messageAdapter.add(message1);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
String readMessage = new String(readBuf, 0, msg.arg1);
readMessage = encrypt.decrypt(readMessage);
MemberData data2 = new MemberData(connectingDevice.getName(),"#C62828");
Log.d("Bug", "handleMessage: " + readMessage);
c.bawp.securemessenger.Message message2 = new c.bawp.securemessenger.Message(readMessage, data2, false);
messageAdapter.add(message2);
break;
case MESSAGE_DEVICE_OBJECT:
connectingDevice = msg.getData().getParcelable(DEVICE_OBJECT);
Toast.makeText(getApplicationContext(), "Connected to " + connectingDevice.getName(),
Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString("toast"),
Toast.LENGTH_SHORT).show();
break;
}
return false;
}
});
private void showPrinterPickDialog() {
dialog = new Dialog(this);
dialog.setContentView(R.layout.layout_bluetooth);
dialog.setTitle("Bluetooth Devices");
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
bluetoothAdapter.startDiscovery();
//Initializing bluetooth adapters
ArrayAdapter<String> pairedDevicesAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
discoveredDevicesAdapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1);
//locate listviews and attach the adapters
ListView listView = dialog.findViewById(R.id.pairedDeviceList);
ListView listView2 = dialog.findViewById(R.id.discoveredDeviceList);
listView.setAdapter(pairedDevicesAdapter);
listView2.setAdapter(discoveredDevicesAdapter);
// Register for broadcasts when a device is discovered
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(discoveryFinishReceiver, filter);
// Register for broadcasts when discovery has finished
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = bluetoothAdapter.getBondedDevices();
// If there are paired devices, add each one to the ArrayAdapter
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
pairedDevicesAdapter.add(device.getName() + "\n" + device.getAddress());
}
} else {
pairedDevicesAdapter.add(getString(R.string.none_paired));
}
//Handling listview item click event
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
bluetoothAdapter.cancelDiscovery();
String info = ((TextView) view).getText().toString();
String address = info.substring(info.length() - 17);
connectToDevice(address);
dialog.dismiss();
}
});
listView2.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
bluetoothAdapter.cancelDiscovery();
String info = ((TextView) view).getText().toString();
String address = info.substring(info.length() - 17);
connectToDevice(address);
dialog.dismiss();
}
});
dialog.findViewById(R.id.cancelButton).setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
dialog.dismiss();
}
});
dialog.setCancelable(true);
dialog.show();
}
private void setStatus(String s) {
status.setText(s);
}
private void connectToDevice(String deviceAddress) {
bluetoothAdapter.cancelDiscovery();
BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceAddress);
chatController.connect(device);
}
private void findViewsByIds() {
status = findViewById(R.id.status);
btnConnect = findViewById(R.id.btn_connect);
listView = findViewById(R.id.list);
inputLayout = findViewById(R.id.input_layout);
Button btnSend = findViewById(R.id.btn_send);
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (Objects.requireNonNull(inputLayout.getEditText()).getText().toString().equals("")) {
Toast.makeText(MainActivity.this, "Please input some texts", Toast.LENGTH_SHORT).show();
} else {
//TODO: here
sendMessage(inputLayout.getEditText().getText().toString());
inputLayout.getEditText().setText("");
}
}
});
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_ENABLE_BLUETOOTH) {
if (resultCode == Activity.RESULT_OK) {
chatController = new ChatController(this, handler);
} else {
Toast.makeText(this, "Bluetooth still disabled, turn off application!", Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void sendMessage(String message) {
if (chatController.getState() != ChatController.STATE_CONNECTED) {
Toast.makeText(this, "Connection was lost!", Toast.LENGTH_SHORT).show();
return;
}
if (message.length() > 0) {
message = encrypt.encrypt(message);
byte[] send = message.getBytes();
chatController.write(send);
}
}
#Override
public void onStart() {
super.onStart();
if (!bluetoothAdapter.isEnabled()) {
Intent dIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
dIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 3000);
startActivity(dIntent);
} else {
chatController = new ChatController(this, handler);
}
}
#Override
public void onResume() {
super.onResume();
if (chatController != null) {
if (chatController.getState() == ChatController.STATE_NONE) {
chatController.start();
}
}
}
#Override
public void onDestroy() {
super.onDestroy();
if (chatController != null)
chatController.stop();
}
private final BroadcastReceiver discoveryFinishReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// When discovery finds a device
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// If it's already paired, skip it, because it's been listed already
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
discoveredDevicesAdapter.add(device.getName() + "\n" + device.getAddress());
}
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
discoveredDevicesAdapter.clear();
//setProgressBarIndeterminateVisibility(false);
// setSupportProgressBarIndeterminateVisibility(true);
setTitle("Select a device to connect");
if (discoveredDevicesAdapter.getCount() == 0) {
discoveredDevicesAdapter.add("No devices found");
}
} else {
discoveredDevicesAdapter.add("Scanning Bluetooth Devices....");
}
}
};
}
I have been trying to add a prediction list of places in my 2 AutoCompleteTextView and I also achieved it in my project but now my DashboardActivity is giving error in setting the adapter. The type of error casting error when setting an adapter
activity_dashboard.xml
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
app:layout_behavior="#string/appbar_scrolling_view_behavior">
<fragment
android:id="#+id/map"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:name="com.google.android.gms.maps.SupportMapFragment" />
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:src="#drawable/map_marker"
/>
<RelativeLayout
android:id="#+id/pickupRL"
android:layout_width="match_parent"
android:layout_alignParentTop="true"
android:layout_height="50dp"
android:layout_marginTop="5pt"
android:layout_marginLeft="10pt"
android:layout_marginRight="10pt"
android:elevation="4pt"
android:background="#drawable/white_border" >
<ImageView
android:id="#+id/pickupIV"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginRight="3pt"
android:layout_centerVertical="true"
android:layout_marginLeft="5pt"
android:src="#drawable/ic_search"
app:tint="#color/colorPrimaryDark"/>
<AutoCompleteTextView
android:id="#+id/pickupATV"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="#+id/pickupIV"
android:layout_centerVertical="true"
android:textSize="15sp"
android:textColor="#color/colorBlack"
android:background="#null"
android:hint="Search location"
android:singleLine="true"
android:imeOptions="actionSearch"/>
</RelativeLayout>
<RelativeLayout
android:id="#+id/dropoffRL"
android:layout_marginTop="5pt"
android:layout_below="#id/pickupRL"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_marginLeft="10pt"
android:layout_marginRight="10pt"
android:elevation="4pt"
android:background="#drawable/white_border" >
<ImageView
android:id="#+id/dropoffIV"
android:layout_width="15dp"
android:layout_height="15dp"
android:layout_marginRight="3pt"
android:layout_centerVertical="true"
android:layout_marginLeft="5pt"
android:src="#drawable/ic_search"
app:tint="#color/colorPrimaryDark"/>
<AutoCompleteTextView
android:id="#+id/dropoffATV"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_toRightOf="#+id/dropoffIV"
android:layout_centerVertical="true"
android:textSize="15sp"
android:textColor="#color/colorBlack"
android:background="#null"
android:hint="Search location"
android:singleLine="true"
android:imeOptions="actionSearch"/>
</RelativeLayout>
<Button
android:id="#+id/btnconfirm"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_marginBottom="30dp"
android:layout_marginLeft="15dp"
android:layout_marginRight="15dp"
android:padding="20dp"
android:text="Comfirm" />
<com.google.android.material.floatingactionbutton.FloatingActionButton
android:id="#+id/currentLocationFAB"
android:backgroundTint="#color/colorWhite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="#id/btnconfirm"
android:layout_alignParentRight="true"
android:layout_marginBottom="5pt"
android:layout_marginRight="10pt"
android:elevation="4pt"
app:fabSize="mini"
app:borderWidth="0dp"
app:elevation="4pt"
app:backgroundTint="#color/colorWhite"
android:src="#drawable/ic_current_location"
android:tint="#color/colorPrimaryDark"/>
</RelativeLayout>
DashboardActivity.java
public class DashboardActivity extends AppCompatActivity implements OnMapReadyCallback, View.OnClickListener, GoogleApiClient.OnConnectionFailedListener {
private Activity activity;
private GoogleMap mMap;
private static final String Tag = "MAP_ACTIVITY";
private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
private static final String COURSE_LOCATION = Manifest.permission.ACCESS_COARSE_LOCATION;
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
private static final float DEFAULT_ZOOM = 15f;
private static final LatLngBounds LAT_LNG_BOUNDS = new LatLngBounds(
new LatLng(-40, -168), new LatLng(71, 136));
private Boolean mLocationPermissionsGranted = false;
private FusedLocationProviderClient mFusedLocationProviderClient;
private final ThreadLocal<PlaceAutocompleteAdapter> mplaceAutoCompeleteAdapter = new ThreadLocal<>();
private GoogleApiClient mGoogleApiClient;
private PlaceInfo mPlace;
private AutoCompleteTextView pickupATV, dropoffATV;
private Button btnconfirm;
private FloatingActionButton currentLocationFAB;
private Toolbar toolbar;
private MenuItem previousItem;
private UtilityModel utilityModel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_dashboard);
bindControls();
bindListeners();
getLocationPermission();
setMap();
}
private void getLocationPermission() {
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION};
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
COURSE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionsGranted = true;
setMap();
} else {
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
} else {
ActivityCompat.requestPermissions(this,
permissions,
LOCATION_PERMISSION_REQUEST_CODE);
}
}
private void bindControls() {
activity = DashboardActivity.this;
utilityModel = new UtilityModel(activity);
toolbar = findViewById(R.id.toolbar);
btnconfirm = findViewById(R.id.btnconfirm);
pickupATV = findViewById(R.id.pickupATV);
dropoffATV = findViewById(R.id.dropoffATV);
currentLocationFAB = findViewById(R.id.currentLocationFAB);
}
private void bindListeners() {
btnconfirm.setOnClickListener(this);
mGoogleApiClient = new GoogleApiClient
.Builder(this)
.addApi(com.google.android.gms.location.places.Places.GEO_DATA_API)
.addApi(Places.PLACE_DETECTION_API)
.enableAutoManage(this, this)
.build();
mplaceAutoCompeleteAdapter.set(new PlaceAutocompleteAdapter(activity, mGoogleApiClient, LAT_LNG_BOUNDS, null));
pickupATV.setOnItemClickListener(mAutocompleteClickListener);
pickupATV.setAdapter(mplaceAutoCompeleteAdapter); // This adapter is causing the trouble
pickupATV.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if (actionId == EditorInfo.IME_ACTION_SEARCH
|| actionId == EditorInfo.IME_ACTION_DONE
|| keyEvent.getAction() == KeyEvent.ACTION_DOWN
|| keyEvent.getAction() == KeyEvent.KEYCODE_ENTER) {
//execute our method for searching
geoLocate(pickupATV);
}
return false;
}
});
dropoffATV.setOnItemClickListener(mAutocompleteClickListener);
mplaceAutoCompeleteAdapter.set(new PlaceAutocompleteAdapter(activity, mGoogleApiClient, LAT_LNG_BOUNDS, null));
dropoffATV.setAdapter(mplaceAutoCompeleteAdapter); // This adapter is causing the trouble
dropoffATV.setOnEditorActionListener(new TextView.OnEditorActionListener() {
#Override
public boolean onEditorAction(TextView textView, int actionId, KeyEvent keyEvent) {
if (actionId == EditorInfo.IME_ACTION_SEARCH
|| actionId == EditorInfo.IME_ACTION_DONE
|| keyEvent.getAction() == KeyEvent.ACTION_DOWN
|| keyEvent.getAction() == KeyEvent.KEYCODE_ENTER) {
//execute our method for searching
geoLocate(dropoffATV);
}
return false;
}
});
currentLocationFAB.setOnClickListener(this);
utilityModel.hideSoftKeyboard();
}
private AdapterView.OnItemClickListener mAutocompleteClickListener = new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
utilityModel.hideSoftKeyboard();
final AutocompletePrediction item = mplaceAutoCompeleteAdapter.get().getItem(i);
final String placeId = item.getPlaceId();
PendingResult<PlaceBuffer> placeResult = Places.GeoDataApi
.getPlaceById(mGoogleApiClient, placeId);
placeResult.setResultCallback(mUpdatePlaceDetailsCallback);
}
};
private ResultCallback<PlaceBuffer> mUpdatePlaceDetailsCallback = new ResultCallback<PlaceBuffer>() {
#SuppressLint("RestrictedApi")
#Override
public void onResult(#NonNull PlaceBuffer places) {
if(!places.getStatus().isSuccess()){
Log.d(Tag, "onResult: Place query did not complete successfully: " + places.getStatus().toString());
places.release();
return;
}
final Place place = places.get(0);
try{
mPlace = new PlaceInfo();
mPlace.setName(place.getName().toString());
Log.d(Tag, "onResult: name: " + place.getName());
mPlace.setAddress(place.getAddress().toString());
Log.d(Tag, "onResult: address: " + place.getAddress());
mPlace.setAttributions(place.getAttributions().toString());
// Log.d(TAG, "onResult: attributions: " + place.getAttributions());
mPlace.setId(place.getId());
Log.d(Tag, "onResult: id:" + place.getId());
mPlace.setLatlng(place.getLatLng());
Log.d(Tag, "onResult: latlng: " + place.getLatLng());
mPlace.setRating(place.getRating());
Log.d(Tag, "onResult: rating: " + place.getRating());
mPlace.setPhoneNumber(place.getPhoneNumber().toString());
Log.d(Tag, "onResult: ic_phone number: " + place.getPhoneNumber());
mPlace.setWebsiteUri(place.getWebsiteUri());
Log.d(Tag, "onResult: website uri: " + place.getWebsiteUri());
Log.d(Tag, "onResult: place: " + mPlace.toString());
}catch (NullPointerException e){
Log.e(Tag, "onResult: NullPointerException: " + e.getMessage() );
}
setMarkerAndMoveCamera(new LatLng(place.getViewport().getCenter().latitude,
place.getViewport().getCenter().longitude), mPlace);
currentLocationFAB.setVisibility(View.VISIBLE);
places.release();
}
};
private void geoLocate(AutoCompleteTextView view) {
String searchString = view.getText().toString().trim();
Geocoder geocoder = new Geocoder(activity);
List<Address> list = new ArrayList<>();
try {
list = geocoder.getFromLocationName(searchString, 1);
} catch (IOException e) {
Log.e(Tag, "geoLocate: IOException: " + e.getMessage());
}
if (list.size() > 0) {
Address address = list.get(0);
setMarkerAndMoveCamera(new LatLng(address.getLatitude(), address.getLongitude()), null);
}
}
private void setMap() {
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if (mLocationPermissionsGranted) {
getCurrentLocation();
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mMap.setMyLocationEnabled(true);
mMap.getUiSettings().setMyLocationButtonEnabled(false);
mMap.setOnCameraMoveListener(new GoogleMap.OnCameraMoveListener() {
#SuppressLint("RestrictedApi")
#Override
public void onCameraMove() {
currentLocationFAB.setVisibility(View.VISIBLE);
}
});
mMap.setOnMarkerDragListener(new GoogleMap.OnMarkerDragListener() {
#Override
public void onMarkerDragStart(Marker marker) {
}
#Override
public void onMarkerDrag(Marker marker) {
}
#SuppressLint("RestrictedApi")
#Override
public void onMarkerDragEnd(Marker marker) {
setMarkerAndMoveCamera(marker.getPosition(), null);
currentLocationFAB.setVisibility(View.VISIBLE);
}
});
mMap.setOnMapClickListener(new GoogleMap.OnMapClickListener() {
#SuppressLint("RestrictedApi")
#Override
public void onMapClick(LatLng latLng) {
setMarkerAndMoveCamera(latLng, null);
currentLocationFAB.setVisibility(View.VISIBLE);
}
});
}
}
private void getCurrentLocation() {
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
try {
if (mLocationPermissionsGranted) {
final Task location = mFusedLocationProviderClient.getLastLocation();
location.addOnCompleteListener(new OnCompleteListener() {
#Override
public void onComplete(#NonNull Task task) {
if (task.isSuccessful()) {
Log.d(Tag, "onComplete: found location!");
Location currentLocation = (Location) task.getResult();
setMarkerAndMoveCamera(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()),null);
} else {
Log.d(Tag, "onFailed: current location is null");
Toast.makeText(activity, "unable to get current location", Toast.LENGTH_SHORT).show();
}
}
});
}
} catch (SecurityException e) {
Log.e(Tag, "getCurrentLocation: SecurityException: " + e.getMessage());
}
}
private void setMarkerAndMoveCamera(LatLng latLng, PlaceInfo placeInfo){
mMap.clear();
mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, DEFAULT_ZOOM));
}
#SuppressLint("RestrictedApi")
#Override
public void onClick(View v) {
if (v == btnconfirm) {
// LatLng currentMarkerLocation = mMap.getCameraPosition().target;
} else if (v == currentLocationFAB) {
currentLocationFAB.setVisibility(View.INVISIBLE);
getCurrentLocation();
}
}
#Override
public void onConnectionFailed(#NonNull ConnectionResult connectionResult) {
}
}
PlaceInfo.java
public class PlaceInfo {
private String name;
private String address;
private String phoneNumber;
private String id;
private Uri websiteUri;
private LatLng latlng;
private float rating;
private String attributions;
public PlaceInfo(String name, String address, String phoneNumber, String id, Uri websiteUri,
LatLng latlng, float rating, String attributions) {
this.name = name;
this.address = address;
this.phoneNumber = phoneNumber;
this.id = id;
this.websiteUri = websiteUri;
this.latlng = latlng;
this.rating = rating;
this.attributions = attributions;
}
public PlaceInfo() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public Uri getWebsiteUri() {
return websiteUri;
}
public void setWebsiteUri(Uri websiteUri) {
this.websiteUri = websiteUri;
}
public LatLng getLatlng() {
return latlng;
}
public void setLatlng(LatLng latlng) {
this.latlng = latlng;
}
public float getRating() {
return rating;
}
public void setRating(float rating) {
this.rating = rating;
}
public String getAttributions() {
return attributions;
}
public void setAttributions(String attributions) {
this.attributions = attributions;
}
#Override
public String toString() {
return "PlaceInfo{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
", phoneNumber='" + phoneNumber + '\'' +
", id='" + id + '\'' +
", websiteUri=" + websiteUri +
", latlng=" + latlng +
", rating=" + rating +
", attributions='" + attributions + '\'' +
'}';
}
}
PlaceAutocompleteAdapter.java
public class PlaceAutocompleteAdapter
extends ArrayAdapter<AutocompletePrediction> implements Filterable {
private static final String TAG = "PlaceAutocompleteAd";
private static final CharacterStyle STYLE_BOLD = new StyleSpan(Typeface.BOLD);
private ArrayList<AutocompletePrediction> mResultList;
private GoogleApiClient mGoogleApiClient;
private LatLngBounds mBounds;
private AutocompleteFilter mPlaceFilter;
public PlaceAutocompleteAdapter(Context context, GoogleApiClient googleApiClient,
LatLngBounds bounds, AutocompleteFilter filter) {
super(context, android.R.layout.simple_expandable_list_item_2, android.R.id.text1);
mGoogleApiClient = googleApiClient;
mBounds = bounds;
mPlaceFilter = filter;
}
public void setBounds(LatLngBounds bounds) {
mBounds = bounds;
}
#Override
public int getCount() {
return mResultList.size();
}
#Override
public AutocompletePrediction getItem(int position) {
return mResultList.get(position);
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View row = super.getView(position, convertView, parent);
AutocompletePrediction item = getItem(position);
TextView textView1 = row.findViewById(android.R.id.text1);
TextView textView2 = row.findViewById(android.R.id.text2);
textView1.setText(item.getPrimaryText(STYLE_BOLD));
textView2.setText(item.getSecondaryText(STYLE_BOLD));
return row;
}
#Override
public Filter getFilter() {
return new Filter() {
#Override
protected FilterResults performFiltering(CharSequence constraint) {
FilterResults results = new FilterResults();
ArrayList<AutocompletePrediction> filterData = new ArrayList<>();
if (constraint != null) {
filterData = getAutocomplete(constraint);
}
results.values = filterData;
if (filterData != null) {
results.count = filterData.size();
} else {
results.count = 0;
}
return results;
}
#Override
protected void publishResults(CharSequence constraint, FilterResults results) {
if (results != null && results.count > 0) {
mResultList = (ArrayList<AutocompletePrediction>) results.values;
notifyDataSetChanged();
} else {
notifyDataSetInvalidated();
}
}
#Override
public CharSequence convertResultToString(Object resultValue) {
if (resultValue instanceof AutocompletePrediction) {
return ((AutocompletePrediction) resultValue).getFullText(null);
} else {
return super.convertResultToString(resultValue);
}
}
};
}
private ArrayList<AutocompletePrediction> getAutocomplete(CharSequence constraint) {
if (mGoogleApiClient.isConnected()) {
Log.i(TAG, "Starting autocomplete query for: " + constraint);
PendingResult<AutocompletePredictionBuffer> results =
Places.GeoDataApi
.getAutocompletePredictions(mGoogleApiClient, constraint.toString(),
mBounds, mPlaceFilter);
AutocompletePredictionBuffer autocompletePredictions = results
.await(60, TimeUnit.SECONDS);
final Status status = autocompletePredictions.getStatus();
if (!status.isSuccess()) {
Toast.makeText(getContext(), "Error contacting API: " + status.toString(),
Toast.LENGTH_SHORT).show();
Log.e(TAG, "Error getting autocomplete prediction API call: " + status.toString());
autocompletePredictions.release();
return null;
}
Log.i(TAG, "Query completed. Received " + autocompletePredictions.getCount()
+ " predictions.");
return DataBufferUtils.freezeAndClose(autocompletePredictions);
}
Log.e(TAG, "Google API client is not connected for autocomplete query.");
return null;
}
}
My Error is located in DashboardActivity.java in bindListener method on pickupATV.setAdapter and dropoffATV.setAdapter
Build Error
Task :app:compileDebugJavaWithJavac FAILED
/Users/muhammadyousuf/StudioProjects/homemoversfyp/app/src/main/java/com/example/daniyal/fyp_project/activities/DashboardActivity.java:162:
error: method setAdapter in class AutoCompleteTextView cannot be
applied to given types;
pickupATV.setAdapter(mplaceAutoCompeleteAdapter); // This adapter is causing the trouble
^ required: T found: ThreadLocal reason: inferred type does not
conform to upper bound(s)
inferred: ThreadLocal
upper bound(s): ListAdapter,Filterable where T is a type-variable:
T extends ListAdapter,Filterable declared in method setAdapter(T)
/Users/muhammadyousuf/StudioProjects/homemoversfyp/app/src/main/java/com/example/daniyal/fyp_project/activities/DashboardActivity.java:181:
error: method setAdapter in class AutoCompleteTextView cannot be
applied to given types;
dropoffATV.setAdapter(mplaceAutoCompeleteAdapter); // This adapter is causing the trouble
^ required: T found: ThreadLocal reason: inferred type does not
conform to upper bound(s)
inferred: ThreadLocal
upper bound(s): ListAdapter,Filterable where T is a type-variable:
T extends ListAdapter,Filterable declared in method setAdapter(T) Note: Some input files use or override a deprecated
API. Note: Recompile with -Xlint:deprecation for details. Note:
/Users/muhammadyousuf/StudioProjects/homemoversfyp/app/src/main/java/com/example/daniyal/fyp_project/activities/DashboardActivity.java
uses unchecked or unsafe operations. Note: Recompile with
-Xlint:unchecked for details. 2 errors
FAILURE: Build failed with an exception.
What went wrong: Execution failed for task
':app:compileDebugJavaWithJavac'. Compilation failed; see the compiler
error output for details.
I solved it myself by using another approach that is the new one used in the docs by developers.google.com. I used the first approach to add as an autocomplete widget.
on my activity's onCreate i initialised Places instance.
Places.initialize(getApplicationContext(), getResources().getString(R.string.google_maps_key));
PlacesClient placesClient = Places.createClient(activity);
again on my onCreate i initialised and declared my pickupFragment and bind it with a listener.
pickupFragment = (AutocompleteSupportFragment) getSupportFragmentManager().findFragmentById(R.id.pickupFragment);
pickupFragment.setCountry("PK");
pickupFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME, Place.Field.ADDRESS, Place.Field.LAT_LNG));
pickupFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
#Override
public void onPlaceSelected(Place place) {
// TODO: Get info about the selected place.
Log.e(TAG, "Place: " + place.getName() + ", " + place.getId() + ", " + place.getLatLng());
}
#Override
public void onError(Status status) {
// TODO: Handle the error.
Log.e(TAG, "An error occurred: " + status);
}
});
and used this piece of code in my xml
<fragment
android:id="#+id/pickupFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:name="com.google.android.libraries.places.widget.AutocompleteSupportFragment" />
I did this for both my pickupFragment and dropoffFragment.
I'm hoping someone can help me. I have created a Sudoku app. I have a grid view that shows string text from a list view. I have a problem with my layout of the Grid View on my phone and tablet; , see 1st and 2nd screens below .
What I'm trying to do is set the screen, so the grid display neatly just above the numbers 1 to 5. Ideally I'd like it to render appropriately on tablet and phone.
On a Phone the last row of the sudoku grid showing underneath the first set of button button See firstImage. Whereas on a Tablet there is a huge gap between the gridvview and the Buttons
What I have I tried so far:
I tried android:layout_above btn1. But that chopped off the last row of the sudoku grid and I had to drag the grid up and down to see the last row on a phone. It also caused the app to crash of a phone. Not good.
I tried putting a frame layout inside the relative layout and putting the gridview inside of that. But that had the also chopped off the last row of the sudoku grid as per layout_above.
Really what I'd like to do is, on a phone I would like to remove or reduce the padding above and below each number in each cell in the grid view. As the cell padding makes each cell in the grid 2 - 3 times bigger than it needs to be. This is a problem on a 5" mobile phone screen. I have tried the following and none of them worked.
How do I get rid of unwanted padding in a Listview row
android:gravity - Made no Difference
How to avoid space between imageview and gridview in linearlayout
listSelector=”#null” - Made no difference
Removing the extra padding in a GridView in android
stretchMode(0); - Everything disappeared.
How do I get rid of unwanted padding in a Listview row
view.setMinimumHeight(0); - Made no difference.
I also tried view.setPadding(); it was useful in that the padding on the left hand side was removed, but it didn't remove the papdding at the top or bottom.
view.setPadding(dpToPx(0, parent), 0, 0, 0);
I am at a loss at this stage about how to move this forward and am worried that trying all these different things is making me more confused. If someone could point me in the correct direction I'd be very grateful. Code is shown below.
content_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout 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="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"
app:layout_behavior="#string/appbar_scrolling_view_behavior"
tools:context="com.example.admin1.sudoku.MainActivity"
android:background="#663399"
tools:showIn="#layout/activity_main">
<Button
android:id="#+id/btn1"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn1Label"
android:layout_above="#+id/btn6"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignBottom="#+id/btn2"
/>
<Button
android:id="#+id/btn2"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn2Label"
android:layout_above="#+id/btn7"
android:layout_toLeftOf="#+id/btn8"
android:layout_toStartOf="#+id/btn8" />
<Button
android:id="#+id/btn3"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn3Label"
android:layout_alignTop="#+id/btn2"
android:layout_toRightOf="#+id/btn2"
android:layout_toEndOf="#+id/btn2" />
<Button
android:id="#+id/btn4"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn4Label"
android:layout_alignTop="#+id/btn3"
android:layout_toRightOf="#+id/btn3"
android:layout_toEndOf="#+id/btn3" />
<Button
android:id="#+id/btn5"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn5Label"
android:layout_alignTop="#+id/btn4"
android:layout_toRightOf="#+id/btn4"
android:layout_toEndOf="#+id/btn4" />
<Button
android:id="#+id/btn6"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn6Label"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<Button
android:id="#+id/btn7"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn7Label"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/btn6"
android:layout_toEndOf="#+id/btn6" />
<Button
android:id="#+id/btn8"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn8Label"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/btn7"
android:layout_toEndOf="#+id/btn7" />
<Button
android:id="#+id/btn9"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn9Label"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/btn3"
android:layout_toEndOf="#+id/btn3" />
<Button
android:id="#+id/btn0"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btn0Label"
android:layout_alignParentBottom="true"
android:layout_toRightOf="#+id/btn9"
android:layout_toEndOf="#+id/btn9" />
<Button
android:id="#+id/btnCheck"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btnCheckLabel"
android:layout_below="#+id/gridView1"
android:layout_alignTop="#+id/btn5"
android:layout_toRightOf="#+id/btn5"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:id="#+id/btnHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/btnHintLabel"
android:layout_alignTop="#+id/btn0"
android:layout_alignParentBottom="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignLeft="#+id/btnCheck"
android:layout_alignStart="#+id/btnCheck" />
<GridView
android:id="#+id/gridView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:numColumns="9"
android:columnWidth="0dp"
android:horizontalSpacing="5dp"
android:verticalSpacing="5dp"
android:clipChildren="true"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:background="#C0C0C0"
android:padding="5dp"
android:textSize="12sp"
android:stretchMode="columnWidth"
android:gravity="clip_vertical"
/>
</RelativeLayout>
MainActivity.java
package com.example.admin1.sudoku;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.DisplayMetrics;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.GridView;
import android.widget.ArrayAdapter;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.graphics.Color;
import android.widget.Toast;
import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import android.content.res.Resources;
import android.media.MediaPlayer;
public class MainActivity extends AppCompatActivity {
// Class that holds the creation of a Sudoku Puzzle
private SudokuPuzzle clsSudoku;
//Variables used throughout the program.
private final int iMaxCells = 81;
private String[] stResult; // Holds the solution to the current puzzle
private int[] iExcluded; // Holds all the blue cells (clues given to the user at the start)
// Placed into List for fast searching
private int iElement;
private boolean blShowResult; // Indicates if the user has clicked Show Result
private boolean blGiveHint; // Indicates if the user has clicked Give Hint
private boolean blSoundOn;
// UI Elements
private View tvCell;
private GridView gridView;
private Menu menu;
private MediaPlayer mp = null;
/* Lists
lstitems holds all the items in the current board including user entries
lstExclude holds all the blue cells (clues given to the user at the start)
adapter
*/
private List<String> lstItems;
private ArrayAdapter<String> adapter ;
private List<Integer> lstExcluded;
public MainActivity() {
stResult = new String[iMaxCells];
blGiveHint = false;
blShowResult = false;
iElement = 0;
blSoundOn = false;
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
// Declare used buttons
Button btn1 = (Button) findViewById(R.id.btn1);
Button btn2 = (Button) findViewById(R.id.btn2);
Button btn3 = (Button) findViewById(R.id.btn3);
Button btn4 = (Button) findViewById(R.id.btn4);
Button btn5 = (Button) findViewById(R.id.btn5);
Button btn6 = (Button) findViewById(R.id.btn6);
Button btn7 = (Button) findViewById(R.id.btn7);
Button btn8 = (Button) findViewById(R.id.btn8);
Button btn9 = (Button) findViewById(R.id.btn9);
Button btn0 = (Button) findViewById(R.id.btn0);
Button btnHint = (Button) findViewById(R.id.btnHint);
Button btnCheck = (Button) findViewById(R.id.btnCheck);
//Creates a new Game
clsSudoku = new SudokuPuzzle();
newGame();
gridView = (GridView) findViewById(R.id.gridView1);
gridView.setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> parent, View v,
int position, long id) {
if (blGiveHint == true){
blGiveHint = false;
//Initialise any hinted cells back to white
clearCells();
}
if (!blShowResult){
tvCell = gridView.getChildAt(iElement);
try{
tvCell.setBackgroundColor(Color.WHITE);
iElement = position;
tvCell = gridView.getChildAt(iElement);
tvCell.setBackgroundColor(Color.RED);
}
catch(Exception e){
}
}
}
});
gridView.setAdapter(adapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1, lstItems) {
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View view = super.getView(position, convertView, parent);
view.setPadding(dpToPx(0, parent), 0, 0, 0);
view.setMinimumHeight(0);
if (position == iElement && !blShowResult){
view.setBackgroundColor(Color.RED);
}
else if (lstExcluded.contains(position)) {
view.setBackgroundColor(Color.WHITE);
}
else{
view.setBackgroundColor(Color.CYAN);
}
return view;
}
#Override
public boolean isEnabled(int position) {
// Item position which you want to disable.
if (!lstExcluded.contains(position) ) {
return false;
}
else {
return true;
}
}
});
btn1.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "1");
adapter.notifyDataSetChanged();
}
}
});
btn2.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "2");
adapter.notifyDataSetChanged();
}
}
});
btn3.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "3");
adapter.notifyDataSetChanged();
}
}
});
btn4.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "4");
adapter.notifyDataSetChanged();
}
}
});
btn5.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "5");
adapter.notifyDataSetChanged();
}
}
});
btn6.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "6");
adapter.notifyDataSetChanged();
}
}
});
btn7.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "7");
adapter.notifyDataSetChanged();
}
}
});
btn8.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "8");
adapter.notifyDataSetChanged();
}
}
});
btn9.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "9");
adapter.notifyDataSetChanged();
}
}
});
btn0.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
if (adapter.isEnabled(iElement) && !blShowResult){
lstItems.set(iElement, "");
adapter.notifyDataSetChanged();
}
}
});
btnHint.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
blGiveHint = true;
giveHint();
}
});
btnCheck.setOnClickListener(new View.OnClickListener(){
#Override
public void onClick(View v){
checkCorrect();
}
});
}
#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_main, menu);
this.menu = 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
switch(id){
case R.id.new_game:
createNewGame();
return true;
case R.id.show_result:
getResult();
return true;
case R.id.sound_toggle:
setSoundSettings();
return true;
default:
return super.onOptionsItemSelected(item);
}
}
// Populate a list for fast searching later
private void populateExcludeList(int[] ipiArray){
lstExcluded.clear();
for (int iCnt = 0; iCnt < ipiArray.length; iCnt++){
lstExcluded.add(ipiArray[iCnt] - 1);
}
Collections.sort(lstExcluded);
}
// Populate a list for fast searching later
private void setBoard(String[] ipstArray){
lstItems.clear();
for (int iCnt = 0; iCnt < ipstArray.length; iCnt++){
lstItems.add(ipstArray[iCnt]);
}
}
// Create a new puzzle
private void newGame(){
String[] stNumbers = new String[iMaxCells];
blShowResult = false;
clsSudoku.swapTwoNumbers();
clsSudoku.swapTwoColumns();
clsSudoku.swapTwoBlocks();
clsSudoku.rotateNintyDegrees();
clsSudoku.clearNumbers();
stNumbers = clsSudoku.getResult("User");
stResult = clsSudoku.getResult("Result");
iExcluded = clsSudoku.getRemoved();
if (lstItems == null) {
lstItems = new ArrayList<String>(Arrays.asList(stNumbers));
}
else {
setBoard(stNumbers);
}
lstExcluded = new ArrayList<Integer>();
populateExcludeList(iExcluded);
iElement = lstExcluded.get(0);
}
private void createNewGame(){
if ( !lstItems.isEmpty() ){
lstItems.clear();
}
newGame();
adapter.notifyDataSetChanged();
}
private void getResult(){
blShowResult = true;
setBoard(stResult);
lstExcluded = new ArrayList<Integer>();
populateExcludeList(iExcluded);
adapter.notifyDataSetChanged();
}
public void giveHint(){
for (int iCnt = 0; iCnt < iMaxCells; iCnt++){
tvCell = gridView.getChildAt(iCnt);
try{
if (lstItems.get(iCnt).equalsIgnoreCase(stResult[iCnt]) == false && blGiveHint == true){
tvCell.setBackgroundColor(Color.RED);
}
else if(lstItems.get(iCnt).equalsIgnoreCase(stResult[iCnt]) && lstExcluded.contains(iCnt) ){
tvCell.setBackgroundColor(Color.WHITE);
}
}
catch(Exception e){
Toast.makeText(this, "Error: " + e.getMessage(),Toast.LENGTH_LONG).show();
}
}
}
public void checkCorrect(){
boolean blErrorFound = false;
int iCntErrors = 0;
int iCntBlanks = 0;
String stMessage = "";
for (int iCnt = 0; iCnt < iMaxCells; iCnt++){
if ( (lstItems.get(iCnt).equalsIgnoreCase("") == true)
){
iCntBlanks = iCntBlanks + 1;
blErrorFound = true;
}
else if((lstItems.get(iCnt).equalsIgnoreCase(stResult[iCnt]) == false) &&
(lstItems.get(iCnt).equalsIgnoreCase("") == false)
){
iCntErrors = iCntErrors + 1;
blErrorFound = true;
}
}
if (!blErrorFound){
stMessage = "Congratulations !!! Your solution is correct";
if (blSoundOn == true){
playSound("congratulations");
}
}
else{
stMessage = "You have " + iCntErrors + " errors and " + iCntBlanks + " squares left to do";
if (blSoundOn == true){
playSound("wrong");
}
}
Toast.makeText(getApplicationContext(), stMessage, Toast.LENGTH_LONG).show();
}
private void clearCells(){
for (int iCnt = 0; iCnt < iMaxCells; iCnt++){
tvCell = gridView.getChildAt(iCnt);
if(lstExcluded.contains(iCnt) ){
tvCell.setBackgroundColor(Color.WHITE);
}
}
}
private void setSoundSettings() {
MenuItem miMenu = menu.findItem(R.id.sound_toggle);
if (blSoundOn) {
blSoundOn = false;
miMenu.setTitle("Turn Sound On");
} else {
blSoundOn = true ;
miMenu.setTitle("Turn Sound Off");
}
}
public void playSound(String stFileName){
int iSoundId;
if (mp != null){
mp.reset();
mp.release();
}
Resources res = getApplicationContext().getResources();
iSoundId = res.getIdentifier(stFileName, "raw", getApplicationContext().getPackageName());
mp = MediaPlayer.create(getApplicationContext(), iSoundId);
mp.start();
}
public int dpToPx(int dp, View v) {
DisplayMetrics displayMetrics = v.getContext().getResources().getDisplayMetrics();
return Math.round(dp * (displayMetrics.xdpi / DisplayMetrics.DENSITY_DEFAULT));
}
}
I have an issue while working with a tab1 class extend fragment called from a fragment list. I have done research and information on the use of fragment within a class but right now I cannot get my setAdapter to work in the tab1 class. Below are my codes: the tab1 class and the XML.
public class Tab1Fragment extends Fragment implements AdapterView.OnItemClickListener {
private static final int ADD_NEW_FRIEND_ID = Menu.FIRST;
private static final int SHOW_DETAILS = 3;
private static final int EXIT_APP_ID = Menu.FIRST + 1;
public IAppManager imService = null;
private FriendListAdapter friendAdapter;
private class FriendListAdapter extends BaseAdapter
{
class ViewHolder {
TextView text;
ImageView icon;
}
private LayoutInflater mInflater;
private Bitmap mOnlineIcon;
private Bitmap mOfflineIcon;
private ListView list;
private ListView listView;
private FriendInfo[] friends = null;
public FriendListAdapter(Context context) {
super();
mInflater = LayoutInflater.from(context);
mOnlineIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.greenstar);
mOfflineIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.redstar);
}
public void setFriendList(FriendInfo[] friends)
{
this.friends = friends;
}
public int getCount() {
return friends.length;
}
public FriendInfo getItem(int position) {
return friends[position];
}
public long getItemId(int position) {
return 0;
}
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder holder;
if (convertView == null)
{
convertView = mInflater.inflate(R.layout.friend_list_screen, null);
holder = new ViewHolder();
holder.text = (TextView) convertView.findViewById(R.id.text);
holder.icon = (ImageView) convertView.findViewById(R.id.icon);
convertView.setTag(holder);
}
else {
holder = (ViewHolder) convertView.getTag();
}
holder.text.setText(friends[position].userName);
holder.icon.setImageBitmap(friends[position].status == STATUS.ONLINE ? mOnlineIcon : mOfflineIcon);
return convertView;
}
}
public class MessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Broadcast receiver ", "received a message");
Bundle extra = intent.getExtras();
if (extra != null)
{
String action = intent.getAction();
if (action.equals(IMService.FRIEND_LIST_UPDATED))
{
Tab1Fragment.this.updateData(FriendController.getFriendsInfo(),
FriendController.getUnapprovedFriendsInfo());
}
}
}
};
public MessageReceiver messageReceiver = new MessageReceiver();
private ServiceConnection mConnection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
imService = ((IMService.IMBinder)service).getService();
FriendInfo[] friends = FriendController.getFriendsInfo(); //imService.getLastRawFriendList();
if (friends != null) {
Tab1Fragment.this.updateData(friends, null); // parseFriendInfo(friendList);
}
getActivity().setTitle(imService.getUsername() + "'s friend list");
}
public void onServiceDisconnected(ComponentName className) {
imService = null;
}
};
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View v = inflater.inflate(R.layout.tab1fragment, container, false);
ListView list = (ListView) v.findViewById(R.id.lvn);
return v;
}
void updateData(FriendInfo[] friends, FriendInfo[] unApprovedFriends)
{
if (friends != null) {
friendAdapter.setFriendList(friends);
setAdapter(friendAdapter);
}
if (unApprovedFriends != null)
{
NotificationManager NM = (NotificationManager) getActivity().getSystemService(getActivity().NOTIFICATION_SERVICE);
if (unApprovedFriends.length > 0)
{
String tmp = new String();
for (int j = 0; j < unApprovedFriends.length; j++) {
tmp = tmp.concat(unApprovedFriends[j].userName).concat(",");
}
Notification notification = new Notification(R.drawable.stat_sample,
getText(R.string.new_friend_request_exist),
System.currentTimeMillis());
Intent i = new Intent(Tab1Fragment.this.getActivity(), UnApprovedFriendList.class);
i.putExtra(FriendInfo.FRIEND_LIST, tmp);
PendingIntent contentIntent = PendingIntent.getActivity(this.getActivity(), 0,
i, 0);
notification.setLatestEventInfo(this.getActivity(), getText(R.string.new_friend_request_exist),
"You have new friend request(s)",
contentIntent);
NM.notify(R.string.new_friend_request_exist, notification);
}
else
{
// if any request exists, then cancel it
NM.cancel(R.string.new_friend_request_exist);
}
}
}
#Override
public void onItemClick(AdapterView<?> parent, View v, int position, long id){
onItemClick(parent, v, position, id);
// Sensor sensor = sensorAdapter.getItem(AdapterView<?> parent
Intent i = new Intent(Tab1Fragment.this.getActivity(), Messaging.class);
FriendInfo friend = friendAdapter.getItem(position);
if (friend.status == STATUS.ONLINE)
{
i.putExtra(FriendInfo.USERNAME, friend.userName);
// i.putExtra(FriendInfo.ID, friend.uid); // Edit //
i.putExtra(FriendInfo.PORT, friend.port);
i.putExtra(FriendInfo.IP, friend.ip);
startActivity(i);
}
else
{
Toast.makeText(Tab1Fragment.this.getActivity(), R.string.user_offline, Toast.LENGTH_SHORT).show();
}
}
}
The XML for the tab:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<ListView
android:id="#+id/lvn"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<TextView android:id="#+id/android:empty"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:text="#string/no_friend"
android:gravity="center_vertical|center_horizontal"/>
</LinearLayout>