I'm working on small android camera application that opens CameraPreview on start. I tryed to set a lot of ColorEffects to my Camera instance, but it doesn't work. There is my code where I use
setColorEffect method:
public void surfaceCreated(SurfaceHolder holder) {
// The Surface has been created, now tell the camera where to draw the preview.
try {
Camera.Parameters parameters = mCamera.getParameters();
parameters.setSceneMode(Camera.Parameters.FLASH_MODE_AUTO);
parameters.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);
mCamera.setDisplayOrientation(90);
mCamera.setParameters(parameters);
mCamera.setPreviewDisplay(holder);
mCamera.startPreview();
} catch (IOException e) {
Log.d(TAG, "Error setting camera preview: " + e.getMessage());
}
}
Permissions
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-feature android:name="android.hardware.camera" />
UPD: I tryed to run my app on android 2.3.6 and color effects work on it. It doesn`t work on android 5.0
Please help me.
This class was deprecated in API level 21.
We recommend using the new android.hardware.camera2 API for new applications.
Turns out Camera.Parameters is deprecated.
Android Developer - Camera.Parameters
You should use this instead for devices with API level > 21:
Android Developer - android.hardware.camera2
Related
Hello Android developers, I am trying to make my app the default sms app on my phone with the following code but its not working as it is not displaying the dialog for a user to choose which app to use as the default sms app. I am aware that as of Android 10 then we need to use the RoleManager class to check if the app is the default sms app and additionally check if the app holds the role and then start an activity for the user to set the current app to have that role. I have followed every required step from the documentation and some previously posted questions on this site but there seems to be an error that is silent because no exception is thrown. Help me make this code display the dialog to the user for changing the app for the sms roles.
//register a delegate for reading the phone number
button.Click += (o, p) =>
{
Toast.MakeText(this,Telephony.Sms.GetDefaultSmsPackage(ApplicationContext),ToastLength.Long).Show();
//check first if the app is the default sms privilege holder
if (Telephony.Sms.GetDefaultSmsPackage(ApplicationContext) != PackageName)
{
//use the role manager api to change the default sms app
//check the api level
if (Build.VERSION.SdkInt > BuildVersionCodes.P)
{
Log.Debug("API", "api greater than 28");
//api level is greater than 28 then use RoleManager class
RoleManager roleManager = (RoleManager)GetSystemService(Context.RoleService);
//check if the role is available first
if (roleManager.IsRoleAvailable(RoleManager.RoleSms))
{
//log the role manager availability
Log.Debug("Sms role available", roleManager.IsRoleAvailable(RoleManager.RoleSms).ToString());
//chek if the role is held
if (roleManager.IsRoleHeld(RoleManager.RoleSms))
{
//means the app has the sms role and we do not need to change
}
else
{
Log.Debug("Info", "Sms Role is not held");
//means the app does not have the sms role and we need to request the user to change
Intent changeIntent = roleManager.CreateRequestRoleIntent(RoleManager.RoleSms);
StartActivityForResult(changeIntent,909);
}
}
else
{
//the role is not avaialble and cannot be changed
Log.Debug("Sms role available",
roleManager.IsRoleAvailable(RoleManager.RoleSms).ToString());
}
}
else
{
//api level is less than or equal to 28 use the deprecated way
Intent changeIntent = new Intent(Telephony.Sms.Intents.ActionChangeDefault);
changeIntent.PutExtra(Telephony.Sms.Intents.ExtraPackageName, PackageName);
StartActivity(changeIntent);
}
}
and here is my manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="SimCardManager.SimCardManager">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.SEND_SMS" />
<uses-permission android:name="android.permission.READ_SMS" />
<uses-permission android:name="android.permission.WRITE_SMS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_NUMBERS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.READ_PRECISE_PHONE_STATE"/>
<uses-permission android:name="android.permission.USE_ICC_AUTH_WITH_DEVICE_IDENTIFIER"/>
<application android:allowBackup="true" android:label="#string/app_name" android:supportsRtl="true" android:theme="#style/AppTheme">
</application>
</manifest>
An answer in Android Java is also accepted as that is what I use to convert Java code to C#, the code is still Android Java working as a Xamarin Android C# binding, Thank You for your time and effort helping me.
I want to use this code in order to reboot my RPI3 running Android Things:
public static void Reboot()
{
try {
Process proc = Runtime.getRuntime().exec(new String[]{"su", "-c", "reboot"});
proc.waitFor();
} catch (Exception ex) {
ex.printStackTrace();
}
}
I get the following error:
java.io.IOException: Cannot run program "su": error=13, Permission denied
I add to the manifest all the permission
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.DOWNLOAD_WITHOUT_NOTIFICATION" />
<uses-permission android:name="android.permission.KILL_BACKGROUND_PROCESSES" />
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.SET_TIME_ZONE"/>
<uses-permission android:name="android.permission.SHUTDOWN"/>
Am I missing something?
/system/bin/reboot binary in DP 4, so as in all the previous dev previews, has world-executable permission, i.e. the following yields
adb shell ls -l /system/bin | grep reboot
-rwxr-xr-x 1 root shell ... reboot
That said, it is yet possible to execute the binary for any user (a.k.a app process in Android) without a need to grab su. Just execute in Java for
rebooting
Runtime.getRuntime().exec("reboot");
or for powering off
Runtime.getRuntime().exec("reboot -p");
No permission's needed in AndroidManifest.xml to run the binary successfully.
Caution: in case of security model changes in newer OS versions this approach may not work.
You can now do a reboot using:
https://developer.android.com/things/reference/com/google/android/things/devicemanagement/DeviceManager.html
Example
public class SomeActivity extends Activity {
void doReboot() {
DeviceManager.getInstance().reboot();
}
void doFactoryReset() {
boolean wipeExternalCard = true;
DeviceManager.getInstance().factoryReset(wipeExternalCard);
}
}
You need the com.google.android.things.permission.REBOOT permission
Access to system-protected features (such as those provided by the PowerManager.reboot() API) will be available to apps running on Android Things in a future developer preview release. You cannot (and should not) attempt to run your app process as the root user via su.
As a side note, the developer images for Android Things are built as userdebug, which means you can access root from the shell by simply rebooting the ADB daemon with the adb root command before you attempt to access the shell. This gives you any root access you may need during development without compromising the device security and allowing app processes to run as root.
You need a root access.
public static void runCmd(String cmd) {
DataOutputStream os;
try {
Process process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(cmd + "\n");
os.writeBytes("exit\n");
os.flush();
os.close();
} catch (IOException e) {
e.printStackTrace();
}
}
Then you can run any commands that require root access like this: runCmd("reboot");
I am newbie to native android development. I am working on android studio. I have a tabbed activity in which i am using 2 tabs. In one tab there is a map with marker on gps location of the user. The second tab is to take picture and then to save it in the storage provided by the OS. For this i followed this tutorial, run the app on my device but it's crashes. I am running it on Marshmallow. Below is the error i get
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=android/com.android.internal.app.ResolverActivity } from ProcessRecord{e8f9820 15070:com.example.accurat.faisal/u0a228} (pid=15070, uid=10228) with revoked permission android.permission.CAMERA
at android.os.Parcel.readException(Parcel.java:1620)
at android.os.Parcel.readException(Parcel.java:1573)
at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3181)
at android.app.Instrumentation.execStartActivity(Instrumentation.java:1541)
at android.app.Activity.startActivityForResult(Activity.java:4298)
at android.support.v4.app.BaseFragmentActivityJB.startActivityForResult(BaseFragmentActivityJB.java:50)
at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:79)
at android.support.v4.app.ActivityCompatJB.startActivityForResult(ActivityCompatJB.java:30)
at android.support.v4.app.ActivityCompat.startActivityForResult(ActivityCompat.java:146)
at android.support.v4.app.FragmentActivity.startActivityFromFragment(FragmentActivity.java:937)
at android.support.v4.app.FragmentActivity$HostCallbacks.onStartActivityFromFragment(FragmentActivity.java:1047)
at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:954)
at android.support.v4.app.Fragment.startActivityForResult(Fragment.java:943)
at com.example.accurat.faisal.Camera$1.onClick(Camera.java:51)
at android.view.View.performClick(View.java:5716)
at android.widget.TextView.performClick(TextView.java:10926)
at android.view.View$PerformClick.run(View.java:22596)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:7325)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230 at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
I searched it and found that i should ask permission for it so i followed this link and tried to add permission check like as bellow
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// Check permission for CAMERA
if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
// Check Permissions Now
// Callback onRequestPermissionsResult interceptado na Activity MainActivity
ActivityCompat.requestPermissions(getActivity(),
new String[]{Manifest.permission.CAMERA},
MainActivity.REQUEST_CAMERA);
}
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE );
}
});
But i am getting red text of CAMERA and REQUEST_CAMERA. Though i have imported them as well but still the red text is showing
import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.RECORD_AUDIO;
import static android.Manifest.permission.WRITE_EXTERNAL_STORAGE;
Below is my manifest file
<uses-permission android:name="com.example.accurat.faisal.permission.MAPS_RECEIVE"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.hardware.camera"/>
I don't know what is the problem and don't know the solution and i am stuck to it.
Any help would be highly appreciated
You need to add permission check in your code and based on user action of accecpt or denial should show the camera preview Beginning in Android 6.0 (API level 23), users grant permissions to apps while the app is running. Also, you need to ask user permission for android.Manifest.permission.WRITE_EXTERNAL_STORAGE if you are creating a file which will be used as an input for image(captured via camera).
After doing tons of research on the topic, I learned that my app may not show up for tablets in the Play Store if I have some permissions that the tablet cannot handle. Here are my current permissions:
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.VIBRATE" android:permission ="false" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.GET_TASKS" />
<uses-permission android:name="android.permission.INTERNET" />
Will any of these permissions cause the app to not show up in the play store?
Some tablets may not be able to handle the <uses-permission android:name="android.permission.READ_PHONE_STATE" /> because don't get calls...So, I need to do something in my java code saying:
if(Device has the ability to get calls){ //Execute code}
So, since the telephone thing is optional, I changed it's permission to:
<uses-feature android:name="android.permission.READ_PHONE_STATE" android:required="false"/>
How do I get that? If you need it, this is where I am actually checking if the user is getting a call, I use it to mute my application:
private PhoneStateListener phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_RINGING) {
onPhoneCallInterrupt(); //Method I created that just mutes the audio
} else if (state == TelephonyManager.CALL_STATE_IDLE) {
} else if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
onPhoneCallInterrupt(); //Method I created that just mutes the audio
}
}
};
So, what do I do to handle the exception that may occur if a tablet is using the app, like this?
if(Device has the ability to get calls){ //Execute code}
Thanks,
Ruchir
TelephonyManager tm = (TelephonyManager) this.getSystemService(Context.TELEPHONY_SERVICE); //gets the current TelephonyManager
if (tm.getSimState() != TelephonyManager.SIM_STATE_ABSENT){
//the device has a sim card
} else {
//no sim card available
}
Check more here
Keep your phone state permission on an if-else block. When user will try to access that feature or you might need to check phone state, throw a dialog box on the screen. This link shows how to ask for user's permission.
From API 23, User's will need to explicitly permit each and every permission so, it is a good thing if you do that for all.
Beside, upon users permission, the manifest file will be overwritten so, you won't have to worry about that either.
Does it solve ur issue?
I creating an app that's using GCM to receive notifications from our servers, am using Google's gcm.jar, and have a customGCMIntentService class handling it. My problem is that only one handset is actually getting a response (or more likely routing the response correctly) from GCM when calling GCMRegistrar.register().
What I'm seeing is that the GCMRegistrar (from the gcm library) is correctly setting my custom broadcast receiver as the retry receiver on the nexus 3 phone, the only one that works, but not on the others. This makes me believe that I might be getting a response from GCM but its not being processed on the three other phones (detail below).
GCMRegistrar Setting the name of retry receiver class to <My_application_package>.CustomGCMBroadcastReceiver
All of them have a data connection that allows communication with GCM, all have an active gmail account on them ( all of them have the playstore working ). I've also run Google's GCM demo on them all without a problem.
The registration code:
//This is almost identical to how Google's GCM demo does it.
private void registerOnGCM(){
checkNotNull(SERVER_URL, "SERVER_URL"); //What it says on the tin
checkNotNull(SENDER_ID, "SENDER_ID");
// Make sure the device has the proper dependencies.
GCMRegistrar.checkDevice(this);
// Make sure the manifest was properly set - comment out this line
// while developing the app, then uncomment it when it's ready.
GCMRegistrar.checkManifest(this);
/*
registerReceiver(mHandleMessageReceiver,
new IntentFilter(HANDLE_MESSAGE));
*/
final String regId = GCMRegistrar.getRegistrationId(getApplicationContext());
if (regId.equals("")) {
// Automatically registers application on startup.
GCMRegistrar.register(getApplicationContext(), SENDER_ID);
}
else {
// Device is already registered on GCM, check server.
if (GCMRegistrar.isRegisteredOnServer(getApplicationContext())) {
// Skips registration.
Log.i(TAG, "Already registered");
} else {
// Try to register again, but not in the UI thread.
// It's also necessary to cancel the thread onDestroy(),
// hence the use of AsyncTask instead of a raw thread.
final Context context = this;
mRegisterTask = new AsyncTask<Void, Void, Void>() {
#Override
protected Void doInBackground(Void... params) {
boolean registered = ServerUtilities.register(context, regId);
if (!registered) {
GCMRegistrar.unregister(context);
}
return null;
}
#Override
protected void onPostExecute(Void result) {
mRegisterTask = null;
}
};
mRegisterTask.execute(null, null, null);
}
}
The code for CustomGCMBroadcastReceiver doesn't matter, nor does the GCMIntentService, since neither of them is ever call'd. Problem isn't with them.
Devices I'm testing on:
HTC Desire GSM running CyanogenMod 7
Google nexus 3 running Android 4.1.1 (Application works on this one)
Motorola T910 running Android 4.0.1
Samsung Galaxy mini running Android 4.2.6
Manifest:
<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- App has permission to read/write files on sd card. Used for RSS document -->
<uses-permission android:name = "android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name = "android.permission.WRITE_EXTERNAL_STORAGE"/>
<!-- GCM connects to Google Services. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- GCM requires a Google account. -->
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<!-- Keeps the processor from sleeping when a message is received. -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<permission
android:name="<My_package_name>.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission
android:name="<My_package_name>.permission.C2D_MESSAGE" />
<!-- This app has permission to register and receive data message. -->
<uses-permission
android:name="com.google.android.c2dm.permission.RECEIVE" />
<application
android:allowBackup="true"
android:theme="#style/AppTheme"
android:label="#string/app_name">
<activity
android:name="<My_package_name>.MasterActivity"
android:screenOrientation="portrait">
</activity>
<activity android:name="<My_package_name>.WebActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<!--
BroadcastReceiver that will receive intents from GCM
services and handle them to the custom IntentService.
The com.google.android.c2dm.permission.SEND permission is necessary
so only GCM services can send data messages for the app.
-->
<receiver
android:name="<My_package_name>.CustomGCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<!-- Receives the actual messages. -->
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<!-- Receives the registration id. -->
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="<My_package_name>" />
</intent-filter>
</receiver>
<!--
Application-specific subclass of GCMBaseIntentService that will
handle received messages.
By default, it must be named .GCMIntentService, unless the
application uses a custom BroadcastReceiver that redefines its name.
-->
<service android:name="<My_package_name>.GCMIntentService"
android:enabled="true"/>
</application>
Might be something I've forgotten to add. Let me know.
All ideas are welcomed.
-MrDresden
Well it seems to have fixed it self by only cleaning, and rebuilding and then deploying that to those other devices.
Why removing all traces from all phones, then running in debug mode on them didn't work, except on one phone I have no idea.