UPDATE - edited code to display my broadcast idea. Using the method causes a !!! FAILED BINDER TRANSACTION !!! and no location data to be displayed by toast.
I was wondering if there was an elegant way to separate google fused location services away from activities. My warning class currently implements location services but I have another activity that takes photos. When a photo is taken I want to associate a location with the image. My current idea is to just use my broadcast receiver in my Bluetooth warning class to listen for a broadcast my camera will send and associate it then with a location. I'm not a fan of the idea because it doesn't separate functionality very well so was hoping for some suggestions or patterns. Code for classes below.
CAMERA CLASS
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.Toast;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class CameraOperations extends AppCompatActivity {
public final static String ACTION_PICTURE_RECEIVED = "ACTION_PICTURE_RECEIVED";
public final static String TRANSFER_DATA = "bitmap";
ImageView mImageView;
String photoPath;
int REQUEST_IMAGE_CAPTURE = 1;
File photoFile = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.camera_view);
mImageView = (ImageView) findViewById(R.id.imageView);
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
Toast.makeText(CameraOperations.this, "No Camera", Toast.LENGTH_SHORT).show();
} else {
dispatchTakePictureIntent();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK){
if(data == null){
Toast.makeText(this, "Data is null", Toast.LENGTH_SHORT);
Bitmap pictureMap = BitmapFactory.decodeFile(photoFile.getAbsolutePath());
mImageView.setImageBitmap(pictureMap);
broadcastUpdate(ACTION_PICTURE_RECEIVED, pictureMap);
}else {
Toast.makeText(this, "Error Occurred", Toast.LENGTH_SHORT).show();
}
}
}
private void broadcastUpdate(final String action, Bitmap picture) {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
picture.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bytes = stream.toByteArray();
Intent intent = new Intent(action);
intent.putExtra(TRANSFER_DATA, bytes);
sendBroadcast(intent);
intent = new Intent(CameraOperations.this, Warning.class);
startActivity(intent);
finish();
}
private File createImageFile() throws IOException {
String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
String imageFileName = "JPEG_" + timeStamp + "_";
File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
File image = File.createTempFile(imageFileName, ".jpg", storageDir);
photoPath = "file:" + image.getAbsolutePath();
return image;
}
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
try{
photoFile = createImageFile();
}catch(IOException e){
e.printStackTrace();
}
if(photoFile != null){
Uri photoUri = Uri.fromFile(photoFile);
takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
}
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
BLUETOOTH WARNING CLASS
import android.Manifest;
import android.bluetooth.BluetoothGattCharacteristic;
import android.bluetooth.BluetoothGattService;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
public class Warning extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private final static String TAG = Warning.class.getSimpleName();
private String mDeviceAddress;
private HandleConnectionService mBluetoothLeService;
private boolean quitService;
private final int PLAY_SERVICES_REQUEST_TIME = 1000;
private Location mLastLocation;
private GoogleApiClient mGoogleClient;
private boolean requestingLocationUpdates = false;
private LocationRequest locationRequest;
private int UPDATE_INTERVAL = 10000; // 10 seconds
private int FASTEST_INTERVAL = 5000; // 5 seconds
private int DISTANCEMOVED = 10; //In meters
private final ServiceConnection mServiceConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
mBluetoothLeService = ((HandleConnectionService.LocalBinder) service).getService();
if (!mBluetoothLeService.initialize()) {
Log.e(TAG, "Unable to initialize Bluetooth");
finish();
}
mBluetoothLeService.connect(mDeviceAddress);
}
#Override
public void onServiceDisconnected(ComponentName componentName) {
mBluetoothLeService = null;
}
};
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
final String action = intent.getAction();
if (HandleConnectionService.ACTION_GATT_DISCONNECTED.equals(action)) {
if (!quitService) {
mBluetoothLeService.connect(mDeviceAddress);
Log.w(TAG, "Attempting to reconnect");
}
Log.w(TAG, "Disconnected, activity closing");
} else if (HandleConnectionService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) {
getGattService(mBluetoothLeService.getSupportedGattService());
} else if (HandleConnectionService.ACTION_DATA_AVAILABLE.equals(action)) {
checkWarning(intent.getByteArrayExtra(HandleConnectionService.EXTRA_DATA));
}else if(CameraOperations.ACTION_PICTURE_RECEIVED.equals(action)){
byte[] bytes = intent.getByteArrayExtra("bitmap");
Bitmap picture = BitmapFactory.decodeByteArray(bytes, 0, bytes.length);
findLocation();
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.second);
Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
setSupportActionBar(myToolbar);
if (checkGoogleServices()) {
buildGoogleApiClient();
}
quitService = false;
Intent intent = getIntent();
mDeviceAddress = intent.getStringExtra(Device.EXTRA_DEVICE_ADDRESS);
Intent gattServiceIntent = new Intent(this, HandleConnectionService.class);
bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE);
}
#Override
protected void onResume() {
super.onResume();
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.mainmenu, menu);
MenuItem connect = menu.findItem(R.id.connect);
connect.setVisible(false);
MenuItem disconnect = menu.findItem(R.id.disconnect);
disconnect.setVisible(true);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent intent;
switch (item.getItemId()) {
case R.id.home:
new AlertDialog.Builder(this)
.setIcon(android.R.drawable.ic_dialog_alert)
.setTitle("Return Home")
.setMessage("Returning home will disconnect you, continue?")
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
quitService = true;
mBluetoothLeService.disconnect();
mBluetoothLeService.close();
Intent intent = new Intent(Warning.this, Main.class);
startActivity(intent);
}
})
.setNegativeButton("No", null)
.show();
return true;
case R.id.connect:
Toast.makeText(this, "Connect Pressed", Toast.LENGTH_SHORT).show();
return true;
case R.id.disconnect:
disconnectOperation();
intent = new Intent(Warning.this, Main.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
case R.id.profiles:
Toast.makeText(this, "Profiles Pressed", Toast.LENGTH_SHORT).show();
return true;
case R.id.camera:
Toast.makeText(this, "Camera Pressed", Toast.LENGTH_SHORT).show();
intent = new Intent(Warning.this, CameraOperations.class);
startActivity(intent);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
if (keyCode == KeyEvent.KEYCODE_BACK) {
quitService = true;
mBluetoothLeService.disconnect();
mBluetoothLeService.close();
Intent intent = new Intent(Warning.this, Main.class);
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(intent);
return true;
}
return super.onKeyDown(keyCode, event);
}
#Override
protected void onDestroy() {
super.onDestroy();
mBluetoothLeService.disconnect();
mBluetoothLeService.close();
System.exit(0);
}
public boolean disconnectOperation(){
this.quitService = true;
mBluetoothLeService.disconnect();
mBluetoothLeService.close();
return true;
}
private void checkWarning(byte[] byteArray) {
if (byteArray != null) {
for (int i = 0; i < byteArray.length; i++) {
if (byteArray[i] == 48) {
findLocation();
}
}
}
}
private void getGattService(BluetoothGattService gattService) {
if (gattService == null) {
return;
}
BluetoothGattCharacteristic characteristicRx = gattService.getCharacteristic(HandleConnectionService.UUID_BLE_SHIELD_RX);
mBluetoothLeService.setCharacteristicNotification(characteristicRx, true);
mBluetoothLeService.readCharacteristic(characteristicRx);
}
private static IntentFilter makeGattUpdateIntentFilter() {
final IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(HandleConnectionService.ACTION_GATT_CONNECTED);
intentFilter.addAction(HandleConnectionService.ACTION_GATT_DISCONNECTED);
intentFilter.addAction(HandleConnectionService.ACTION_GATT_SERVICES_DISCOVERED);
intentFilter.addAction(HandleConnectionService.ACTION_DATA_AVAILABLE);
intentFilter.addAction(CameraOperations.ACTION_PICTURE_RECEIVED);
return intentFilter;
}
private boolean checkGoogleServices() {
GoogleApiAvailability googleAPI = GoogleApiAvailability.getInstance();
int available = googleAPI.isGooglePlayServicesAvailable(this);
if (available != ConnectionResult.SUCCESS) {
if (googleAPI.isUserResolvableError(available)) {
googleAPI.getErrorDialog(this, available, PLAY_SERVICES_REQUEST_TIME).show();
}
return false;
}
return true;
}
public void findLocation() {
int REQUEST_CODE_ASK_PERMISSIONS = 123;
double latitude = 0.0;
double longitude = 0.0;
if(Build.VERSION.SDK_INT >= 23){
boolean fineLocationAccess = ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
boolean courseLocationAccess = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED;
boolean accessGranted = fineLocationAccess && courseLocationAccess;
if (accessGranted) {
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleClient);
if(mLastLocation != null) {
latitude = mLastLocation.getLatitude();
longitude = mLastLocation.getLongitude();
Toast.makeText(this, "latitude: " + latitude + " longitude: " + longitude, Toast.LENGTH_LONG).show();
}else{
Log.i("Warning", "Unable to get Location");
}
}else{
Log.i("Connection", "Request permission");
}
}else{
mLastLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleClient);
if(mLastLocation != null) {
latitude = mLastLocation.getLatitude();
longitude = mLastLocation.getLongitude();
Toast.makeText(this, "latitude: " + latitude + " longitude: " + longitude, Toast.LENGTH_LONG).show();
}else{
Log.i("Warning", "Unable to get Location");
}
}
}
public void buildGoogleApiClient() {
mGoogleClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API).build();
}
#Override
public void onConnected(Bundle bundle) {
Log.w("Connected", " : " + mGoogleClient.isConnected());
}
#Override
public void onConnectionSuspended(int i) {
Toast.makeText(this, "Location Services Stopped", Toast.LENGTH_SHORT).show();
}
#Override
public void onConnectionFailed(ConnectionResult connectionResult) {
Toast.makeText(this, "Location Services Connection Fail", Toast.LENGTH_SHORT).show();
}
#Override
protected void onStart() {
super.onStart();
if (mGoogleClient != null) {
mGoogleClient.connect();
}
}
}
I think your original idea is actually pretty sound as long as you construct it a certain way. The activity that is knowledgeable about the location information can update and store that location independent of any other activity. This would probably be ideal to have as a service actually that runs every x amount of time, or when the location changes.
Inside of that same class you can have a generic broadcast receiver that handles request for that location information. You can make this as generic as you want in terms of allowing other applications/activities you make also being to leverage it, as long as the location data is returned in a way that is usable to each requester.
From within your activity that takes photos (and eventually any activity you desire), when you take a photo, you can send a broadcast requesting that location information, with some default or null info if none is returned. One of the complexities is knowing how long to wait for this location info before completing. In this scenario the location activity is the 'generalized' one in that multiple activities can request location data if you construct it correctly.
Another potentially robust approach is to make the photo taking activity the generalized one. One way to do this is that when you take a photo, you can have your photo activity send broadcast to the location activity that contains the photos filepath/uri/identifying information, but you don't wait for a response. Instead, you make the location activity listen for this broadcast, and write to the photos meta data with the location using the provided identifying info to find said photo. In this way your photo taking app isn't stuck waiting for the location activity to finish (or event start if it ever does).
Good luck, sounds like a fun project.
Related
I added achievements to my Google Play game following Google's tutorial. They unlock fine and if I display achievements in-game immediately they show up. If I quit the game and go to the Google Game's app they don't show up and they disappear from in-game also. Any ideas? I've tried multiple accounts. Thanks!
package com.b1stable.tth;
import java.io.File;
import java.io.FileFilter;
import java.util.Locale;
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.FileSystems;
import java.util.Vector;
import android.os.Bundle;
import android.os.Build;
import android.content.Context;
import android.content.Intent;
import android.graphics.Canvas;
import android.graphics.Color;
import android.net.Uri;
import android.os.Vibrator;
import android.os.VibrationEffect;
import android.util.Log;
import android.view.Surface;
import android.view.Gravity;
import org.libsdl.app.SDLActivity;
import com.b1stable.tth.License_Viewer_Activity;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentActivity;
import com.google.android.gms.auth.api.signin.GoogleSignIn;
import com.google.android.gms.auth.api.signin.GoogleSignInAccount;
import com.google.android.gms.auth.api.signin.GoogleSignInClient;
import com.google.android.gms.auth.api.signin.GoogleSignInOptions;
import com.google.android.gms.auth.api.signin.GoogleSignInResult;
import com.google.android.gms.auth.api.Auth;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.games.AchievementsClient;
import com.google.android.gms.games.AnnotatedData;
import com.google.android.gms.games.EventsClient;
import com.google.android.gms.games.Games;
import com.google.android.gms.games.GamesClient;
import com.google.android.gms.games.LeaderboardsClient;
import com.google.android.gms.games.Player;
import com.google.android.gms.games.PlayersClient;
import com.google.android.gms.games.event.Event;
import com.google.android.gms.games.event.EventBuffer;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Task.*;
public class TTH_Activity extends SDLActivity
{
final static int LICENSE_REQUEST = 1;
native static void resume_after_showing_license();
native static void resume_after_showing_achievements();
native static void pause();
native static void resume();
// Client used to sign in with Google APIs
private GoogleSignInClient mGoogleSignInClient;
private AchievementsClient mAchievementsClient = null;
private boolean signin_failed = false;
// request codes we use when invoking an external activity
private static final int RC_UNUSED = 5001;
private static final int RC_SIGN_IN = 9001;
// This is so the screen is never cleared pure black, only shim::black (r:35, g:30, b:60)
static boolean paused = false;
private static final String TAG = "TTH";
#Override
public void onCreate(Bundle savedInstance)
{
super.onCreate(savedInstance);
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == LICENSE_REQUEST) {
if (data != null) {
if (resultCode == RESULT_OK && data.getExtras().getString("MESSAGE").equals("OK")) {
show_license_result = 0;
}
else if (resultCode == RESULT_CANCELED && data.getExtras().getString("MESSAGE").equals("FAIL")) {
show_license_result = 1;
}
else {
show_license_result = 1;
}
}
else {
show_license_result = 1;
}
resume_after_showing_license();
}
if (requestCode == RC_SIGN_IN) {
GoogleSignInResult result = Auth.GoogleSignInApi.getSignInResultFromIntent(data);
if (result.isSuccess()) {
// The signed in account is stored in the result.
GoogleSignInAccount signedInAccount = result.getSignInAccount();
onConnected(signedInAccount);
}
else {
String message = result.getStatus().getStatusMessage();
if (message == null || message.isEmpty()) {
message = "An error occurred!";
}
new AlertDialog.Builder(this).setMessage(message).setNeutralButton(android.R.string.ok, null).show();
onDisconnected();
}
}
}
public void onStart() {
super.onStart();
}
#Override
public void onStop()
{
super.onStop();
pause();
}
#Override
public void onRestart()
{
super.onRestart();
resume();
}
#Override
public void onResume()
{
super.onResume();
signInSilently();
}
#Override
public void onPause()
{
super.onPause();
mAchievementsClient = null;
}
#Override
public void onPostResume()
{
super.onPostResume();
paused = true;
}
public void logString(String s)
{
Log.d("TTH", s);
}
public String getAppdataDir()
{
return getFilesDir().getAbsolutePath();
}
public String getSDCardDir()
{
File f = getExternalFilesDir(null);
if (f != null) {
return f.getAbsolutePath();
}
else {
return getFilesDir().getAbsolutePath();
}
}
static int show_license_result;
public void showLicense()
{
show_license_result = -1;
Intent intent = new Intent(this, License_Viewer_Activity.class);
startActivityForResult(intent, LICENSE_REQUEST);
}
public int getShowLicenseResult()
{
return show_license_result;
}
/*
public void openURL(String url)
{
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
}
*/
public void rumble(int milliseconds)
{
Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
if (v != null && v.hasVibrator()) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
v.vibrate(VibrationEffect.createOneShot(milliseconds, VibrationEffect.DEFAULT_AMPLITUDE));
}
else {
v.vibrate(milliseconds);
}
}
}
public boolean has_touchscreen()
{
return getPackageManager().hasSystemFeature("android.hardware.touchscreen");
}
public boolean has_vibrator()
{
Vibrator v = (Vibrator)getSystemService(Context.VIBRATOR_SERVICE);
if (v != null) {
return v.hasVibrator();
}
else {
return false;
}
}
public void start_draw()
{
if (paused) {
paused = false;
}
}
public String get_android_language()
{
return Locale.getDefault().getLanguage();
}
private static File[] list_dir_files = null;
public void list_dir_start(String path)
{
try {
int slash = path.lastIndexOf('/');
final String glob = path.substring(slash+1).replace("*", ".*"); // +1 works even if not found (-1+1 == 0)
String dir = path.substring(0, slash);
File f = new File(dir);
list_dir_files = f.listFiles(new FileFilter() {
public boolean accept(File f)
{
try {
if (f.getName().matches(glob)) {
return true;
}
else {
return false;
}
}
catch (Exception e) {
Log.d("TTH", "list_dir_start FileFilter throwing " + e.getMessage());
return false;
}
}
});
}
catch (Exception e) {
list_dir_files = null;
Log.d("TTH", "list_dir_start throwing " + e.getMessage());
}
}
public String list_dir_next()
{
if (list_dir_files == null) {
return "";
}
else if (list_dir_files.length == 0) {
list_dir_files = null;
return "";
}
else {
File f = list_dir_files[0];
String name = f.getName();
if (list_dir_files.length == 1) {
list_dir_files = null;
}
else {
File[] new_list = new File[list_dir_files.length-1];
for (int i = 1; i < list_dir_files.length; i++) {
new_list[i-1] = list_dir_files[i];
}
list_dir_files = new_list;
}
return name;
}
}
private static final String ARC_DEVICE_PATTERN = ".+_cheets|cheets_.+";
public boolean is_chromebook()
{
// Google uses this, so should work?
return Build.DEVICE != null && Build.DEVICE.matches(ARC_DEVICE_PATTERN);
}
private static final int RC_ACHIEVEMENT_UI = 9003;
public boolean show_achievements()
{
if (mAchievementsClient == null) {
return false;
}
mAchievementsClient.getAchievementsIntent().addOnSuccessListener(new OnSuccessListener<Intent>() {
#Override
public void onSuccess(Intent intent) {
startActivityForResult(intent, RC_ACHIEVEMENT_UI);
resume_after_showing_achievements();
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(Exception e) {
resume_after_showing_achievements();
}
}).addOnCompleteListener(new OnCompleteListener<Intent>() {
#Override
public void onComplete(Task<Intent> task) {
resume_after_showing_achievements();
}
});
return true;
}
public void achieve(String id)
{
if (mAchievementsClient != null) {
mAchievementsClient.unlock(id);
}
}
private void startSignInIntent() {
GoogleSignInClient signInClient = GoogleSignIn.getClient(this, GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN);
Intent intent = signInClient.getSignInIntent();
startActivityForResult(intent, RC_SIGN_IN);
}
private void signInSilently() {
if (signin_failed == true || mAchievementsClient != null) {
return;
}
GoogleSignInOptions signInOptions = GoogleSignInOptions.DEFAULT_GAMES_SIGN_IN;
GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(this);
if (GoogleSignIn.hasPermissions(account, signInOptions.getScopeArray())) {
// Already signed in.
// The signed in account is stored in the 'account' variable.
//GoogleSignInAccount signedInAccount = account;
onConnected(account);
}
else {
// Haven't been signed-in before. Try the silent sign-in first.
GoogleSignInClient signInClient = GoogleSignIn.getClient(this, signInOptions);
signInClient.silentSignIn().addOnCompleteListener(
this,
new OnCompleteListener<GoogleSignInAccount>() {
#Override
public void onComplete(#NonNull Task<GoogleSignInAccount> task) {
if (task.isSuccessful()) {
// The signed in account is stored in the task's result.
GoogleSignInAccount signedInAccount = task.getResult();
onConnected(signedInAccount);
}
else {
// Player will need to sign-in explicitly using via UI.
// See [sign-in best practices](http://developers.google.com/games/services/checklist) for guidance on how and when to implement Interactive Sign-in,
// and [Performing Interactive Sign-in](http://developers.google.com/games/services/android/signin#performing_interactive_sign-in) for details on how to implement
// Interactive Sign-in.
startSignInIntent();
}
}
}
);
}
}
public void start_google_play_games_services() {
/*
runOnUiThread(new Runnable() {
public void run() {
signInSilently();
}
});
*/
}
private void onConnected(GoogleSignInAccount googleSignInAccount) {
Log.d(TAG, "onConnected(): connected to Google APIs");
GamesClient gamesClient = Games.getGamesClient(this, googleSignInAccount);
gamesClient.setViewForPopups(findViewById(android.R.id.content));
gamesClient.setGravityForPopups(Gravity.TOP | Gravity.CENTER_HORIZONTAL);
mAchievementsClient = Games.getAchievementsClient(this, googleSignInAccount);
}
private void onDisconnected() {
Log.d(TAG, "onDisconnected()");
mAchievementsClient = null;
signin_failed = true;
}
}
Hello iam stuck in problem since yesterday searched everything anywhere i create application which show device which arre connected to same router wifi , then iam able to connect both device using this exmple
https://developer.android.com/guide/topics/connectivity/wifip2p.html#creating-app
everything is okay both devices are connected but when transfer file serviceintent is not starting so thats why i cant transfer anything , there is not log error but happend nothing when i choose image to send
MainActivity Class
package com.b.wifip2p;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.Uri;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WpsInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pGroup;
import android.net.wifi.p2p.WifiP2pInfo;
import android.net.wifi.p2p.WifiP2pManager;
import android.os.AsyncTask;
import android.os.Environment;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.format.Formatter;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.ServerSocket;
import java.net.Socket;
import java.sql.SQLOutput;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class MainActivity extends AppCompatActivity implements WifiP2pManager.PeerListListener, WifiP2pManager.ConnectionInfoListener {
Button button;
private boolean isWifiP2pEnabled = false;
private boolean retryChannel = false;
private final IntentFilter intentFilter = new IntentFilter();
private WifiP2pManager.Channel channel;
WifiP2pManager.Channel mChannel = null;
WifiP2pManager mManager;
private WifiP2pInfo info;
BroadCast broadCast;
private BroadcastReceiver receiver = null;
static List peers = new ArrayList();
ListView lv;
static Adapater myadapter;
ArrayList<DeviceInfo_Bean>list=new ArrayList<>();
private WifiP2pDevice device;
String hostaddd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
lv=findViewById(R.id.lv);
myadapter=new Adapater(this,list);
button=findViewById(R.id.button);
lv.setAdapter(myadapter);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
intentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
lv.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
connect();
}
});
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
System.out.println("---sucess discover");
}
#Override
public void onFailure(int reasonCode) {
System.out.println("---fail");
}
});
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("image/*");
startActivityForResult(intent, 007);
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
int ipAddress = wifiInfo.getIpAddress();
System.out.println("---ip"+ipAddress);
}
});
}
#Override
public void onResume() {
super.onResume();
broadCast = new BroadCast(mManager, mChannel, MainActivity.this);
registerReceiver(broadCast, intentFilter);
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(broadCast);
}
private static WifiP2pManager.PeerListListener peerListListener = new WifiP2pManager.PeerListListener() {
#Override
public void
onPeersAvailable(WifiP2pDeviceList peerList) {
List<WifiP2pDevice> refreshedPeers = (List<WifiP2pDevice>) peerList.getDeviceList();
if (!refreshedPeers.equals(peers)) {
peers.clear();
peers.addAll(refreshedPeers);
System.out.println("---ref"+refreshedPeers);
}
if (peers.size() == 0) {
Log.d("-----deviceno", "No devices found");
return;
}
}
};
#Override
public void onPeersAvailable(WifiP2pDeviceList peers) {
for (WifiP2pDevice device : peers.getDeviceList())
{
list.clear();
String address=device.deviceAddress;
String name=device.deviceName;
System.out.println("---name"+name+address);
list.add(new DeviceInfo_Bean(name,address));
}
myadapter.notifyDataSetChanged();
Log.i("----", "Found some peers!!! " + peers.getDeviceList());
}
public void connect() {
DeviceInfo_Bean device = list.get(0);
WifiP2pConfig config = new WifiP2pConfig();
config.deviceAddress = device.address;
config.wps.setup = WpsInfo.PBC;
System.out.println("device in"+device.address);
mManager.connect(mChannel, config, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
Toast.makeText(MainActivity.this, "Connected.",
Toast.LENGTH_SHORT).show();
}
#Override
public void onFailure(int reason) {
Toast.makeText(MainActivity.this, "Connect failed. Retry.",
Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
// User has picked an image. Transfer it to group owner i.e peer using
// FileTransferService.
Uri uri = data.getData();
// TextView statusText = (TextView) mContentView.findViewById(R.id.status_text);
// statusText.setText("Sending: " + uri);
// Log.d(WiFiDirectActivity.TAG, "Intent----------- " + uri);
Intent serviceIntent = new Intent(MainActivity.this, FileTransferService.class);
serviceIntent.setAction(FileTransferService.ACTION_SEND_FILE);
serviceIntent.putExtra(FileTransferService.EXTRAS_FILE_PATH, uri.toString());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_ADDRESS,
info.groupOwnerAddress.getHostAddress());
serviceIntent.putExtra(FileTransferService.EXTRAS_GROUP_OWNER_PORT, 8988);
startService(serviceIntent);
}
#Override
public void onPointerCaptureChanged(boolean hasCapture) {
}
public static class FileServerAsyncTask extends AsyncTask<Void, Void, String> {
private Context context;
//private TextView statusText;
/**
* #param context
*
*/
public FileServerAsyncTask(Context context) {
this.context = context;
//this.statusText = (TextView) statusText;
}
#Override
protected String doInBackground(Void... params) {
try {
ServerSocket serverSocket = new ServerSocket(8988);
System.out.println("---socket");
Socket client = serverSocket.accept();
///Log.d(WiFiDirectActivity.TAG, "Server: connection done");
final File f = new File(Environment.getExternalStorageDirectory() + "/"
+ context.getPackageName() + "/wifip2pshared-" + System.currentTimeMillis()
+ ".jpg");
File dirs = new File(f.getParent());
if (!dirs.exists())
dirs.mkdirs();
f.createNewFile();
//Log.d(WiFiDirectActivity.TAG, "server: copying files " + f.toString());
OutputStream stream = client.getOutputStream();
String s="---mymsg";
stream.write(s.getBytes());
Log.e("hello","context value "+context);
InputStream inputstream = client.getInputStream();
copyFile(inputstream, new FileOutputStream(f));
serverSocket.close();
return f.getAbsolutePath();
} catch (IOException e) {
// Log.e(WiFiDirectActivity.TAG, e.getMessage());
return null;
}
}
/*
* (non-Javadoc)
* #see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
#Override
protected void onPostExecute(String result) {
if (result != null) {
// statusText.setText("File copied - " + result);
Intent intent = new Intent();
intent.setAction(android.content.Intent.ACTION_VIEW);
intent.setDataAndType(Uri.parse("file://" + result), "image/*");
context.startActivity(intent);
}
}
/*
* (non-Javadoc)
* #see android.os.AsyncTask#onPreExecute()
*/
#Override
protected void onPreExecute() {
// statusText.setText("Opening a server socket");
}
}
public static boolean copyFile(InputStream inputStream, OutputStream out) {
byte buf[] = new byte[1024];
int len;
long startTime=System.currentTimeMillis();
try {
while ((len = inputStream.read(buf)) != -1) {
out.write(buf, 0, len);
}
out.close();
inputStream.close();
long endTime=System.currentTimeMillis()-startTime;
Log.v("","Time taken to transfer all bytes is : "+endTime);
} catch (IOException e) {
// Log.d(WiFiDirectActivity.TAG, e.toString());
return false;
}
return true;
}
public void onConnectionInfoAvailable(final WifiP2pInfo info) {
System.out.println("---info");
this.info=info;
// view.setText("Group Owner IP - " + info.groupOwnerAddress.getHostAddress());
InetAddress groupOwnerAddress = info.groupOwnerAddress;
System.out.println("--g"+groupOwnerAddress);
System.out.println("--info"+info.groupOwnerAddress.getHostAddress());
if (info.groupFormed && info.isGroupOwner) {
new FileServerAsyncTask(getApplication())
.execute();
} else if (info.groupFormed) {
// The other device acts as the client. In this case, we enable the
// get file button.
}
// hide the connect button
// mContentView.findViewById(R.id.btn_connect).setVisibility(View.GONE);
}
public void showDetails(WifiP2pDevice device) {
this.device = device;
// this.getView().setVisibility(View.VISIBLE);
// TextView view = (TextView) mContentView.findViewById(R.id.device_address);
// view.setText(device.deviceAddress);
//view = (TextView) mContentView.findViewById(R.id.device_info);
//view.setText(device.toString());
System.out.println("---device"+device.deviceAddress);
}
}'
Broadcast
package com.b.wifip2p;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.net.NetworkInfo;
import android.net.wifi.p2p.WifiP2pConfig;
import android.net.wifi.p2p.WifiP2pDevice;
import android.net.wifi.p2p.WifiP2pDeviceList;
import android.net.wifi.p2p.WifiP2pManager;
import android.util.Log;
import android.net.wifi.p2p.WifiP2pManager.PeerListListener;
import java.nio.channels.Channel;
/**
* Created by BHM on 3/3/2018.
*/
public class BroadCast extends BroadcastReceiver {
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private MainActivity activity;
PeerListListener peerListListener=null;
public BroadCast(WifiP2pManager manager, WifiP2pManager.Channel channel,
MainActivity activity) {
super();
this.mManager = manager;
this.mChannel = channel;
this.activity = (MainActivity) activity;
}
#Override
public void onReceive(Context context, Intent intent) {
System.out.println("-----broadcast");
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
// UI update to indicate wifi p2p status.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
// Wifi Direct mode is enabled
// activity.setIsWifiP2pEnabled(true);
} else {
//activity.setIsWifiP2pEnabled(false);
// activity.resetData();
}
// Log.d(WiFiDirectActivity.TAG, "P2P state changed - " + state);
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// request available peers from the wifi p2p manager. This is an
// asynchronous call and the calling activity is notified with a
// callback on PeerListListener.onPeersAvailable()
if (mManager != null) {
// mManager.requestPeers(mChannel, (PeerListListener) mChannel);
}
// Log.d(WiFiDirectActivity.TAG, "P2P peers changed");
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
if (mManager == null) {
return;
}
NetworkInfo networkInfo = (NetworkInfo) intent
.getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);
if (networkInfo.isConnected()) {
// we are connected with the other device, request connection
// info to find group owner IP
mManager.requestConnectionInfo(mChannel, activity);
} else {
// It's a disconnect
// activity.resetData();
}
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// DeviceListFragment fragment = (DeviceListFragment) activity.getFragmentManager()
// .findFragmentById(R.id.frag_list);
// fragment.updateThisDevice((WifiP2pDevice) intent.getParcelableExtra(
// WifiP2pManager.EXTRA_WIFI_P2P_DEVICE));
intent.getParcelableExtra(
WifiP2pManager.EXTRA_WIFI_P2P_DEVICE);
}
}
}
FileTransferService here intent is not coming
package com.b.wifip2p;
import android.app.IntentService;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Handler;
import android.util.Log;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectOutputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
/**
* Created by BHM on 3/4/2018.
*/
class FileTransferService extends IntentService {
private static final int SOCKET_TIMEOUT = 5000;
public static final String ACTION_SEND_FILE = "com.example.android.wifidirect.SEND_FILE";
public static final String EXTRAS_FILE_PATH = "file_url";
public static final String EXTRAS_GROUP_OWNER_ADDRESS = "go_host";
public static final String EXTRAS_GROUP_OWNER_PORT = "go_port";
public FileTransferService(String name) {
super(name);
}
#Override
protected void onHandleIntent(Intent intent) {
System.out.println("--intent");
Context context = getApplicationContext();
if (intent.getAction().equals(ACTION_SEND_FILE)) {
String fileUri = intent.getExtras().getString(EXTRAS_FILE_PATH);
String host = intent.getExtras().getString(EXTRAS_GROUP_OWNER_ADDRESS);
Socket socket = new Socket();
int port = intent.getExtras().getInt(EXTRAS_GROUP_OWNER_PORT);
try {
// Log.d(WiFiDirectActivity.TAG, "Opening client socket - ");
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);
// Log.d(WiFiDirectActivity.TAG, "Client socket - " + socket.isConnected());
OutputStream stream = socket.getOutputStream();
ContentResolver cr = context.getContentResolver();
InputStream is = null;
try {
is = cr.openInputStream(Uri.parse(fileUri));
} catch (FileNotFoundException e) {
// Log.d(WiFiDirectActivity.TAG, e.toString());
}
MainActivity.copyFile(is, stream);
// Log.d(WiFiDirectActivity.TAG, "Client: Data written");
} catch (IOException e) {
// Log.e(WiFiDirectActivity.TAG, e.getMessage());
} finally {
if (socket != null) {
if (socket.isConnected()) {
try {
socket.close();
} catch (IOException e) {
// Give up
e.printStackTrace();
}
}
}
}
}
}
}
I know this is a slightly old question by now, but for those looking for answers:
I would recommend checking that you have the intent filters properly in your AndroidManifest.xml file.
It should look something like:
<activity android:name="ShareActivity">
<intent-filter>
<action android:name="android.intent.action.ACTION_SEND_FILE"/>
<category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain"/>
</intent-filter>
</activity>
I'm developing Google Fit API application and last 2 days I've been trying to store and retrieve data belongs to the BPM data type in different android applications. Meanwhile retrieving it returns zero points, although meanwhile inserting framework reports that everyting is inserted. I created OAuth keys for both applications, each of them has a subscription to this data type. Also I use enableServerQueries() for retrieval.
Datasource is being created as
daataSource=new DataSource.Builder().setName("measurementsSource").setDataType(DataType.TYPE_HEART_RATE_BPM).
setAppPackageName(getApplicationContext())
.setType(TYPE_RAW).build();
Does anyone has any ideas how to fetch data in a proper way?
Upd. According to the advice, I've added full code to add 1 point of custom DataType which I'd like to use. I've tried it number of times, but it still says 'ok' and no data could be available for getting back (for example, with API explorer).
package test.com.cloudydiscoverer;
import android.content.Intent;
import android.content.IntentSender;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.Scopes;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Scope;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.fitness.Fitness;
import com.google.android.gms.fitness.data.DataPoint;
import com.google.android.gms.fitness.data.DataSet;
import com.google.android.gms.fitness.data.DataSource;
import com.google.android.gms.fitness.data.DataType;
import com.google.android.gms.fitness.data.Field;
import com.google.android.gms.fitness.request.DataTypeCreateRequest;
import com.google.android.gms.fitness.result.DataTypeResult;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import static android.content.ContentValues.TAG;
import static com.google.android.gms.fitness.data.DataSource.TYPE_RAW;
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_OAUTH = 1;
private static boolean authInProgress = false;
protected GoogleApiClient googleApiClient = null;
private GoogleApiClient.ConnectionCallbacks connectionCallbacks = null;
private void buildFitnessClient() {
GoogleApiClient.Builder builder = new GoogleApiClient.Builder(this);
builder.addApi(Fitness.RECORDING_API);
builder.addApi(Fitness.SENSORS_API);
builder.addApi(Fitness.BLE_API);
builder.addApi(Fitness.SESSIONS_API);
builder.addApi(Fitness.HISTORY_API);
builder.addApi(Fitness.CONFIG_API);
builder.addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE)); //TODO; verify scopes
builder.addScope(new Scope(Scopes.FITNESS_ACTIVITY_READ_WRITE));
builder.addScope(new Scope(Scopes.FITNESS_LOCATION_READ_WRITE));
builder.addScope(new Scope(Scopes.FITNESS_BODY_READ_WRITE));
googleApiClient = builder.build();
}
public boolean flag=false;
#Override
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
connectionCallbacks = new GoogleApiClient.ConnectionCallbacks() {
#Override
public void onConnected(Bundle bundle) {
/* try {
Thread.sleep(120000);
} catch (InterruptedException e) {
e.printStackTrace();
}
*/
DataTypeCreateRequest request = new DataTypeCreateRequest.Builder()
.setName("test.com.cloudydiscoverer.cloudy_s")
.addField("value", Field.FORMAT_INT32)
.build();
Fitness.ConfigApi.createCustomDataType(googleApiClient, request)
.setResultCallback(new ResultCallback<DataTypeResult>() {
#Override
public void onResult(#NonNull DataTypeResult dataTypeResult) {
if (!dataTypeResult.getStatus().isSuccess()) {
Log.i(TAG, "DataType creation/retrieval failed with result: " + dataTypeResult.getStatus().getStatusMessage());
} else {
Log.i(TAG, "created");
DataSource wSource=new DataSource.Builder().setName(dataTypeResult.getDataType().getName()+".source").setDataType(DataType.TYPE_HEART_RATE_BPM).
setType(TYPE_RAW).setAppPackageName("test.com.cloudydiscoverer").build();
/* DataSource wetSource = new DataSource.Builder()
.setDataType(dataTypeResult.getDataType())
.build();*/
DataPoint b = DataPoint.create(wSource);
b.setTimestamp(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
b.setFloatValues(5.0f);
//b.getValue(dataTypeResult.getDataType().getFields().get(0)).setInt(42);
DataSet dataSet = DataSet.create(wSource);
dataSet.add(b);
Fitness.HistoryApi.insertData(googleApiClient, dataSet).setResultCallback(new ResultCallback<Status>() {
#Override
public void onResult(#NonNull Status status) {
Log.i(TAG, String.valueOf(status.isSuccess()));
}
}
);
}
}
});
}
#Override
public void onConnectionSuspended(int i) {
if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_NETWORK_LOST) {
Toast.makeText(MainActivity.this, "Network is unavailable. " +
"Connection will be restored automatically.", Toast.LENGTH_SHORT).show();
} else if (i == GoogleApiClient.ConnectionCallbacks.CAUSE_SERVICE_DISCONNECTED) {
Toast.makeText(MainActivity.this, "Service has been disconnected. " +
"Connection will be restored automatically.", Toast.LENGTH_SHORT).show();
}
}
};
GoogleApiClient.OnConnectionFailedListener onConnectionFailedListener = new GoogleApiClient.OnConnectionFailedListener() {
#Override
public void onConnectionFailed(ConnectionResult result) {
Log.i(TAG, "Connection failed with result: " + result.getErrorCode());
if (!result.hasResolution()) {
return;
}
if (!authInProgress) {
try {
Toast.makeText(MainActivity.this, "You need to authorize.", Toast.LENGTH_SHORT).show();
authInProgress = true;
result.startResolutionForResult(MainActivity.this, REQUEST_OAUTH);
} catch (IntentSender.SendIntentException e) {
Toast.makeText(MainActivity.this, "Exception has been caught.", Toast.LENGTH_SHORT).show();
}
}
}
};
Log.i("1","1");
buildFitnessClient();
googleApiClient.registerConnectionCallbacks(connectionCallbacks);
googleApiClient.registerConnectionFailedListener(onConnectionFailedListener);
Log.i("2","2");
googleApiClient.connect();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == REQUEST_OAUTH) {
authInProgress = false;
if (resultCode == RESULT_OK) {
if ((!googleApiClient.isConnected()) || (!googleApiClient.isConnecting()))
googleApiClient.connect();
} else {
Log.i(TAG, "Nothing could be done.");
}
}
}
}
I am trying to save an array list into a xml file in the internal storage using Xmlserializer. The app scans for BLE and when a Stop button is pressed it should save some parameters from the list of BLE that it has detected. It runs perfect and when I pressed the stop button it stops the scan and displays in the mobile screen a toast message that the xml file has been created successfully. However, when I seach for the xml file, it doesn´t appear anywhere as if it hasn´t been created. I don´t know the reason of this problem. Here is the code I have implemented:
package com.example.newblescan;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import org.xmlpull.v1.XmlSerializer;
import com.example.newblescan.R;
import android.app.Activity;
import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.format.DateFormat;
import android.util.Xml;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.ListView;
import android.widget.Toast;
import com.example.newblescan.adapter.BleDevicesAdapter;
/**
* Activity for scanning and displaying available Bluetooth LE devices.
*/
public class DeviceScanActivity extends ListActivity {
private static final int REQUEST_ENABLE_BT = 1;
private static final long SCAN_PERIOD = 100;
private BleDevicesAdapter leDeviceListAdapter;
private BluetoothAdapter bluetoothAdapter;
private Scanner scanner;
private Save save;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActionBar().setTitle(R.string.title_devices);
// Use this check to determine whether BLE is supported on the device. Then you can
// selectively disable BLE-related features.
if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
// Initializes a Bluetooth adapter. For API level 18 and above, get a reference to
// BluetoothAdapter through BluetoothManager.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();
// Checks if Bluetooth is supported on the device.
if (bluetoothAdapter == null) {
Toast.makeText(this, R.string.error_bluetooth_not_supported, Toast.LENGTH_SHORT).show();
finish();
return;
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.gatt_scan, menu);
if (scanner == null || !scanner.isScanning()) {
menu.findItem(R.id.menu_stop).setVisible(false);
menu.findItem(R.id.menu_scan).setVisible(true);
menu.findItem(R.id.menu_refresh).setActionView(null);
} else {
menu.findItem(R.id.menu_stop).setVisible(true);
menu.findItem(R.id.menu_scan).setVisible(false);
menu.findItem(R.id.menu_refresh).setActionView(
R.layout.actionbar_indeterminate_progress);
}
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.menu_scan:
leDeviceListAdapter.clear();
if (scanner == null) {
scanner = new Scanner(bluetoothAdapter, mLeScanCallback);
scanner.startScanning();
invalidateOptionsMenu();
}
break;
case R.id.menu_stop:
if (scanner != null) {
save = new Save(leDeviceListAdapter);
scanner.stopScanning();
try {
save.savedata();
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
scanner = null;
invalidateOptionsMenu();
}
break;
}
return true;
}
#Override
protected void onResume() {
super.onResume();
// Ensures Bluetooth is enabled on the device. If Bluetooth is not currently enabled,
// fire an intent to display a dialog asking the user to grant permission to enable it.
if (!bluetoothAdapter.isEnabled()) {
final Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
return;
}
init();
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// User chose not to enable Bluetooth.
if (requestCode == REQUEST_ENABLE_BT) {
if (resultCode == Activity.RESULT_CANCELED) {
finish();
} else {
init();
}
}
super.onActivityResult(requestCode, resultCode, data);
}
#Override
protected void onPause() {
super.onPause();
if (scanner != null) {
scanner.stopScanning();
scanner = null;
}
}
#Override
protected void onListItemClick(ListView l, View v, int position, long id) {
final BluetoothDevice device = leDeviceListAdapter.getDevice(position);
if (device == null)
return;
//final Intent intent = new Intent(this, DeviceServicesActivity.class);
//intent.putExtra(DeviceServicesActivity.EXTRAS_DEVICE_NAME, device.getName());
//intent.putExtra(DeviceServicesActivity.EXTRAS_DEVICE_ADDRESS, device.getAddress());
//startActivity(intent);
}
private void init() {
if (leDeviceListAdapter == null) {
leDeviceListAdapter = new BleDevicesAdapter(getBaseContext());
setListAdapter(leDeviceListAdapter);
}
if (scanner == null) {
scanner = new Scanner(bluetoothAdapter, mLeScanCallback);
scanner.startScanning();
}
invalidateOptionsMenu();
}
// Device scan callback.
private BluetoothAdapter.LeScanCallback mLeScanCallback =
new BluetoothAdapter.LeScanCallback() {
#Override
public void onLeScan(final BluetoothDevice device, final int rssi, byte[] scanRecord) {
runOnUiThread(new Runnable() {
#Override
public void run() {
leDeviceListAdapter.addDevice(device, rssi);
leDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
private static class Scanner extends Thread {
private final BluetoothAdapter bluetoothAdapter;
private final BluetoothAdapter.LeScanCallback mLeScanCallback;
private volatile boolean isScanning = false;
Scanner(BluetoothAdapter adapter, BluetoothAdapter.LeScanCallback callback) {
bluetoothAdapter = adapter;
mLeScanCallback = callback;
}
public boolean isScanning() {
return isScanning;
}
public void startScanning() {
synchronized (this) {
isScanning = true;
start();
}
}
public void stopScanning() {
synchronized (this) {
isScanning = false;
bluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
#Override
public void run() {
try {
while (true) {
synchronized (this) {
if (!isScanning)
break;
bluetoothAdapter.startLeScan(mLeScanCallback);
}
sleep(SCAN_PERIOD);
synchronized (this) {
bluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
} catch (InterruptedException ignore) {
} finally {
bluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
}
public class Save {
/**
*
*/
private BleDevicesAdapter leDeviceListAdapter;
Save(BleDevicesAdapter BLEList) {
leDeviceListAdapter = BLEList;
}
public void savedata() throws FileNotFoundException{
String filename = "Dragon.txt";
//String date = (DateFormat.format("dd-MM-yyyy hh:mm:ss", new java.util.Date()).toString());
FileOutputStream fos = null;
int size = leDeviceListAdapter.getCount();
//Bundle extras = getIntent().getExtras();
//long timestamp = extras.getLong("currentTime");
try {
fos= openFileOutput(filename, Context.MODE_PRIVATE);
XmlSerializer serializer = Xml.newSerializer();
serializer.setOutput(fos, "UTF-8");
serializer.startDocument(null, Boolean.valueOf(true));
serializer.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
serializer.startTag("", "root");
//serializer.startTag("", "timestamp");
//serializer.text(date);
//serializer.endTag("", "timestamp");
for(int j = 0 ; j < size ; j++)
{
BluetoothDevice devices = leDeviceListAdapter.getDevice(j);
//Integer signal = leDeviceListAdapter.getRSSI(j);
serializer.startTag("", "name");
serializer.text(devices.getName());
serializer.endTag("", "name");
serializer.startTag("", "address");
serializer.text(devices.getAddress());
serializer.endTag("", "address");
//serializer.startTag(null, "rssi");
//serializer.setProperty(null, signal);
//serializer.endTag(null, "rssi");
}
//ObjectOutputStream out = new ObjectOutputStream(fos);
//out.write((int) timestamp);
//out.writeObject(leDeviceListAdapter);
//out.close();
serializer.endDocument();
serializer.flush();
fos.close();
Toast.makeText(DeviceScanActivity.this, R.string.list_saved, Toast.LENGTH_SHORT).show();
} catch (FileNotFoundException e){
e.printStackTrace();
} catch (IOException e){
e.printStackTrace();
}
}
}
}
In the class Save, I implement the method savedata to save the list into a xml file.
Does anyone know what is the problem? Pleasee help!!!!
openFileOutput puts it in the /data/data/your_packagename/files directory. This directory can only be read by root and by your app- you will not be able to find the file in any other program without rooting your device. You will not be able to find it in a file explorer unless you have root access. If you want to be able to see the file, you need to write it somewhere world accessible, such as the sd card.
I'm trying to send parameters string through putExtra function to the activity from the service, I have this code for my Server.java:
package com.winacro.andRHOME;
import java.util.Calendar;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Context;
import android.content.Intent;
import android.os.Binder;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
public class Server extends Service{
IBinder mBinder = new LocalBinder();
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
public class LocalBinder extends Binder {
public Server getServerInstance() {
return Server.this;
}
}
public void switchSpeaker(int hr, int min){
Toast.makeText(Server.this, hr +" , " +min, Toast.LENGTH_LONG).show();
String sendMessage = "1";
/* Intent myIntent = new Intent(Server.this, andRHOME.class);
myIntent.putExtra("sendMessage","1");
startActivity(myIntent);
PendingIntent pi = PendingIntent.getService(Server.this, 0, myIntent, 0);
AlarmManager almmgr = (AlarmManager) getSystemService(ALARM_SERVICE);
Calendar cldr = Calendar.getInstance();
int min1 = cldr.get(Calendar.MINUTE);
cldr.setTimeInMillis(System.currentTimeMillis());
cldr.add(Calendar.SECOND, 30);
almmgr.set(AlarmManager.RTC_WAKEUP, cldr.getTimeInMillis(), pi);*/
}
}
And This is the code for the Activity of whose sendMessage() method I want to access or pass in string variables too but My app is getting crashed, kindly help here!
package com.winacro.andRHOME;
import android.app.Activity;
import android.app.Application;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Intent;
import android.content.res.Configuration;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.Window;
import android.view.View.OnClickListener;
import android.view.inputmethod.EditorInfo;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
/**
* This is the main Activity that displays the current chat session.
*/
public class andRHOME extends Activity {
// Debugging
private static final String TAG = "andRHOME";
private static final boolean D = true;
// Message types sent from the BluetoothChatService Handler
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_NAME = 4;
public static final int MESSAGE_TOAST = 5;
// Key names received from the BluetoothChatService Handler
public static final String DEVICE_NAME = "device_name";
public static final String TOAST = "toast";
// Intent request codes
private static final int REQUEST_CONNECT_DEVICE_SECURE = 1;
private static final int REQUEST_CONNECT_DEVICE_INSECURE = 2;
private static final int REQUEST_ENABLE_BT = 3;
String inp;
// Layout Views
private TextView mTitle;
//private ListView mConversationView;
//private EditText mOutEditText;
//private Button mSendButton;
private ToggleButton TB1;
private ToggleButton TB2;
private ToggleButton TB3;
private ToggleButton TB4;
// Name of the connected device
private String mConnectedDeviceName = null;
// Array adapter for the conversation thread
private ArrayAdapter<String> mConversationArrayAdapter;
// String buffer for outgoing messages
public StringBuffer mOutStringBuffer;
// Local Bluetooth adapter
private BluetoothAdapter mBluetoothAdapter = null;
// Member object for the chat services
public BluetoothChatService mChatService = null;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(D) Log.e(TAG, "+++ ON CREATE +++");
// Set up the window layout
requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
setContentView(R.layout.main);
getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_title);
// Set up the custom title
mTitle = (TextView) findViewById(R.id.title_left_text);
mTitle.setText(R.string.app_name);
mTitle = (TextView) findViewById(R.id.title_right_text);
// Get local Bluetooth adapter
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
// If the adapter is null, then Bluetooth is not supported
if (mBluetoothAdapter == null) {
Toast.makeText(this, "Bluetooth is not available", Toast.LENGTH_LONG).show();
finish();
return;
}
Bundle bundle = getIntent().getExtras();
inp = bundle.getString("sendMessage");
sendMessage(inp);
}
#Override
public void onStart() {
super.onStart();
if(D) Log.e(TAG, "++ ON START ++");
// If BT is not on, request that it be enabled.
// setupChat() will then be called during onActivityResult
if (!mBluetoothAdapter.isEnabled()) {
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BT);
// Otherwise, setup the chat session
} else {
if (mChatService == null) setupChat();
}
}
#Override
public synchronized void onResume() {
super.onResume();
if(D) Log.e(TAG, "+ ON RESUME +");
// Performing this check in onResume() covers the case in which BT was
// not enabled during onStart(), so we were paused to enable it...
// onResume() will be called when ACTION_REQUEST_ENABLE activity returns.
if (mChatService != null) {
// Only if the state is STATE_NONE, do we know that we haven't started already
if (mChatService.getState() == BluetoothChatService.STATE_NONE) {
// Start the Bluetooth chat services
mChatService.start();
}
}
}
private void setupChat() {
Log.d(TAG, "setupChat()");
// Initialize the array adapter for the conversation thread
mConversationArrayAdapter = new ArrayAdapter<String>(this, R.layout.message);
//mConversationView = (ListView) findViewById(R.id.in);
// mConversationView.setAdapter(mConversationArrayAdapter);
// Initialize the compose field with a listener for the return key
//mOutEditText = (EditText) findViewById(R.id.edit_text_out);
// mOutEditText.setOnEditorActionListener(mWriteListener);
// Initialize the send button with a listener that for click events
//mSendButton = (Button) findViewById(R.id.button_send);
/*mSendButton.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// Send a message using content of the edit text widget
//TextView view = (TextView) findViewById(R.id.edit_text_out);
String message = "0";
sendMessage(message);
}
});*/
TB1 = (ToggleButton) findViewById(R.id.toggleButton1);
TB1.setOnClickListener(new OnClickListener() {
public void onClick(View v){
if (TB1.isChecked()){
String message = "1";
sendMessage(message);
} else if (!TB1.isChecked()){
String message = "6";
sendMessage(message);
}
}
});
TB2 = (ToggleButton) findViewById(R.id.ToggleButton01);
TB2.setOnClickListener(new OnClickListener() {
public void onClick(View v){
if (TB2.isChecked()){
String message = "0";
sendMessage(message);
} else if (!TB2.isChecked()){
String message = "5";
sendMessage(message);
}
}
});
TB3 = (ToggleButton) findViewById(R.id.ToggleButton02);
TB3.setOnClickListener(new OnClickListener() {
public void onClick(View v){
if (TB3.isChecked()){
String message = "2";
sendMessage(message);
} else if (!TB3.isChecked()){
String message = "7";
sendMessage(message);
}
}
});
TB4 = (ToggleButton) findViewById(R.id.ToggleButton03);
TB4.setOnClickListener(new OnClickListener() {
public void onClick(View v){
if (TB4.isChecked()){
String message = "3";
sendMessage(message);
} else if (!TB4.isChecked()){
String message = "8";
sendMessage(message);
}
}
});
// Initialize the BluetoothChatService to perform bluetooth connections
mChatService = new BluetoothChatService(this, mHandler);
// Initialize the buffer for outgoing messages
mOutStringBuffer = new StringBuffer("");
}
#Override
public synchronized void onPause() {
super.onPause();
if(D) Log.e(TAG, "- ON PAUSE -");
}
#Override
public void onStop() {
super.onStop();
if(D) Log.e(TAG, "-- ON STOP --");
}
#Override
public void onDestroy() {
super.onDestroy();
// Stop the Bluetooth chat services
if (mChatService != null) mChatService.stop();
if(D) Log.e(TAG, "--- ON DESTROY ---");
}
private void ensureDiscoverable() {
if(D) Log.d(TAG, "ensure discoverable");
if (mBluetoothAdapter.getScanMode() !=
BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE) {
Intent discoverableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(discoverableIntent);
}
}
/**
* Sends a message.
* #param message A string of text to send.
*/
private void sendMessage(String message) {
// Check that we're actually connected before trying anything
if (mChatService.getState() != BluetoothChatService.STATE_CONNECTED) {
Toast.makeText(this, R.string.not_connected, Toast.LENGTH_SHORT).show();
return;
}
// Check that there's actually something to send
if (message.length() > 0) {
// Get the message bytes and tell the BluetoothChatService to write
byte[] send = message.getBytes();
mChatService.write(send);
// Reset out string buffer to zero and clear the edit text field
mOutStringBuffer.setLength(0);
//mOutEditText.setText(mOutStringBuffer);
}
}
// The action listener for the EditText widget, to listen for the return key
private TextView.OnEditorActionListener mWriteListener =
new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView view, int actionId, KeyEvent event) {
// If the action is a key-up event on the return key, send the message
if (actionId == EditorInfo.IME_NULL && event.getAction() == KeyEvent.ACTION_UP) {
String message = view.getText().toString();
sendMessage(message);
}
if(D) Log.i(TAG, "END onEditorAction");
return true;
}
};
// The Handler that gets information back from the BluetoothChatService
private final Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MESSAGE_STATE_CHANGE:
if(D) Log.i(TAG, "MESSAGE_STATE_CHANGE: " + msg.arg1);
switch (msg.arg1) {
case BluetoothChatService.STATE_CONNECTED:
mTitle.setText(R.string.title_connected_to);
mTitle.append(mConnectedDeviceName);
mConversationArrayAdapter.clear();
break;
case BluetoothChatService.STATE_CONNECTING:
mTitle.setText(R.string.title_connecting);
break;
case BluetoothChatService.STATE_LISTEN:
case BluetoothChatService.STATE_NONE:
mTitle.setText(R.string.title_not_connected);
break;
}
break;
case MESSAGE_WRITE:
byte[] writeBuf = (byte[]) msg.obj;
// construct a string from the buffer
String writeMessage = new String(writeBuf);
mConversationArrayAdapter.add("Me: " + writeMessage);
break;
case MESSAGE_READ:
byte[] readBuf = (byte[]) msg.obj;
// construct a string from the valid bytes in the buffer
String readMessage = new String(readBuf, 0, msg.arg1);
mConversationArrayAdapter.add(mConnectedDeviceName+": " + readMessage);
break;
case MESSAGE_DEVICE_NAME:
// save the connected device's name
mConnectedDeviceName = msg.getData().getString(DEVICE_NAME);
Toast.makeText(getApplicationContext(), "Connected to "
+ mConnectedDeviceName, Toast.LENGTH_SHORT).show();
break;
case MESSAGE_TOAST:
Toast.makeText(getApplicationContext(), msg.getData().getString(TOAST),
Toast.LENGTH_SHORT).show();
break;
}
}
};
public void onActivityResult(int requestCode, int resultCode, Intent data) {
if(D) Log.d(TAG, "onActivityResult " + resultCode);
switch (requestCode) {
case REQUEST_CONNECT_DEVICE_SECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, true);
}
break;
case REQUEST_CONNECT_DEVICE_INSECURE:
// When DeviceListActivity returns with a device to connect
if (resultCode == Activity.RESULT_OK) {
connectDevice(data, false);
}
break;
case REQUEST_ENABLE_BT:
// When the request to enable Bluetooth returns
if (resultCode == Activity.RESULT_OK) {
// Bluetooth is now enabled, so set up a chat session
setupChat();
} else {
// User did not enable Bluetooth or an error occured
Log.d(TAG, "BT not enabled");
Toast.makeText(this, R.string.bt_not_enabled_leaving, Toast.LENGTH_SHORT).show();
finish();
}
}
}
private void connectDevice(Intent data, boolean secure) {
// Get the device MAC address
String address = data.getExtras()
.getString(DeviceListActivity.EXTRA_DEVICE_ADDRESS);
// Get the BLuetoothDevice object
BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
// Attempt to connect to the device
mChatService.connect(device, secure);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.option_menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
Intent serverIntent = null;
switch (item.getItemId()) {
case R.id.scan:
// Launch the DeviceListActivity to see devices and do scan
serverIntent = new Intent(this, DeviceListActivity.class);
startActivityForResult(serverIntent, REQUEST_CONNECT_DEVICE_SECURE);
return true;
case R.id.timer:
// Launch the DeviceListActivity to see devices and do scan
Intent myIntent = new Intent("com.winacro.andRHOME.Timer");
startActivity(myIntent);
return true;
/*case R.id.discoverable:
// Ensure this device is discoverable by others
ensureDiscoverable();
return true;*/
}
return false;
}
}