Android Bluetooth Discovery API Isn't Working on Android 6.0 - java

I've made an app, that is discovering nearby bluetooth devices and etc. I can get bluetooth adapter, open-close processes, get paired devices, discovering process. Everthing is fine but discovery process isn't working properly.
I tested my app on 5 different real devices. At the moment I realized I have a problem on Android version but I'm not sure about that.
My app's discovery process is working on,
Huawei P7 - Android Version: 4.4.2
Sony Xperia Z - Android Version: 5.1.1
Samsung Galaxy J3 - Android Version: 5.1.1
My app's discovery process isn't working on,
Samsung Galaxy S7 - Android Version: 6.0.1
Samsung Galaxy J7 - Android Version: 6.0.1
MainActivity.java
package com.sphinxlike.bluetoothexample;
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.Handler;
import android.os.Parcelable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
import static java.lang.System.out;
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
/* DECLERATIONS */
// Button
Button openBtn = null; // Open button
Button closeBtn = null; // Close button
Button listBtn = null; // Paired devices list button
Button searchBtn = null; // Discovery new devices button
// Bluetooth
private BluetoothAdapter mBluetoothAdapter = null; // Local bluetooth adapter variable
private static final int REQUEST_ENABLE_BT = 1; // Bluetooth open intent variable
String mDeviceName = null;
String mDeviceAddress = null;
public static String EXTRA_ADDRESS = "device_address";
// XML
TextView tvDeviceName = null; // To show local bluetooth device's name
TextView tvBluetoothState = null; // To show bluetooth state
ListView lvDeviceList = null; // To list paired devices or discovered devices
// Set, List, Array Adapter
private Set<BluetoothDevice> mPairedDevicesSet = null; // Paired devices Set
private Set<BluetoothDevice> mNewDevicesSet = null; // New devices Set
ArrayAdapter mPairedDevicesAdapter = null; // Paired devices array adapter
ArrayAdapter mNewDevicesAdapter = null; // New devices array adapter
ArrayList bluetoothDeviceList = null; // Listing bluetooth devices
private ArrayList<BluetoothDevice> btDeviceList = new ArrayList<BluetoothDevice>();
// Bluetooth State Updater
private Handler mHandler; // Loop in UI
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Initializes UI elements
tvDeviceName = (TextView)findViewById(R.id.deviceName);
tvBluetoothState = (TextView)findViewById(R.id.bluetoothState);
openBtn = (Button)findViewById(R.id.openBluetooth);
closeBtn = (Button)findViewById(R.id.closeBluetooth);
listBtn = (Button)findViewById(R.id.listBluetooth);
searchBtn = (Button)findViewById(R.id.searchBluetooth);
lvDeviceList = (ListView)findViewById(R.id.deviceList);
// Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// Button checks
openBtn.setOnClickListener((View.OnClickListener) this);
closeBtn.setOnClickListener((View.OnClickListener) this);
listBtn.setOnClickListener((View.OnClickListener) this);
searchBtn.setOnClickListener((View.OnClickListener) this);
// To update bluetooth state text view
tvBluetoothState.setText(String.valueOf(mBluetoothAdapter.getState()));
// If the phone does not support bluetooth adapter
if (mBluetoothAdapter == null) {
tvBluetoothState.setText("Your phone has not Bluetooth Adapter");
openBtn.setEnabled(false);
closeBtn.setEnabled(false);
listBtn.setEnabled(false);
searchBtn.setEnabled(false);
}
// Updater loop
mHandler = new Handler();
mHandler.post(mUpdate);
}
// Updater Loop
private Runnable mUpdate = new Runnable() {
public void run() {
getBluetoothState();
mHandler.postDelayed(this, 500);
}
};
// Button onClick method
public void onClick(View v) {
switch (v.getId()) {
case R.id.openBluetooth:
if (!mBluetoothAdapter.isEnabled()) {
Intent bluetoothAcIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(bluetoothAcIntent, REQUEST_ENABLE_BT);
} else {
Toast.makeText(getApplicationContext(), "Bluetooth is already open", Toast.LENGTH_SHORT).show();
}
break;
case R.id.closeBluetooth:
if (mBluetoothAdapter.isEnabled()) {
mBluetoothAdapter.disable();
} else {
Toast.makeText(getApplicationContext(), "Bluetooth is already close", Toast.LENGTH_SHORT).show();
}
break;
case R.id.listBluetooth:
pairedDevicesList();
break;
case R.id.searchBluetooth:
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mBroadcastReceiver, filter);
mBluetoothAdapter.startDiscovery();
break;
}
};
#Override
public void onDestroy() {
unregisterReceiver(mBroadcastReceiver);
super.onDestroy();
}
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
// Whenever a remote Bluetooth device is found
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Toast.makeText(getApplicationContext(), device.getName() + ":" + device.getAddress(), Toast.LENGTH_LONG).show();
// lvDeviceList.setAdapter(mPairedDevicesAdapter); // Set list view elements with adapter elements
}
}
};
// Show bluetooth state on UI
public void getBluetoothState() {
tvDeviceName.setText("Device Name: " + mBluetoothAdapter.getName());
switch(mBluetoothAdapter.getState()) { // Set bluetooth state text view
case 10: // STATE_OFF
tvBluetoothState.setText("Bluetooth is closed");
bluetoothDeviceList = new ArrayList(); // Initialize global array list variable that is declared
mPairedDevicesAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, bluetoothDeviceList); // Get array list and use in array adapter
lvDeviceList.setAdapter(mPairedDevicesAdapter); // Set list view elements with adapter elements
break;
case 11: // STATE_TURNING_ON
tvBluetoothState.setText("Bluetooth is opening");
break;
case 12: // STATE_ON
tvBluetoothState.setText("Bluetooth is opened");
break;
case 13: // STATE_TURNING_OFF
tvBluetoothState.setText("Bluetooth is closing");
break;
}
// If bluetooth adapter -> Set buttons
if (mBluetoothAdapter.isEnabled()) {
// Enable listing button
listBtn.setEnabled(true);
searchBtn.setEnabled(true);
} else {
// Disable listing button
listBtn.setEnabled(false);
searchBtn.setEnabled(false);
}
}
// Get paired device list and adapt to list view
public void pairedDevicesList()
{
if (!mBluetoothAdapter.isEnabled()) {
Toast.makeText(getApplicationContext(), "Open the Bluetooth", Toast.LENGTH_SHORT).show();
} else {
mPairedDevicesSet = mBluetoothAdapter.getBondedDevices(); // Get paired devices
bluetoothDeviceList = new ArrayList(); // Initialize global array list variable that is declared
if (mPairedDevicesSet.size()>0) {
for (BluetoothDevice bt : mPairedDevicesSet) { // for-each loop
mDeviceName = bt.getName();
mDeviceAddress = bt.getAddress();
bluetoothDeviceList.add(mDeviceName + "\n" + mDeviceAddress); // get the device name and add to array list object
}
} else if (mPairedDevicesSet.size()<=0){
Toast.makeText(getApplicationContext(), "No paired devices", Toast.LENGTH_SHORT).show();
}
mPairedDevicesAdapter = new ArrayAdapter(this,android.R.layout.simple_list_item_1, bluetoothDeviceList); // Get array list and use in array adapter
lvDeviceList.setAdapter(mPairedDevicesAdapter); // Set list view elements with adapter elements
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
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="com.sphinxlike.bluetoothexample.MainActivity"
android:orientation="vertical">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Device Name"
android:id="#+id/deviceName"/>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="20dp">
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="#+id/openBluetooth"
android:text="B. Open"
android:textAllCaps="false"
android:layout_gravity="center"
android:gravity="center"/>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="#+id/closeBluetooth"
android:text="B. Close"
android:textAllCaps="false"
android:layout_gravity="center"
android:gravity="center"/>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="#+id/listBluetooth"
android:text="List Paired"
android:textAllCaps="false"
android:layout_gravity="center"
android:gravity="center"/>
<Button
android:layout_width="0dp"
android:layout_weight="1"
android:layout_height="wrap_content"
android:id="#+id/searchBluetooth"
android:text="Search"
android:textAllCaps="false"
android:layout_gravity="center"
android:gravity="center"/>
</LinearLayout>
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:hint="Bluetooth State"
android:id="#+id/bluetoothState"
android:layout_gravity="center"
android:gravity="center"/>
<ListView
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:id="#+id/deviceList">
</ListView>
</LinearLayout>

Firstly, thanks #Tomasz Czura. I solved problem with multiple runtime permission request.
Android Developer 6.0 Changes page says:
To access the hardware identifiers of nearby external devices via Bluetooth and Wi-Fi scans, your app must now have the ACCESS_FINE_LOCATION or ACCESS_COARSE_LOCATION permissions:
So, I added permission to AndroidManifest.XML:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
then I rearranged my activity like this:
public class MainActivity extends AppCompatActivity {
...
int ACTION_REQUEST_MULTIPLE_PERMISSION = 1; // Any number
#Override
protected void onCreate(Bundle savedInstanceState) {
...
int pCheck = this.checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION");
pCheck += this.checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION");
pCheck += this.checkSelfPermission("Manifest.permission.BLUETOOTH_ADMIN");
pCheck += this.checkSelfPermission("Manifest.permission.BLUETOOTH");
if (pCheck != 0) {
this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.BLUETOOTH_ADMIN, Manifest.permission.BLUETOOTH}, ACTION_REQUEST_MULTIPLE_PERMISSION);
}
}
}
It worked.

You have to ask for Bluetooth permissions at run time in Android 6.0 -
ActivityCompat.requestPermissions(..)

Related

SupportFragment Map in Navigation Drawer Activity Very Slow and Unresponsive

I'm trying to use a SupportFragment Google Map with a navigation drawer, initializing the map every two seconds with new overlays pulled from a server. I should also mention that the google maps supportfragment is the default supportfragment, so it is already supposed to be open when the app starts. The problem is that the app is very slow and unresponsive when I run it, prompting my phone to open a dialog asking to close the app because it is unresponsive. I am assuming that it may be getMapAsync(), but that is just a very broad guess. I'm trying to fix the problem to make the app just as responsive when it was a regular fragment and without a navigationdrawer. Here is the code for some of the files that are relevant with the problem. If you need any other information or any other files, feel free to ask.
MainActivity.java:
package com.main.main;
import android.app.FragmentManager;
import android.graphics.Color;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.view.View;
import android.support.design.widget.NavigationView;
import android.support.v4.view.GravityCompat;
import android.support.v4.widget.DrawerLayout;
import android.support.v7.app.ActionBarDrawerToggle;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.LatLngBounds;
import com.google.android.gms.maps.model.Polygon;
import com.google.android.gms.maps.model.PolygonOptions;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutionException;
public class MainActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, OnMapReadyCallback {
private SupportMapFragment sMapFragment;
private android.support.v4.app.FragmentManager sFm;
private GoogleMap mMap;
List<ParkingSpot> list; //list of parking spots
private static final LatLng DEFAULT_ZOOM_IN = new LatLng(40, -120); //default zoom-in of map
public static final String IP_ADDRESS = "some ip";
public static final String DATABASE = "some db";
public static final String USER_USERNAME = "something";
public static final String USER_PASSWORD = "something";
public LatLngBounds bounds;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
sMapFragment = SupportMapFragment.newInstance();
setContentView(R.layout.activity_main);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
ActionBarDrawerToggle toggle = new ActionBarDrawerToggle(
this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close);
drawer.setDrawerListener(toggle);
toggle.syncState();
NavigationView navigationView = (NavigationView) findViewById(R.id.nav_view);
navigationView.setNavigationItemSelectedListener(this);
if(bounds == null) {
sFm = getSupportFragmentManager();
sFm.beginTransaction().remove(sMapFragment).commit();
sFm.beginTransaction().add(R.id.map, sMapFragment).commit();
}
try {
Object result = new LongOperation().execute().get();
} catch (InterruptedException e) {
throw new NullPointerException("INTERRUPTED EXCEPTION");
} catch (ExecutionException e) {
throw new NullPointerException("EXECUTION EXCEPTION");
}
}
#Override
public void onBackPressed() {
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
if (drawer.isDrawerOpen(GravityCompat.START)) {
drawer.closeDrawer(GravityCompat.START);
} else {
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
#SuppressWarnings("StatementWithEmptyBody")
#Override
public boolean onNavigationItemSelected(MenuItem item) {
// Handle navigation view item clicks here.
FragmentManager fm = getFragmentManager();
int id = item.getItemId();
sFm.beginTransaction().hide(sMapFragment).commitAllowingStateLoss();
if (id == R.id.nav_map) {
Toast.makeText(MainActivity.this, "MAP CLICKED!", Toast.LENGTH_SHORT);
sFm.beginTransaction().show(sMapFragment).commitAllowingStateLoss();
} else if (id == R.id.nav_history) {
Toast.makeText(MainActivity.this, "HISTORY CLICKED!", Toast.LENGTH_SHORT);
} else if (id == R.id.nav_notifications) {
Toast.makeText(MainActivity.this, "NOTIFICATIONS CLICKED!", Toast.LENGTH_SHORT);
} else if (id == R.id.nav_help) {
Toast.makeText(MainActivity.this, "HELP CLICKED!", Toast.LENGTH_SHORT);
} else if (id == R.id.nav_settings) {
Toast.makeText(MainActivity.this, "SETTINGS CLICKED!", Toast.LENGTH_SHORT);
}
DrawerLayout drawer = (DrawerLayout) findViewById(R.id.drawer_layout);
drawer.closeDrawer(GravityCompat.START);
return true;
}
#Override
public void onMapReady(GoogleMap googleMap) {
try {
Object result = new LongOperation().execute().get();
mMap = googleMap;
mMap.clear();
if (bounds == null) { //only completes first time when bounds == null
CameraPosition cameraPosition = new CameraPosition.Builder() //zooms in camera on default location
.target(DEFAULT_ZOOM_IN) //location (LatLng)
.zoom(18) //zoom integer
.build(); //builds camera
mMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition)); //animates camera to spot
mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); //sets map to hybrid type
}
bounds = mMap.getProjection().getVisibleRegion().latLngBounds; //gets latlng for next query based on camera spot
PolygonOptions rectOptions;
for (ParkingSpot spot : list) { //loops through ArrayList of Parking Spots, adding them to map
rectOptions = new PolygonOptions()
.addAll(spot.getCoordinates())
.clickable(true); //adds all coordinates to map
if (spot.getStatus() == 'F') { //see ParkingSpot.java for char definitions/explanations
rectOptions.fillColor(Color.RED);
} else if (spot.getStatus() == 'T') {
rectOptions.fillColor(Color.GREEN);
} else if (spot.getStatus() == 'H') {
rectOptions.fillColor(Color.YELLOW);
}
Polygon polygon = mMap.addPolygon(rectOptions); //adds rectangle to map
spot.setPolygonId(polygon.getId());
}
mMap.setOnPolygonClickListener(new GoogleMap.OnPolygonClickListener() {
#Override
public void onPolygonClick(Polygon polygon) {
Toast.makeText(MainActivity.this, "You clicked on polygon " + getInfoById(polygon.getId()), Toast.LENGTH_SHORT).show();
}
});
mMap.setMyLocationEnabled(true);
mMap.setOnMyLocationButtonClickListener(new GoogleMap.OnMyLocationButtonClickListener() {
#Override
public boolean onMyLocationButtonClick() {
return false;
}
});
} catch (SecurityException e) {
throw new NullPointerException("SECURITY EXCEPTION");
} catch (InterruptedException e) {
throw new NullPointerException("INTERRUPTED EXCEPTION");
} catch (ExecutionException e) {
throw new NullPointerException("EXECUTION EXCEPTION");
}
}
public String getInfoById(String id) {
for (ParkingSpot spot : list) {
if (spot.getPolygonId().equals(id)) {
return spot.toString();
}
}
return "-1";
}
private class LongOperation extends AsyncTask<String, Void, List> { //main network operation to initialize list
#Override
protected List<ParkingSpot> doInBackground(String... params) {
list = new ArrayList<ParkingSpot>(); //initializes list to ArrayList
String url = "jdbc:mysql://" + IP_ADDRESS + "/" + DATABASE; //creates URL for MySQL query
try {
Class.forName("com.mysql.jdbc.Driver"); //Driver for MySQL query
Connection con = DriverManager.getConnection(url, USER_USERNAME, USER_PASSWORD); //Starts connection to server
PreparedStatement pst; //initializes PreparedStatement outside to allow scope
if (bounds == null) { //if requesting first time
pst = con.prepareStatement("select * from sample_parking_spots");
} else { //if requesting later than first time;
String statement = "select * from sample_parking_spots where coord1lat>=" + bounds.southwest.latitude + " and coord3lat<=" + bounds.northeast.latitude + " and coord3lon>=" + bounds.southwest.longitude + " and coord1lon<=" + bounds.northeast.longitude;
pst = con.prepareStatement(statement);
}
ResultSet rs = pst.executeQuery(); //gets information from server
while (rs.next()) {
String uid = "U" + rs.getString("id"); //gets UID
String coordinate1Lat = rs.getString("coord1lat"); //gets top left latitude (x)
String coordinate1Lon = rs.getString("coord1lon"); //gets top left longitude (y)
String coordinate3Lat = rs.getString("coord3lat"); //gets bottom right latitude (x)
String coordinate3Lon = rs.getString("coord3lon"); //gets bottom right longitude (y)
char status = rs.getString("status").charAt(0); //get status as char
list.add(new ParkingSpot(uid, status, coordinate1Lat, coordinate1Lon, coordinate3Lat, coordinate3Lon)); //adds new ParkingSpot object to ArrayList
}
return list;
} catch (RuntimeException e) {
throw new NullPointerException("SOME OTHER RUNTIME EXCEPTION");
//Json parser can't find some variable or UID or NullPointerException
} catch (SQLException e) {
throw new NullPointerException("SQL EXCEPTION");
//if credentials for SQL are bad or something is wrong with the server
} catch (ClassNotFoundException e) {
throw new NullPointerException("CLASS NOT FOUND EXCEPTION");
//if cannot find SQL driver
}
}
#Override
protected void onPostExecute(List result) { //called after doInBackground completes
super.onPostExecute(list);
list = result; //sets public list to List initialized from database
Timer timer = new Timer("updateMapAvailTask");
TimerTask myTask = new TimerTask() { //creates new task to execute again after timer
#Override
public void run() {
try {
Object result = new LongOperation().execute().get(); //second network thread to download data and initialize map
//gets object so ENTIRE LongOperation thread completes
} catch (InterruptedException e) {
throw new NullPointerException("INTERRUPTED EXCEPTION");
} catch (ExecutionException e) {
throw new NullPointerException("EXECUTION EXCEPTION");
}
}
};
sMapFragment.getMapAsync(MainActivity.this);
timer.schedule(myTask, 2000); //schedules for server pull to happen every couple of seconds
}
}
}
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.main.main.MainActivity"
tools:showIn="#layout/app_bar_main">
<FrameLayout
android:id="#+id/content_frame"
android:layout_width="match_parent"
android:layout_height="match_parent"></FrameLayout>
<FrameLayout
android:id="#+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent" />
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/drawer_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:openDrawer="start">
<include
layout="#layout/app_bar_main"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.NavigationView
android:id="#+id/nav_view"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_gravity="start"
android:fitsSystemWindows="true"
app:headerLayout="#layout/nav_header_main"
app:menu="#menu/activity_main_drawer" />
activity_main_drawer.xml:
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group android:checkableBehavior="single">
<item
android:id="#+id/nav_map"
android:icon="#drawable/ic_map"
android:title="Map" />
<item
android:id="#+id/nav_history"
android:icon="#drawable/ic_search_history"
android:title="History" />
<item
android:id="#+id/nav_notifications"
android:icon="#drawable/ic_error"
android:title="Notifications" />
</group>
<item android:title="User">
<menu>
<item
android:id="#+id/nav_help"
android:icon="#drawable/ic_help"
android:title="Help" />
<item
android:id="#+id/nav_settings"
android:icon="#drawable/ic_settings"
android:title="Settings" />
</menu>
</item>
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.main.main">
<!--
The ACCESS_COARSE/FINE_LOCATION permissions are not required to use
Google Maps Android API v2, but you must specify either coarse or fine
location permissions for the 'MyLocation' functionality.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
android:name="android.support.multidex.MultiDexApplication">
<!--
The API key for Google Maps-based APIs is defined as a string resource.
(See the file "res/values/google_maps_api.xml").
Note that the API key is linked to the encryption key used to sign the APK.
You need a different API key for each encryption key, including the release key that is used to
sign the APK for publishing.
You can define the keys for the debug and release targets in src/debug/ and src/release/.
-->
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
You AsyncTask actually is blocking the UI thread.
The AsyncTask.get() method is a blocking call, you should just do AsyncTask.execute(). In your case, replace new LongOperation().execute().get() with just new LongOperation().execute().

Android bluetooth app crashing on startup

When the app first starts it immediately crashes on startup. I have narrowed down the problem to one line but not really sure what to do =/ here are the two classes in the app so far:
package com.example.bluetooth_app;
import java.util.Set;
import android.app.Activity;
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.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
public class Bluetooth {
private BluetoothAdapter mBluetoothAdapter;
private Activity activity; //Activity to store main window's activity
private ArrayAdapter<String> pDevices; //Array adapter for storing already paired devices
private ArrayAdapter<String> nDevices; //Array adapter for storing newly discovered devices
private IntentFilter filter; //Filter for catching bluetooth device actions
private Button sButton; //Scan button
private ListView lvBox; //listview box
/**
* default constructor, basic initializations
*/
public Bluetooth(Activity activity) {
this.activity = activity; //Set class activity to the activity passed to it by the main activity window
pDevices = new ArrayAdapter<String>(activity, R.layout.activity_bluetooth__app);
nDevices = new ArrayAdapter<String>(activity, R.layout.activity_bluetooth__app);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
sButton = (Button) activity.findViewById(R.id.scanButton); //sButton = scan button
sButton.setOnClickListener(new View.OnClickListener() { //Listener to check if button is pressed
public void onClick(View v) { //If button is pressed start discovering and hide button
startDiscovering();
sButton.setVisibility(4); //Make button invisible
}
});
lvBox = (ListView) activity.findViewById(R.id.deviceList); // lvBox = deviceList listview
lvBox.setAdapter(pDevices);
// Register for broadcasts when a device is discovered
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
activity.registerReceiver(mReceiver, filter);
// Register for broadcasts when discovery has finished
filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
activity.registerReceiver(mReceiver, filter);
}
/**
* Check if bluetooth is enabled, if not enable it
*/
public void getAdapter() {
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivityForResult(enableBtIntent, 1);
}
}
/**
* Check if device is bluetooth compatible
*/
public boolean isCompat() {
if(mBluetoothAdapter == null) {
return false; //TODO: better error handling
} else {
return true;
}
}
/**
* Close some shit so we do not eat up resources
*/
public void destroy() {
if(mBluetoothAdapter != null) {
mBluetoothAdapter.cancelDiscovery(); //cancel discovering devices
}
activity.unregisterReceiver(mReceiver);
}
/**
* Start discovering devices with bluetooth adapter
*/
public void startDiscovering() {
if(mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();
}
public void pairedDevices() {
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
sButton.setText("found some");
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
pDevices.add(device.getName() + "\n" + device.getAddress());
}
}
}
/**
* The BroadcastReceiver that listens for discovered devices and changes the title when
* discovery is finished
*/
private final BroadcastReceiver mReceiver = 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) {
nDevices.add(device.getName() + "\n" + device.getAddress());
}
// When discovery is finished, change the Activity title
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
sButton.setVisibility(0); //Make button visible again
if (nDevices.getCount() == 0) {
sButton.setText("none");
//TODO: none found do something
}
}
}
};
}
and:
package com.example.bluetooth_app;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import com.example.bluetooth_app.Bluetooth;
public class Bluetooth_App extends ActionBarActivity {
private Bluetooth bT;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_bluetooth__app);
bT = new Bluetooth(this);
bT.isCompat();
bT.getAdapter();
bT.pairedDevices();
}
#Override
protected void onDestroy() {
super.onDestroy();
bT.destroy();
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.bluetooth__app, 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();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
The problem is in the first class, this line: lvBox.setAdapter(pDevices);,if I comment it out it runs just fine, if not it crashes on startup. Any help would be appreciated - thanks.
EDIT1 - no it has a listview called deviceList, XML file:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android: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="com.example.bluetooth_app.Bluetooth_App" >
<Button
android:id="#+id/scanButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_alignParentTop="true"
android:layout_marginRight="28dp"
android:layout_marginTop="21dp"
android:text="Scan" />
<ListView
android:id="#+id/deviceList"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignRight="#+id/button1"
android:layout_below="#+id/button1"
android:layout_marginRight="26dp"
android:layout_marginTop="48dp" >
</ListView>
</RelativeLayout>
Note that you seem to be reusing your activity's layout file R.layout.activity_bluetooth__app when initializing your ArrayAdapters in Bluetooth_App. This is probably not what you meant to do. The resource passed to the ArrayAdapter constructors should represent the layout of a single AdapterView row, and must contain a TextView with id text1 (to use a more customized row layout, you would need to subclass ArrayAdapter and override getView).

Android Studio - Cannot Resolve Symbol items in Array Adapter

I am currently trying to implement a Bluetooth connection in an Android application using a few different tutorials and am running into issues trying to add detected paired devices to a ListView for the user to choose from.
It is currently throwing the error "Cannot resolve symbol items" in the line below, but I'm not sure what to replace items with or if that's the only issue.
itemsAdapter = new ArrayAdapter(this, android.R.layout.simple_list_item_1, items);
I would really appreciate it if someone could correct my syntax in the Java code.
Thanks!
Java Code
package com.example.khite.wheelnav;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.view.MenuItem;
import android.view.View;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import java.util.Set;
public class ConnectActivity extends ActionBarActivity {
private static final int REQUEST_ENABLE_BT = 1234;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_connect);
// Create Bluetooth Adapter
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
Intent intent;
intent = new Intent(this, NoBluetoothActivity.class);
startActivity(intent);
}
// Enable Bluetooth
if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
// Create an Array Adapter to Add Devices to
ArrayAdapter<String> itemsAdapter;
itemsAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
//Query Paired Devices
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
itemsAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
// Add Paired Devices to a List View
ListView listView = (ListView) findViewById(R.id.listView);
listView.setAdapter(itemsAdapter);
}
public void openChooseFunctionActivity(View view){
//open choose function activity
Intent intent;
intent = new Intent(this, ChooseFunctionActivity.class);
startActivity(intent);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
XML Code
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin"
tools:context="com.example.khite.wheelnav.ConnectActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Continue"
android:id="#+id/button2"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:onClick="openChooseFunctionActivity"
android:background="#ff8180fd"
android:textColor="#ff000000" />
<ListView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="#+id/listView"
android:layout_centerHorizontal="true" />
</RelativeLayout>
initialized first your items collection, then an adapter
//Query Paired Devices
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// If there are paired devices
List<String> items = new ArrayList<String>();
if (pairedDevices.size() > 0) {
// Loop through paired devices
for (BluetoothDevice device : pairedDevices) {
// Add the name and address to an array adapter to show in a ListView
items.add(device.getName() + "\n" + device.getAddress());
}
}
// Create an Array Adapter to Add Devices to
ArrayAdapter<String> itemsAdapter;
itemsAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
"items" in your code is not initalized at all. You have to pass a String[] or List<String> object as the last parameter of the ArrayAdapter constructor.
"Cannot resolve symbol x" generally means variable x cannot be found.

Access fragment from activity besides main activity

I have an existing application that I am trying to modify and could really use some help.
It is a chat application. The original flow of the application was as follows:
Launch-> Splash Screen Activity-> MainActivity (extending Actionbar Sherlock)
Once in the main activity the default fragment is the ChatRoomFragment. From there you can select different tabs and interact with the application.
What I would like to change about the flow to is the following:
Launch->Splash Screen Activity-> Terms of Service/Sign -> MainMenu->MainActivity
I have created the mainmenu layout to contain 4 buttons. Join, Search, Profile, Settings
Here is the problem. My Join button works fine, onClick simply triggers the intent to start MainActivity and and the chat room loads. From this screen you can access the different tabs and fragments within the application.
However, I now would like to have the "search" button set to open a dialog. With a editText field and a search button. Upon clicking search it should pass the search string to the PlacesSearchFragment and populate results.
I copied the code from within my application where this search is normally completed (inside the ChatRoomsFragment but it will not work from within my mainMenu Activity.
How do I start the new fragment from the menu activity??
Code Below:
menuActivity.java
package com.peekatucorp.peekatu;
//import android.support.v7.app.ActionBarActivity;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v4.app.FragmentTransaction;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.actionbarsherlock.app.ActionBar;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import com.loopj.android.http.RequestParams;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
public class menuActivity extends Activity implements ActionBar.TabListener {
Button b1;
Button b2;
Button b3;
EditText txtsearch;
final private static int DIALOG_LOGIN = 1;
final private static int DIALOG_FORGET = 2;
final private static int DIALOG_SEARCH = 3;
private android.app.FragmentTransaction ft;
#Override
public void onCreate(Bundle savedInstanceState) {
SharedPreferences preferences = this.getSharedPreferences("MyPreferences", MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
super.onCreate(savedInstanceState);
setContentView(R.layout.mainmenu);
if(preferences.getString("Username", "").length()<=0 || preferences.getString("loggedin_user", "").length()<=0){
showDialog(DIALOG_LOGIN);
}
b1= (Button) this.findViewById(R.id.joinbutton);
b1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
Intent intent = new Intent(menuActivity.this, MainActivity.class);
menuActivity.this.startActivity(intent);
SharedPreferences preferences = getSharedPreferences("MyPreferences", MODE_PRIVATE);
SharedPreferences.Editor editor = preferences.edit();
editor.putString("loadMain", "1");
editor.commit();
}
});
b2= (Button) this.findViewById(R.id.searchbutton);
b2.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
showDialog(DIALOG_SEARCH);
}
}
);
}
#Override
protected Dialog onCreateDialog(int id) {
AlertDialog dialogDetails = null;
switch (id) {
case DIALOG_LOGIN:
if(true){
....some code}
break;
case DIALOG_FORGET:
if(true){
...some code
}
break;
case DIALOG_SEARCH:
if(true){
LayoutInflater inflater = LayoutInflater.from(this);
View dialogview = inflater.inflate(R.layout.menusearch_layout, null);
AlertDialog.Builder dialogbuilder = new AlertDialog.Builder(this);
dialogbuilder.setTitle("Where ya headed?");
dialogbuilder.setView(dialogview);
dialogDetails = dialogbuilder.create();
}
}
return dialogDetails;
}
#Override
protected void onPrepareDialog(int id, Dialog dialog) {
switch (id) {
case DIALOG_LOGIN:
...some code
break;
case DIALOG_SEARCH:
final AlertDialog alertDialog3 = (AlertDialog) dialog;
final Button btnLocalsearch = (Button) alertDialog3
.findViewById(R.id.local_search);
final Button btnSearch = (Button) alertDialog3
.findViewById(R.id.btn_search);
final EditText txtsearch = (EditText) alertDialog3
.findViewById(R.id.txtsearch);
btnSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
//showDialog(DIALOG_FORGET);
//alertDialog3.dismiss();
// TODO Auto-generated method stub
menuActivity m = com.peekatucorp.peekatu.menuActivity.this;
final TabInfo tab = com.peekatucorp.peekatu.menuActivity.this.getCurrentTabInfo();
final PlacesSearchFragment fragment = new PlacesSearchFragment().setNAV(m).setSearch(txtsearch.getText().toString(),"1");
// fragment.setText(characters[position]);
// second, you push the fragment. It becomes visible and the up button is
// shown
m.pushFragment(tab, fragment);
}
});
}
mainmenu.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<ImageView
android:layout_width="wrap_content"
android:layout_height="65dp"
android:layout_marginLeft="10dip"
android:src="#drawable/registration_banner3"
android:id="#+id/imageView" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Join Chat"
android:id="#+id/joinbutton"
android:layout_below="#+id/imageView"
android:layout_alignLeft="#+id/imageView"
android:layout_alignStart="#+id/imageView"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Search"
android:id="#+id/searchbutton"
android:layout_below="#+id/joinbutton"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_marginTop="55dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Profile"
android:id="#+id/prfbutton"
android:layout_below="#+id/searchbutton"
android:layout_marginTop="72dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignLeft="#+id/searchbutton"
android:layout_alignStart="#+id/searchbutton" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Settings"
android:id="#+id/settingsbutton"
android:layout_below="#+id/prfbutton"
android:layout_marginTop="51dp"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
<LinearLayout android:id="#+id/footer"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#layout/footer_repeat"
android:layout_alignParentBottom="true">
</LinearLayout>
</RelativeLayout>
ChatRoomsFragment.java (WORKING FRAGMENT)
public class ChatRoomsFragment extends SherlockFragment implements OnItemSelectedListener{
String[] items;
List<String> list;
Spinner my_spin;
RadioButton mainRoom;
RadioButton customRoom;
RadioButton GPSRoom;
EditText privateRoom;
EditText GPSsearch;
TextView GPSaddress;
String selected_public;
Context contexxt;
ImageLoader imageLoader;
public AbstractTabStackNavigationActivity navact;
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, final Bundle savedInstanceState) {
setRetainInstance(true);
final View v = inflater.inflate(R.layout.chatrooms_layout, container, false);
contexxt = v.getContext();
// setRetainInstance(true);
SharedPreferences preferences = v.getContext().getSharedPreferences("MyPreferences", this.getActivity().MODE_PRIVATE);
my_spin=(Spinner)v.findViewById(R.id.spinner1);
my_spin.setOnItemSelectedListener(this);
selected_public = preferences.getString("selected_room", "Adult Lobby");
AsyncHttpClient client = new AsyncHttpClient();
RequestParams params = new RequestParams();
GPSsearch = (EditText)v.findViewById(R.id.cr_gps_search);
GPSaddress = (TextView)v.findViewById(R.id.cr_gps_address);
GPSaddress.setText(preferences.getString("user_location", ""));
Button search_go = (Button)v.findViewById(R.id.cr_go_search);
Button address_go = (Button)v.findViewById(R.id.cr_go_address);
Button changeroom = (Button)v.findViewById(R.id.cr_changeroom);
//Button changeroom2 = (Button)v.findViewById(R.id.cr_changeRoom2);
search_go.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View arg0) {
// TODO Auto-generated method stub
MainActivity m = (MainActivity)getActivity();
final TabInfo tab = m.getCurrentTabInfo();
final PlacesSearchFragment fragment = new PlacesSearchFragment().setNAV(m).setSearch(GPSsearch.getText().toString(),"1");
// fragment.setText(characters[position]);
// second, you push the fragment. It becomes visible and the up button is
// shown
m.pushFragment(tab, fragment);
}
});
Can someone please explain to me how to get it to load the fragment. Thank you. Let me know if I am leaving out any relevant code. Im getting a null pointer exception as my error.
Well, first of all, here is the code I was talking about in my comment:
btnSearch.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(final View v) {
menuActivity m = dialog.getOwningActivity();
final TabInfo tab = m.getCurrentTabInfo();
final PlacesSearchFragment fragment = new PlacesSearchFragment().setNAV(m).setSearch(txtsearch.getText().toString(),"1");
m.pushFragment(tab, fragment);
...
However, now that I type this up, it doesn't make sense that the NPE was on the call to pushFragment like you said. If the activity outer-class reference was really the null pointer, then it should have crashed a few lines earlier, calling getCurrentTabInfo. Thus I don't think this code change will help. Please take a second look at the stack you are seeing, and tell me what line the NPE is happening on.

Android App OnClick Crashing

So i have a simple app, just a menu with a few buttons, when a button is clicked you are brought to a new page. The page has a button, which when clicked, keeps changing its background image until it runs out of images (list of image names stored in strings), then you are brought back to the main menu. I can do this twice, then on the third attempt, if i click a button on the menu the app crashes. This doesnt happen on the emulator, only when i run it on my phone. I dont know why this is happening
package com.example.otapp;
import com.example.otapp.R.raw;
import android.content.Intent;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.util.DisplayMetrics;
import android.view.Display;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
import android.media.MediaPlayer;
public class MainActivity extends ActionBarActivity {
public static String DPExtension;//Holds the letters dp
public String list;
public static int Screen_Height;//holds screen height
public static int Screen_Width;//holds screen width
public Intent intent;
public MediaPlayer audio;
public final static String EXTRA_MESSAGE = "com.example.otapp.MESSAGE";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//this code block is for getting the screen proportions
Display getdisplay = getWindowManager().getDefaultDisplay();
DisplayMetrics dispMetrics = new DisplayMetrics();
getdisplay.getMetrics(dispMetrics);
float densitydp = getResources().getDisplayMetrics().density;
float ScreenHeightdp = dispMetrics.heightPixels / densitydp;
float ScreenWidthdp = dispMetrics.widthPixels / densitydp;
//Below dimension value holders do not use pixel density
float ScreenHeightCheck = dispMetrics.heightPixels;
float ScreenWidthCheck = dispMetrics.heightPixels;
DPExtension = "dp";
Screen_Height = (int) ScreenHeightCheck;
Screen_Width = (int) ScreenWidthCheck;
//The printlns are so I can discern the outputs in LogCat
//System.out.println("Screen Height:" + Screen_Height);
//System.out.println("Screen Width:" + Screen_Width);
View Button1 = findViewById(R.id.Button01);
LinearLayout.LayoutParams params = (LayoutParams) Button1.getLayoutParams();
params.height = Screen_Height/3;
Button1.setLayoutParams(params);
View Button2 = findViewById(R.id.Button02);
Button2.setLayoutParams(params);
View Button3 = findViewById(R.id.Button03);
Button3.setLayoutParams(params);
View Button4 = findViewById(R.id.Button04);
Button4.setLayoutParams(params);
Button1.setOnClickListener(onClickListener);
Button2.setOnClickListener(onClickListener);
Button3.setOnClickListener(onClickListener);
Button4.setOnClickListener(onClickListener);
Button1.setBackgroundResource(getResources().getIdentifier("gettingup", "drawable", getPackageName()));
intent = new Intent(this, DisplayMessageActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
audio = MediaPlayer.create(MainActivity.this, raw.buttonsound);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
private OnClickListener onClickListener = new OnClickListener() {
#Override
public void onClick(View v) {
// play sound
audio.start();
// do different things for each different button
switch(v.getId()) {
case R.id.Button01:
list = "Get Up";
intent.putExtra(EXTRA_MESSAGE, list);
startActivity(intent);
break;
case R.id.Button02:
list = "Get Dressed";
intent.putExtra(EXTRA_MESSAGE, list);
startActivity(intent);
break;
case R.id.Button03:
list = "Get Dressed";
intent.putExtra(EXTRA_MESSAGE, list);
startActivity(intent);
break;
case R.id.Button04:
list = "Get Dressed";
intent.putExtra(EXTRA_MESSAGE, list);
startActivity(intent);
break;
}
}
};
#Override
public boolean onOptionsItemSelected(MenuItem item) {
int id = item.getItemId();
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
}
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent" android:layout_height="match_parent" android:background="#1E90FF">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical">
<Button
android:id="#+id/Button01"
android:layout_width="match_parent"
android:layout_height="125dp"
android:text="#string/button_send"/>
<Button
android:id="#+id/Button03"
android:layout_width="match_parent"
android:layout_height="125dp"
android:text="#string/button2_send" />
<Button
android:id="#+id/Button04"
android:layout_width="match_parent"
android:layout_height="125dp"
android:text="#string/button3_send" />
<Button
android:id="#+id/Button02"
android:layout_width="match_parent"
android:layout_height="125dp"
android:text="#string/button4_send" />
</LinearLayout>
</ScrollView>
If the source above is formatted correctly, line 99, which is where the NullPointerException is thrown, is:
audio.start();
This means that audio is null. It is declared on line 83:
audio = MediaPlayer.create(MainActivity.this, raw.buttonsound);
Most likely what's happening is that the MediaPlayer.create is unable to located the raw.buttonsound. I'd debug at this line and verify that the MediaPlayer is failing to create the audio.
Try moving the definition of the onClickListener object into the onCreate method.
You can declare it as a member variable, but you should create the object and assign it to the field in onCreate()

Categories