I'm working on a project that needs to distinguish a device type at startup, so whether it's a phone, tablet or foldable. I can distinguish between phone and tablet but is there a way to detect whether an android device is a foldable?
Check the link --> https://developer.android.com/
It seems that these is no particular API or configuration for detecting fordable device.
Some of my own idea is to check the screen resolution size? As that would differ somehow from other phones !
is simple:
I use this code im my apps, I share it with you
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
TelephonyManager manager = (TelephonyManager)getApplicationContext().getSystemService(Context.TELEPHONY_SERVICE);
if (Objects.requireNonNull(manager).getPhoneType() == TelephonyManager.PHONE_TYPE_NONE) {
Toast.makeText(MainActivity.this, "Detected... You're using a Tablet", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(MainActivity.this, "Detected... You're using a Mobile Phone", Toast.LENGTH_SHORT).show();
}
}
}
Related
I'm working on an NFC based app developed in Xamarin for Android.
The app has a 'Connect' button and the NFC scanning process starts only when that button
is tapped.
With proper intents configured, whenever an NFC tag is detected, HandleNewIntent() method gets called and NFC read procedure is followed.
internal void HandleNewIntent(Intent intent)
{
try
{
if (intent.Action == NfcAdapter.ActionTagDiscovered || intent.Action == NfcAdapter.ActionNdefDiscovered)
{
_currentTag = intent.GetParcelableExtra(NfcAdapter.ExtraTag) as Tag;
if (_currentTag != null)
{
Task.Run(() => { ReadDataFromTag(_currentTag); });
}
}
}
catch (Exception ex)
{
//Display error
}
}
In normal cases this works fine. However, if the phone is kept in contact with the NFC tag and then the 'Connect' button is tapped on, then the TagDiscovered intent never gets fired. User has to take the phone away, bring it back in contact with the NFC tag and then only the event gets fired.
I observed the same behaviour with generic NFC apps on play store, and on 2 different Android phones.
Looks like Android keeps the NFC of phone tied up when in contact with NFC tag because of which the intents are not detected. Is there anything to be done to release such links (if any) before initiating new NFC connection?
All NFC is handled by the System NFC service and System App and is normally triggered by a Tag coming in to range and then an Intent being delivered to the right app immediately, therefore the system NFC service has already delivered the Intent to another App before you App has had the button pressed.
You don't show all the code that you do to setup your Apps' NFC configuration but as you are talking about Intents you are probably using the old and unreliable enableForegroundDispatch API which has a number of issues.
While it is more normal to enable foreground NFC detection as soon as you App is resumed and then process the Tag on immediate detection, it is possible to store the Tag object until a button is pressed.
I suggest that you use the better and newer enableReaderMode API that has less of a problem because it is a more direct interface to the NFC hardware and thus you use case seems to work using the code below.
public class MainActivity extends AppCompatActivity implements NfcAdapter.ReaderCallback{
private NfcAdapter mNfcAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void Button(View view) {
Log.v("TAG", "DetailedScoresActivity:onTagDiscovered:Start");
mNfcAdapter = NfcAdapter.getDefaultAdapter(this);
if(mNfcAdapter!= null) {
Bundle options = new Bundle();
options.putInt(NfcAdapter.EXTRA_READER_PRESENCE_CHECK_DELAY, 250);
mNfcAdapter.enableReaderMode(this,
this,
NfcAdapter.FLAG_READER_NFC_A |
NfcAdapter.FLAG_READER_NFC_B |
NfcAdapter.FLAG_READER_NFC_F |
NfcAdapter.FLAG_READER_NFC_V |
NfcAdapter.FLAG_READER_NFC_BARCODE |
NfcAdapter.FLAG_READER_SKIP_NDEF_CHECK |
NfcAdapter.FLAG_READER_NO_PLATFORM_SOUNDS,
options);
}
}
public void onTagDiscovered(Tag tag) {
Log.v("TAG", "onTagDiscovered:Start");
}
#Override
protected void onPause() {
super.onPause();
if(mNfcAdapter!= null)
mNfcAdapter.disableReaderMode(this);
}
}
For me you can place a Tag against the phone and then start the App and as soon as the Button is clicked and `enableReaderMode` is enabled then `onTagDiscovered` is triggered with the Tag object.
I am using flutter and have disabled normal apps from recording the screen.
Here is the code
getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,
WindowManager.LayoutParams.FLAG_SECURE);
The problem is there are some phones where screen recordings apps are pre-installed and above code can't stop them from recording the screen.
So is there any other way to stop these apps from recording the screen?
On other answers I saw that this was not possible but there are some apps on playstore which successfully achieve this. So there must be a way.
I was thinking, as screen recording apps are drawn over , they might be detected through a piece of code hence we can show a pop up while screen recording app is drawn over.
Is it possible ? If yes how can we detect if the app is drawn over our app.
Thanks.
As far as I'm aware, there is no official way to universally prevent screen grabs/recordings.
This is because FLAG_SECURE just prevents capturing on non-secure displays:
Window flag: treat the content of the window as secure, preventing it from appearing in screenshots or from being viewed on non-secure displays.
But apps that have elevated permissions can create a secure virtual display and use screen mirroring to record your screen, which does not respect the secure flag.
Read this article for more info:
That would mean that an Android device casting to a DRM-protected display like a TV would always display sensitive screens, since the concept of secure really means “copyrighted”. For apps, Google forestalled this issue by preventing apps not signed by the system key from creating virtual “secure” displays
Regarding how some apps still manage to do it, you could try these:
Check if there are any external/virtual displays connected, and hide/show your content based on that. see this
Don't show your content on rooted devices
Adding this code to my MainActivity.java solved the problem:
protected void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (!this.setSecureSurfaceView()) {
Log.e("MainActivity", "Could not secure the MainActivity!");
}
}
private final boolean setSecureSurfaceView() {
ViewGroup content = (ViewGroup) this.findViewById(android.R.id.content);
//Intrinsics.checkExpressionValueIsNotNull(content, "content");
if (!this.isNonEmptyContainer((View) content)) {
return false;
} else {
View splashView = content.getChildAt(0);
//Intrinsics.checkExpressionValueIsNotNull(splashView, "splashView");
if (!this.isNonEmptyContainer(splashView)) {
return false;
} else {
View flutterView = ((ViewGroup) splashView).getChildAt(0);
//Intrinsics.checkExpressionValueIsNotNull(flutterView, "flutterView");
if (!this.isNonEmptyContainer(flutterView)) {
return false;
} else {
View surfaceView = ((ViewGroup) flutterView).getChildAt(0);
if (!(surfaceView instanceof SurfaceView)) {
return false;
} else {
((SurfaceView) surfaceView).setSecure(true);
this.getWindow().setFlags(8192, 8192);
return true;
}
}
}
}
}
private final boolean isNonEmptyContainer(View view) {
if (!(view instanceof ViewGroup)) {
return false;
} else {
return ((ViewGroup) view).getChildCount() >= 1;
}
}
Import the required things.
I am developing an app for an Android custom build.
This app needs to subscribe to AudioDeviceCallback in Android's AudioManager.
I'm using:
mAudioManager.registerAudioDeviceCallback(new MyDeviceCallback(), null);
where:
private class MyDeviceCallback extends AudioDeviceCallback {
#Override
public void onAudioDevicesAdded(AudioDeviceInfo[] addedDevices) {
Log.d(LOG_TAG, "onAudioDevicesAdded(): New devices detected");
updateAuxStatus();
}
#Override
public void onAudioDevicesRemoved(AudioDeviceInfo[] devices) {
Log.d(LOG_TAG, "onAudioDevicesAdded(): devices removed");
updateAuxStatus();
}
private void updateAuxStatus() {
AudioDeviceInfo[] devices = mAudioManager.getDevices(AudioManager.GET_DEVICES_INPUTS);
boolean isPluggedIn = false;
for (AudioDeviceInfo device : devices) {
if (device.getType() == AudioDeviceInfo.TYPE_LINE_ANALOG) {
isPluggedIn = true;
}
}
onAuxPluggedInChanged(isPluggedIn);
}
}
This works fine when I run the app with normal user (u0_aXX) but when I run the app as system sharedUser (adding to the Manifest):
android:sharedUserId="android.uid.system"
This callback is being called only after subscribing, but never again. Even when other apps without system user are getting the call normally.
I've traced the call to the AudioManager code and found that postEventFromNative in the AudioPortEventHandler is never being called for my app when it is running as system sharedUser. Since that is a jni call I stopped because I don't fully understand how it works.
What really troubles me is that when running without system sharedUser the same code is working as intended. Is there some restriction to system sharedUser that might be causing this problem?
In the AudioPolicy, registerClient use uid as the key. When the phone booted, system_server or telecom already register notification, if your app run as system user, it will never working.
mNotificationClients.add(uid, notificationClient);
i want to set the system preference (by code) for just using 2g networks instead of using 3g. so far i haven't found anything that could have helped me. i suppose i need to set it via the ConnectionManager? can anyone point me in the right direction here?
Unfortunately, you can't do this. The best you can do is take the user to the relevant settings screen (Mobile Network Settings), where they can choose for themselves. There's no API to actually change the setting.
Some ROMs (e.g. CyanogenMod) build this into the system, and there may be options if you are rooted/installed as a system app, but if you want something standard/mass applicable then I'm afraid you're out of luck.
use the following code
public class CheckNetworkType extends Activity
{
private static final String tag = "CheckNetworkType";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE);
if(tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_EDGE )
{
// Network type is 2G
Log.v(tag, "2G or GSM");
}
else
if(tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_CDMA)
{
// Network type is 2G
Log.v(tag, "2G or CDMA");
}
else
if(tm.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS)
{
// Network type is 3G
Log.v(tag, "3G Network available.");
}
}
}
I have people complaining my application gets FC when they launch it (meanwhile others never had a single problem). Here is my full activity source. Since it happens on devices I don't own I can not fix it. From what they tell me it doesn't work on: Motorola Blackflip, Motorola Dext, Motorola CLIQ XT. Guess Motorola doesn't like my app after all...
Could it be that I allow a minSdkVersion="3"? I tested 1.5 on the emulator and worked fine...
Thank you in advance for your responses.
public class workit extends Activity implements OnClickListener {
Button yay;
Button yay0;
Button yay1;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.main);
yay = (Button) findViewById(R.id.gostart);
yay.setOnClickListener(this);
yay0 = (Button) findViewById(R.id.dontstart);
yay0.setOnClickListener(this);
yay1 = (Button) findViewById(R.id.exit);
yay1.setVisibility(ImageView.GONE);
ImageView inizio = (ImageView)findViewById(R.id.start);
inizio.setVisibility(ImageView.VISIBLE);
inizio.setBackgroundResource(R.drawable.start);
}
public void onClick(View v) {
// TODO Auto-generated method stub
if (v == yay0) {
finish();
}
if (v == yay) {
ImageView inizio = (ImageView)findViewById(R.id.start);
inizio.setVisibility(ImageView.GONE);
WebView work = new WebView(this);
setContentView(work);
work.loadUrl("file:///android_asset/index1.html");
work.setWebViewClient( new work());
work.setBackgroundColor(0);
work.getSettings().setBuiltInZoomControls(true);
work.getSettings().setDefaultZoom(ZoomDensity.FAR);
}
if (v == yay1) {
finish();
}
}
private class work extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.contains("exit.html")) {
// TODO: do what you have to do
finish();
}
view.loadUrl(url);
return true;
}
}
}
Your best bet is to ask somebody to send you the LogCollector output (in my experience, users are very happy to provide you information to debug problems. There are some really cool people out there). That should give you a callstack, and information on what kind of exception you triggered (NullPointerException, etc).
Next up - what are you building your app against? There should be an "Android x.x" entry in your project structure somewhere. If you're building something that is supposed to run on Android 1.5, then make sure you actually build against 1.5. You CAN build against 2.0 if you want, but if you need to use 2.0-specific functions, you'll have to encapsulate them properly. (This has been explained in detail on stackoverflow several times.)
On an unrelated note - I recommend more informative variable names. "yay0" doesn't mean anything to anyone who hasn't been working intimately with the code for a while.