This question already has answers here:
Android L (5.x) Turn ON/OFF "Mobile Data" programmatically
(3 answers)
Closed 2 years ago.
Although this is a "duplicate", the current answers are out of date and, mostly, no longer apply. I thought it would be good to provide an updated resource here, if possible, to save people time, as I have just done, researching this issue.
I've been googling around to see the latest information on being able to enable and disable mobile data from within an app (if wifi is not available).
This is one of the latest things I can find:
Did you know you can no longer Disable/Enable Data on lollipop from a widget?
There is an answer to that, I quote:
There was never an API for it. Developers were using a workaround by calling the method via Reflections. All Google did was close this "exploit".
There is also this discussion:
Replacement for setMobileDataEnabled() api
Which is Feb 2015.
There are these questions here:
How to disable Mobile Data on Android
This was asked in 2010 and the latest answer was updated with a one liner on Dec 2014.
Enable/disable data connection in android programmatically
And this, the accepted answer in 2012.
What's the latest on this issue?
Can it still be done?
It wont work on non-rooted phone as they added MODIFY_PHONE_STATE permission check. This permission is only given to system or signature apps refer-here.
Check the code below from PhoneInterfaceManager:
#Override
public void setDataEnabled(boolean enable) {
enforceModifyPermission();
mPhone.setDataEnabled(enable);
}
private void enforceModifyPermission() {
mApp.enforceCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE, null);
}
Unless you have a rooted phone I don't think you can enable and disable data programmatically because in order to do so we have to include MODIFY_PHONE_STATE permission which is only given to system or signature apps.
setMobileDataEnabled() method is no longer callable via reflection. It was callable since Android 2.1 (API 7) to Android 4.4 (API 19) via reflection, but as of Android 5.0 and later, even with the rooted phones, the setMobileDataEnabled() method is not callable.
Fast forward to the end of 2018...
The short answer is it is no longer allowed to enable/disable mobile data programmatically. Here is the solution that I use all the time.
This code opens system data usage settings screen, where the user can disable mobile data manually.
public void enableDisableMobileData() {
Intent intent = new Intent();
intent.setComponent(new ComponentName(
"com.android.settings",
"com.android.settings.Settings$DataUsageSummaryActivity"));
startActivity(intent);
}
EDIT 2019:
The answer above does not work starting on API 28. This is what works:
Intent intent = new Intent(Settings.ACTION_DATA_USAGE_SETTINGS);
startActivity(intent);
None of the above worked for me, but if your device is rooted, you may use this for enabling it.
private void enableMobileData(){
try {
String[] cmds = {"svc data enable"};
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd + "\n");
}
os.writeBytes("exit\n");
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
And this for disabling it:
private void disableMobileData(){
try {
String[] cmds = {"svc data disable"};
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd + "\n");
}
os.writeBytes("exit\n");
os.flush();
} catch (Exception e) {
e.printStackTrace();
}
}
Easy Method.
public void setMobileDataState(boolean mobileDataEnabled)
{
try{
ConnectivityManager dataManager;
dataManager = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
Method dataMtd = ConnectivityManager.class.getDeclaredMethod("setMobileDataEnabled", boolean.class);
dataMtd.setAccessible(true);
dataMtd.invoke(dataManager, mobileDataEnabled);
}catch(Exception ex){
//Error Code Write Here
}
}
Related
I'm trying to create a method in java that returns if Android OS has a pending update.
I've read in AndroidDeveloper that it's possible by creating a DPC that installs "work profile" on the device. But is there a way to avoid that and get it via java?
Check this section inside the android developer docs describing this process using the DevicePolicyManager or see the below snippet from the page:
SystemUpdateInfo updateInfo = dpm.getPendingSystemUpdate(adminName);
if (updateInfo != null) {
Long firstAvailable = updateInfo.getReceivedTime();
Log.i(TAG, "Update first available: " + new Date(firstAvailable));
}
I'm working on a simple to-do list app, and I'm trying to read/write data from/to internal storage. I'm trying to understand when exactly those read/write methods should be called.
I know that the activity class has an onCreate() method which will be a reasonable location for my read method, but where should I call my write method?
I want to call it when the app closes/ends, so I'd assume onDestory() is a good location, but i heard that onDestroy() may not be a good location for data storage operations and i should use onStop().
Any help or ideas?
It depends on Application Lifecycle.
And see This.
onStop() invokes when user press home button(Hard Key).
And then, if memory insufficient or another reason, Android Memory Manager will kill your app instant and onDestory() will never called.
The best thing you have to is make a button to save datas. Of course, Include onStop() save routine.
Following the table in the Android Developers Guide on the Activity Lifecycle, your app may be killed by the system any time without warning after either onPause() (for Pre-HONEYCOMB devices) or after onStop(). So you probably want to write your data in these methods to make sure nothing gets lost. So for newer devices (API level 11 and up), onStop() should be fine. If your app should run on older devices as well, onPause() would be the best place.
This is Just sample code. But you get the idea. Create a custom method implementing the code below and call it on some events like "onClick" or any other.
File file;
FileOutputStream strem = null;
String line = "Hey this is my name";
try {
file = new File("sdcard/newFile.txt");
strem = new FileOutputStream(file);
byte[] bytes = line.getBytes();
strem.write(bytes);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
strem.close();
} catch (IOException e) {
e.printStackTrace();
}
}
We are creating an app where you can share an app, which sends the user to the google play store to download another app.
My question is, how can I know if some user actually downloaded and installed that app?
Is there a some sort of callback you get from the play store?
Try calling startActivityForResult() with the Play Store intent. Then, override the onActivityResult() method in your Activity and check if the app is installed. This might help: How to check programmatically if an application is installed or not in Android?
isAppInstalledBefore("com.example.anappblabla");
private boolean isAppInstalledBefore(String packageName) {
PackageManager pm = getPackageManager();
boolean installed = false;
try {
pm.getPackageInfo(packageName, PackageManager.GET_ACTIVITIES);
installed = true;
} catch (PackageManager.NameNotFoundException e) {
installed = false;
}
return installed; //returns boolean
}
No, but:
What I would do is trying to get the package name (generally in the URL for example: https://play.google.com/store/apps/details?id=dev.laurentmeyer.contactautocompleteview of the target app (which is unique): something like dev.laurentmeyer.whateverApp (it's the one I'm personally using). Then scan the installed apps with this Helper and you'll be sure if it has been installed or not.
I need help with my java project. I'm currently trying to send a message in a Skype conversation when a specific action happens.
For this, I am using the java-skype API v1.4 by taskan.
Here's my code:
try {
for (Group group : Skype.getContactList().getAllGroups()) {
if ((group.getDisplayName()).equals("Nameofthegroup")) { //Whatever the group name is
String id = group.getId();
Skype.chat(id).send(ep.getDisplayName() + " joins !");
ep.sendMessage("Die ID: "+ id);
}
}
} catch (Exception e3) {
e3.printStackTrace();
}
I've also tried:
try {
String id = Skype.getContactList().getGroup("Groupname").getId();
Skype.chat(id).send(p + "joins!");
} catch (SkypeException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
My problem is that Skype registers that a external program tries to do something, but after I allow access for Java, nothing else happens. No messages are sent.
Sorry for the late answer but assuming you haven't yet picked an answer the problem is still open.
I was trying to get groups the same way with you but unfortunately it doesn't work like this. I do not if this is API problem or just because microsoft dropped support from third party APIs some of its features not working.
I managed to work this around by searching for chats not for groups. Also it would be much easier if you just bookmark (add at favorites) the chat (group) you want to find.
Chat group = null;
for ( Chat c : Skype.getAllBookmarkedChats() ){
group = c;
}
I just have the group chat in my favorites so it is super easy to retrieve it! If you have more chats and you need a more general way to find a specific one there are also several ways to do this.
for (Chat c : Skype.getAllChats()){
c.getAllMembers();
c.getId();
c.getWindowTitle();
}
group = c;
But this would be harder. The getId() way may be look easier but I didn't manage to get it working. Don't know again if it was my problem or just the API but whatever I tried simple just didn't work.
And do not forget to print your results at console to ease yourself.
In the end if you manage to get your group chat it is really easy to send a message:
group.send("Hi chat! This is java!!");
EDIT
This api works only for p2p chats. If you want to create a p2p chat you need to use the /createmoderatedchat command in any chat and it will create a new empty p2p chat. Any other group will be automatic cloud-based.
Also check this
SECOND EDIT
API is completely dead
I don't know too much about the Skype API, but you can check the samples for help. If you want to send a chat message when someone sends you a chat message you can use the AutoAnswering example:
package com.skype.sample;
import com.skype.ChatMessage;
import com.skype.ChatMessageAdapter;
import com.skype.Skype;
import com.skype.SkypeException;
public class AutoAnswering {
public static void main(String[] args) throws Exception {
Skype.setDaemon(false); // to prevent exiting from this program
Skype.addChatMessageListener(new ChatMessageAdapter() {
public void chatMessageReceived(ChatMessage received) throws SkypeException {
if (received.getType().equals(ChatMessage.Type.SAID)) {
received.getSender().send("I'm working. Please, wait a moment.");
}
}
});
}
}
Your code has an undefined variable ep in it and I can't give you a better answer because of that. I would've made a comment asking about it, but Stack Overflow doesn't let new people make comments.
I'm still learning how to extract data from a website and I really hope I'll get some nice answers adequate for a starter. Anyways, my goal here is to extract the data in the background of my app(without openning and showing it in my app). The idea is that data then would be stored for later use.
The API I'm using has 2 GetMethods:
GetProductJSON(which has JSON Response) and GetProduct(with a Comma Seperated Values(CSV) Response)
Here is an example of the JSON Response website:
{"0":{"productname":"Neutrogena Lips Stick 4.8g","imageurl":"http://ecx.images- amazon.com/images/I/31E1ct854gL._SL160_.jpg","producturl":"","price":"5.65","currency":"USD","saleprice":"","storename":"N/A"}}
The Comma Seperated Values Response looks like this:
"productname","imageurl","producturl","price","currency","saleprice","storename"
"Neutrogena Lips Stick 4.8g","http://ecx.images-amazon.com/images/I/31E1ct854gL._SL160_.jpg","","5.65","USD","","N/A"
Here is how I call the website:
url = url.replace("{CODE}", codeValue);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(url));
cardPresenter.setPendingIntent(createPendingIntent(getContext(), intent));
Any suggestions on how to make this a background task and how to actually get the data in java so that I can use them on a Livecard.
First, you need to have access to the Internet. Include the following permission into your AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
Using GDK and AsyncTask:
import android.os.AsyncTask;
public class RetrieveData extends AsyncTask<String, String, String> {
#Override
protected String doInBackground(String... resource) {
String data;
try {
URL url = new URL(resource[0]);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
InputStream in = new BufferedInputStream(connection.getInputStream());
data = convertStreamToString(in);
in.close();
} catch (Exception e) {
e.printStackTrace();
}
return data;
}
private String convertStreamToString(InputStream in) {
Scanner s = new Scanner(in);
return s.useDelimiter("\\A").hasNext() ? s.next() : "";
}
}
The method convertStreamToString() is described there.
In your Service or Activity:
String retrievedData;
try {
retrievedData = new RetrieveData().execute("http://www.example.com/GetProductJSON").get();
} catch (Exception e) {
e.printStackTrace();
}
// Process data
Hope that helps.
You have at least these choices using GDK: 1) create an asynch task; or 2) create a private service that you assign tasks to periodically.
The first thing you will need to do in your Android Application is to add permission to access the Internet in your AndroidManifest.xml file. Add this tag as a sibling of <application>.
<uses-permission android:name="android.permission.INTERNET"/>
You will then need to consider in what manner you will make the HTTP requests. In an ideal application, you need to use the AsyncTask class to make these requests to avoid blocking the UI thread.
If you are just looking for a quick proof of concept, you can permit these requests on the UI thread by modifying your policy. Add this code to your onCreate() method in the MainActivity
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
This is not an advisable long term solution since it blocks the UI thread, but there are StackOverflow topics on it. How to fix android.os.NetworkOnMainThreadException?.
Here is another article on the concept of an AsyncTask http://www.androiddesignpatterns.com/2012/06/app-force-close-honeycomb-ics.html.
Although you seem to be indicating you're using the GDK, you may want to consider a server-push via the Mirror API instead. Since you need to fetch the information via the network anyway, you're losing out on many of the advantages the GDK offers.
With the Mirror API, you would create a new timeline item with timeline.insert and save the id of the card that was created. You would probably want to give your user the option to pin the card so it is placed in the "now" area of the timeline.
When updating, you can call timeline.update with the new information.
Keep in mind that you do need to update the card periodically or it may fall off the timeline or out of the pinned area after seven days of inactivity.