Android WebView geolocation - java

I know this question has been asked a lot of time but i could not find any help.
I am trying to built an app that loads a website that uses geolocation.
When the app loads, it should open up a google map with my location on it. On a web browser it works fine.
link i am trying to access is https://pas.irsglobal.net/test/
My code is as follows.
//MainActivity.java
package za.co.opexsolutions.www.panicapp;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
/**
* WebViewClient subclass loads all hyperlinks in the existing WebView
*/
public class GeoWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// When user clicks a hyperlink, load in the existing WebView
view.loadUrl(url);
return true;
}
}
/**
* WebChromeClient subclass handles UI-related calls
* Note: think chrome as in decoration, not the Chrome browser
*/
public class GeoWebChromeClient extends WebChromeClient {
#Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
// Always grant permission since the app itself requires location
// permission and the user has therefore already granted it
callback.invoke(origin, true, false);
}
}
WebView wv;
String mypage = "https://pas.irsglobal.net/test/";
String mypage_error = "file:///android_asset/mypage_error/index.html";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
wv = (WebView) findViewById(R.id.wv);
wv.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
wv.setWebViewClient(new GeoWebViewClient());
wv.getSettings().setJavaScriptEnabled(true);
wv.getSettings().setGeolocationEnabled(true);
wv.setWebChromeClient(new GeoWebChromeClient());
wv.setFocusable(true);
wv.setFocusableInTouchMode(true);
wv.getSettings().setRenderPriority(WebSettings.RenderPriority.HIGH);
wv.getSettings().setCacheMode(WebSettings.LOAD_NO_CACHE);
wv.getSettings().setDomStorageEnabled(true);
wv.getSettings().setDatabaseEnabled(true);
wv.getSettings().setAppCacheEnabled(true);
wv.setWebChromeClient(new WebChromeClient() {
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
// callback.invoke(String origin, boolean allow, boolean remember);
callback.invoke(origin, true, false);
}
});
wv.loadUrl(mypage);
wv.setWebViewClient(new WebViewClient(){
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
wv.loadUrl(mypage_error);
}
});
}
}
//Manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.CALL_PHONE"></uses-permission>
<uses-permission android:name="android.permission.LOCATION_HARDWARE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<application
android:allowBackup="true"
android:icon="#mipmap/shipping"
android:label="#string/app_name"
android:roundIcon="#mipmap/shipping"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".HomeActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".MainActivity"></activity>
</application>

OK, After a some time of searching what could be the problem, I hope this will help others too.
The problem in this case it is not my code, but the Android version i was running on the emulator. (I was using Android 7 Nougat).
Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running, not when they install the app.
If the device is running Android 6.0 or higher, and your app's target SDK is 23 or higher: The app has to list the permissions in the manifest, and it must request each permission it needs while the app is running. The user can grant or deny each permission, and the app can continue to run with limited capabilities even if the user denies a permission request.
For full assistance Please Click Here

Related

USB broadcast receiver (ACTION_POWER) not working

I am trying to implement a basic receiver for USB connection. Found a reference here.
I searched a lot, but can't make it to work...
package com.example.usbtethering;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "USB connected.", Toast.LENGTH_SHORT).show();
Log.v("AAAAAAAA", "AAAAAAAAAAAAAAAAAAAAAAAA");
}
}
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.usbtethering">
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/Theme.USBTethering">
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main"
android:theme="#style/Theme.USBTethering.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".MyReceiver">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
</application>
</manifest>
On emulator, I am changing the following setting:
I see the status is changing on the phone bar, but my code is not executed.
Any idea what I am missing?
TL;DR (XY)
My goal is to enable USB tethering automatically when connected to USB, only if hour is between 8:00-22:00. The idea is to block internet usage outside of the specified hours.
On the phone - settings, app-store, browsers, Youtube and hotspot are password locked. So the internet can only be used for Whatsapp, waze, and USB tethering. However this currently requires the "administrator" to manually enable/disable USB tethering in settings each time.
So I intend to create this app which I think should be simple, give it permission to change settings:
Enable tethering on each USB connection between 8:00 and 22:00.
Disable tethering (if enabled) on 22:00.
I have moderate C++/python programming experience, and some Java, but this is my first attempt to Android.
As part of the Android 8.0 (API level 26) Background Execution Limits,
apps that target the API level 26 or higher can no longer register
broadcast receivers for implicit broadcasts in their manifest.
However, several broadcasts are currently exempted from these
limitations. Apps can continue to register listeners for the following
broadcasts, no matter what API level the apps target.
So from the API > 28 Version you must register the reciver for that you can use this piece of code in your Activity or if you want to listen to the Power Connection changes in the background use a Service
IntentFilter ACTION_POWER_CONNECTED = new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED");
IntentFilter ACTION_POWER_DISCONNECTED = new IntentFilter("android.intent.action.ACTION_POWER_DISCONNECTED");
registerReceiver(new MyReceiver(), ACTION_POWER_CONNECTED);
registerReceiver(new MyReceiver(), ACTION_POWER_DISCONNECTED);
I believe you want to use a Service this is an example :
First you need to Create a Service (PowerSerivce) in the manifest file :
<service
android:name=".PowerService"
android:stopWithTask="false" />
<!-- If set to true,
this service with be automatically stopped when the user remove a task rooted in an activity owned by the application-->
And this is the PowerService.java :
import android.app.Service;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.IBinder;
import android.util.Log;
import androidx.annotation.Nullable;
public class PowerService extends Service {
#Nullable
#Override
public IBinder onBind(Intent intent) {
return null;
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter ACTION_POWER_CONNECTED = new IntentFilter("android.intent.action.ACTION_POWER_CONNECTED");
IntentFilter ACTION_POWER_DISCONNECTED = new IntentFilter("android.intent.action.ACTION_POWER_DISCONNECTED");
registerReceiver(new MyReceiver(), ACTION_POWER_CONNECTED);
registerReceiver(new MyReceiver(), ACTION_POWER_DISCONNECTED);
Log.d("Service", "onStartCommand: " );
return Service.START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
Log.e("Service", "onDestroy: " );
}
}
And this is MyReciver :
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.widget.Toast;
public class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.ACTION_POWER_CONNECTED")){
Toast.makeText(context, "CONNECTED", Toast.LENGTH_LONG).show();
}else if(intent.getAction().equals("android.intent.action.ACTION_POWER_DISCONNECTED")){
Toast.makeText(context, "DISCONNECTED", Toast.LENGTH_LONG).show();
}
}
}
And finaly you need to start this Service in my case i started it only for API>=26
normally in APIs below 26 you don't need this Service (you can check it by yourself). in this code I started the PowerService only for version above API 26
// add this code in your first activity or where you want
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
startService(new Intent(this, PowerService.class)):
}
References :
Service
Implicit Broadcast
Exceptions

Android Studio: geolocation not working. Failing to get geolocation in Webview

I'm using a WebView to show different html pages. In these i'm implementing a map from mapbox, but it won't find the users location.
Even if I open up different https pages in the WebView the location will never be found on these sides.
I allowed location permissions and added different user-permissions to the Android Manifest.
These pages locate the location of my devices fine, if i dont open them up from the WebView in my app im working on.
The page i created myself includes a map which works with the api of leaflet.com.
This is some simple Code im trying to make it work with.
import android.support.annotation.NonNull;
import android.support.design.widget.BottomNavigationView;
import android.support.v7.app.AppCompatActivity;
import android.view.MenuItem;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.widget.TextView;
public class MainActivity extends AppCompatActivity {
private TextView mTextMessage;
private BottomNavigationView.OnNavigationItemSelectedListener mOnNavigationItemSelectedListener
= new BottomNavigationView.OnNavigationItemSelectedListener() {
#Override
public boolean onNavigationItemSelected(#NonNull MenuItem item) {
switch (item.getItemId()) {
case R.id.navigation_home:
mTextMessage.setText(R.string.title_home);
return true;
case R.id.navigation_dashboard:
mTextMessage.setText(R.string.title_dashboard);
return true;
case R.id.navigation_notifications:
mTextMessage.setText(R.string.title_notifications);
return true;
}
return false;
}
};
private WebView mWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView myWebView = (WebView) findViewById(R.id.map);
WebSettings webSettings = myWebView.getSettings();
webSettings.setJavaScriptEnabled(true);
webSettings.setDomStorageEnabled(true);
webSettings.setGeolocationEnabled(true);
webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
webSettings.setBuiltInZoomControls(true);
webSettings.setGeolocationEnabled(true);
//myWebView.loadUrl("file:///android_asset/leaflet.html");
myWebView.loadUrl("https://mylocation.org");
mTextMessage = (TextView) findViewById(R.id.message);
BottomNavigationView navigation = (BottomNavigationView) findViewById(R.id.navigation);
navigation.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener);
}
}
And this is the Code of the manifest.xml where i gave different user-permissions
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.hsos.spotit">
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<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>
I hope someone can help me with that, because im spending hours to figure this out. There are nearly no questions in the internet which come close to this or any solution.
Greetings
You need to set up a WebChromeClient method to request the appropriate permissions:
private String geolocationOrigin;
private GeolocationPermissions.Callback geolocationCallback;
WebSettings webSettings = webView.getSettings();
//required for Geolocation
webSettings.setGeolocationEnabled(true);
webView.setWebChromeClient(new MyGeoWebChromeClient());
public class MyGeoWebChromeClient extends WebChromeClient {
#Override
public void onGeolocationPermissionsShowPrompt(String origin, GeolocationPermissions.Callback callback) {
// Geolocation permissions coming from this app's Manifest will only be valid for devices with
// API_VERSION < 23. On API 23 and above, we must check for permissions, and possibly
// ask for them.
String perm = Manifest.permission.ACCESS_FINE_LOCATION;
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M ||
ContextCompat.checkSelfPermission(MainActivity.this, perm) == PackageManager.PERMISSION_GRANTED) {
// we're on SDK < 23 OR user has already granted permission
callback.invoke(origin, true, false);
} else {
if (!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, perm)) {
// ask the user for permission
ActivityCompat.requestPermissions(MainActivity.this, new String[]{perm}, REQUEST_FINE_LOCATION);
// we will use these when user responds
geolocationOrigin = origin;
geolocationCallback = callback;
}
}
}
}
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_FINE_LOCATION:
boolean allow = false;
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// user has allowed this permission
allow = true;
}
if (geolocationCallback != null) {
// call back to web chrome client
geolocationCallback.invoke(geolocationOrigin, allow, false);
}
break;
}
}

Am I missing something to get google maps to open from android webview

Iam new to the android programming environment and am creating my first app. I am trying to get webview to open google maps when a google maps link is clicked within webview. Am I missing something as to why this is still opening the link in webview and not executing google maps instead? And when it is opening in webview it shows the destination fine but it does not show my location and states it is unable to determine my location on the bottom of the page being displayed
Here is the MainActivity
package com.example.micha.myapplication;
import android.content.Intent;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.webkit.CookieManager;
import android.webkit.DownloadListener;
import android.webkit.GeolocationPermissions;
import android.webkit.WebChromeClient;
import android.webkit.WebSettings;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class MainActivity extends AppCompatActivity {
/**
* WebViewClient subclass loads all hyperlinks in the existing WebView
*/
public class GeoWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// When user clicks a hyperlink, load in the existing WebView
view.loadUrl(url);
return true;
}
}
/**
* WebChromeClient subclass handles UI-related calls
* Note: think chrome as in decoration, not the Chrome browser
*/
public class GeoWebChromeClient extends WebChromeClient {
#Override
public void onGeolocationPermissionsShowPrompt(String origin,
GeolocationPermissions.Callback callback) {
// Always grant permission since the app itself requires location
// permission and the user has therefore already granted it
callback.invoke(origin, true, false);
}
}
private WebView myWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myWebView = findViewById(R.id.webView);
WebView myWebView = findViewById(R.id.webView);
WebSettings webSettings = myWebView.getSettings();
myWebView.setWebViewClient(new GeoWebViewClient());
webSettings.setJavaScriptEnabled(true);
myWebView.getSettings().setGeolocationEnabled(true);
CookieManager.getInstance().setAcceptCookie(true);
//webSettings.setDomStorageEnabled(true);
myWebView.clearHistory();
myWebView.clearFormData();
myWebView.clearCache(true);
myWebView.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if( url.startsWith("http:") || url.startsWith("https:") ) {
return false;
}
if(url.contains("https://www.google.com/maps/"))
{
Uri gmmIntentUri = Uri.parse(url);
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
if (mapIntent.resolveActivity(getPackageManager()) != null) {
startActivity(mapIntent);
}
return true;
}
// Otherwise allow the OS to handle things like tel, mailto, etc.
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity( intent );
return true;
}
});
myWebView.loadUrl("http://www.example.com");
//THIS IS TO DOWNLOAD THE PDF FILES OR OTHER DOWNLOAD LINKS
myWebView.setDownloadListener(new DownloadListener() {
#Override
public void onDownloadStart(String url, String userAgent,
String contentDisposition, String mimetype,
long contentLength) {
startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
}
});
}
#Override
public void onBackPressed() {
if (myWebView.canGoBack()) {
myWebView.goBack();
return;
}
super.onBackPressed();
}
}
Here is the AndroidManifest.XML
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.micha.myapplication">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACTION_DIAL"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_DOWNLOAD_MANAGER"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_GPS" />
<uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
<uses-permission android:name="android.permission.ACCESS_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_principal"
android:label="Admin Tools"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.NoActionBar">
<activity android:name=".MainActivity"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Found the problem.
if( url.startsWith("http:") || url.startsWith("https:") ) {
was preventing google maps from opening as it was forcing any url with https to stay within the webview. modified it to
if( url.startsWith("http:")) {
and all is good now.

Function Isolating Camera's LED Light and java.lang.NullPointerException: Attempt to invoke virtual method 'void android.hardware.Camera$Parameters

I am struggling to control the LED light next to my camera in the app I am trying to make for my own education purposes. I have tried to follow the methods in http://www.mkyong.com/android/how-to-turn-onoff-camera-ledflashlight-in-android/ , but I am trying to make the function more abstract and more general in order to increase reusable functionality and make the code more readable.
Upon creating my activity we first check, using PackageManager, that a LED camera does in fact exist. I then open the camera. The onClick function runs the functions changeScreen() and toggleLight(). Here you can see the clear advantages of using abstraction, ie toggleLight() works as a black box, using code set out elsewhere. The changeScreen function I know is correct, well before adding toggleLight() it was working correctly.
As the code should be correct, as it was taken from the example, I believe I have a problem with variable scope.
1) Where does the boolean isLighOn need to be declared, in the function or in the activity?
2) Same problem with the camera variable
How else should I go about creating an abstract function toggleLight()? I have checked around on this website, but a lot of posts send you to the link provided above. Moreover I believe an answer to this question would help many users and would provide reusable code.
Here is my code so far and I have posted the error I am getting below again.
package com.mycompany.myapplication;
import android.app.*;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.drawable.ColorDrawable;
import android.hardware.Camera;
import android.os.*;
import android.util.Log;
import android.view.*;
import android.widget.*;
public class MainActivity extends Activity {
public RelativeLayout container;
private boolean isLighOn = false;
private Camera camera;
#Override
protected void onStop() {
super.onStop();
if (camera != null) {
camera.release();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Context context = this;
PackageManager pm = context.getPackageManager();
// if device support camera?
if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
Log.e("err", "Device has no camera!");
return;
}
camera = Camera.open();
container = (RelativeLayout) findViewById(R.id.MainActivity);
container.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
changeScreen(v);
toggleLight();
}
});
}
public void changeScreen(View v) {
ColorDrawable cd = (ColorDrawable) this.container.getBackground();
TextView ON = (TextView) findViewById(R.id.ON);
TextView OFF = (TextView) findViewById(R.id.OFF);
if (cd != null && cd.getColor() == getResources().getColor(R.color.BLACK)) {
container.setBackgroundColor(getResources().getColor(R.color.WHITE));
OFF.setVisibility(View.INVISIBLE);
ON.setVisibility(View.VISIBLE);
} else {
container.setBackgroundColor(getResources().getColor(R.color.BLACK));
OFF.setVisibility(View.VISIBLE);
ON.setVisibility(View.INVISIBLE);
}
}
public void toggleLight(){
final Camera.Parameters p = camera.getParameters();
if (isLighOn) {
Log.i("info", "torch is turn off!");
p.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);
camera.setParameters(p);
camera.stopPreview();
isLighOn = false;
} else {
Log.i("info", "torch is turn on!");
p.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
camera.setParameters(p);
camera.startPreview();
isLighOn = true;
}
}
}
When I load the app on my Android Studio emulator, I get the screen "ON". However, when you click the screen the app crashes. This is only error message I can find in the IDE. I am not sure how to interpret this error message.
In response to a comment below I am now posting the code containing the permissions.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.mycompany.myapplication">
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Don't rely on an emulator to produce reliable camera behavior. Always verify camera-related code on real device!

getGSMSignalStrength() Always Returns 99

I know there is another question on here relating to this, but I don't think it applies to me, as I'm pretty sure I use GSM (isGSM() returns true). In any case, getCdmaDbm returns -1 for me anyway. I am using Android 4.1.1 and an HTC One X. Here is my code (most of which isn't mine):
MainActivity:
package com.example.receptionlookup;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.telephony.PhoneStateListener;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.view.Menu;
import android.widget.Toast;
public class MainActivity extends Activity {
TelephonyManager Tel;
MyPhoneStateListener MyListener;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
/* Update the listener, and start it */
MyListener = new MyPhoneStateListener();
Tel = ( TelephonyManager )getSystemService(Context.TELEPHONY_SERVICE);
Tel.listen(MyListener ,PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.activity_main, menu);
return true;
}
/* Called when the application is minimized */
#Override
protected void onPause()
{
super.onPause();
Tel.listen(MyListener, PhoneStateListener.LISTEN_NONE);
}
/* Called when the application resumes */
#Override
protected void onResume()
{
super.onResume();
Tel.listen(MyListener,PhoneStateListener.LISTEN_SIGNAL_STRENGTHS);
}
/* —————————– */
/* Start the PhoneState listener */
/* —————————– */
private class MyPhoneStateListener extends PhoneStateListener
{
/* Get the Signal strength from the provider, each tiome there is an update */
#Override
public void onSignalStrengthsChanged(SignalStrength signalStrength)
{
super.onSignalStrengthsChanged(signalStrength);
Toast.makeText(getApplicationContext(), "Go to Firstdroid!!! GSM Cinr = "
+ String.valueOf(signalStrength.getGsmSignalStrength()), Toast.LENGTH_SHORT).show();
}
};/* End of private Class */
}
AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.receptionlookup"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="com.example.receptionlookup.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>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
</manifest>
Does anyone know what the problem is? If I go to Settings->About->Network, I can see the signal strength there. Isn't there some way to just read this value? I've tried several third party apps, and none of them are able to read my signal strength either. I've also tried the proprietary getGSMSignalBar() method, but I get a NoSuchMethodException.
As you can read in the 3GPP 127 007 8.5 the implementation of the at+csq is optional (the command which suppose to give the signal strength). Apparently HTC hide this value from 3rd party applications and they probably have another way to achieve that value for display in their own proprietary Settings application.
The fact that other applications also cannot get that information justifies my case.
This issue is tightly related to yours - thay said that HTC is one of the OEMs that does not worth the modem related developing time.
Try this:
Class signalStrengthClass = signalStrength.getClass();
try {
Method method = signalStrengthClass.getMethod(
"getGsmSignalBar", null);
method.setAccessible(true);
Integer bars = (Integer) method.invoke(signalStrength,
(Object[]) null);
}
} catch (Exception e) {
e.printStackTrace();
}

Categories