I've set up the http://bingmapsandroidsdk.codeplex.com/ to try bing maps instead of google maps on Android. Because I was unable to set that up.
I'm able to run Bing maps on my emulator but I'm unable to run it on my device(Galaxy S2).
I have a wifi connection on my phone but I'm still unable to get past the load screen.
I also checked this question but it doesn't solve the problem Working on Emulator but not on the real Android device
So my code:
Manifest
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.ACCESS_GPS"></uses-permission>
<uses-sdk android:minSdkVersion="5" android:targetSdkVersion="15"/>
<application android:icon="#drawable/bingmaps_icon" android:label="#string/app_name" android:allowBackup="false">
<activity android:name=".MainActivity"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="SplashActivity"></activity>
</application>
Starting Activity copied from the Bing-sdk
package org.bingmaps.app;
import java.util.HashMap;
import org.bingmaps.app.R;
import org.bingmaps.sdk.BingMapsView;
import org.bingmaps.sdk.Coordinate;
import org.bingmaps.sdk.EntityClickedListener;
import org.bingmaps.sdk.EntityLayer;
import org.bingmaps.sdk.MapLoadedListener;
import org.bingmaps.sdk.MapMovedListener;
import org.bingmaps.sdk.MapStyles;
import org.bingmaps.sdk.Pushpin;
import org.bingmaps.sdk.PushpinOptions;
import android.app.Activity;
import android.app.ProgressDialog;
import android.location.Location;
import android.location.LocationListener;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ViewFlipper;
import android.widget.ZoomButton;
public class MainActivity extends Activity {
private BingMapsView bingMapsView;
private GPSManager _GPSManager;
private EntityLayer _gpsLayer;
private ProgressDialog _loadingScreen;
private Activity _baseActivity;
CharSequence[] _dataLayers;
boolean[] _dataLayerSelections;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
//OPTION Lock map orientation
setRequestedOrientation(1);
setContentView(R.layout.main);
Initialize();
}
private void Initialize()
{
_baseActivity = this;
_GPSManager = new GPSManager((Activity)this, new GPSLocationListener());
//Add more data layers here
_dataLayers = new String[] { getString(R.string.traffic)};
_dataLayerSelections = new boolean[ _dataLayers.length ];
_loadingScreen = new ProgressDialog(this);
_loadingScreen.setCancelable(false);
_loadingScreen.setMessage(this.getString(R.string.loading) + "...");
bingMapsView = (BingMapsView) findViewById(R.id.mapView);
//Create handler to switch out of Splash screen mode
final Handler viewHandler = new Handler() {
public void handleMessage(Message msg) {
((ViewFlipper) findViewById(R.id.flipper)).setDisplayedChild(1);
}
};
//Add a map loaded event handler
bingMapsView.setMapLoadedListener(new MapLoadedListener() {
public void onAvailableChecked() {
// hide splash screen and go to map
viewHandler.sendEmptyMessage(0);
//Add GPS layer
_gpsLayer = new EntityLayer(Constants.DataLayers.GPS);
bingMapsView.getLayerManager().addLayer(_gpsLayer);
UpdateGPSPin();
}
});
//Add a entity clicked event handler
bingMapsView.setEntityClickedListener(new EntityClickedListener() {
public void onAvailableChecked(String layerName, int entityId) {
HashMap<String, Object> metadata = bingMapsView.getLayerManager().GetMetadataByID(layerName, entityId);
DialogLauncher.LaunchEntityDetailsDialog(_baseActivity, metadata);
}
});
//Load the map
bingMapsView.loadMap(Constants.BingMapsKey, _GPSManager.GetCoordinate(), Constants.DefaultGPSZoomLevel, this.getString(R.string.mapCulture));
// Create zoom out button functionality
final ZoomButton zoomOutBtn = (ZoomButton) findViewById(R.id.zoomOutBtn);
zoomOutBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
bingMapsView.zoomOut();
}
});
// Create zoom button in functionality
final ZoomButton zoomInBtn = (ZoomButton) findViewById(R.id.zoomInBtn);
zoomInBtn.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
bingMapsView.zoomIn();
}
});
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.layout.menu, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle item selection
switch (item.getItemId()) {
//Map Mode menu items
case R.id.autoBtn:
bingMapsView.setMapStyle(MapStyles.Auto);
item.setChecked(!item.isChecked());
return true;
case R.id.roadBtn:
bingMapsView.setMapStyle(MapStyles.Road);
item.setChecked(!item.isChecked());
return true;
case R.id.aerialBtn:
bingMapsView.setMapStyle(MapStyles.Aerial);
item.setChecked(!item.isChecked());
return true;
case R.id.birdseyeBtn:
bingMapsView.setMapStyle(MapStyles.Birdseye);
item.setChecked(!item.isChecked());
return true;
//More option items
case R.id.aboutMenuBtn:
DialogLauncher.LaunchAboutDialog(this);
return true;
case R.id.layersMenuBtn:
DialogLauncher.LaunchLayersDialog(this, bingMapsView, _dataLayers, _dataLayerSelections);
return true;
case R.id.clearMapMenuBtn:
bingMapsView.getLayerManager().clearLayer(null);
//unselect all layers
for(int i=0;i<_dataLayerSelections.length;i++){
_dataLayerSelections[i] = false;
}
//re-add GPS layer
bingMapsView.getLayerManager().clearLayer(Constants.DataLayers.GPS);
UpdateGPSPin();
return true;
//GPS Menu Item
case R.id.gpsMenuBtn:
Coordinate coord = _GPSManager.GetCoordinate();
if(coord != null){
//Center on users GPS location
bingMapsView.setCenterAndZoom(coord, Constants.DefaultGPSZoomLevel);
}
return true;
//Search Menu Item
case R.id.searchMenuBtn:
DialogLauncher.LaunchSearchDialog(this, bingMapsView, loadingScreenHandler);
return true;
//Directions Menu Item
case R.id.directionsMenuBtn:
DialogLauncher.LaunchDirectionsDialog(this, bingMapsView, loadingScreenHandler);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private void UpdateGPSPin(){
PushpinOptions opt = new PushpinOptions();
opt.Icon = Constants.PushpinIcons.GPS;
Pushpin p = new Pushpin(_GPSManager.GetCoordinate(), opt);
if (p.Location != null) {
_gpsLayer.clear();
_gpsLayer.add(p);
_gpsLayer.updateLayer();
}
}
#SuppressWarnings("unused")
private final MapMovedListener mapMovedListener = new MapMovedListener() {
public void onAvailableChecked() {
//OPTION Add logic to Update Layers here.
//This will update data layers when the map is moved.
}
};
/**
* Handler for loading Screen
*/
protected Handler loadingScreenHandler = new Handler() {
public void handleMessage(Message msg) {
if (msg.arg1 == 0) {
_loadingScreen.hide();
} else {
_loadingScreen.show();
}
}
};
public class GPSLocationListener implements LocationListener {
public void onLocationChanged(Location arg0) {
UpdateGPSPin();
}
public void onProviderDisabled(String arg0) {
}
public void onProviderEnabled(String arg0) {
}
public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
}
}
}
ERRORS from LOGCAT: non
bing maps for android does not work for android versions 3.0 and higher
Related
UPDATE: I have edited my question to include the working code. I have solved my issue. See my latest/last post.
UPDATE2: Code has been updated as of 2018-06-08. Here is the repo:
https://github.com/amboxer21/FlashLightApp
NOTE: I compile from the Linux command line with ant.
I have a torch app I am trying to get working but I am having no luck. Can any one point out what I am missing and explain? I would really appreciate it!
I can compile with no issues. I can push with no issues. I can toggle the on and off button with no issues. I can see this with the toasts I have put in place. Basically all functions seem to get called properly but the LED light on the back camera just does not come on. I am using a Nexus 6 on 5.1.1 and developing on Linux. Also I figure its worth mentioning here but I am able to compile a 3rd party torch app on my Linux box and the torch woks.
Main Activity:
package com.flash.light;
import android.util.Log;
import android.os.Bundle;
import android.os.IBinder;
import android.os.Message;
import android.os.Handler;
import android.os.Messenger;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceView;
import android.view.MenuInflater;
import android.view.SurfaceHolder;
import android.view.View.OnClickListener;
import android.widget.Toast;
import android.widget.Button;
import android.widget.ToggleButton;
import android.hardware.Camera;
import android.hardware.Camera.Parameters;
import android.app.Activity;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningServiceInfo;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.Intent;
import android.content.Context;
import android.content.ComponentName;
import android.content.ServiceConnection;
import android.support.v7.app.ActionBar;
import android.support.v7.widget.Toolbar;
import android.support.v7.view.ActionMode;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatDelegate;
import android.support.v7.app.AppCompatCallback;
public class FlashLight extends Activity implements SurfaceHolder.Callback, AppCompatCallback {
private static final String TAG = "FlashLight FlashLight";
private Camera mCam;
private Parameters params;
private ToggleButton flashLight;
private SurfaceView surfaceView;
private Messenger mService = null;
private SurfaceHolder surfaceHolder;
private boolean mBound;
private boolean hasCameraFlash;
private boolean isBound = false;
private boolean isFlashOn = false;
private static long backPressedTime = 0;
private static Message mtn;
private static Message msg;
private static AppCompatDelegate delegate;
private static ComponentName componentName;
private static PackageManager packageManager;
public void isServiceBound() {
isBound = getApplicationContext().bindService(new Intent(getApplicationContext(),
FlashLightService.class), mConnection, Context.BIND_AUTO_CREATE );
if(isBound) {
getApplicationContext().unbindService(mConnection);
}
}
public void toast(String text) {
Toast.makeText(getApplicationContext(), text, Toast.LENGTH_LONG).show();
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceDisconnected(ComponentName name) {
mService = null;
mBound = false;
}
#Override
public void onServiceConnected(ComponentName name, IBinder service) {
mService = new Messenger(service);
mBound = true;
}
};
#Override
public void onBackPressed() {
long mTime = System.currentTimeMillis();
if(mTime - backPressedTime > 2000) {
backPressedTime = mTime;
Toast.makeText(this, "Press back again to close app.", Toast.LENGTH_SHORT).show();
}
else {
finish();
super.onBackPressed();
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu items for use in the action bar
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu, menu);
return super.onCreateOptionsMenu(menu);
}
private AppCompatDelegate getDelegate() {
if (delegate == null) {
delegate = AppCompatDelegate.create(this, this);
}
return delegate;
}
public boolean supportRequestWindowFeature(int featureId) {
return getDelegate().requestWindowFeature(featureId);
}
public void invalidateOptionsMenu() {
getDelegate().invalidateOptionsMenu();
}
#Override
public void onSupportActionModeStarted(ActionMode mode) { }
#Override
public void onSupportActionModeFinished(ActionMode mode) { }
public ActionMode startSupportActionMode(ActionMode.Callback callback) {
return getDelegate().startSupportActionMode(callback);
}
#Nullable
#Override
public ActionMode onWindowStartingSupportActionMode(ActionMode.Callback callback) {
return null;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
return true;
case R.id.configureMenu:
Intent configureIntent = new Intent(getApplicationContext(), Configure.class);
startActivityForResult(configureIntent, 0);
default:
return super.onOptionsItemSelected(item);
}
}
#Override
public void onDestroy() {
super.onDestroy();
try {
isServiceBound();
if(mCam != null) {
mCam.stopPreview();
mCam.release();
}
}
catch(Exception e) {
e.printStackTrace();
}
}
#Override
protected void onSaveInstanceState(Bundle savedInstanceState) {
savedInstanceState.putBoolean("isFlashOn", isFlashOn);
super.onSaveInstanceState(savedInstanceState);
}
#Override
public void onRestoreInstanceState(Bundle savedInstanceState) {
super.onRestoreInstanceState(savedInstanceState);
isFlashOn = savedInstanceState.getBoolean("isFlashOn");
}
private boolean isMyServiceRunning(Class<?> serviceClass) {
ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
for (RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
if(!isMyServiceRunning(FlashLightService.class)) {
Intent serviceIntent = new Intent(getApplicationContext(), FlashLightService.class);
startService(serviceIntent);
getApplicationContext().bindService(new Intent(getApplicationContext(), FlashLightService.class), mConnection,
Context.BIND_AUTO_CREATE);
}
delegate = AppCompatDelegate.create(this, this);
delegate.onCreate(savedInstanceState);
delegate.setContentView(R.layout.main);
Toolbar toolbar = (Toolbar) findViewById(R.id.action_toolbar);
delegate.setSupportActionBar(toolbar);
delegate.getSupportActionBar().setDisplayShowTitleEnabled(true);
if(savedInstanceState != null) {
isFlashOn = savedInstanceState.getBoolean("isFlashOn");
}
surfaceView = (SurfaceView)findViewById(R.id.preview);
surfaceHolder = surfaceView.getHolder();
surfaceHolder.addCallback(FlashLight.this);
surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
hasCameraFlash = getApplicationContext().getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
if(!(hasCameraFlash)) {
toast("Camera does not have flash feature.");
return;
}
else {
getCamera();
}
flashLight = (ToggleButton)findViewById(R.id.flashLight);
flashLight.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
try {
if(!(isFlashOn)) {
params = mCam.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_TORCH);
mCam.setParameters(params);
mCam.startPreview();
isFlashOn = true;
}
else {
params = mCam.getParameters();
params.setFlashMode(Parameters.FLASH_MODE_OFF);
mCam.setParameters(params);
mCam.stopPreview();
isFlashOn = false;
}
}
catch(Exception e) {
e.printStackTrace();
}
}
});
}
public void getCamera() throws NullPointerException {
try {
if(mCam == null) {
mCam = Camera.open();
}
}
catch(NullPointerException e) {
e.printStackTrace();
}
}
public void surfaceCreated(SurfaceHolder holder) {
try {
mCam.setPreviewDisplay(holder);
}
catch(Exception e) {
e.printStackTrace();
}
}
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { }
public void surfaceDestroyed(SurfaceHolder holder) { }
}
main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:background="#E8E8E8"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<android.support.v7.widget.Toolbar
android:background="#3F51B5"
android:id="#+id/action_toolbar"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:label="#string/app_name">
</android.support.v7.widget.Toolbar>
<SurfaceView
android:id="#+id/preview"
android:layout_width="1dp"
android:layout_height="1dp"/>
<ToggleButton
android:textOn=""
android:textOff=""
android:id="#+id/flashLight"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginBottom="100dp"
android:background="#drawable/check"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"/>
</RelativeLayout>
Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.flash.light"
android:versionCode="1"
android:versionName="1.0">
<!-- PERMISSIONS -->
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.FLASHLIGHT"/>
<!-- FEATURES -->
<uses-feature android:name="android.hardware.camera"/>
<uses-feature android:name="android.hardware.touchscreen"/>
<uses-feature android:name="android.hardware.camera.flash"/>
<uses-feature android:name="android.hardware.camera.autofocus"/>
<!-- TARGET SDK VERSION -->
<uses-sdk android:minSdkVersion="21"/>
<application android:label="#string/app_name"
android:icon="#drawable/ic_launcher">
<activity android:name="FlashLight"
android:screenOrientation="portrait"
android:theme="#style/Theme.AppCompat.NoActionBar"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<service android:name=".FlashLightService" android:enabled="true"/>
</application>
</manifest>
Turns out I needed a surfaceHolder and surfaceView in order to call the startPreview method.
Here is my working torch app via github -> https://github.com/amboxer21/FlashLightApp
I am trying to access the notifications on my android phone using the AccessibilityService.
I tried making a service and calling it from the main activity. I've also added meta for the service. It's not working. I cannot see the triggering of the service.
I'm using Android L for testing. In accessibility settings I've added my app 'Notify' as on.
Thanks in advance.
My main Activity
package com.example.tony.notify;
import android.content.Intent;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// startActivityForResult(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS), 0);
Intent i = new Intent(this, MyAccessibilityService.class);
startService(i);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
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);
}
}
This is my service class
package com.example.tony.notify;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.util.Log;
import android.view.accessibility.AccessibilityEvent;
import android.widget.Toast;
/**
* Created by tony on 9/7/15.
*/
public class MyAccessibilityService extends AccessibilityService {
final String TAG = "Notification service";
private String getEventType(AccessibilityEvent event) {
switch (event.getEventType()) {
case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:
return "TYPE_NOTIFICATION_STATE_CHANGED";
case AccessibilityEvent.TYPE_VIEW_CLICKED:
return "TYPE_VIEW_CLICKED";
case AccessibilityEvent.TYPE_VIEW_FOCUSED:
return "TYPE_VIEW_FOCUSED";
case AccessibilityEvent.TYPE_VIEW_LONG_CLICKED:
return "TYPE_VIEW_LONG_CLICKED";
case AccessibilityEvent.TYPE_VIEW_SELECTED:
return "TYPE_VIEW_SELECTED";
case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:
return "TYPE_WINDOW_STATE_CHANGED";
case AccessibilityEvent.TYPE_VIEW_TEXT_CHANGED:
return "TYPE_VIEW_TEXT_CHANGED";
}
return "default";
}
private String getEventText(AccessibilityEvent event) {
StringBuilder sb = new StringBuilder();
for (CharSequence s : event.getText()) {
sb.append(s);
}
return sb.toString();
}
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
Log.v(TAG, String.format(
"onAccessibilityEvent: [type] %s [class] %s [package] %s [time] %s [text] %s",
getEventType(event), event.getClassName(), event.getPackageName(),
event.getEventTime(), getEventText(event)));
}
#Override
public void onInterrupt() {
Log.v(TAG, "onInterrupt");
}
#Override
protected void onServiceConnected() {
Toast.makeText(getApplicationContext(),"connected",Toast.LENGTH_SHORT).show();
super.onServiceConnected();
Log.v(TAG, "onServiceConnected");
AccessibilityServiceInfo info = new AccessibilityServiceInfo();
info.flags = AccessibilityServiceInfo.DEFAULT;
info.eventTypes = AccessibilityEvent.TYPES_ALL_MASK;
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
setServiceInfo(info);
}
}
My manifest for declaring service
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tony.notify" >
<uses-permission android:name="android.permission.BIND_ACCESSIBILITY_SERVICE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<service android:name=".MyAccessibilityService"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/accessibilityservice" />
</service>
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Please help. Thanks in advance. I've tried looking into some examples. I couldn't find errors.
I got it working on L though, it's not really working on api 16, I tested on one. Can anyone suggest an addition to make it work on api 14+
Manifest File
package com.example.tony.acctest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.tony.acctest.MyAccessibilityService.Constants;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MA LOG";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final IntentFilter mIntentFilter = new IntentFilter(Constants.ACTION_CATCH_NOTIFICATION);
registerReceiver(NotificationCatcherReceiver, mIntentFilter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
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);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(NotificationCatcherReceiver);
}
private final BroadcastReceiver NotificationCatcherReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, intent.getStringExtra(Constants.EXTRA_PACKAGE));
Log.v(TAG, intent.getStringExtra(Constants.EXTRA_MESSAGE));
}
};
}
My service class
package com.example.tony.acctest;
import android.accessibilityservice.AccessibilityService;
import android.accessibilityservice.AccessibilityServiceInfo;
import android.annotation.TargetApi;
import android.app.Notification;
import android.content.Intent;
import android.os.Build;
import android.os.Parcelable;
import android.view.accessibility.AccessibilityEvent;
import java.util.List;
public class MyAccessibilityService extends AccessibilityService {
private final AccessibilityServiceInfo info = new AccessibilityServiceInfo();
#TargetApi(Build.VERSION_CODES.ICE_CREAM_SANDWICH)
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
final int eventType = event.getEventType();
if (eventType == AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED) {
final String sourcePackageName = (String)event.getPackageName();
Parcelable parcelable = event.getParcelableData();
if (parcelable instanceof Notification) {
List<CharSequence> messages = event.getText();
if (messages.size() > 0) {
try {
final String notificationMsg = (String) messages.get(0);
Intent mIntent = new Intent(Constants.ACTION_CATCH_NOTIFICATION);
mIntent.putExtra(Constants.EXTRA_PACKAGE, sourcePackageName);
mIntent.putExtra(Constants.EXTRA_MESSAGE, notificationMsg);
MyAccessibilityService.this.getApplicationContext().sendBroadcast(mIntent);
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
#Override
public void onInterrupt() {
}
#Override
public void onServiceConnected() {
info.eventTypes = AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_ALL_MASK;
} else {
info.feedbackType = AccessibilityServiceInfo.FEEDBACK_GENERIC;
}
info.notificationTimeout = 100;
this.setServiceInfo(info);
}
public static final class Constants {
public static final String EXTRA_MESSAGE = "extra_message";
public static final String EXTRA_PACKAGE = "extra_package";
public static final String ACTION_CATCH_NOTIFICATION = "com.example.tony.acctest.CATCH_NOTIFICATION";
}
}
This is my Main activity
package com.example.tony.acctest;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;
import com.example.tony.acctest.MyAccessibilityService.Constants;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MA LOG";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final IntentFilter mIntentFilter = new IntentFilter(Constants.ACTION_CATCH_NOTIFICATION);
registerReceiver(NotificationCatcherReceiver, mIntentFilter);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
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);
}
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(NotificationCatcherReceiver);
}
private final BroadcastReceiver NotificationCatcherReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.v(TAG, intent.getStringExtra(Constants.EXTRA_PACKAGE));
Log.v(TAG, intent.getStringExtra(Constants.EXTRA_MESSAGE));
}
};
}
I had done this when my widget got enabled:
#Override
public void onEnabled(Context context) {
super.onEnabled(context);
String enabledListeners = Settings.Secure.getString(
context.getContentResolver(), "enabled_notification_listeners");
if (!enabledListeners.contains("Myalert")) {
Intent i = new Intent(
"android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS");
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
}
And in my manifest:
<service
android:name="com.edgealert.NotificationMonitor"
android:label="MyAlert"
android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE" >
<intent-filter>
<action android:name="android.service.notification.NotificationListenerService" >
</action>
</intent-filter>
</service>
<receiver android:name=".MyReceiver" >
<intent-filter>
<action android:name="com.samsung.android.cocktail.action.COCKTAIL_UPDATE" />
</intent-filter>
<meta-data
android:name="com.samsung.android.cocktail.provider"
android:resource="#xml/single_cocktail" />
</receiver>
I develop an bluetooth app which will connect to a paired device and send a message, but I have to test connection before. I've tried many options, but nothing works in good way. So could you send me any example of code which can do it? I made an thread, but I can't get an good state of connection to build an "if" function. Here is the code:
package com.example.szukacz;
import java.lang.reflect.Method;
import java.util.Set;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
public class MainActivity extends Activity {
LinearLayout sparowaneUrzadzenia;
public void lokalizowanie() {
Intent intencja = new Intent(this, Lokalizator.class);
startActivity(intencja);
}
public void parowanie(View v) {
Intent intencja = new Intent(this, Parowanie.class);
startActivity(intencja);
}
boolean isRunning;
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
String status = (String)msg.obj;
if(status == "polaczony") {
alarm();
showToast("prawda, zwraca" + status);
} else {
showToast("wykonanie x, zwraca: " + status);
};
}
};
public void alarm() {
showToast("Alarm!!!");
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
sparowaneUrzadzenia = (LinearLayout) findViewById(R.id.listaUrzadzenGlowna);
pokazSparowane();
}
public void onStop() {
super.onStop();
isRunning = false;
}
public void onStart() {
super.onStart();
Thread testPolaczen = new Thread(new Runnable() {
public void run() {
try {
for(int i = 0; i < 1000000; i++) {
Thread.sleep(5000);
testujPolaczenia();
int stan = 0;
String status = Integer.toString(stan);
Message msg = handler.obtainMessage(1, (String)status);
if(isRunning == true) {
handler.sendMessage(msg);
}
}
} catch (Throwable t) {
// watek stop
}
}
});
isRunning = true;
testPolaczen.start();
}
private void testujPolaczenia() {
}
public void pokazSparowane(){
/*
* Wyświetlanie listy sparowanych urządzeń .
* */
Log.d("INFO","Sparowane dla tego urzÄ…dzenia");
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
for (BluetoothDevice device : pairedDevices) {
Log.d("INFO",device.getName()+" - "+device.getAddress());
// dodawanie urzadzen do listy
Button urzadzenie = new Button(getApplicationContext());
urzadzenie.setText(device.getName());
// urzadzenie.setTextColor(0xffffff); //jak ustawic na czarny kolor napsisów ?
urzadzenie.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v)
{
showToast("klik");
lokalizowanie();
}
});
sparowaneUrzadzenia.addView(urzadzenie);
}
} else {
showToast("brak sparowanych urzadzen");
}
}
#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;
}
private void showToast(String message) {
Toast.makeText(getApplicationContext(), message, Toast.LENGTH_SHORT).show();
}
#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);
}
}
thanks!
I faced the same problem as I am working on an app which may use TTS while it is running. I think there is no way to check if there is any bluetooth device connected by the BluetoothAdapter class immediately except creating a broadcast receiver and monitor the changes of status of bluetooth.
After scratching my head for a few hours, I found a quite subtle way to solve this problem. I tried, it works pretty well for me.
AudioManager audioManager = (AudioManager) getApplicationContext.getSystemService(Context.AUDIO_SERVICE);
if (audioManager.isBluetoothA2dpOn()) {
//audio is currently being routed to bluetooth -> bluetooth is connected
}
Source: http://developer.android.com/training/managing-audio/audio-output.html
I think it's to late for answer to your question but I think can helps somebody :
If you use Thread you have to create a BroadcastReceiver in your main activity on create :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_digital_metrix_connexion);
BroadcastReceiver bState = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED))
{
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
BluetoothAdapter.ERROR);
switch (state)
{
case BluetoothAdapter.ACTION_ACL_CONNECTED:
{
//Do something you need here
System.out.println("Connected");
break;
}
default:
System.out.println("Default");
break;
}
}
}
};
}
BluetoothAdapter.STATE_CONNECTED is one state over many, for exemple it's possible to check if device connecting or disconnecting thanks to BluetoothAdapter.ACTION_ACL_DISCONNECTED or BluetoothAdapter.ACTION_ACL_DISCONNECTED_REQUEST .
After, you have to create a filter in your thread class or in you main activity if you don't use thread :
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
This filter check the bluetoothadapter state.
And now you have to register your filter so if you use thread pass context in parameter of your thread like this context.registerReceiver(bState,filter);
or in your main Activity : registerReceiver(bState,filter);
If you have any question don't hesitate to ask me.
Hope I helps you somebody.
I am trying to make a loop in Android app which is triggered by a button click.
After reading tips on making loops/delays on SO ( for example here), I decided to use message handler approach instead of Runnable.
In the code below, toastLoop() is executed and it prints "starting in x" seconds.
However, the message does not seem to be posted with that delay.
Or, the message is posted but the handler does not receive it.
I am a newbie and I am probably making a silly mistake somewhere.
What am I missing in the code below? Or is this code totally stupid?
package com.example.testapp;
import android.annotation.TargetApi;
import android.content.Context;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.support.v4.app.FragmentActivity;
import android.support.v4.app.NavUtils;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
public class ExecActivity extends FragmentActivity {
static Context context = null;
String LOG_TAG = "FTR";
static boolean test_status = false;
ToastLoop toast_loop;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_exec);
// Show the Up button in the action bar.
setupActionBar();
}
/**
* Set up the {#link android.app.ActionBar}, if the API is available.
*/
#TargetApi(Build.VERSION_CODES.HONEYCOMB)
private void setupActionBar() {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
getActionBar().setDisplayHomeAsUpEnabled(true);
}
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.exec, menu);
return true;
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
// This ID represents the Home or Up button. In the case of this
// activity, the Up button is shown. Use NavUtils to allow users
// to navigate up one level in the application structure. For
// more details, see the Navigation pattern on Android Design:
//
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
//
NavUtils.navigateUpFromSameTask(this);
return true;
}
return super.onOptionsItemSelected(item);
}
class ToastLoop {
private final int loop_max_duration = 60; // in seconds
final int TOAST = 1;
Handler handler = new Handler() {
#Override
public void handleMessage(Message msg) {
Log.i(LOG_TAG, "Handler(): msg: " + msg.what);
switch (msg.what) {
case TOAST:
Toast.makeText( ExecActivity.this, "Doing my thing", Toast.LENGTH_SHORT).show();
if ( test_status) { // test is still running
toastLoop();
}
break;
default:
Toast.makeText(ExecActivity.this, "Unhandled", Toast.LENGTH_SHORT).show();
break;
}
}
};
public boolean toastLoop() {
if ( test_status) { // test is still running
long curr_time_milli = System.currentTimeMillis();
long window_position_sec = (long)( ((long)(curr_time_milli/1000))/loop_max_duration); // fraction discarded
long loop_start_time_sec = (window_position_sec + 1 ) * loop_max_duration;
long actual_start_time_milli = loop_start_time_sec * 1000;
Log.i(LOG_TAG, "toastLoop(): starting in " + ((actual_start_time_milli - curr_time_milli)/1000) );
Message msg = handler.obtainMessage( TOAST);
handler.sendMessageAtTime( msg, actual_start_time_milli );
return true;
}
return false;
}
}
public boolean beginTest( View view) {
Log.i(LOG_TAG, "in beginTest()");
test_status = true;
toast_loop = new ToastLoop();
toast_loop.toastLoop();
return true;
}
public boolean endTest( View view) {
Log.i(LOG_TAG, "in endTest()");
test_status = false;
return true;
}
}
Hi i am new to android..
i have the following code..
package squash.trainer;
import android.app.Activity;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
public class SquashTrainerActivity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Button btn_start = (Button) findViewById(R.id.btn_start);
//btn_start.setOnClickListener(new View.OnClickListener() {
// public void onClick(View v) {
// setContentView(R.layout.selecttopmenu);
// }});
}
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater. inflate(R.menu.mainmenu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
switch (item. getItemId() ) {
case R. id.btn1:
BugsSequence();
return true;
case R. id.btn2:
return true;
case R. id.btn3:
return true;
case R. id.btn4:
return true;
default:
return super. onOptionsItemSelected(item) ;
}
}
private void BugsSequence() {
// TODO Auto-generated method stub
}
}
for each case i want to use the a class to load the new layout and logic...
currently i have a test class called Bugssequence
package squash.trainer;
import android.os.Bundle;
import android.app.Activity;
//import android.view.View;
//import android.widget.Button;
public class BugsSequence extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
//super.onCreate(savedInstanceState);
setContentView(R.layout.selecttopmenu);
}
/**
* #param args
*/
public static void main(String[] args) {
//
}
}
How can i get it load the new layout.. when i press on button 1.. it does nothing..
or is there a better way to load 4 different layouts /class(logic) one for each of the menus. Should i even be creating new activities for each screen / layout ?
Thanks you for your assistance...
Complete guide can be found here: http://developer.android.com/guide/topics/fundamentals/activities.html
At first, your activity should be declared in the manifest
<activity android:name=".YourActivity"
android:label="#string/youractivitylabel">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
and then you can start YourActivity from code:
Intent intent = new Intent(this, YourActivity.class);
startActivity(intent);
You can put easily some extra data into the intent and/or start it for a result
startActivityForResult(intent, PICK_CONTACT_REQUEST);
Read the link above, it's very useful!