how to access downloads folder in android? - java

I am new android, i'm making an app in which one can download files to downloads folder (using Download Manager). I can see pictures if i go to downloads folder in emulator. So if i want to show a slideshow of downloaded files how can i get the access to that folder? Secondly how to add progress bar to this code:--
import java.util.Arrays;
import android.app.Activity;
import android.app.DownloadManager;
import android.app.DownloadManager.Query;
import android.app.DownloadManager.Request;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
public class Download_managerActivity extends Activity {
private long quueue_for_url;
private DownloadManager dm;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (DownloadManager.ACTION_DOWNLOAD_COMPLETE.equals(action)) {
long downloadId = intent.getLongExtra(
DownloadManager.EXTRA_DOWNLOAD_ID, 0);
Query query = new Query();
query.setFilterById(quueue_for_url);
Cursor c = dm.query(query);
if (c.moveToFirst()) {
int columnIndex = c
.getColumnIndex(DownloadManager.COLUMN_STATUS);
if (DownloadManager.STATUS_SUCCESSFUL == c
.getInt(columnIndex)) {
ImageView view = (ImageView) findViewById(R.id.imageView1);
String uri_String_abcd = c
.getString(c
.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
view.setImageURI(Uri.parse(uri_String_abcd));
}
}
}
}
};
registerReceiver(receiver, new IntentFilter(
DownloadManager.ACTION_DOWNLOAD_COMPLETE));
}
public void onClick(View view) {
dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
Request request_for_url = new Request(
Uri.parse("http://fc03.deviantart.net/fs14/i/2007/086/9/1/Steve_Jobs_portrait_by_tumb.jpg"));
Request request_for_url1 = new Request(
Uri.parse("http://2.bp.blogspot.com/_q7Rxg4wqDyc/S5ZRVLxVYuI/AAAAAAAAAvU/fQAUZ2XFcp8/s400/katrina-kaif.jpg"));
Request request_for_url2 = new Request(
Uri.parse("http://www.buzzreactor.com/sites/default/files/Bill-Gates1.jpg"));
quueue_for_url = dm.enqueue(request_for_url);
quueue_for_url = dm.enqueue(request_for_url1);
quueue_for_url = dm.enqueue(request_for_url2);
}
public void showDownload(View view) {
Intent i = new Intent();
//try more options to show downloading , retrieving and complete
i.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS);
startActivity(i);
}
}
I want to add a button which performs the function of taking the pictures from downloads folder and then display like a slideshow.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="cmpe235.lab1"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="9" />
<uses-permission android:name="android.permission.INTERNET"></uses-permission>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".Download_managerActivity"
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>
main.xml:-
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical" android:layout_width="fill_parent"
android:layout_height="fill_parent">
<Button android:text="Start Download" android:id="#+id/button1"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal|center" android:textColor="#0000A0"
android:typeface="serif" android:onClick="onClick"></Button>
<Button android:text="View Downloads" android:id="#+id/button2"
android:layout_width="wrap_content" android:layout_height="wrap_content"
android:layout_gravity="center_vertical|center_horizontal|center" android:textColor="#0000A0"
android:typeface="serif" android:onClick="showDownload"></Button>
<ImageView android:layout_height="wrap_content" android:id="#+id/imageView1"
android:src="#drawable/icon" android:layout_width="wrap_content"></ImageView>
</LinearLayout>

For your first question try
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
(available since API 8)
To access individual files in this directory use either File.list() or File.listFiles().
Seems that reporting download progress is only possible in notification, see here.

Updated
getExternalStoragePublicDirectory() is deprecated.
To get the download folder from a Fragment,
val downloadFolder = requireContext().getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
From an Activity,
val downloadFolder = getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)
downloadFolder.listFiles() will list the Files.
downloadFolder?.path will give you the String path of the download folder.
Update:
The Direct filesystem access to storage has become limited in recent versions of Android.
context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) gives you the directory /emulated/0/Android/data/{package}/files/Download. If you want to have the public downloads folder, look into the Storage Access Framework of Android documentation.

You need to set this permission in your manifest.xml file
android.permission.WRITE_EXTERNAL_STORAGE

If you are using Marshmallow, you have to either:
Request permissions at runtime (the user will get to allow or deny the request) or:
The user must go into Settings -> Apps -> {Your App} -> Permissions and
grant storage access.
This is because in Marshmallow, Google completely revamped how permissions work.

If you're using a shell, the filepath to the Download (no "s") folder is
/storage/emulated/0/Download

You should add next permission:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And then here is usages in code:
val externalFilesDir = context.getExternalFilesDir(DIRECTORY_DOWNLOADS)

Related

Ble Broadcast receiver not displaying on listview

(DISCLAIMER: SUPER NEW TO ANDROID STUDIO) I'm creating an app to scan for ble devices and display them on the list but it seems like no devices are being discovered and being displayed on the listview. Any help is appreciated. I'm planning to update the Textview with the number of devices that are found. I haven't set up the scanfilters yet since I'm still trying to figure out the UUIDs for the tags that I'm using. I also changed the min sdk to 23 since it was giving me an error while setting the scanmode, callback, and matchmode.
MainActivity.java
package com.example.tygatraxseconddraft;
import androidx.appcompat.app.AppCompatActivity;
import android.Manifest;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.le.BluetoothLeScanner;
import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.os.ParcelUuid;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.Toast;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "TWESBTSCANNER";
public static final int REQUEST_ACCESS_COARSE_LOCATION = 1;
public static final int REQUEST_ENABLE_BLUETOOTH = 11;
private ListView listView;
private Button scanningBtn;
private BluetoothAdapter bluetoothAdapter;
private final ArrayList<String> mDeviceList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listView = findViewById(R.id.device_list);
scanningBtn = findViewById(R.id.scanning_btn);
hasPermissions();
checkBluetoothState();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
listView = findViewById(R.id.device_list);
scanningBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
BluetoothLeScanner scanner = adapter.getBluetoothLeScanner();
final ScanCallback scanCallback = new ScanCallback() { //studio made it not private
#Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
// ...do whatever you want with this found device
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
// Ignore for now
}
#Override
public void onScanFailed(int errorCode) {
// Ignore for now
}
};
UUID SERVICE_DATA_UUID = UUID.fromString("00005246-0000-1000-8000-00805f9b34fb");//filter for the Nordic tags
UUID[] serviceUUIDs = new UUID[]{SERVICE_DATA_UUID};
List<ScanFilter> filters = null;
if (serviceUUIDs != null) {
filters = new ArrayList<>();
for (UUID serviceUUID : serviceUUIDs) {
ScanFilter filter = new ScanFilter.Builder()
.setServiceUuid(new ParcelUuid(serviceUUID))
.build();
filters.add(filter);
}
}
ScanSettings scanSettings = new ScanSettings.Builder()
.setScanMode(ScanSettings.SCAN_MODE_LOW_POWER)
.setCallbackType(ScanSettings.CALLBACK_TYPE_ALL_MATCHES)
.setMatchMode(ScanSettings.MATCH_MODE_AGGRESSIVE)
.setNumOfMatches(ScanSettings.MATCH_NUM_ONE_ADVERTISEMENT)
.setReportDelay(0L)
.build();
if (scanner != null) {
scanner.startScan(null, scanSettings, scanCallback); // must set scan settings first
Log.d(TAG, "scan started");
} else {
Log.e(TAG, "could not get scanner object");
}
}
});
}
#Override
protected void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
public final BroadcastReceiver mReceiver = new BroadcastReceiver() { //
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
mDeviceList.add(device.getName() + "\n" + device.getAddress());
Log.i("BT", device.getName() + "\n" + device.getAddress());
listView.setAdapter(new ArrayAdapter<String>(context, android.R.layout.simple_list_item_1, mDeviceList));
}
}
};
private boolean hasPermissions() { //checks and asks for location permission
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
if (getApplicationContext().checkSelfPermission(Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[] { Manifest.permission.ACCESS_COARSE_LOCATION }, REQUEST_ACCESS_COARSE_LOCATION);
return false;
}
}
return true;
}
//ENABLE WHEN TESTING ON PHONE
private void checkBluetoothState() {
//gets the bluetooth adapter
BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(bluetoothAdapter.isEnabled()){
Toast.makeText(this,"Bluetooth is enabled", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Please turn on Bluetooth", Toast.LENGTH_SHORT).show();
Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableIntent, REQUEST_ENABLE_BLUETOOTH);
}//requests permission if bluetooth is not enabled
}
}
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tygatraxseconddraft">
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- Needed only if your app looks for Bluetooth devices.
You must add an attribute to this permission, or declare the
ACCESS_FINE_LOCATION permission, depending on the results when you
check location usage in your app. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN"/>
<!-- Needed only if your app makes the device discoverable to Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- Needed only if your app communicates with already-paired Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION_LOCATION"/>
<!--Makes the app show up for only ble enabled devices-->
<uses-feature
android:name="android.hardware.bluetooth_le"
android:required="true"/>
<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.TygaTraxsecondDraft">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#color/white"
tools:context=".MainActivity">
<TextView
android:id="#+id/number_devices"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:text="#string/number_of_devices"
android:textColor="#color/black"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<Button
android:id="#+id/scanning_btn"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="50dp"
android:text="#string/button_text"
android:textColor="#212121"
app:backgroundTint="#color/gray"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent" />
<ListView
android:id="#+id/device_list"
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_marginStart="24dp"
android:layout_marginTop="24dp"
android:layout_marginEnd="24dp"
android:layout_marginBottom="24dp"
app:layout_constraintBottom_toTopOf="#+id/scanning_btn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="#+id/number_devices" />
</androidx.constraintlayout.widget.ConstraintLayout>
In case this is needed
colors.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="purple_200">#FFBB86FC</color>
<color name="purple_500">#FF6200EE</color>
<color name="purple_700">#FF3700B3</color>
<color name="teal_200">#FF03DAC5</color>
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="gray">#7393B3</color>
</resources>
strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Tyga Trax (second draft)</string>
<string name="button_text">Scan</string>
<string name="number_of_devices">There are </string>
</resources>
New Answer
I just realised you are simply doing nothing with the found devices right now, your ScanCallback is empty. You should add something like this to see the results:
final ScanCallback scanCallback = new ScanCallback() { //studio made it not private
#Override
public void onScanResult(int callbackType, ScanResult result) {
BluetoothDevice device = result.getDevice();
Log.d(TAG, "BLE scan found Device " + device.getName() + " with MAC " + device.getAddress());
// TODO: add device to ListView
}
#Override
public void onBatchScanResults(List<ScanResult> results) {
// Ignore for now
}
#Override
public void onScanFailed(int errorCode) {
// Ignore for now
}
};
You should see the found devices in your log now
Previous Answer
You are requesting the ACCESS_COARSE_LOCATION permission but your target SDK is 31. The guide for Bluetooth permissions states
ACCESS_FINE_LOCATION is necessary because a Bluetooth scan can gather information about the location of the user. This information may come from the user's own devices, as well as Bluetooth beacons in use at locations such as shops and transit facilities.
and also
Note: If your app targets Android 9 (API level 28) or lower, you can declare the ACCESS_COARSE_LOCATION permission instead of the ACCESS_FINE_LOCATION permission.
It even states to use ACCESS_BACKGROUND_LOCATION for devices with Android 10 or above. But there are new permissions for a target SDK of 31 (Android 12) as stated in this document.
<manifest>
<!-- Request legacy Bluetooth permissions on older devices. -->
<uses-permission android:name="android.permission.BLUETOOTH"
android:maxSdkVersion="30" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"
android:maxSdkVersion="30" />
<!-- Needed only if your app looks for Bluetooth devices.
You must add an attribute to this permission, or declare the
ACCESS_FINE_LOCATION permission, depending on the results when you
check location usage in your app. -->
<uses-permission android:name="android.permission.BLUETOOTH_SCAN" />
<!-- Needed only if your app makes the device discoverable to Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_ADVERTISE" />
<!-- Needed only if your app communicates with already-paired Bluetooth
devices. -->
<uses-permission android:name="android.permission.BLUETOOTH_CONNECT" />
...
</manifest>
As you can see the legacy Bluetooth permissions like BLUETOOTH are added as well, but have the option android:maxSdkVersion="30" set to only work up to Android 11.

How to create notification in Android with API 21 or higher

I have trouble creating notification from the application in Android. API must be API 21 or higher. I've probably tried 100 ways with Android Developer and other websites.
minSDK must be API21
I opened it on API26
This is my activity_main.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
android:paddingBottom="#dimen/activity_vertical_margin" tools:context=".MainActivity">
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Click for Notification"
android:id="#+id/buckysButton"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true"
android:onClick="buckysButtonClicked" />
</RelativeLayout>
This is MainActivity.java
package pl.wat.pz.notification;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.Intent;
import android.support.v4.app.NotificationCompat;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends AppCompatActivity {
NotificationCompat.Builder notification;
private static final int uniqueID = 45612;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
notification = new NotificationCompat.Builder(this);
notification.setAutoCancel(true);
}
public void buckysButtonClicked(View view){
//Build the notification
notification.setSmallIcon(R.mipmap.ic_launcher);
notification.setTicker("This is the ticker");
notification.setWhen(System.currentTimeMillis());
notification.setContentTitle("Here is the title");
notification.setContentText("I am the body text of your notification");
Intent intent = new Intent(this, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
notification.setContentIntent(pendingIntent);
//Builds notification and issues it
NotificationManager nm = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nm.notify(uniqueID, notification.build());
}
}
And the manifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="pl.wat.pz.notification">
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
And here image from android emulator
After click button nothing happened ;((
notification.setSmallIcon(R.mipmap.ic_launcher);
AFAIK, you cannot use a mipmap resource here, and your launcher icon is not a suitable notification icon on Android 4.4 and higher.
Create a separate drawable resource for your notification icon. If you are using Android Studio, the Image Asset wizard can assist with this.
Also, if your targetSdkVersion is 26 or higher, you need to set up a notification channel when running on Android 8.0+. This directory contains many sample apps that are up-to-date with respect to raising a Notification.

How can I turn on and off mobile data using toggle button?

Today I have done a task using toggle button. The mobile data needs to be turned on when I press the enable toggle button, and it should be turned off when I press the same button. I had done everything and when I press the enable button, the mobile data remains off. In fact I have added all the manifest permissions. The mobile data should turn on when I press the toggle button. Please help me friends,and also let me know where I committed mistake. I hereby enclosed my XML and Java coding. Please help me friends, Many thanks in advance.
MainActivity.java:
import android.app.Activity;
import android.content.Context;
import android.net.ConnectivityManager;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import android.os.Bundle;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MainActivity extends Activity{
// constants
static final String STATUS_ON = "Mobile Data: Enable";
static final String STATUS_OFF = "Mobile Data: Disable";
static final String TURN_ON = "Enable";
static final String TURN_OFF = "Disable";
// controls
TextView TVMobileData;
ToggleButton tBMobileData;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// load controls
TVMobileData=(TextView)findViewById(R.id.TVMobileData);
tBMobileData=(ToggleButton)findViewById(R.id.tBMobileData);
// set click event for button
tBMobileData.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
// check current state first
boolean state = isMobileDataEnable();
// toggle the state
if(state)toggleMobileDataConnection(false);
else toggleMobileDataConnection(true);
// update UI to new state
updateUI(!state);
}
});
}
public void updateUI(boolean state) {
//set text according to state
if(state) {
TVMobileData.setText(STATUS_ON);
tBMobileData.setText(TURN_OFF);
} else {
TVMobileData.setText(STATUS_OFF);
tBMobileData.setText(TURN_ON);
}
}
public boolean isMobileDataEnable() {
boolean mobileDataEnabled = false; // Assume disabled
ConnectivityManager cm = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
try {
Class cmClass = Class.forName(cm.getClass().getName());
Method method = cmClass.getDeclaredMethod("getMobileDataEnabled");
method.setAccessible(true); // Make the method callable
// get the setting for "mobile data"
mobileDataEnabled = (Boolean)method.invoke(cm);
} catch (Exception e) {
// Some problem accessible private API and do whatever error handling you want here
}
return mobileDataEnabled;
}
public boolean toggleMobileDataConnection(boolean ON)
{
try {
//create instance of connectivity manager and get system connectivity service
final ConnectivityManager conman = (ConnectivityManager) this.getSystemService(Context.CONNECTIVITY_SERVICE);
//create instance of class and get name of connectivity manager system service class
final Class conmanClass = Class.forName(conman.getClass().getName());
//create instance of field and get mService Declared field
final Field iConnectivityManagerField= conmanClass.getDeclaredField("mService");
//Attempt to set the value of the accessible flag to true
iConnectivityManagerField.setAccessible(true);
//create instance of object and get the value of field conman
final Object iConnectivityManager = iConnectivityManagerField.get(conman);
//create instance of class and get the name of iConnectivityManager field
final Class iConnectivityManagerClass= Class.forName(iConnectivityManager.getClass().getName());
//create instance of method and get declared method and type
final Method setMobileDataEnabledMethod= iConnectivityManagerClass.getDeclaredMethod("setMobileDataEnabled",Boolean.TYPE);
//Attempt to set the value of the accessible flag to true
setMobileDataEnabledMethod.setAccessible(true);
//dynamically invoke the iConnectivityManager object according to your need (true/false)
setMobileDataEnabledMethod.invoke(iConnectivityManager, ON);
} catch (Exception e){
}
return true;
}
}
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="arun.com.togglebuttonexample.MainActivity">
<TextView
android:id="#+id/TVMobileData"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_marginTop="90dp"
android:text="Mobile Data: Disable"
android:textColor="#1BD6E0"
android:textSize="40sp" />
<ToggleButton
android:id="#+id/tBMobileData"
android:layout_width="225dp"
android:layout_height="225dp"
android:layout_centerInParent="true"
android:textSize="30sp"
android:textOff="Enable"
android:textOn="Disable" />
</RelativeLayout>
AndroidManifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="arun.com.togglebuttonexample">
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
You can access mobile data on / off programmaticaly below android 4.4 but not above 4.4 as It's require MODIFY_PHONE_STATE permission check. This permission is only given to system or signature apps. so It wont work on non-rooted phone.

An android application that chooses photo from gallery and uploads into the firebase batabase

Like I said in my title I am trying to learn to use databases in android application. So I thought of creating a sample application that takes photos from gallery and uploads the image into the firebase database. However, my application collapses itself after I select a photo from gallery.
Here is my android manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.trump.demo_cameraapp">
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.INTERNET" />
<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">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
</application>
</manifest>
Here is my layout file, activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_height="match_parent"
android:layout_width = "match_parent"
android:gravity="center"
android:orientation="vertical">
<ImageView
android:id="#+id/imageView1"
android:layout_height="match_parent"
android:layout_width="match_parent"
android:layout_weight="2">
</ImageView>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Choose Photo!"
android:textColor="#color/Blue"
android:id="#+id/chooseButton"/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text = "Upload Photo!"
android:textColor="#color/colorPrimaryDark"
android:id="#+id/uploadButton"/>
</LinearLayout>
I have the following lines of code in MainActivity
package com.example.trump.demo_cameraapp;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnSuccessListener;
import com.google.firebase.storage.FirebaseStorage;
import com.google.firebase.storage.StorageReference;
import com.google.firebase.storage.UploadTask;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final int PICK_IMAGE_REQUEST = 1;
int TAKE_PHOTO_CODE = 0;
public static int count = 0;
private ImageView mImageView;
private StorageReference storage;
private ProgressDialog mProgressDialog;
public static final int GALLERY_INTENT = 2;
/**
* Called when the activity is first created.
*/
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// Here, we are making a folder named picFolder to store
// pics taken by the camera using this application.
mImageView = (ImageView) findViewById(R.id.imageView1);
Button choose = (Button) findViewById(R.id.chooseButton);
choose.setOnClickListener(this);
Button upload = (Button) findViewById(R.id.uploadButton);
upload.setOnClickListener(this);
}
private void showFileChooser(){
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"Select an image"),PICK_IMAGE_REQUEST);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data!=null && data.getData()!=null) {
Log.d("ResultOK", String.valueOf(RESULT_OK));
Log.d("CameraDemo", "Pic saved");
mProgressDialog.setMessage("Uploading...");
mProgressDialog.show();
Uri uri = data.getData();
try {
Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), uri);
mImageView.setImageBitmap(bitmap);
} catch (IOException e) {
e.printStackTrace();
}
StorageReference filepath = storage.child("images").child(uri.getLastPathSegment());
filepath.putFile(uri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>(){
#Override
public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
Toast.makeText(MainActivity.this, "Upload Successful", Toast.LENGTH_SHORT).show();
mProgressDialog.dismiss();
}
});
}
}
#Override
public void onClick(View view) {
if(view.getId() == R.id.chooseButton){
showFileChooser();
}else if(view.getId() == R.id.uploadButton){
}
}
}
I have not yet written codes to upload the image on firebase database. All I am trying to do right now is to display the image I picked from gallery in the imageview of my app. However, like I said before it's not displaying anything right now and as soon as I choose some photo from gallery it collapses. Any help regarding the issue would be very appreciated.
I think there is no issue with your image picker code, what i found a problem is that you are using mProgressDialog without initializing it in the onCreate() method. So what is recommend is that you first initialize mProgressDialog object in your onCreate() method right after you the initialization of mImageView. And i hope that your application will not collapse now.

Is there something that needs to be added to avoid memory leaks when switching between activities?

I'm trying to figure out how to have multiple activities with my application. I have striped it down to the lowest element to make it easy to see what I'm doing and understand my question.
When the program runs it shows a screen (activity) that says “Multiple Activities Example (screen1). It has a “Button 1” to click to see the next activity.
Clicking the Button 1 will take you to a different activity screen that says “Multiple Activities Example (screen2). It has a button 2 that when pressed will go back to screen1.
I was trying to figure out some type of return method to go back to the previous screen, but couldn't figure out any.
So, my concern/question is, is there some type of memory leak where using this method is going deeper into layers that require some type of return?
The code is attached.
MainActivity:
package apollo.MultipleActivities;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
public void button1_click(View v) {
Intent myIntent = new Intent(this, SecondActivity.class);
startActivity(myIntent);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Second Activity:
package apollo.MultipleActivities;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class SecondActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.secondactivity);
}
public void button2_click(View v) {
Intent myIntent = new Intent(this, MainActivity.class);
startActivity(myIntent);
}
}
Main Activity XML Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/screen1" />
<Button
android:id="#+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="#string/button1" android:onClick="button1_click"/>
</LinearLayout>
Second Activity XML Layout:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="#string/screen2" />
<Button
android:id="#+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="button2_click"
android:text="#string/button2" />
</LinearLayout>
Manifest file:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="apollo.MultipleActivities"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="19" />
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity
android:name="apollo.MultipleActivities.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=".SecondActivity"></activity>
</application>
</manifest>
The app runs perfect and do exactly what I'm trying to have it do. My concern is about the integrity of the overall Android. If the program stays running and is used a lot, am I in for memory leak crashes down the road.
Thanks!
I was trying to figure out some type of return method to go back to the previous screen, but couldn't figure out any.
Option #1: Call finish() instead of startActivity() in SecondActivity. This will destroy the current activity and return control to the preceding activity, which in this case is MainActivity.
Option #2: Add FLAG_ACTIVITY_REORDER_TO_FRONT on the Intent you use to start MainActivity from SecondActivity to bring the existing instance of MainActivity to the top of the back stack. Pressing BACK from there would return you to SecondActivity, which may not be what you have in mind.

Categories