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
Related
I've been working on a project which uses wowza media engine to live stream on a website when video is taken through an android phone. But I'm unable to find the surfaceview as findviewbyId returns null.
imports
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.Window;
import android.view.WindowManager;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import android.support.v7.appcompat.R;
import edu.purdue.shishir.libs.Session;
import edu.purdue.shishir.libs.SessionBuilder;
import edu.purdue.shishir.libs.audio.AudioQuality;
import edu.purdue.shishir.libs.gl.SurfaceView;
import edu.purdue.shishir.libs.rtsp.RtspClient;
MainActivity.java
public class MainActivity extends AppCompatActivity implements RtspClient.Callback,
Session.Callback, SurfaceHolder.Callback {
// log tag
public final static String TAG = MainActivity.class.getSimpleName();
// surfaceview
private static SurfaceView mSurfaceView;
// Rtsp session
private Session mSession;
private static RtspClient mClient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
// getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
requestWindowFeature(Window.FEATURE_NO_TITLE);
mSurfaceView = (SurfaceView) findViewById(R.id.surface);
mSurfaceView.getHolder().addCallback(this);
// Initialize RTSP client
initRtspClient();
}
#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);
}
private void toggleStreaming() {
if (!mClient.isStreaming()) {
// Start camera preview
mSession.startPreview();
// Start video stream
mClient.startStream();
} else {
// already streaming, stop streaming
// stop camera preview
mSession.stopPreview();
// stop streaming
mClient.stopStream();
}
}
private void initRtspClient() {
// Configures the SessionBuilder
mSession = SessionBuilder.getInstance()
.setContext(getApplicationContext())
.setAudioEncoder(SessionBuilder.AUDIO_NONE)
.setAudioQuality(new AudioQuality(8000, 16000))
.setVideoEncoder(SessionBuilder.VIDEO_H264)
.setSurfaceView(mSurfaceView).setPreviewOrientation(0)
.setCallback(this).build();
// Configures the RTSP client
mClient = new RtspClient();
mClient.setSession(mSession);
mClient.setCallback(this);
mSurfaceView.setAspectRatioMode(SurfaceView.ASPECT_RATIO_PREVIEW);
String ip, port, path;
// We parse the URI written in the Editext
Pattern uri = Pattern.compile("rtsp://(.+):(\\d+)/(.+)");
Matcher m = uri.matcher(AppConfig.STREAM_URL);
m.find();
ip = m.group(1);
port = m.group(2);
path = m.group(3);
mClient.setCredentials(AppConfig.PUBLISHER_USERNAME,
AppConfig.PUBLISHER_PASSWORD);
mClient.setServerAddress(ip, Integer.parseInt(port));
mClient.setStreamPath("/" + path);
}
private void alertError(final String msg) {
final String error = (msg == null) ? "Unknown error: " : msg;
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setMessage(error).setPositiveButton("Ok",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
}
});
AlertDialog dialog = builder.create();
dialog.show();
}
#Override
protected void onResume() {
super.onResume();
toggleStreaming();
}
#Override
protected void onPause(){
super.onPause();
toggleStreaming();
}
#Override
public void onDestroy() {
super.onDestroy();
mClient.release();
mSession.release();
mSurfaceView.getHolder().removeCallback(this);
}
#Override
public void onSessionError(int reason, int streamType, Exception e) {
switch (reason) {
case Session.ERROR_CAMERA_ALREADY_IN_USE:
break;
case Session.ERROR_CAMERA_HAS_NO_FLASH:
break;
case Session.ERROR_INVALID_SURFACE:
break;
case Session.ERROR_STORAGE_NOT_READY:
break;
case Session.ERROR_CONFIGURATION_NOT_SUPPORTED:
break;
case Session.ERROR_OTHER:
break;
}
if (e != null) {
alertError(e.getMessage());
e.printStackTrace();
}
}
#Override
public void onRtspUpdate(int message, Exception exception) {
switch (message) {
case RtspClient.ERROR_CONNECTION_FAILED:
case RtspClient.ERROR_WRONG_CREDENTIALS:
alertError(exception.getMessage());
exception.printStackTrace();
break;
}
}
#Override
public void surfaceCreated(SurfaceHolder holder) {
}
#Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
#Override
public void surfaceDestroyed(SurfaceHolder holder) {
}
#Override
public void onBitrareUpdate(long bitrate) {
}
#Override
public void onPreviewStarted() {
}
#Override
public void onSessionConfigured() {
}
#Override
public void onSessionStarted() {
}
#Override
public void onSessionStopped() {
}
}
But R.id.surface cannot be resolved.
Activity_main.xml
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/surface_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_alignParentLeft="true"
android:layout_alignParentTop="true"
android:background="#android:color/black"
tools:ignore="RtlHardcoded">
<edu.purdue.shishir.libs.gl.SurfaceView
android:id="#+id/surface"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center" />
</FrameLayout>
you forgot to load the Activity_main.xml layout in the onCreate.
Please, add following code in onCreate
setContentView(R.layout.activity_main);
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 am following this tutorial: https://www.sinch.com/tutorials/android-messaging-tutorial-using-sinch-and-parse
Github for tutorial: https://github.com/sinch/android-messaging-tutorial
The issue I have is that the service does not seem to start at all. I have gone over the code and cannot spot anything that looks wrong (but then again i'm a beginner lol).
I am not receiving any broadcast back in the MenuFragment3 class and due to that the progressDialog just keeps spinning. I have also checked to see if a service is running on both a number of emulators and a real device, like I said it seems as though the service never starts and I really cannot see why.
If you need anything more let me know and thanks for any help!
Firstly I start the service when a user logs in here:
serviceIntent = new Intent(getApplicationContext(), MessageService.class);
startService(serviceIntent);
Heres the manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.yupo.dominic.yupo" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name=".UserAuth"
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=".Login"
android:label="#string/title_login_area">
</activity>
<activity
android:name=".StudentLogged"
android:label="#string/title_student_area">
</activity>
<activity
android:name=".Register"
android:label="#string/register">
</activity>
<activity
android:name=".LectureLogged"
android:label="#string/title_lecture_area">
</activity>
<service android:name=".MessageService">
</service>
</application>
</manifest>
Heres the MessageService class:
package com.yupo.dominic.yupo;
import android.app.Service;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import com.parse.Parse;
import com.parse.ParseUser;
import com.sinch.android.rtc.ClientRegistration;
import com.sinch.android.rtc.Sinch;
import com.sinch.android.rtc.SinchClient;
import com.sinch.android.rtc.SinchClientListener;
import com.sinch.android.rtc.SinchError;
import com.sinch.android.rtc.messaging.MessageClient;
import com.sinch.android.rtc.messaging.MessageClientListener;
import com.sinch.android.rtc.messaging.WritableMessage;
public class MessageService extends Service implements SinchClientListener {
private static final String APP_KEY = "mykeyiscorrect";
private static final String APP_SECRET = "mysecretiscorrect";
private static final String ENVIRONMENT = "sandbox.sinch.com";
private final MessageServiceInterface serviceInterface = new MessageServiceInterface();
private SinchClient sinchClient = null;
private MessageClient messageClient = null;
private String currentUserId;
private LocalBroadcastManager broadcaster;
private Intent broadcastIntent = new Intent("com.yupo.dominic.yupo.StudentLogged");
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Parse.initialize(this, "thisiscorrect", "thisiscorrect");
currentUserId = ParseUser.getCurrentUser().getObjectId();
if (currentUserId != null && !isSinchClientStarted()) {
startSinchClient(currentUserId);
}
broadcaster = LocalBroadcastManager.getInstance(this);
return super.onStartCommand(intent, flags, startId);
}
public void startSinchClient(String username) {
sinchClient = Sinch.getSinchClientBuilder().context(this).userId(username).applicationKey(APP_KEY)
.applicationSecret(APP_SECRET).environmentHost(ENVIRONMENT).build();
sinchClient.addSinchClientListener(this);
sinchClient.setSupportMessaging(true);
sinchClient.setSupportActiveConnectionInBackground(true);
sinchClient.checkManifest();
sinchClient.start();
}
private boolean isSinchClientStarted() {
return sinchClient != null && sinchClient.isStarted();
}
#Override
public void onClientFailed(SinchClient client, SinchError error) {
broadcastIntent.putExtra("success", false);
broadcaster.sendBroadcast(broadcastIntent);
sinchClient = null;
}
#Override
public void onClientStarted(SinchClient client) {
broadcastIntent.putExtra("success", true);
broadcaster.sendBroadcast(broadcastIntent);
client.startListeningOnActiveConnection();
messageClient = client.getMessageClient();
}
#Override
public void onClientStopped(SinchClient client) {
sinchClient = null;
}
#Override
public IBinder onBind(Intent intent) {
return serviceInterface;
}
#Override
public void onLogMessage(int level, String area, String message) {
}
#Override
public void onRegistrationCredentialsRequired(SinchClient client, ClientRegistration clientRegistration) {
}
public void sendMessage(String recipientUserId, String textBody) {
if (messageClient != null) {
WritableMessage message = new WritableMessage(recipientUserId, textBody);
messageClient.send(message);
}
}
public void addMessageClientListener(MessageClientListener listener) {
if (messageClient != null) {
messageClient.addMessageClientListener(listener);
}
}
public void removeMessageClientListener(MessageClientListener listener) {
if (messageClient != null) {
messageClient.removeMessageClientListener(listener);
}
}
#Override
public void onDestroy() {
sinchClient.stopListeningOnActiveConnection();
sinchClient.terminate();
}
public class MessageServiceInterface extends Binder {
public void sendMessage(String recipientUserId, String textBody) {
MessageService.this.sendMessage(recipientUserId, textBody);
}
public void addMessageClientListener(MessageClientListener listener) {
MessageService.this.addMessageClientListener(listener);
}
public void removeMessageClientListener(MessageClientListener listener) {
MessageService.this.removeMessageClientListener(listener);
}
public boolean isSinchClientStarted() {
return MessageService.this.isSinchClientStarted();
}
}
}
Here my version of the ListUsersActivity from the tutorial (For me it is called MenuFragment3 which is part of a sliding menu which is called from the StudentLogged or LectureLogged activities)
package com.yupo.dominic.yupo;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.support.v4.app.Fragment;
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.content.LocalBroadcastManager;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;
import com.parse.FindCallback;
import com.parse.ParseQuery;
import com.parse.ParseUser;
import java.util.ArrayList;
import java.util.List;
public class MenuFragment3 extends Fragment{
View rootview;
ArrayList<String> names;
ParseUser currentUser;
String currentUserId;
ListView usersListView;
ArrayAdapter<String> namesArrayAdapter;
ProgressDialog progressDialog;
BroadcastReceiver receiver;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
currentUser = ParseUser.getCurrentUser();
if(currentUser.getString("type").equalsIgnoreCase("Lecturer"))
{
rootview = inflater.inflate(R.layout.menu3_2_layout, container, false);
}
else
{
rootview = inflater.inflate(R.layout.menu3_layout, container, false);
}
progressDialog = new ProgressDialog(getActivity());
progressDialog.setTitle("Loading");
progressDialog.setMessage("Please wait...");
progressDialog.show();
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getActivity(), "broadcast received", Toast.LENGTH_SHORT).show();
Boolean success = intent.getBooleanExtra("success", false);
progressDialog.dismiss();
//show a toast message if the Sinch
//service failed to start
if (!success) {
Toast.makeText(getActivity(), "Messaging service failed to start", Toast.LENGTH_LONG).show();
}
}
};
LocalBroadcastManager.getInstance(getActivity()).registerReceiver(receiver, new IntentFilter("com.yupo.dominic.yupo.StudentLogged"));
currentUserId = ParseUser.getCurrentUser().getObjectId();
names = new ArrayList<String>();
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereNotEqualTo("objectId", currentUserId);
query.findInBackground(new FindCallback<ParseUser>() {
public void done(List<ParseUser> userList, com.parse.ParseException e) {
if (e == null) {
for (int i=0; i<userList.size(); i++) {
names.add(userList.get(i).getUsername().toString());
}
usersListView = (ListView)rootview.findViewById(R.id.usersListView);
namesArrayAdapter =
new ArrayAdapter<String>(getActivity(),
R.layout.user_list_item, names);
usersListView.setAdapter(namesArrayAdapter);
usersListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
#Override
public void onItemClick(AdapterView<?> a, View v, int i, long l) {
openConversation(names, i);
}
});
} else {
Toast.makeText(getActivity(),
"Error loading user list",
Toast.LENGTH_LONG).show();
}
}
});
return rootview;
}
public void openConversation(ArrayList<String> names, int pos) {
ParseQuery<ParseUser> query = ParseUser.getQuery();
query.whereEqualTo("username", names.get(pos));
query.findInBackground(new FindCallback<ParseUser>() {
public void done(List<ParseUser> user, com.parse.ParseException e) {
if (e == null) {
//Intent intent = new Intent(getActivity(), MessagingActivity.class);
//intent.putExtra("RECIPIENT_ID", user.get(0).getObjectId());
//startActivity(intent);
Toast.makeText(getActivity(),
"working",
Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(getActivity(),
"Error finding that user",
Toast.LENGTH_SHORT).show();
}
}
});
}
}
You're trying to initialize Parse using your Sinch key and secret. In addition, you should initialize Parse in your application's onCreate method. Try:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
currentUserId = ParseUser.getCurrentUser().getObjectId();
if (currentUserId != null && !isSinchClientStarted()) {
startSinchClient(currentUserId);
}
broadcaster = LocalBroadcastManager.getInstance(this);
return super.onStartCommand(intent, flags, startId);
}
Before making this as duplicate:: I see a lot of threads supporting this, but none of them works in waking up or turning the screen on when the screen is completely turned off (or in sleep mode).
My aim: when the USB is connected or the device is plugged in to AC power the screen has to turn off (that is happening), and when the power/ USB is unplugged the screen has to turn on back to the app. (not working).
Note: If the screen is dimmed out to the lowest instead of turning it off we can turn the brightness on back when required, but that is not what I want.
The links that is suppoting this questions are:
1. wake-android-device-up
2. is-there-a-way-to-force-an-android-device-to-stay-awake
3. android-how-to-turn-screen-on-and-off-programmatically
4. turning-on-screen-programmatically
5. how-to-unlock-the-screen-when-broadcastreceiver-is-called
Here is the code that I am using It successfully turns the screen OFF, but will not Turn it on. You can also download the code project from : Download Here
Class Name: MainActivity
package com.power.screenmode;
import android.app.Activity;
import android.app.KeyguardManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Bundle;
import android.os.PowerManager;
import android.os.PowerManager.WakeLock;
import android.util.Log;
import android.view.WindowManager;
import android.widget.TextView;
import com.power.screenmode.BackgroundService.PowerUtil;
public class MainActivity extends Activity {
private TextView txt_PowerConnected;
private boolean isChargerConnected = false;
private Context mContext;
private WindowManager.LayoutParams params ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
firstLoad();
initViews();
doTask();
startService();
}
#Override
protected void onResume() {
// powerMethod();
super.onResume();
}
private void firstLoad(){
mContext = MainActivity.this;
}
private void initViews(){
setContentView(R.layout.activity_main);
txt_PowerConnected = (TextView)findViewById(R.id.txt_PowerConnected);
}
private void doTask(){
isChargerConnected = PowerUtil.isConnected(mContext);
params = getWindow().getAttributes();
if(isChargerConnected){
txt_PowerConnected.setText("Charger Connected");
turnScreenOFF();
System.out.println("Power Connected - doTask");
}else{
txt_PowerConnected.setText("Charger Not Connected");
turnScreenON();
System.out.println("Power Disconnected - doTask");
}
}
private void startService(){
try {
Intent service = new Intent(this, BackgroundService.class);
startService(service);
Log.i("SCREEN_MODE", "background service calling");
} catch (Exception e) {
e.printStackTrace();
}
// register the receiver to listen to battery change
this.registerReceiver(this.receiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
private void turnScreenOFF(){
params = getWindow().getAttributes();
/** Turn OFF: */
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 0.0f; // 0.1f to turn the brightness to lowest
getWindow().setAttributes(params);
}
private void turnScreenON(){
params = getWindow().getAttributes();
/** Turn ON: */
params.flags = WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON;
params.screenBrightness = 1.0f;
getWindow().setAttributes(params);
// I have tried the below method also but it didn't work\\\
// powerMethod();
}
private void powerMethod(){
KeyguardManager km = (KeyguardManager) mContext.getSystemService(Context.KEYGUARD_SERVICE);
final KeyguardManager.KeyguardLock kl = km.newKeyguardLock("MyKeyguardLock");
kl.disableKeyguard();
PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
WakeLock wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyWakeLock");
wakeLock.acquire();
if(wakeLock.isHeld()){
wakeLock.release();
}
}
BroadcastReceiver receiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
if (plugged == BatteryManager.BATTERY_PLUGGED_AC ||plugged == BatteryManager.BATTERY_PLUGGED_USB ){
System.out.println("Charger connected -- receiver");
turnScreenOFF();
} else{
System.out.println("Charger Disconnected -- receiver");
turnScreenON();
}
}
};
}
The Background service class:
/**
*
*/
package com.power.screenmode;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.TimeUnit;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.BatteryManager;
import android.os.Handler;
import android.os.IBinder;
import android.util.Log;
import android.view.WindowManager;
/**
* #author Prasildas
*
*/
public class BackgroundService extends Service {
public static final int INITDELAY_TASK = 0;
public static final int INTERVAL_TASK1 = 1;
private ScheduledExecutorService scheduler;
public static ScheduledFuture<?> schedule_Background;
private Handler tableUpdateHandler;
WindowManager.LayoutParams params ;
#Override
public void onCreate() {
super.onCreate();
Log.i("SCREEN_MODE", "Started");
tableUpdateHandler = new Handler();
scheduler = Executors.newScheduledThreadPool(2);
schedule_Background = scheduler.scheduleAtFixedRate(task_CheckScreenMode, INITDELAY_TASK, INTERVAL_TASK1, TimeUnit.SECONDS);
Log.i("SCREEN_MODE", "Created background service --> Live Mode");
}
/**
* To stop the background check
*/
public void stopBackgroundTask() {
if (schedule_Background != null) {
schedule_Background.cancel(true);
}
}
/** The background task in the service -- Shaking the cart with the badge numbers updating
*/
private Runnable task_CheckScreenMode = new Runnable() {
#Override
public void run() {
tableUpdateHandler.post(new Runnable() {
#Override
public void run() {
try {
PowerUtil.isConnected(getApplicationContext());
Log.i("SCREEN_MODE", "background running powerutil");
}
catch (Exception e) {
e.printStackTrace();
}
}
});
}
};
public static class PowerUtil {
public static boolean isConnected(Context context) {
Intent intent = context.registerReceiver(null, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
int plugged = intent.getIntExtra(BatteryManager.EXTRA_PLUGGED, -1);
return plugged == BatteryManager.BATTERY_PLUGGED_AC || plugged == BatteryManager.BATTERY_PLUGGED_USB;
}
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(final Intent intent) {
return null;
}
#Override
public void onDestroy() {
Log.i("SCREEN_MODE", "background service task 1 destroyed");
super.onDestroy();
}
}
The Manifest File:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.power.screenmode"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="18" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.BATTERY_STATS" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.power.screenmode.MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name="com.power.screenmode.BackgroundService" >
</service>
</application>
</manifest>
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