BluetoothOppLauncherActivity.java 11.2 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
/*
 * Copyright (c) 2008-2009, Motorola, Inc.
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * - Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * - Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * - Neither the name of the Motorola, Inc. nor the names of its contributors
 * may be used to endorse or promote products derived from this software
 * without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

package com.android.bluetooth.opp;

Tao Liejun's avatar
Tao Liejun committed
35 36
import com.android.bluetooth.R;

37 38 39 40
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
41
import java.util.ArrayList;
42

43
import android.app.Activity;
Nick Pelly's avatar
Nick Pelly committed
44
import android.bluetooth.BluetoothDevice;
45
import android.bluetooth.BluetoothDevicePicker;
46
import android.content.Intent;
47
import android.content.ContentResolver;
48
import android.content.Context;
49 50 51 52 53 54 55
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.provider.Settings;

/**
 * This class is designed to act as the entry point of handling the share intent
Tao Liejun's avatar
Tao Liejun committed
56 57
 * via BT from other APPs. and also make "Bluetooth" available in sharing method
 * selection dialog.
58 59 60
 */
public class BluetoothOppLauncherActivity extends Activity {
    private static final String TAG = "BluetoothLauncherActivity";
Nick Pelly's avatar
Nick Pelly committed
61 62
    private static final boolean D = Constants.DEBUG;
    private static final boolean V = Constants.VERBOSE;
63 64 65 66 67 68 69

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Intent intent = getIntent();
        String action = intent.getAction();
Nick Pelly's avatar
Nick Pelly committed
70
        BluetoothDevice device = null;
Martijn Coenen's avatar
Martijn Coenen committed
71
        boolean isHandover = false;
72

Tao Liejun's avatar
Tao Liejun committed
73
        if (action.equals(Intent.ACTION_SEND) || action.equals(Intent.ACTION_SEND_MULTIPLE)) {
74 75 76 77 78
            /*
             * Other application is trying to share a file via Bluetooth,
             * probably Pictures, videos, or vCards. The Intent should contain
             * an EXTRA_STREAM with the data to attach.
             */
79 80 81 82
            if (intent.getBooleanExtra(Constants.EXTRA_CONNECTION_HANDOVER, false)) {
                device = (BluetoothDevice)intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                isHandover = true;
            }
83
            if (action.equals(Intent.ACTION_SEND)) {
84
                // TODO: handle type == null case
85 86
                String type = intent.getType();
                Uri stream = (Uri)intent.getParcelableExtra(Intent.EXTRA_STREAM);
87 88 89 90 91 92
                CharSequence extra_text = intent.getCharSequenceExtra(Intent.EXTRA_TEXT);
                // If we get ACTION_SEND intent with EXTRA_STREAM, we'll use the
                // uri data;
                // If we get ACTION_SEND intent without EXTRA_STREAM, but with
                // EXTRA_TEXT, we will try send this TEXT out; Currently in
                // Browser, share one link goes to this case;
93
                if (stream != null && type != null) {
Nick Pelly's avatar
Nick Pelly committed
94
                    if (V) Log.v(TAG, "Get ACTION_SEND intent: Uri = " + stream + "; mimetype = "
95 96 97 98
                                + type);
                    // Save type/stream, will be used when adding transfer
                    // session to DB.
                    BluetoothOppManager.getInstance(this).saveSendingFileInfo(type,
99
                            stream.toString(), isHandover);
100 101 102 103 104 105 106
                } else if (extra_text != null && type != null) {
                    if (V) Log.v(TAG, "Get ACTION_SEND intent with Extra_text = "
                                + extra_text.toString() + "; mimetype = " + type);
                    Uri fileUri = creatFileForSharedContent(this, extra_text);

                    if (fileUri != null) {
                        BluetoothOppManager.getInstance(this).saveSendingFileInfo(type,
107
                                fileUri.toString(), isHandover);
108
                    }
109
                } else {
Tao Liejun's avatar
Tao Liejun committed
110
                    Log.e(TAG, "type is null; or sending file URI is null");
111 112 113
                    finish();
                    return;
                }
Tao Liejun's avatar
Tao Liejun committed
114 115
            } else if (action.equals(Intent.ACTION_SEND_MULTIPLE)) {
                ArrayList<Uri> uris = new ArrayList<Uri>();
116
                String mimeType = intent.getType();
Tao Liejun's avatar
Tao Liejun committed
117
                uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
118
                if (mimeType != null && uris != null) {
Nick Pelly's avatar
Nick Pelly committed
119
                    if (V) Log.v(TAG, "Get ACTION_SHARE_MULTIPLE intent: uris " + uris + "\n Type= "
120
                                + mimeType);
121 122
                    BluetoothOppManager.getInstance(this).saveSendingFileInfo(mimeType,
                            uris, isHandover);
123
                } else {
Tao Liejun's avatar
Tao Liejun committed
124
                    Log.e(TAG, "type is null; or sending files URIs are null");
125 126 127 128 129
                    finish();
                    return;
                }
            }

130
            if (!isBluetoothAllowed()) {
131 132 133 134 135 136 137 138 139 140
                Intent in = new Intent(this, BluetoothOppBtErrorActivity.class);
                in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                in.putExtra("title", this.getString(R.string.airplane_error_title));
                in.putExtra("content", this.getString(R.string.airplane_error_msg));
                this.startActivity(in);

                finish();
                return;
            }

141
            // TODO: In the future, we may send intent to DevicePickerActivity
142 143 144
            // directly,
            // and let DevicePickerActivity to handle Bluetooth Enable.
            if (!BluetoothOppManager.getInstance(this).isEnabled()) {
Nick Pelly's avatar
Nick Pelly committed
145
                if (V) Log.v(TAG, "Prepare Enable BT!! ");
146 147 148
                Intent in = new Intent(this, BluetoothOppBtEnableActivity.class);
                in.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                this.startActivity(in);
Nick Pelly's avatar
Nick Pelly committed
149
            } else if (device == null) {
Nick Pelly's avatar
Nick Pelly committed
150
                if (V) Log.v(TAG, "BT already enabled!! ");
151
                Intent in1 = new Intent(BluetoothDevicePicker.ACTION_LAUNCH);
152
                in1.setFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
Tao Liejun's avatar
Tao Liejun committed
153
                in1.putExtra(BluetoothDevicePicker.EXTRA_NEED_AUTH, false);
154 155 156
                in1.putExtra(BluetoothDevicePicker.EXTRA_FILTER_TYPE,
                        BluetoothDevicePicker.FILTER_TYPE_TRANSFER);
                in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_PACKAGE,
Tao Liejun's avatar
Tao Liejun committed
157
                        Constants.THIS_PACKAGE_NAME);
158
                in1.putExtra(BluetoothDevicePicker.EXTRA_LAUNCH_CLASS,
Tao Liejun's avatar
Tao Liejun committed
159 160
                        BluetoothOppReceiver.class.getName());

161
                this.startActivity(in1);
Nick Pelly's avatar
Nick Pelly committed
162 163 164
            } else {
                // we already know where to send to
                BluetoothOppManager.getInstance(this).startTransfer(device);
165 166 167
            }
        } else if (action.equals(Constants.ACTION_OPEN)) {
            Uri uri = getIntent().getData();
Nick Pelly's avatar
Nick Pelly committed
168
            if (V) Log.v(TAG, "Get ACTION_OPEN intent: Uri = " + uri);
169 170 171 172 173 174 175 176 177 178

            Intent intent1 = new Intent();
            intent1.setAction(action);
            intent1.setClassName(Constants.THIS_PACKAGE_NAME, BluetoothOppReceiver.class.getName());
            intent1.setData(uri);
            this.sendBroadcast(intent1);
        }
        finish();
    }

179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209
    /* Returns true if Bluetooth is allowed given current airplane mode settings. */
    private final boolean isBluetoothAllowed() {
        final ContentResolver resolver = this.getContentResolver();

        // Check if airplane mode is on
        final boolean isAirplaneModeOn = Settings.System.getInt(resolver,
                Settings.System.AIRPLANE_MODE_ON, 0) == 1;
        if (!isAirplaneModeOn) {
            return true;
        }

        // Check if airplane mode matters
        final String airplaneModeRadios = Settings.System.getString(resolver,
                Settings.System.AIRPLANE_MODE_RADIOS);
        final boolean isAirplaneSensitive = airplaneModeRadios == null ? true :
                airplaneModeRadios.contains(Settings.System.RADIO_BLUETOOTH);
        if (!isAirplaneSensitive) {
            return true;
        }

        // Check if Bluetooth may be enabled in airplane mode
        final String airplaneModeToggleableRadios = Settings.System.getString(resolver,
                Settings.System.AIRPLANE_MODE_TOGGLEABLE_RADIOS);
        final boolean isAirplaneToggleable = airplaneModeToggleableRadios == null ? false :
                airplaneModeToggleableRadios.contains(Settings.System.RADIO_BLUETOOTH);
        if (isAirplaneToggleable) {
            return true;
        }

        // If we get here we're not allowed to use Bluetooth right now
        return false;
210
    }
211

212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
    private Uri creatFileForSharedContent(Context context, CharSequence shareContent) {
        if (shareContent == null) {
            return null;
        }

        Uri fileUri = null;
        FileOutputStream outStream = null;
        try {
            String fileName = getString(R.string.bluetooth_share_file_name) + ".html";
            context.deleteFile(fileName);

            String uri = shareContent.toString();
            String content = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html;"
                + " charset=UTF-8\"/></head><body>" + "<a href=\"" + uri + "\">" + uri + "</a></p>"
                + "</body></html>";
            byte[] byteBuff = content.getBytes();

            outStream = context.openFileOutput(fileName, Context.MODE_PRIVATE);
            if (outStream != null) {
                outStream.write(byteBuff, 0, byteBuff.length);
                fileUri = Uri.fromFile(new File(context.getFilesDir(), fileName));
                if (fileUri != null) {
                    if (D) Log.d(TAG, "Created one file for shared content: "
                            + fileUri.toString());
                }
            }
        } catch (FileNotFoundException e) {
            Log.e(TAG, "FileNotFoundException: " + e.toString());
            e.printStackTrace();
        } catch (IOException e) {
            Log.e(TAG, "IOException: " + e.toString());
        } catch (Exception e) {
            Log.e(TAG, "Exception: " + e.toString());
        } finally {
            try {
                if (outStream != null) {
                    outStream.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return fileUri;
    }
256
}